/* xwpset, a simple Xinerama wallpaper setting tool
 * Copyright (C) 2003 James Curbo <james@teyandei.net>
 * Licensed under the GNU General Public License v2.
 *
 * A little bit modified by Jérémy Bobbio <lunar@debian.org>
 */


#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xinerama.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

GdkPixmap *make_root_pixmap(GdkScreen *screen, gint width, gint height);
void set_root_pixmap(GdkPixmap *pixmap, GdkScreen *screen);

int main(int argc, char **argv)
{
	GdkWindow *root;
	GdkScreen *screen;
	GdkGC *gc;
	gint w, h;
	XineramaScreenInfo *xinerama_info = NULL;
	gint xinerama_info_num = 0;

	GdkPixbuf *w1 = NULL, *w2 = NULL;

	GdkPixmap *pixmap;

	int i;
	int event_base, error_base;
	int xinerama;
	
	Display *dpy = XOpenDisplay(NULL);
	assert(dpy);

	if (argc < 3) {
		printf("Usage: xwpset image1 image2\n");
		exit(EXIT_FAILURE);
	}
	
	gdk_init(&argc, &argv);
	
	screen = gdk_screen_get_default();
	root = gdk_screen_get_root_window(screen);

	gdk_window_clear(root);

	if (root == NULL) {
		g_error("Couldn't get root window.");
	}

	gdk_drawable_get_size(root, &w, &h);

	printf("size of root window: %d x %d\n", w, h);

	xinerama = XineramaQueryExtension(dpy, &event_base, &error_base);
	if (xinerama) {
		xinerama = XineramaIsActive(dpy);
		xinerama_info = XineramaQueryScreens(dpy, &xinerama_info_num);
	}

	printf("This Xserver has %d Xinerama screens.\n", xinerama_info_num);

	for(i=0; i<xinerama_info_num; i++) {
		printf("Xinerama screen %d characteristics:\n",
				xinerama_info[i].screen_number);
		printf("X origin: %d\n", xinerama_info[i].x_org);
		printf("Y origin: %d\n", xinerama_info[i].y_org);
		printf("width: %d\n", xinerama_info[i].width);
		printf("height: %d\n", xinerama_info[i].height);
	}


        w1 = gdk_pixbuf_new_from_file_at_scale(argv[1], xinerama_info[0].width,
                                               xinerama_info[0].height, TRUE, NULL);
	if (w1 == NULL) {
		perror("problem reading file 1");
		exit(EXIT_FAILURE);
	}

	printf("width: %d height %d\n",
			gdk_pixbuf_get_width(w1),
			gdk_pixbuf_get_height(w1));
	
        w2 = gdk_pixbuf_new_from_file_at_scale(argv[2], xinerama_info[1].width,
                                               xinerama_info[1].height, TRUE, NULL);
	if (w2 == NULL) {
		perror("problem reading file 2");
		exit(EXIT_FAILURE);
	}

	pixmap = make_root_pixmap(screen,
		xinerama_info[0].width * 2,
		xinerama_info[0].height * 2);

	gc = gdk_gc_new(pixmap);

	gdk_pixbuf_render_to_drawable(w1,
					pixmap,
					gc,
					0,
					0,
					0,
					0,
					-1,
					-1,
					GDK_RGB_DITHER_MAX,
					0,
					0);

	gdk_pixbuf_render_to_drawable(w2,
					pixmap,
					gc,
					0,
					0,
					xinerama_info[1].x_org,
					xinerama_info[1].y_org,
					-1,
					-1,
					GDK_RGB_DITHER_MAX,
					0,
					0);


	set_root_pixmap(pixmap, screen);

	return 0;

}


GdkPixmap *make_root_pixmap(GdkScreen *screen, gint width, gint height)
{
	Display *display;
	char *display_name;
	Pixmap result;
	GdkPixmap *gdk_pixmap;
	int screen_num;

	screen_num = DefaultScreen(GDK_DISPLAY());

	gdk_flush();

	display_name = DisplayString(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()));

	display = XOpenDisplay(display_name);

	XSetCloseDownMode(display, RetainPermanent);

	result = XCreatePixmap (display,
				RootWindow(display, screen_num),
				width, height,
				DefaultDepth(display, screen_num));

	XCloseDisplay(display);

	gdk_pixmap = gdk_pixmap_foreign_new(result);

	gdk_drawable_set_colormap(GDK_DRAWABLE(gdk_pixmap),
			gdk_drawable_get_colormap(gdk_get_default_root_window()));
	return gdk_pixmap;
}

void set_root_pixmap(GdkPixmap *pixmap, GdkScreen *screen)
{
	Atom type;
        gulong nitems, bytes_after;
        gint format;
        guchar *data_esetroot;
        Pixmap pixmap_id;
        Display *display;
        int screen_num;

	screen_num = DefaultScreen (GDK_DISPLAY ());

        if (pixmap != NULL && pixmap != (GdkPixmap *) -1)
                pixmap_id = GDK_WINDOW_XWINDOW (pixmap);
        else
                pixmap_id = 0;
			
	display = GDK_DISPLAY ();							
        XGrabServer (display);

        XGetWindowProperty (display, RootWindow (display, screen_num),
                            XInternAtom (display, "ESETROOT_PMAP_ID", False),
                            0L, 1L, False, XA_PIXMAP,
                            &type, &format, &nitems, &bytes_after,
                            &data_esetroot);

        if (type == XA_PIXMAP) {
                if (format == 32 && nitems == 1) {
                        Pixmap old_pixmap;

                        old_pixmap = *((Pixmap *) data_esetroot);

                        if (pixmap != (GdkPixmap *) -1 && old_pixmap != pixmap_id)
                                XKillClient (display, old_pixmap);
                        else if (pixmap == (GdkPixmap *) -1)
                                pixmap_id = old_pixmap;
                }

                XFree (data_esetroot);
        }

        if (pixmap != NULL && pixmap != (GdkPixmap *) -1) {
                XChangeProperty (display, RootWindow (display, screen_num),
                                 XInternAtom (display, "ESETROOT_PMAP_ID", FALSE),
                                 XA_PIXMAP, 32, PropModeReplace,
                                 (guchar *) &pixmap_id, 1);
                XChangeProperty (display, RootWindow (display, screen_num),
                                 XInternAtom (display, "_XROOTPMAP_ID", FALSE),
                                 XA_PIXMAP, 32, PropModeReplace,
                                 (guchar *) &pixmap_id, 1);

                XSetWindowBackgroundPixmap (display, RootWindow (display, screen_num),
                                            pixmap_id);
        } else if (pixmap == NULL) {
                XDeleteProperty (display, RootWindow (display, screen_num),
                                 XInternAtom (display, "ESETROOT_PMAP_ID", FALSE));
                XDeleteProperty (display, RootWindow (display, screen_num),
                                 XInternAtom (display, "_XROOTPMAP_ID", FALSE));
        }

        XClearWindow (display, RootWindow (display, screen_num));
        XUngrabServer (display);
        XFlush (display);
}

