+static void
+set_icon_stock_pixbuf (GdkDragContext *context,
+ const gchar *stock_id,
+ GdkPixbuf *pixbuf,
+ gint hot_x,
+ gint hot_y)
+{
+ GtkWidget *window;
+ gint width, height;
+ GdkScreen *screen;
+
+ g_return_if_fail (context != NULL);
+ g_return_if_fail (pixbuf != NULL || stock_id != NULL);
+ g_return_if_fail (pixbuf == NULL || stock_id == NULL);
+
+ screen = gdk_drawable_get_screen (context->source_window);
+
+ /* Push a NULL colormap to guard against gtk_widget_push_colormap() */
+ gtk_widget_push_colormap (NULL);
+ window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (window), screen);
+ set_can_change_screen (window, TRUE);
+ gtk_widget_pop_colormap ();
+
+ gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
+
+ if (stock_id)
+ {
+ pixbuf = gtk_widget_render_icon (window, stock_id,
+ GTK_ICON_SIZE_DND, NULL);
+
+ if (!pixbuf)
+ {
+ g_warning ("Cannot load drag icon from stock_id %s", stock_id);
+ gtk_widget_destroy (window);
+ return;
+ }
+
+ }
+ else
+ g_object_ref (pixbuf);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_width (pixbuf);
+
+ gtk_widget_set_size_request (window,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+
+ g_signal_connect_closure (window, "realize",
+ g_cclosure_new (G_CALLBACK (icon_window_realize),
+ pixbuf,
+ (GClosureNotify)g_object_unref),
+ FALSE);
+
+ gtk_drag_set_icon_window (context, window, hot_x, hot_y, TRUE);
+}
+
+/**
+ * gtk_drag_set_icon_pixbuf:
+ * @context: the context for a drag. (This must be called
+ * with a context for the source side of a drag)
+ * @pixbuf: the #GdkPixbuf to use as the drag icon.
+ * @hot_x: the X offset within @widget of the hotspot.
+ * @hot_y: the Y offset within @widget of the hotspot.
+ *
+ * Sets @pixbuf as the icon for a given drag.
+ **/
+void
+gtk_drag_set_icon_pixbuf (GdkDragContext *context,
+ GdkPixbuf *pixbuf,
+ gint hot_x,
+ gint hot_y)
+{
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
+ g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+
+ set_icon_stock_pixbuf (context, NULL, pixbuf, hot_x, hot_y);
+}
+
+/**
+ * gtk_drag_set_icon_stock:
+ * @context: the context for a drag. (This must be called
+ * with a context for the source side of a drag)
+ * @stock_id: the ID of the stock icon to use for the drag.
+ * @hot_x: the X offset within the icon of the hotspot.
+ * @hot_y: the Y offset within the icon of the hotspot.
+ *
+ * Sets the the icon for a given drag from a stock ID.
+ **/
+void
+gtk_drag_set_icon_stock (GdkDragContext *context,
+ const gchar *stock_id,
+ gint hot_x,
+ gint hot_y)
+{
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
+ g_return_if_fail (stock_id != NULL);
+
+ set_icon_stock_pixbuf (context, stock_id, NULL, hot_x, hot_y);
+}
+
+/**
+ * gtk_drag_set_icon_pixmap:
+ * @context: the context for a drag. (This must be called
+ * with a context for the source side of a drag)
+ * @colormap: the colormap of the icon
+ * @pixmap: the image data for the icon
+ * @mask: the transparency mask for the icon
+ * @hot_x: the X offset within @pixmap of the hotspot.
+ * @hot_y: the Y offset within @pixmap of the hotspot.
+ *
+ * Sets @pixmap as the icon for a given drag. GTK+ retains
+ * references for the arguments, and will release them when
+ * they are no longer needed. In general, gtk_drag_set_icon_pixbuf()
+ * will be more convenient to use.
+ **/