added dirchanger dmenu, dmenu search

This commit is contained in:
Alexander Bocken 2023-03-29 22:51:37 +02:00
parent 157646f54c
commit 7e957f8310
Signed by: Alexander
GPG Key ID: 1D237BE83F9B05E8
9 changed files with 239 additions and 50 deletions

View File

@ -98,6 +98,8 @@ install: all
mkdir -p $(DESTDIR)$(EGPREFIX)
cp etc/examples/* $(DESTDIR)$(EGPREFIX)
chmod 755 $(DESTDIR)$(EGPREFIX)/*
@echo "INSTALL bin/nsxiv-dirchanger"
cp nsxiv-dirchanger $(DESTDIR)$(PREFIX)/bin/
uninstall: uninstall-icon
@echo "REMOVE bin/nsxiv"
@ -108,4 +110,5 @@ uninstall: uninstall-icon
rm -f $(DESTDIR)$(PREFIX)/share/applications/nsxiv.desktop
@echo "REMOVE share/nsxiv/"
rm -rf $(DESTDIR)$(EGPREFIX)
@echo "REMOVE bin/nsxiv-dirchanger"
rm -rf $(DESTDIR)$(PREFIX)/bin/nsxiv-dirchanger

View File

@ -246,6 +246,50 @@ bool cg_change_contrast(arg_t d)
return change_color_modifier(d, &img.contrast);
}
bool cg_dmenu_search(arg_t _)
{
extern char nsxiv_xid[64];
extern const char *const dmenu_search_cmd[];
char output[4096];
int i, rfd, wfd, goto_img = -1;
ssize_t n;
snprintf(nsxiv_xid, sizeof nsxiv_xid, "0x%.8lX", win.xwin);
if (spawn(&rfd, &wfd, (char **)dmenu_search_cmd) < 0)
return false;
for (i = 0; i < filecnt; ++i) {
dprintf(wfd, "%s\n", files[i].name);
}
close(wfd);
if ((n = read(rfd, output, sizeof output - 1)) > 0) {
char *e = memchr(output, '\n', n);
if (e != NULL)
*e = '\0';
else
output[n] = '\0';
for (i = 0; i < filecnt; ++i) {
if (STREQ(output, files[i].name)) {
goto_img = i;
break;
}
}
}
close(rfd);
return navigate_to(goto_img);
}
bool cg_toggle_invert(arg_t _)
{
img.invert = !img.invert;
img_update_color_modifiers(&img);
if (mode == MODE_THUMB)
tns.dirty = true;
return true;
}
bool ci_navigate(arg_t n)
{
if (prefix > 0)
@ -478,3 +522,4 @@ bool ct_select(arg_t _)
return dirty;
}

View File

@ -6,6 +6,7 @@
bool cg_change_gamma(arg_t);
bool cg_change_brightness(arg_t);
bool cg_change_contrast(arg_t);
bool cg_toggle_invert(arg_t);
bool cg_first(arg_t);
bool cg_mark_range(arg_t);
bool cg_n_or_last(arg_t);
@ -22,6 +23,8 @@ bool cg_toggle_fullscreen(arg_t);
bool cg_toggle_image_mark(arg_t);
bool cg_unmark_all(arg_t);
bool cg_zoom(arg_t);
bool cg_dmenu_search(arg_t);
bool cg_dmenu_cd(arg_t);
/* image mode */
bool ci_alternate(arg_t);
bool ci_cursor_navigate(arg_t);
@ -51,6 +54,7 @@ bool ct_select(arg_t);
#define g_change_gamma { cg_change_gamma, MODE_ALL }
#define g_change_brightness { cg_change_brightness, MODE_ALL }
#define g_change_contrast { cg_change_contrast, MODE_ALL }
#define g_toggle_invert { cg_toggle_invert, MODE_ALL }
#define g_first { cg_first, MODE_ALL }
#define g_mark_range { cg_mark_range, MODE_ALL }
#define g_n_or_last { cg_n_or_last, MODE_ALL }
@ -67,6 +71,8 @@ bool ct_select(arg_t);
#define g_toggle_image_mark { cg_toggle_image_mark, MODE_ALL }
#define g_unmark_all { cg_unmark_all, MODE_ALL }
#define g_zoom { cg_zoom, MODE_ALL }
#define g_dmenu_search { cg_dmenu_search, MODE_ALL }
#define g_dmenu_cd { cg_dmenu_cd, MODE_ALL }
/* image mode */
#define i_alternate { ci_alternate, MODE_IMAGE }
@ -95,3 +101,4 @@ bool ct_select(arg_t);
#endif /* _MAPPINGS_CONFIG */
#endif /* COMMANDS_H */

View File

