#include <gtk/gtk.h>

static gboolean
on_button_press (GtkWidget      *widget,
		 GdkEventButton *event)
{
  if (event->button == 3)
    {
      GtkWidget *menu;

      menu = g_object_get_data (G_OBJECT (widget), "menu");
      if (!menu)
	{
	  GtkWidget *menuitem;
	  int i;
	  
	  menu = gtk_menu_new ();
	  for (i = 0; i < 10; i++)
	    {
	      char *str = g_strdup_printf ("Item %d", i);
	      menuitem = gtk_menu_item_new_with_label (str);
	      g_free (str);
	      
	      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
	    }
	  
	  gtk_widget_show_all (menu);

	  g_object_set_data (G_OBJECT (widget), "menu", menu);
	}

      gtk_menu_popup (GTK_MENU (menu),
		      NULL, NULL,
		      NULL, NULL,
		      event->button, event->time);
      
      return TRUE;
    }

  return FALSE;
}

static void
hookup_menu (GtkWidget *widget)
{
  gtk_widget_add_events (widget, GDK_BUTTON_PRESS_MASK);
  g_signal_connect (widget, "button-press-event", G_CALLBACK (on_button_press), NULL);
}

int main (int argc, char **argv)
{
  GtkWidget *window;
  GdkPixbuf *pixbuf;
  GdkPixmap *pixmap;
  GtkStyle *style;
  GError *error = 0;

  gtk_init (&argc, &argv);
  
  if (argc != 2)
    {
      g_printerr ("Usage: window-background FILENAME\n");
      return 1;
    }

  pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
  if (!pixbuf)
    {
      g_printerr ("Error loading background image: %s\n", error->message);
      g_error_free (error);
      return 1;
    }

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  hookup_menu (window);
  
  gtk_window_set_title (GTK_WINDOW (window), "gtk_widget_set_style()\n");

  gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf,
						  gtk_widget_get_colormap (window),
						  &pixmap,
						  NULL,
						  0x80);

  style = gtk_style_new ();
  style->bg_pixmap[GTK_STATE_NORMAL] = pixmap;
  gtk_widget_set_style (window, style);
  g_object_unref (style);

  /* If you show the window at this point, everything works as expected.
   *
   * If you add the following two lines, painting breaks; GTK+ has been
   * told that you'll repaint the window, and you don't
   */
  gtk_widget_set_app_paintable (window, TRUE);
  gtk_widget_set_double_buffered (window, FALSE);

  /* Adding the following hack to unset the EXPOSURE mask from the
   * window *should* fix the problem; GDK now knows that you aren't
   * going to repaint the window, but it doesn't fix it. This is
   * a GDK bug
   */
  gtk_widget_realize (window);
  gdk_window_set_events (window->window, GDK_BUTTON_PRESS_MASK);

  gtk_widget_show (window);

  gtk_main ();

  return 0;
}
