#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "desktop-window.h"

#ifdef PLATFORM_OS_UNIX

#include <gdk/gdk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/Xatom.h>

#ifdef HAVE_GTK3
#include <cairo.h>
#include <cairo-xlib.h>

// GTK3 compatibility
#undef GDK_DISPLAY
#define GDK_DISPLAY() GDK_DISPLAY_XDISPLAY(gdk_display_get_default())
#endif

#ifndef GDK_WINDOW_XWINDOW
#define GDK_WINDOW_XWINDOW(w) GDK_WINDOW_XID(w)
#endif


static Window
get_desktop_window (Window the_window)
{
  Atom prop, type, prop2;
  int format;
  unsigned long length, after;
  unsigned char *data;
  unsigned int nchildren;
  Window w, root, *children, parent;

  prop = XInternAtom(GDK_DISPLAY(), "_XROOTPMAP_ID", True);
  prop2 = XInternAtom(GDK_DISPLAY(), "_XROOTCOLOR_PIXEL", True);

  if (prop == None && prop2 == None)
    return None;

  for (w = the_window; w; w = parent) {
    if ((XQueryTree(GDK_DISPLAY(), w, &root, &parent, &children, &nchildren)) == False)
      return None;

    if (nchildren)
      XFree(children);

    if (prop != None) {
      XGetWindowProperty(GDK_DISPLAY(), w, prop, 0L, 1L, False, AnyPropertyType,
       &type, &format, &length, &after, &data);
    } else if (prop2 != None) {
      XGetWindowProperty(GDK_DISPLAY(), w, prop2, 0L, 1L, False, AnyPropertyType,
       &type, &format, &length, &after, &data);
    } else  {
      continue;
    }

    if (type != None) {
      return w;
    }
  }
  return None;
}

static Pixmap
get_pixmap_prop (Window the_window, char *prop_id)
{
  Atom prop, type;
  int format;
  unsigned long length, after;
  unsigned char *data;

  Window desktop_window = get_desktop_window(the_window);

  if (desktop_window == None)
    desktop_window = GDK_ROOT_WINDOW();

  if (desktop_window == None)
    return None;
  
  prop = XInternAtom(GDK_DISPLAY(), prop_id, True);

  if (prop == None)
    return None;

  XGetWindowProperty(GDK_DISPLAY(), desktop_window, prop, 0L, 1L, False,
         AnyPropertyType, &type, &format, &length, &after,
         &data);

  if (type == XA_PIXMAP)
    return *((Pixmap *)data);

  return None;
}

void
set_desktop_background(GdkWindow *window)
{
  Pixmap xpm = get_pixmap_prop(GDK_WINDOW_XWINDOW(window), "_XROOTPMAP_ID");

#ifdef HAVE_GTK3
  if (xpm != None)
    {
      GdkScreen *screen = gdk_window_get_screen(window);
      GdkDisplay *display = gdk_window_get_display(window);
      Window root_return;
      int x, y;
      unsigned int width, height, bw, depth_ret;
      cairo_surface_t *surface = NULL;

      gdk_x11_display_error_trap_push(display);

      if (XGetGeometry(GDK_SCREEN_XDISPLAY(screen),
                       xpm,
                       &root_return,
                       &x, &y, &width, &height, &bw, &depth_ret))
        {
          surface = cairo_xlib_surface_create(GDK_SCREEN_XDISPLAY (screen),
                                              xpm,
                                              GDK_VISUAL_XVISUAL(gdk_screen_get_system_visual(screen)),
                                              width, height);
        }
      gdk_x11_display_error_trap_pop_ignored(display);

      cairo_pattern_t *pattern = cairo_pattern_create_for_surface(surface);
      gdk_window_set_background_pattern(window, pattern);

      cairo_surface_destroy(surface);
    }
  else
    {
      GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
      gdk_window_set_background_rgba(window, &black);
    }
      
#else
  if (xpm != None)
    {
      GdkPixmap *gpm = gdk_pixmap_foreign_new(xpm);
      gdk_window_set_back_pixmap (window, gpm, FALSE);
      g_object_unref (gpm);
    }
#endif
}

#endif