@ -13,7 +13,7 @@ static const char *DEFAULT_MARK_COLOR = NULL; /* NULL means it will default to
#if HAVE_LIBFONTS
static const char *DEFAULT_BAR_BG = NULL; /* NULL means it will default to window background */
static const char *DEFAULT_BAR_FG = NULL; /* NULL means it will default to window foreground */
static const char *DEFAULT_FONT = "monospace-8";
static const char *DEFAULT_FONT = "monospace-12";
/* if true, statusbar appears on top of the window */
static const bool TOP_STATUSBAR = false;
@ -82,12 +82,18 @@ static const int THUMB_SIZE = 3;
#endif
#ifdef INCLUDE_MAPPINGS_CONFIG
char nsxiv_xid[64]; /* will be set to nsxiv's xid when dmenu_search is invoked */
const char *const dmenu_search_cmd[] = {
"dmenu", "-l", "16", "-i", NULL
};
const char *const dmenu_cd_cmd[] = {
"nsxiv-dirchanger", NULL
};
/* these modifiers will be used when processing keybindings */
static const unsigned int USED_MODMASK = ShiftMask | ControlMask | Mod1Mask;
/* abort the keyhandler */
static const KeySym KEYHANDLER_ABORT = XK_Escape;
/* keyboard mappings for image and thumbnail mode: */
static const keymap_t keys[] = {
/* modifiers key function argument */
@ -100,6 +106,8 @@ static const keymap_t keys[] = {
{ 0, XK_G, g_n_or_last, None },
{ 0, XK_r, g_reload_image, None },
{ 0, XK_D, g_remove_image, None },
{ 0, XK_slash, g_dmenu_search, None },
{ ControlMask, XK_d, g_dmenu_cd, None},
{ ControlMask, XK_h, g_scroll_screen, DIR_LEFT },
{ ControlMask, XK_Left, g_scroll_screen, DIR_LEFT },
{ ControlMask, XK_j, g_scroll_screen, DIR_DOWN },
@ -125,6 +133,7 @@ static const keymap_t keys[] = {
{ ControlMask, XK_bracketleft, g_change_brightness, -1 },
{ 0, XK_parenleft, g_change_contrast, -1 },
{ 0, XK_parenright, g_change_contrast, +1 },
{ 0, XK_i, g_toggle_invert, None },
{ 0, XK_h, t_move_sel, DIR_LEFT },
{ 0, XK_Left, t_move_sel, DIR_LEFT },
@ -211,3 +220,4 @@ static const cursor_t imgcursor[3] = {
};
#endif

126
image.c
View File

@ -101,6 +101,7 @@ void img_init(img_t *img, win_t *win)
imlib_context_set_color_modifier(img->cmod);
img->brightness = 0;
img->contrast = 0;
img->invert = false;
img_change_color_modifier(img, options->gamma, &img->gamma);
img->ss.on = options->slideshow > 0;
@ -702,12 +703,81 @@ static bool img_fit(img_t *img)
}
}
void render_core(win_t* win, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh,
bool alpha)
{
Imlib_Image im, bg, bbg;
Imlib_Color_Modifier cmod;
XColor c;
if (imlib_image_has_alpha()) {
im = imlib_context_get_image();
cmod = imlib_context_get_color_modifier();
if ((bg = imlib_create_image(dw, dh)) == NULL)
error(EXIT_FAILURE, ENOMEM, NULL);
imlib_context_set_image(bg);
imlib_image_set_has_alpha(1);
if (alpha) {
int i, c, r;
DATA32 col[2] = { 0xFF666666, 0xFF999999 };
DATA32 * data = imlib_image_get_data();
for (r = 0; r < dh; r++) {
i = r * dw;
if (r == 0 || r == 8) {
for (c = 0; c < dw; c++)
data[i++] = col[!(c & 8) ^ !r];
} else {
memcpy(&data[i], &data[(r & 8) * dw], dw * sizeof(data[0]));
}
}
imlib_image_put_back_data(data);
} else {
imlib_image_clear();
c = win->win_bg_postmul;
imlib_context_set_color(c.red >> 8, c.green >> 8, c.blue >> 8,
win->win_alpha);
imlib_image_fill_rectangle(0, 0, dw, dh);
}
imlib_blend_image_onto_image(im, 1, sx, sy, sw, sh, 0, 0, dw, dh);
imlib_context_set_color_modifier(NULL);
if (!alpha && win->win_alpha < 0xFF) {
/* blend onto black to get premultiplied alpha */
if ((bbg = imlib_create_image(dw, dh)) == NULL)
error(EXIT_FAILURE, ENOMEM, NULL);
imlib_context_set_image(bbg);
imlib_image_set_has_alpha(1);
imlib_context_set_color(0, 0, 0, 0xFF);
imlib_image_fill_rectangle(0, 0, dw, dh);
imlib_blend_image_onto_image(bg, 1, 0, 0, dw, dh, 0, 0, dw, dh);
imlib_image_copy_alpha_to_image(bg, 0, 0);
imlib_context_set_image(bg);
imlib_free_image();
imlib_context_set_image(bbg);
}
imlib_context_set_blend(0);
imlib_render_image_on_drawable(dx, dy);
imlib_context_set_blend(1);
imlib_free_image();
imlib_context_set_color_modifier(cmod);
} else {
imlib_image_set_has_alpha(1);
imlib_context_set_blend(0);
imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw, dh);
imlib_context_set_blend(1);
}
}
void img_render(img_t *img)
{
win_t *win;
int sx, sy, sw, sh;
int dx, dy, dw, dh;
Imlib_Image bg;
win = img->win;
img_fit(img);
@ -756,45 +826,7 @@ void img_render(img_t *img)
/* manual blending, for performance reasons.
* see https://phab.enlightenment.org/T8969#156167 for more details.
*/
if (imlib_image_has_alpha()) {
if ((bg = imlib_create_image(dw, dh)) == NULL) {
error(0, ENOMEM, "Failed to create image");
goto fallback;
}
imlib_context_set_image(bg);
imlib_image_set_has_alpha(0);
if (img->alpha_layer) {
int i, c, r;
uint32_t col[2] = { 0xFF666666, 0xFF999999 };
uint32_t *data = imlib_image_get_data();
for (r = 0; r < dh; r++) {
i = r * dw;
if (r == 0 || r == 8) {
for (c = 0; c < dw; c++)
data[i++] = col[!(c & 8) ^ !r];
} else {
memcpy(&data[i], &data[(r & 8) * dw], dw * sizeof(data[0]));
}
}
imlib_image_put_back_data(data);
} else {
XColor c = win->win_bg;
imlib_context_set_color(c.red >> 8, c.green >> 8, c.blue >> 8, 0xFF);
imlib_image_fill_rectangle(0, 0, dw, dh);
}
imlib_context_set_blend(1);
imlib_context_set_operation(IMLIB_OP_COPY);
imlib_blend_image_onto_image(img->im, 0, sx, sy, sw, sh, 0, 0, dw, dh);
imlib_context_set_color_modifier(NULL);
imlib_render_image_on_drawable(dx, dy);
imlib_free_image();
imlib_context_set_color_modifier(img->cmod);
} else {
fallback:
imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw, dh);
}
render_core(win, sx, sy, sw, sh, dx, dy, dw, dh, img->alpha);
img->dirty = false;
}
@ -1016,6 +1048,19 @@ void img_update_color_modifiers(img_t *img)
if (img->contrast != 0)
imlib_modify_color_modifier_contrast(steps_to_range(img->contrast, CONTRAST_MAX, 1.0));
if (img->invert) {
size_t i;
uint8_t r[256], g[256], b[256], a[256];
imlib_get_color_modifier_tables(r, g, b, a);
for (i = 0; i < ARRLEN(r); i++) {
r[i] = 255 - r[i];
g[i] = 255 - g[i];
b[i] = 255 - b[i];
}
imlib_set_color_modifier_tables(r, g, b, a);
}
img->dirty = true;
}
@ -1066,3 +1111,4 @@ bool img_frame_animate(img_t *img)
else
return false;
}

