#include "config.h"
#include "DragIcon.h"
#include "GdkCairoUtilities.h"
#include <gtk/gtk.h>
namespace WebCore {
#ifdef GTK_API_VERSION_2
static gboolean dragIconWindowDrawEventCallback(GtkWidget*, GdkEventExpose* event, DragIcon* icon)
{
RefPtr<cairo_t> context = adoptRef(gdk_cairo_create(event->window));
icon->draw(context.get());
return TRUE;
}
#else
static gboolean dragIconWindowDrawEventCallback(GtkWidget*, cairo_t* context, DragIcon* icon)
{
if (!gdk_cairo_get_clip_rectangle(context, 0))
return FALSE;
icon->draw(context);
return TRUE;
}
#endif // GTK_API_VERSION_2
DragIcon::DragIcon()
: isComposited(gdk_screen_is_composited(gdk_screen_get_default()))
, m_window(0)
{
if (!isComposited)
return;
m_window = gtk_window_new(GTK_WINDOW_POPUP);
#ifdef GTK_API_VERSION_2
g_signal_connect(m_window, "expose-event", G_CALLBACK(dragIconWindowDrawEventCallback), this);
#else
g_signal_connect(m_window, "draw", G_CALLBACK(dragIconWindowDrawEventCallback), this);
#endif
GdkScreen* screen = gtk_widget_get_screen(m_window);
#ifdef GTK_API_VERSION_2
GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen);
if (rgba)
gtk_widget_set_colormap(m_window, rgba);
#else
GdkVisual* visual = gdk_screen_get_rgba_visual(screen);
if (!visual)
visual = gdk_screen_get_system_visual(screen);
gtk_widget_set_visual(m_window, visual);
#endif // GTK_API_VERSION_2
}
DragIcon::~DragIcon()
{
if (m_window)
gtk_widget_destroy(m_window);
}
void DragIcon::draw(cairo_t* context)
{
cairo_rectangle(context, 0, 0,
cairo_image_surface_get_width(m_image.get()),
cairo_image_surface_get_height(m_image.get()));
cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(context, m_image.get(), 0, 0);
cairo_fill(context);
}
void DragIcon::setImage(cairo_surface_t* image)
{
ASSERT(image);
m_image = image;
m_imageSize = IntSize(cairo_image_surface_get_width(image), cairo_image_surface_get_height(image));
if (isComposited) {
gtk_window_resize(GTK_WINDOW(m_window), m_imageSize.width(), m_imageSize.height());
return;
}
#ifdef GTK_API_VERSION_2
m_pixbuf = adoptGRef(cairoSurfaceToGdkPixbuf(image));
#endif
}
void DragIcon::useForDrag(GdkDragContext* context)
{
IntPoint hotspot(m_imageSize);
hotspot.scale(0.5, 0.5);
useForDrag(context, hotspot);
}
void DragIcon::useForDrag(GdkDragContext* context, const IntPoint& hotspot)
{
if (isComposited) {
gtk_drag_set_icon_widget(context, m_window, hotspot.x(), hotspot.y());
return;
}
#ifdef GTK_API_VERSION_2
gtk_drag_set_icon_pixbuf(context, m_pixbuf.get(), hotspot.x(), hotspot.y());
#else
gtk_drag_set_icon_surface(context, m_image.get());
#endif
}
}