/*
 * slaxsetroot -- Set the root pixmap. Source code forked from Esetroot
 * Esetroot was Written by Nat Friedman <ndf@mit.edu> with modifications by Gerald Britton <gbritton@mit.edu> and Michael Jennings <mej@eterm.org>
 * esetroot cvs_ident[] = "$Id: Esetroot.c,v 1.17 2003/04/22 15:14:20 mej Exp $";
 *
 * slaxsetroot was written by Tomas M <http://www.slax.org/>
 * Needs imlib2 and freetype2, don't ask me why
 * imlib2 needs libjpeg, etc.
 */

#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>

#ifdef PIXMAP_SUPPORT
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xos.h>
#include <Imlib2.h>

void set_pixmap_property(Pixmap p);

Display *Xdisplay;
Screen *scr;
Window Xroot;
int screen;

#define Xdepth	 (DefaultDepth(Xdisplay, screen))

void
set_pixmap_property(Pixmap p)
{

    Atom prop_root, prop_esetroot, type;
    int format;
    unsigned long length, after;
    unsigned char *data_root, *data_esetroot;

    prop_root = XInternAtom(Xdisplay, "_XROOTPMAP_ID", True);
    prop_esetroot = XInternAtom(Xdisplay, "ESETROOT_PMAP_ID", True);

    if (prop_root != None && prop_esetroot != None) {
        XGetWindowProperty(Xdisplay, Xroot, prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root);
        if (type == XA_PIXMAP) {
            XGetWindowProperty(Xdisplay, Xroot, prop_esetroot, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_esetroot);
            if (data_root && data_esetroot) {
                if (type == XA_PIXMAP && *((Pixmap *) data_root) == *((Pixmap *) data_esetroot)) {
                    XKillClient(Xdisplay, *((Pixmap *) data_root));
                }
            }
        }
    }
    /* This will locate the property, creating it if it doesn't exist */
    prop_root = XInternAtom(Xdisplay, "_XROOTPMAP_ID", False);
    prop_esetroot = XInternAtom(Xdisplay, "ESETROOT_PMAP_ID", False);

    /* The call above should have created it.  If that failed, we can't continue. */
    if (prop_root == None || prop_esetroot == None) {
        fprintf(stderr, "Esetroot:  creation of pixmap property failed.\n");
        exit(1);
    }
    XChangeProperty(Xdisplay, Xroot, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &p, 1);
    XChangeProperty(Xdisplay, Xroot, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &p, 1);
    XSetCloseDownMode(Xdisplay, RetainPermanent);
    XFlush(Xdisplay);
}
#endif

int
main(int argc, char *argv[])
{
#ifdef PIXMAP_SUPPORT
    unsigned char fit = 1;
    char *displayname = NULL, *fname = NULL, *bgcolor = NULL;
    Imlib_Image im;
    Pixmap p = None, temp_pmap = None, m = None;
    register unsigned char i;
    GC gc;
    XGCValues gcv;
    XColor xcolor;
    int w, h, x, y;

    if (argc < 2) {
        fprintf(stderr, "%s [-display <display_name>] pixmap\n", *argv);
        exit(0);
    }
    for (i = 1; i < argc; i++) {
        if (*argv[i] != '-') {
            break;
        }
        if (argv[i][1] == 'd') {
            displayname = argv[++i];
        } else {
            fprintf(stderr, "%s:  Unrecognized option \'%c\'\n\n", *argv, argv[i][1]);
            fprintf(stderr, "%s [-display <display_name>] pixmap\n", *argv);
            exit(2);
        }
    }

    fname = argv[i];

    if (!displayname) {
        displayname = getenv("DISPLAY");
    }
    if (!displayname) {
        displayname = ":0.0";
    }
    if ((Xdisplay = XOpenDisplay(displayname)) == 0) {
        fprintf(stderr, "%s:  Unable to open display %s\n", *argv, displayname);
        exit(1);
    }
    screen = DefaultScreen(Xdisplay);
    Xroot = RootWindow(Xdisplay, screen);
    scr = ScreenOfDisplay(Xdisplay, screen);
    imlib_context_set_display(Xdisplay);
    imlib_context_set_visual(DefaultVisual(Xdisplay, DefaultScreen(Xdisplay)));
    im = imlib_load_image_immediately(fname);
    if (im == NULL) {
        fprintf(stderr, "%s:  Unable to load image file \"%s\".\n", *argv, fname);
        exit(1);
    }
    imlib_context_set_image(im);

    p = XCreatePixmap(Xdisplay, Xroot, scr->width, scr->height, Xdepth);
    gcv.foreground = gcv.background = BlackPixel(Xdisplay, screen);
    if (bgcolor && XParseColor(Xdisplay, DefaultColormap(Xdisplay, screen), bgcolor, &xcolor)
        && XAllocColor(Xdisplay, DefaultColormap(Xdisplay, screen), &xcolor)) {
        gcv.foreground = gcv.background = xcolor.pixel;
    }
    gc = XCreateGC(Xdisplay, p, (GCForeground | GCBackground), &gcv);
    XFillRectangle(Xdisplay, p, gc, 0, 0, scr->width, scr->height);

    // regardless of parameters, set it always to scale+fit+crop

    int im_w, im_h;
    im_w = imlib_image_get_width();
    im_h = imlib_image_get_height();

    if ( (double) im_w/im_h < (double) scr->width / scr->height )
    {
       w = (int) scr->width;
       h = (int) (im_h * scr->width / im_w);
       x = 0;
       y = (int) ((scr->height - h) / 2);
    }
    else
    {
       w = (int) (im_w * scr->height / im_h);
       h = (int) scr->height;
       x = (int) ((scr->width - w) / 2);
       y = 0;
    }


    imlib_context_set_anti_alias(1);
    imlib_context_set_dither(1);
    imlib_context_set_blend(0);
    imlib_context_set_drawable(Xroot);
    imlib_render_pixmaps_for_whole_image_at_size(&temp_pmap, &m, w, h);

    if (temp_pmap != None) {
        if (m) {
            XFreePixmap(Xdisplay, m);
            m = None;
        }
        XSetTile(Xdisplay, gc, temp_pmap);
        XSetTSOrigin(Xdisplay, gc, x, y);
        XSetFillStyle(Xdisplay, gc, FillTiled);
        XFillRectangle(Xdisplay, p, gc, x, y, w, h);
        XGrabServer(Xdisplay);
        set_pixmap_property(p);
        XSetWindowBackgroundPixmap(Xdisplay, Xroot, p);
        XClearWindow(Xdisplay, Xroot);
        XUngrabServer(Xdisplay);
        XFlush(Xdisplay);
    }
#else
    USE_VAR(argc);
    USE_VAR(argv);
    fprintf(stderr, "Eterm was built without pixmap support, so Esetroot is fairly useless.  Sorry.\n");
#endif
    return 0;
}