44
main.c
View File

@ -150,7 +150,6 @@ static void check_add_file(const char *filename, bool given)
files[fileidx].flags |= FF_WARN;
fileidx++;
}
static void add_entry(const char *entry_name)
{
int start;
@ -180,6 +179,15 @@ static void add_entry(const char *entry_name)
}
}
void add_entry_test(){
char * filename = "/home/alex/dls/pix/Wien_-_Michaelerkirche,_Hochaltar.JPG";
fprintf(stdout, "Trying to add file %s to entries\n", filename);
add_entry(filename);
filecnt = fileidx;
fileidx = options->startnum < filecnt ? options->startnum : 0;
cg_reload_image(MODE_ALL);
}
void remove_file(int n, bool manual)
{
if (n < 0 || n >= filecnt)
@ -953,3 +961,37 @@ int main(int argc, char *argv[])
return 0;
}
bool cg_dmenu_cd(arg_t _){
extern char nsxiv_xid[64];
extern const char *const dmenu_cd_cmd[];
char output[4096];
int i, rfd, wfd, goto_img = -1;
ssize_t n;
snprintf(nsxiv_xid, sizeof nsxiv_xid, "0x%.8lX", win.xwin);
if (spawn(&rfd, &wfd, (char **)dmenu_cd_cmd) < 0)
return false;
for (i = 0; i < filecnt; ++i) {
dprintf(wfd, "%s\n", files[i].name);
}
close(wfd);
if ((n = read(rfd, output, sizeof output - 1)) > 0) {
char *e = memchr(output, '\n', n);
if (e != NULL)
*e = '\0';
else
output[n] = '\0';
fprintf(stdout, "Trying to add file %s to entries\n", output);
add_entry(output);
filecnt = fileidx;
fileidx = options->startnum < filecnt ? options->startnum : 0;
cg_reload_image(MODE_ALL);
}
close(rfd);
return True;
}

