summaryrefslogtreecommitdiff
path: root/src/wallpaper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallpaper.c')
-rw-r--r--src/wallpaper.c242
1 files changed, 129 insertions, 113 deletions
diff --git a/src/wallpaper.c b/src/wallpaper.c
index 2f7810f..db14a8c 100644
--- a/src/wallpaper.c
+++ b/src/wallpaper.c
@@ -1,7 +1,7 @@
/* wallpaper.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2011 Daniel Friesel.
+Copyright (C) 2010-2018 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -24,12 +24,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <limits.h>
+#include <sys/stat.h>
+
#include "feh.h"
#include "filelist.h"
#include "options.h"
#include "wallpaper.h"
-#include <limits.h>
-#include <sys/stat.h>
+
Window ipc_win = None;
Window my_ipc_win = None;
Atom ipc_atom = None;
@@ -89,7 +91,7 @@ static void feh_wm_set_bg_scaled(Pixmap pmap, Imlib_Image im, int use_filelist,
feh_wm_load_next(&im);
gib_imlib_render_image_on_drawable_at_size(pmap, im, x, y, w, h,
- 1, 0, !opt.force_aliasing);
+ 1, 1, !opt.force_aliasing);
if (use_filelist)
gib_imlib_free_image_and_decache(im);
@@ -130,7 +132,7 @@ static void feh_wm_set_bg_centered(Pixmap pmap, Imlib_Image im, int use_filelist
y + ((offset_y > 0) ? offset_y : 0),
w,
h,
- 1, 0, 0);
+ 1, 1, 0);
if (use_filelist)
gib_imlib_free_image_and_decache(im);
@@ -158,11 +160,36 @@ static void feh_wm_set_bg_filled(Pixmap pmap, Imlib_Image im, int use_filelist,
render_x = ( cut_x ? ((img_w - render_w) >> 1) : 0);
render_y = ( !cut_x ? ((img_h - render_h) >> 1) : 0);
+ if ((opt.geom_flags & XValue) && cut_x) {
+ if (opt.geom_flags & XNegative) {
+ render_x = img_w - render_w + opt.geom_x;
+ } else {
+ render_x = opt.geom_x;
+ }
+ if (render_x < 0) {
+ render_x = 0;
+ } else if (render_x + render_w > img_w) {
+ render_x = img_w - render_w;
+ }
+ }
+ else if ((opt.geom_flags & YValue) && !cut_x) {
+ if (opt.geom_flags & YNegative) {
+ render_y = img_h - render_h + opt.geom_y;
+ } else {
+ render_y = opt.geom_y;
+ }
+ if (render_y < 0) {
+ render_y = 0;
+ } else if (render_y + render_h > img_h) {
+ render_y = img_h - render_h;
+ }
+ }
+
gib_imlib_render_image_part_on_drawable_at_size(pmap, im,
render_x, render_y,
render_w, render_h,
x, y, w, h,
- 1, 0, !opt.force_aliasing);
+ 1, 1, !opt.force_aliasing);
if (use_filelist)
gib_imlib_free_image_and_decache(im);
@@ -210,7 +237,7 @@ static void feh_wm_set_bg_maxed(Pixmap pmap, Imlib_Image im, int use_filelist,
gib_imlib_render_image_on_drawable_at_size(pmap, im,
render_x, render_y,
render_w, render_h,
- 1, 0, !opt.force_aliasing);
+ 1, 1, !opt.force_aliasing);
if (use_filelist)
gib_imlib_free_image_and_decache(im);
@@ -294,97 +321,30 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
unsigned long length, after;
unsigned char *data_root = NULL, *data_esetroot = NULL;
Pixmap pmap_d1, pmap_d2;
- gib_list *l;
- /* string for sticking in ~/.fehbg */
- char *fehbg = NULL;
- char fehbg_args[512];
- fehbg_args[0] = '\0';
- char *argptr = fehbg_args;
char *home;
- char filbuf[4096];
- char *bgfill = NULL;
- bgfill = opt.image_bg == IMAGE_BG_WHITE ? "--image-bg white" : "--image-bg black" ;
-
-#ifdef HAVE_LIBXINERAMA
- if (opt.xinerama) {
- if (opt.xinerama_index >= 0) {
- snprintf(argptr, sizeof(fehbg_args),
- "--xinerama-index %d", opt.xinerama_index);
- }
- }
- else
- snprintf(argptr, sizeof(fehbg_args), "--no-xinerama");
- argptr += strlen(argptr);
-#endif /* HAVE_LIBXINERAMA */
- if ((opt.geom_flags & XValue) && (sizeof(fehbg_args) - strlen(fehbg_args) > 60)) {
- snprintf(argptr, sizeof(fehbg_args) - strlen(fehbg_args), " --geometry %c%d",
- opt.geom_flags & XNegative ? '-' : '+',
- opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x);
- argptr += strlen(argptr);
- if (opt.geom_flags & YValue) {
- snprintf(argptr, sizeof(fehbg_args) - strlen(fehbg_args), "%c%d",
- opt.geom_flags & YNegative ? '-' : '+',
- opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y);
- argptr += strlen(argptr);
- }
- }
/* local display to set closedownmode on */
Display *disp2;
Window root2;
int depth2;
- int in, out, w, h;
+ int w, h;
D(("Falling back to XSetRootWindowPixmap\n"));
- /* Put the filename in filbuf between ' and escape ' in the filename */
- out = 0;
-
- if (fil && !use_filelist) {
- filbuf[out++] = '\'';
-
- fil = feh_absolute_path(fil);
-
- for (in = 0; fil[in] && out < 4092; in++) {
-
- if (fil[in] == '\'')
- filbuf[out++] = '\\';
- filbuf[out++] = fil[in];
- }
- filbuf[out++] = '\'';
- free(fil);
-
- } else {
- for (l = filelist; l && out < 4092; l = l->next) {
- filbuf[out++] = '\'';
-
- fil = feh_absolute_path(FEH_FILE(l->data)->filename);
-
- for (in = 0; fil[in] && out < 4092; in++) {
-
- if (fil[in] == '\'')
- filbuf[out++] = '\\';
- filbuf[out++] = fil[in];
- }
- filbuf[out++] = '\'';
- filbuf[out++] = ' ';
- free(fil);
- }
- }
-
-
- filbuf[out++] = 0;
+ XColor color;
+ Colormap cmap = DefaultColormap(disp, DefaultScreen(disp));
+ if (opt.image_bg)
+ XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color);
+ else
+ XAllocNamedColor(disp, cmap, "black", &color, &color);
if (scaled) {
pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth);
#ifdef HAVE_LIBXINERAMA
if (opt.xinerama_index >= 0) {
- if (opt.image_bg == IMAGE_BG_WHITE)
- gcval.foreground = WhitePixel(disp, DefaultScreen(disp));
- else
- gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
+ gcval.foreground = color.pixel;
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height);
XFreeGC(disp, gc);
@@ -403,16 +363,12 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
#endif /* HAVE_LIBXINERAMA */
feh_wm_set_bg_scaled(pmap_d1, im, use_filelist,
0, 0, scr->width, scr->height);
- fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-scale", filbuf, NULL);
} else if (centered) {
D(("centering\n"));
pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth);
- if (opt.image_bg == IMAGE_BG_WHITE)
- gcval.foreground = WhitePixel(disp, DefaultScreen(disp));
- else
- gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
+ gcval.foreground = color.pixel;
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height);
@@ -433,18 +389,13 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
XFreeGC(disp, gc);
- fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-center", filbuf, NULL);
-
} else if (filled == 1) {
pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth);
#ifdef HAVE_LIBXINERAMA
if (opt.xinerama_index >= 0) {
- if (opt.image_bg == IMAGE_BG_WHITE)
- gcval.foreground = WhitePixel(disp, DefaultScreen(disp));
- else
- gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
+ gcval.foreground = color.pixel;
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height);
XFreeGC(disp, gc);
@@ -464,15 +415,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
feh_wm_set_bg_filled(pmap_d1, im, use_filelist
, 0, 0, scr->width, scr->height);
- fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-fill", filbuf, NULL);
-
} else if (filled == 2) {
pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth);
- if (opt.image_bg == IMAGE_BG_WHITE)
- gcval.foreground = WhitePixel(disp, DefaultScreen(disp));
- else
- gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
+ gcval.foreground = color.pixel;
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height);
@@ -493,29 +439,85 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
XFreeGC(disp, gc);
- fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-max", filbuf, NULL);
-
} else {
if (use_filelist)
feh_wm_load_next(&im);
w = gib_imlib_image_get_width(im);
h = gib_imlib_image_get_height(im);
pmap_d1 = XCreatePixmap(disp, root, w, h, depth);
- gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 0, 0);
- fehbg = estrjoin(" ", "feh --bg-tile", filbuf, NULL);
+ gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 1, 0);
}
- if (fehbg && !opt.no_fehbg) {
+ if (!opt.no_fehbg) {
home = getenv("HOME");
if (home) {
FILE *fp;
char *path;
+ char *absolute_path;
struct stat s;
+ gib_list *filelist_pos = filelist;
path = estrjoin("/", home, ".fehbg", NULL);
if ((fp = fopen(path, "w")) == NULL) {
weprintf("Can't write to %s", path);
} else {
- fprintf(fp, "#!/bin/sh\n%s\n", fehbg);
+ fputs("#!/bin/sh\n", fp);
+ fputs(cmdargv[0], fp);
+ fputs(" --bg-", fp);
+ if (centered)
+ fputs("center", fp);
+ else if (scaled)
+ fputs("scale", fp);
+ else if (filled == 1)
+ fputs("fill", fp);
+ else if (filled == 2)
+ fputs("max", fp);
+ else
+ fputs("tile", fp);
+ if (opt.image_bg) {
+ fputs(" --image-bg ", fp);
+ fputs(shell_escape(opt.image_bg), fp);
+ }
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama) {
+ if (opt.xinerama_index >= 0) {
+ fprintf(fp, " --xinerama-index %d", opt.xinerama_index);
+ }
+ }
+ else {
+ fputs(" --no-xinerama", fp);
+ }
+#endif /* HAVE_LIBXINERAMA */
+ if (opt.geom_flags & XValue) {
+ fprintf(fp, " --geometry %c%d",
+ opt.geom_flags & XNegative ? '-' : '+',
+ opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x);
+ if (opt.geom_flags & YValue) {
+ fprintf(fp, "%c%d",
+ opt.geom_flags & YNegative ? '-' : '+',
+ opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y);
+ }
+ }
+ if (opt.force_aliasing) {
+ fputs(" --force-aliasing", fp);
+ }
+ fputc(' ', fp);
+ if (use_filelist) {
+ for (int i = 0; i < cmdargc; i++) {
+ if (filelist_pos && !strcmp(FEH_FILE(filelist_pos->data)->filename, cmdargv[i])) {
+ /* argument is a file */
+ absolute_path = feh_absolute_path(cmdargv[i]);
+ fputs(shell_escape(absolute_path), fp);
+ filelist_pos = filelist_pos->next;
+ free(absolute_path);
+ fputc(' ', fp);
+ }
+ }
+ } else if (fil) {
+ absolute_path = feh_absolute_path(fil);
+ fputs(shell_escape(absolute_path), fp);
+ free(absolute_path);
+ }
+ fputc('\n', fp);
fclose(fp);
stat(path, &s);
if (chmod(path, s.st_mode | S_IXUSR | S_IXGRP) != 0) {
@@ -525,8 +527,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
free(path);
}
}
-
- free(fehbg);
/* create new display, copy pixmap to new display */
disp2 = XOpenDisplay(NULL);
@@ -779,10 +779,11 @@ void enl_ipc_send(char *str)
return;
}
-static sighandler_t *enl_ipc_timeout(int sig)
+void enl_ipc_timeout(int sig)
{
- timeout = 1;
- return((sighandler_t *) sig);
+ if (sig == SIGALRM)
+ timeout = 1;
+ return;
}
char *enl_wait_for_reply(void)
@@ -842,7 +843,8 @@ char *enl_ipc_get(const char *msg_data)
char *enl_send_and_wait(char *msg)
{
char *reply = IPC_TIMEOUT;
- sighandler_t old_alrm;
+ struct sigaction e17_sh, feh_sh;
+ sigset_t e17_ss;
/*
* Shortcut this func and return IPC_FAKE
@@ -861,7 +863,19 @@ char *enl_send_and_wait(char *msg)
sleep(1);
}
}
- old_alrm = (sighandler_t) signal(SIGALRM, (sighandler_t) enl_ipc_timeout);
+
+ if ((sigemptyset(&e17_ss) == -1) || sigaddset(&e17_ss, SIGALRM) == -1) {
+ weprintf("Failed to set up temporary E17 signal masks");
+ return reply;
+ }
+ e17_sh.sa_handler = enl_ipc_timeout;
+ e17_sh.sa_mask = e17_ss;
+ e17_sh.sa_flags = 0;
+ if (sigaction(SIGALRM, &e17_sh, &feh_sh) == -1) {
+ weprintf("Failed to set up temporary E17 signal handler");
+ return reply;
+ }
+
for (; reply == IPC_TIMEOUT;) {
timeout = 0;
enl_ipc_send(msg);
@@ -873,6 +887,8 @@ char *enl_send_and_wait(char *msg)
ipc_win = None;
}
}
- signal(SIGALRM, old_alrm);
+ if (sigaction(SIGALRM, &feh_sh, NULL) == -1) {
+ weprintf("Failed to restore signal handler");
+ }
return(reply);
}