#include <gtk/gtk.h>
#ifndef GDK_WINDOWING_X11
#error "This test only supports X11."
#endif
#include <gdk/gdkx.h>
#include <X11/Xlib.h>

static void
get_bounds (GtkWidget *window,
            gint      *top,
            gint      *bottom,
            gint      *left,
            gint      *right)
{
   GdkRectangle geometry;
   GdkScreen *screen;
   gint n_monitors;
   gint i;
   gint maxX = 0;
   gint maxY = 0;
   gint minX = 0;
   gint minY = 0;

   g_return_if_fail(GTK_IS_WINDOW(window));
   g_return_if_fail(top != NULL);
   g_return_if_fail(bottom != NULL);
   g_return_if_fail(left != NULL);
   g_return_if_fail(right != NULL);

   *top = *bottom = *left = *right = 0;
   screen = gtk_window_get_screen(GTK_WINDOW(window));
   n_monitors = gdk_screen_get_n_monitors(screen);

   for (i = 0; i < n_monitors; i++) {
      gdk_screen_get_monitor_geometry(screen, i, &geometry);

      if (geometry.width <= 0 || geometry.height <= 0) {
         continue;
      }

      if (geometry.y < minY) {
         *top = i;
         minY = geometry.y;
      }
      if (geometry.y + geometry.height > maxY) {
         *bottom = i;
         maxY = geometry.y + geometry.height;
      }
      if (geometry.x < minX) {
         *left = i;
         minX = geometry.x;
      }
      if (geometry.x + geometry.width > maxX) {
         *right = i;
         maxX = geometry.x + geometry.width;
      }
   }
}

static void
button_toggled (GtkWidget *widget,
                gpointer   user_data)
{
   XClientMessageEvent xclient = { 0 };
   GdkAtom atom = gdk_atom_intern("_NET_WM_FULLSCREEN_MONITORS", FALSE);
   GtkWindow *window = user_data;
   GdkScreen *screen;
   Display *display;
   gint top = 0;
   gint bottom = 0;
   gint left = 0;
   gint right = 0;

   g_assert(GTK_IS_TOGGLE_BUTTON(widget));
   g_assert(GTK_IS_WINDOW(window));
   g_assert(atom != GDK_NONE);

   gtk_window_fullscreen(window);

   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
      get_bounds(GTK_WIDGET(window), &top, &bottom, &left, &right);
   }

   screen = gtk_window_get_screen(window);
   if (gdk_x11_screen_supports_net_wm_hint(screen, atom)) {
      g_debug("Sending _NET_WM_FULLSCREEN_MONITORS with "
              "top=%d bottom=%d left=%d right=%d",
              top, bottom, left, right);
      gdk_error_trap_push();
      display = GDK_SCREEN_XDISPLAY(screen);
      XGrabServer(display);
      xclient.type = ClientMessage;
      xclient.window = GDK_WINDOW_XID(gtk_widget_get_window(widget));
      xclient.message_type = gdk_x11_atom_to_xatom(atom);
      xclient.format = 32;
      xclient.data.l[0] = top;
      xclient.data.l[1] = bottom;
      xclient.data.l[2] = left;
      xclient.data.l[3] = right;
      xclient.data.l[4] = 1; /* Source indication */
      XSendEvent(display,
                 GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
                 FALSE,
                 SubstructureRedirectMask | SubstructureNotifyMask,
                 (XEvent *)&xclient);
      XUngrabServer(display);
      gdk_display_sync(gdk_screen_get_display(screen));
      gdk_x11_display_error_trap_pop_ignored(gdk_screen_get_display(screen));
   }
}

gint
main (gint   argc,
      gchar *argv[])
{
   GtkWidget *align;
   GtkWidget *button;
   GtkWidget *window;

   gtk_init(&argc, &argv);

   button = g_object_new(GTK_TYPE_TOGGLE_BUTTON,
                         "label", "Toggle _NET_WM_FULLSCREEN_MONITORS hint.",
                         "visible", TRUE,
                         NULL);
   align = g_object_new(GTK_TYPE_ALIGNMENT,
                        "child", button,
                        "visible", TRUE,
                        "xscale", 0.0f,
                        "yscale", 0.0f,
                        NULL);
   window = g_object_new(GTK_TYPE_WINDOW,
                         "child", align,
                         "title", "Test _NET_WM_FULLSCREEN_MONITORS",
                         NULL);

   g_signal_connect(button, "toggled", G_CALLBACK(button_toggled), window);
   gtk_window_fullscreen(GTK_WINDOW(window));
   gtk_window_present(GTK_WINDOW(window));
   gtk_main();

   return 0;
}
