From cd710f583f5ab8650fa2e41c08dc9a6332a5680f Mon Sep 17 00:00:00 2001 From: miseran Date: Tue, 12 Oct 2021 01:46:35 +0200 Subject: [PATCH] Fix behaviour when TrueColor / 24 bit depth is not available (#114) * Fix regression introduced in c7ca547 which made nsxiv not start in non-TrueColor X server. * Introduce a new fix for embedding into tabbed-alpha. * Fixes a visual glitch from original sxiv when drawing transparent images in 8 bit depth. In 8 bit PseudoColor, `.pixel` is just an index into the 256 defined colors and thus trying to extract rgb bits from it would result in visual glitch. The values `.color.red` on the other hand and so on are always integers between 0 and 0xFFFF representing the color as expected. * Use XColor for win_bg/fg and mrk_fg Co-authored-by: NRK --- image.c | 4 ++-- nsxiv.h | 6 +++--- thumbs.c | 8 ++++---- window.c | 39 +++++++++++++++------------------------ 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/image.c b/image.c index 0349d12..69f9049 100644 --- a/image.c +++ b/image.c @@ -577,7 +577,7 @@ void img_render(img_t *img) int sx, sy, sw, sh; int dx, dy, dw, dh; Imlib_Image bg; - unsigned long c; + XColor c; win = img->win; img_fit(img); @@ -646,7 +646,7 @@ void img_render(img_t *img) imlib_image_put_back_data(data); } else { c = win->win_bg; - imlib_context_set_color(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF, 0xFF); + imlib_context_set_color(c.red >> 8, c.green >> 8, c.blue >> 8, 0xFF); imlib_image_fill_rectangle(0, 0, dw, dh); } imlib_blend_image_onto_image(img->im, 0, sx, sy, sw, sh, 0, 0, dw, dh); diff --git a/nsxiv.h b/nsxiv.h index 6ae2289..d65875b 100644 --- a/nsxiv.h +++ b/nsxiv.h @@ -416,9 +416,9 @@ struct win { Window xwin; win_env_t env; - unsigned long win_bg; - unsigned long win_fg; - unsigned long mrk_fg; + XColor win_bg; + XColor win_fg; + XColor mrk_fg; #if HAVE_LIBFONTS XftColor bar_bg; XftColor bar_fg; diff --git a/thumbs.c b/thumbs.c index c9e92b7..7e2415c 100644 --- a/thumbs.c +++ b/thumbs.c @@ -44,7 +44,7 @@ char* tns_cache_filepath(const char *filepath) if (*filepath != '/') return NULL; - + if (strncmp(filepath, cache_dir, strlen(cache_dir)) != 0) { /* don't cache images inside the cache directory! */ len = strlen(cache_dir) + strlen(filepath) + 2; @@ -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->win_bg; + unsigned long col = win->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->mrk_fg; + col = win->mrk_fg.pixel; win_draw_rect(win, x, y, tns->bw + 2, tns->bw + 2, true, 1, col); @@ -490,7 +490,7 @@ 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->win_fg : win->win_bg; + unsigned long col = hl ? win->win_fg.pixel : win->win_bg.pixel; int oxy = (tns->bw + 1) / 2 + 1, owh = tns->bw + 2; win_draw_rect(win, t->x - oxy, t->y - oxy, t->w + owh, t->h + owh, diff --git a/window.c b/window.c index 9f22fba..5e1392f 100644 --- a/window.c +++ b/window.c @@ -80,12 +80,11 @@ void xft_alloc_color(const win_env_t *e, const char *name, XftColor *col) } #endif /* HAVE_LIBFONTS */ -void win_alloc_color(const win_env_t *e, const char *name, unsigned long *pixel) +void win_alloc_color(const win_env_t *e, const char *name, XColor *col) { - XColor screen, exact; - if (!XAllocNamedColor(e->dpy, e->cmap, name, &screen, &exact)) + XColor screen; + if (!XAllocNamedColor(e->dpy, e->cmap, name, &screen, col)) error(EXIT_FAILURE, 0, "Error allocating color '%s'", name); - *pixel = exact.pixel; } const char* win_res(XrmDatabase db, const char *name, const char *def) @@ -112,9 +111,6 @@ void win_init(win_t *win) #endif char *res_man; XrmDatabase db; - XVisualInfo vis; - XWindowAttributes attr; - Window parent; memset(win, 0, sizeof(win_t)); @@ -125,19 +121,9 @@ void win_init(win_t *win) e->scr = DefaultScreen(e->dpy); e->scrw = DisplayWidth(e->dpy, e->scr); e->scrh = DisplayHeight(e->dpy, e->scr); - - parent = options->embed != 0 ? options->embed : RootWindow(e->dpy, e->scr); - - if (options->embed == 0) { - e->depth = DefaultDepth(e->dpy, e->scr); - } else { - XGetWindowAttributes(e->dpy, parent, &attr); - e->depth = attr.depth; - } - - XMatchVisualInfo(e->dpy, e->scr, e->depth, TrueColor, &vis); - e->vis = vis.visual; - e->cmap = XCreateColormap(e->dpy, parent, e->vis, None); + e->depth = DefaultDepth(e->dpy, e->scr); + e->vis = DefaultVisual(e->dpy, e->scr); + e->cmap = DefaultColormap(e->dpy, e->scr); if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0) error(0, 0, "No locale support"); @@ -197,6 +183,7 @@ void win_open(win_t *win) XWMHints hints; pid_t pid; char hostname[256]; + XSetWindowAttributes attrs; e = &win->env; parent = options->embed != 0 ? options->embed : RootWindow(e->dpy, e->scr); @@ -238,8 +225,12 @@ void win_open(win_t *win) win->y = 0; } + attrs.colormap = e->cmap; + attrs.border_pixel = 0; + win->xwin = XCreateWindow(e->dpy, parent, win->x, win->y, win->w, win->h, 0, - e->depth, InputOutput, e->vis, 0, NULL); + e->depth, InputOutput, e->vis, + CWColormap | CWBorderPixel, &attrs); if (win->xwin == None) error(EXIT_FAILURE, 0, "Error creating X window"); @@ -317,7 +308,7 @@ 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->win_bg); + XSetForeground(e->dpy, gc, win->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); @@ -398,7 +389,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->win_bg); + XSetForeground(e->dpy, gc, win->win_bg.pixel); XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); } @@ -455,7 +446,7 @@ void win_draw_bar(win_t *win) XSetForeground(e->dpy, gc, win->bar_bg.pixel); XFillRectangle(e->dpy, win->buf.pm, gc, 0, win->h, win->w, win->bar.h); - XSetForeground(e->dpy, gc, win->win_bg); + XSetForeground(e->dpy, gc, win->win_bg.pixel); XSetBackground(e->dpy, gc, win->bar_bg.pixel); if ((len = strlen(r->buf)) > 0) {