View File

@ -178,11 +178,13 @@ struct img {
win_t *win;
float x;
float y;
float alpha;
Imlib_Color_Modifier cmod;
int gamma;
int brightness;
int contrast;
bool invert;
scalemode_t scalemode;
float zoom;
@ -218,6 +220,7 @@ void img_update_color_modifiers(img_t*);
bool img_change_color_modifier(img_t*, int, int*);
bool img_frame_navigate(img_t*, int);
bool img_frame_animate(img_t*);
void render_core(win_t*, int, int, int, int, int, int, int, int, bool);
Imlib_Image img_open(const fileinfo_t*);
#if HAVE_LIBEXIF
void exif_auto_orientate(const fileinfo_t*);
@ -382,9 +385,11 @@ struct win {
Window xwin;
win_env_t env;
XColor win_bg;
XColor win_bg; /* pre-multiplied alpha */
XColor win_bg_postmul; /* post-multiplied alpha */
XColor win_fg;
XColor mrk_fg;
unsigned int win_alpha;
#if HAVE_LIBFONTS
XftColor bar_bg;
XftColor bar_fg;
@ -455,3 +460,4 @@ extern int prefix;
extern bool title_dirty;
#endif /* NSXIV_H */

View File

@ -442,7 +442,7 @@ void tns_render(tns_t *tns)
t->x = x + (thumb_sizes[tns->zl] - t->w) / 2;
t->y = y + (thumb_sizes[tns->zl] - t->h) / 2;
imlib_context_set_image(t->im);
imlib_render_image_on_drawable_at_size(t->x, t->y, t->w, t->h);
render_core(win, 0, 0, t->w, t->h, t->x, t->y, t->w, t->h, false);
if (tns->files[i].flags & FF_MARK)
tns_mark(tns, i, true);
} else {

View File

@ -112,9 +112,12 @@ static const char *win_res(XrmDatabase db, const char *name, const char *def)
void win_init(win_t *win)
{
win_env_t *e;
const char *win_bg, *win_fg, *mrk_fg;
const char *win_bg, *win_fg, *mrk_fg, *win_alpha;
char *res_man;
XrmDatabase db;
XVisualInfo vis;
float alpha;
char *endptr;
#if HAVE_LIBFONTS
const char *bar_fg, *bar_bg, *f;
@ -130,9 +133,16 @@ 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);
e->depth = DefaultDepth(e->dpy, e->scr);
e->vis = DefaultVisual(e->dpy, e->scr);
e->cmap = DefaultColormap(e->dpy, e->scr);
if (XMatchVisualInfo(e->dpy, e->scr, 32, TrueColor, &vis)) {
e->depth = 32;
e->vis = vis.visual;
e->cmap = XCreateColormap(e->dpy, DefaultRootWindow(e->dpy), e->vis, None);
} else {
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");
@ -148,6 +158,25 @@ void win_init(win_t *win)
win_alloc_color(e, win_fg, &win->win_fg);
win_alloc_color(e, mrk_fg, &win->mrk_fg);
/* apply alpha */
win->win_bg_postmul = win->win_bg;
win_alpha = win_res(db, RES_CLASS ".window.alpha", "1.0");
alpha = strtof(win_alpha, &endptr);
if (!(*endptr == '\0' && alpha >= 0.0 && alpha <= 1.0))
error(EXIT_FAILURE, 0, "Error parsing alpha");
win->win_alpha = 0xFF;
if (e->depth == 32 && alpha < 1.0) {
win->win_alpha *= alpha;
win->win_bg.red *= alpha;
win->win_bg.green *= alpha;
win->win_bg.blue *= alpha;
win->win_bg.pixel =
(((unsigned long) win->win_bg.blue >> 8) << 0) |
(((unsigned long) win->win_bg.green >> 8) << 8) |
(((unsigned long) win->win_bg.red >> 8) << 16) |
(((unsigned long) win->win_alpha ) << 24);
}
#if HAVE_LIBFONTS
bar_bg = win_res(db, RES_CLASS ".bar.background", DEFAULT_BAR_BG ? DEFAULT_BAR_BG : win_bg);
bar_fg = win_res(db, RES_CLASS ".bar.foreground", DEFAULT_BAR_FG ? DEFAULT_BAR_FG : win_fg);
@ -543,3 +572,4 @@ void win_cursor_pos(win_t *win, int *x, int *y)
if (!XQueryPointer(win->env.dpy, win->xwin, &w, &w, &i, &i, x, y, &ui))
*x = *y = 0;
}