]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dnd.cpp
new file added
[wxWidgets.git] / src / gtk / dnd.cpp
index 0ce223efb432ac320ca0544a5ca3af7ec3363717..acb68d6af29be701de0c8b03a93daebf993c5964 100644 (file)
@@ -26,6 +26,7 @@
 #include "wx/scopeguard.h"
 
 #include <gtk/gtk.h>
+#include "wx/gtk/private/gtk2-compat.h"
 
 //----------------------------------------------------------------------------
 // global data
@@ -148,7 +149,7 @@ static wxDragResult ConvertFromGTK(long action)
         case GDK_ACTION_MOVE:
             return wxDragMove;
     }
-    
+
     return wxDragNone;
 }
 
@@ -218,7 +219,7 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget),
     wxDragResult suggested_action = drop_target->GTKFigureOutSuggestedAction();
 
     wxDragResult result = wxDragNone;
-        
+
     if (drop_target->m_firstMotion)
     {
         // the first "drag_motion" event substitutes a "drag_enter" event
@@ -237,18 +238,18 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget),
         result_action = GDK_ACTION_LINK;
     else
         result_action = GDK_ACTION_MOVE;
-        
+
     // is result action actually supported
-    bool ret ((result_action != GDK_ACTION_DEFAULT) &&
-              (context->actions & result_action));
-        
+    bool ret (result_action != GDK_ACTION_DEFAULT) &&
+               (gdk_drag_context_get_actions(context) & result_action);
+
     if (ret)
         gdk_drag_status( context, result_action, time );
 
     // after this, invalidate the drop_target's GdkDragContext
     drop_target->GTKSetDragContext( NULL );
 
-    // this has to be done because GDK has no "drag_enter" event 
+    // this has to be done because GDK has no "drag_enter" event
     drop_target->m_firstMotion = false;
 
     return ret;
@@ -281,14 +282,14 @@ static gboolean target_drag_drop( GtkWidget *widget,
     {
         // cancel the whole thing
         gtk_drag_finish( context,
-                          FALSE,        // no success 
+                          FALSE,        // no success
                           FALSE,        // don't delete data on dropping side
                           time );
-                          
+
         drop_target->GTKSetDragContext( NULL );
-        
+
         drop_target->m_firstMotion = true;
-         
+
         return FALSE;
     }
 
@@ -363,7 +364,7 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
     /* Owen Taylor: "call gtk_drag_finish() with
        success == TRUE" */
 
-    if ((data->length <= 0) || (data->format != 8))
+    if (gtk_selection_data_get_length(data) <= 0 || gtk_selection_data_get_format(data) != 8)
     {
         /* negative data length and non 8-bit data format
            qualifies for junk */
@@ -378,7 +379,7 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
        this is only valid for the duration of this call */
     drop_target->GTKSetDragData( data );
 
-    wxDragResult result = ConvertFromGTK(context->action);
+    wxDragResult result = ConvertFromGTK(gdk_drag_context_get_selected_action(context));
 
     if ( wxIsDragResultOk( drop_target->OnData( x, y, result ) ) )
     {
@@ -436,17 +437,18 @@ wxDragResult wxDropTarget::GTKFigureOutSuggestedAction()
 {
     if (!m_dragContext)
         return wxDragError;
-    
+
     // GTK+ always supposes that we want to copy the data by default while we
     // might want to move it, so examine not only suggested_action - which is
     // only good if we don't have our own preferences - but also the actions
     // field
     wxDragResult suggested_action = wxDragNone;
+    const GdkDragAction actions = gdk_drag_context_get_actions(m_dragContext);
     if (GetDefaultAction() == wxDragNone)
     {
         // use default action set by wxDropSource::DoDragDrop()
         if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove &&
-            (m_dragContext->actions & GDK_ACTION_MOVE ) )
+            (actions & GDK_ACTION_MOVE))
         {
             // move is requested by the program and allowed by GTK+ - do it, even
             // though suggested_action may be currently wxDragCopy
@@ -454,7 +456,7 @@ wxDragResult wxDropTarget::GTKFigureOutSuggestedAction()
         }
         else // use whatever GTK+ says we should
         {
-            suggested_action = ConvertFromGTK(m_dragContext->suggested_action);
+            suggested_action = ConvertFromGTK(gdk_drag_context_get_suggested_action(m_dragContext));
 
 #if 0
             // RR: I don't understand the code below: if the drag comes from
@@ -471,18 +473,18 @@ wxDragResult wxDropTarget::GTKFigureOutSuggestedAction()
         }
     }
     else if (GetDefaultAction() == wxDragMove &&
-            (m_dragContext->actions & GDK_ACTION_MOVE))
+            (actions & GDK_ACTION_MOVE))
     {
 
         suggested_action = wxDragMove;
     }
     else
     {
-        if (m_dragContext->actions & GDK_ACTION_COPY)
+        if (actions & GDK_ACTION_COPY)
             suggested_action = wxDragCopy;
-        else if (m_dragContext->actions & GDK_ACTION_MOVE)
+        else if (actions & GDK_ACTION_MOVE)
             suggested_action = wxDragMove;
-        else if (m_dragContext->actions & GDK_ACTION_LINK)
+        else if (actions & GDK_ACTION_LINK)
             suggested_action = wxDragLink;
         else
             suggested_action = wxDragNone;
@@ -504,7 +506,7 @@ GdkAtom wxDropTarget::GTKGetMatchingPair(bool quiet)
     if (!m_dragContext)
         return (GdkAtom) 0;
 
-    GList *child = m_dragContext->targets;
+    const GList* child = gdk_drag_context_list_targets(m_dragContext);
     while (child)
     {
         GdkAtom formatAtom = (GdkAtom)(child->data);
@@ -533,12 +535,14 @@ bool wxDropTarget::GetData()
     if (!m_dataObject)
         return false;
 
-    wxDataFormat dragFormat( m_dragData->target );
+    wxDataFormat dragFormat(gtk_selection_data_get_target(m_dragData));
 
     if (!m_dataObject->IsSupportedFormat( dragFormat ))
         return false;
 
-    m_dataObject->SetData( dragFormat, (size_t)m_dragData->length, (const void*)m_dragData->data );
+    m_dataObject->SetData(dragFormat,
+        (size_t)gtk_selection_data_get_length(m_dragData),
+        (const void*)gtk_selection_data_get_data(m_dragData));
 
     return true;
 }
@@ -605,7 +609,7 @@ source_drag_data_get  (GtkWidget          *WXUNUSED(widget),
                        guint               WXUNUSED(time),
                        wxDropSource       *drop_source )
 {
-    wxDataFormat format( selection_data->target );
+    wxDataFormat format(gtk_selection_data_get_target(selection_data));
 
     wxLogTrace(TRACE_DND, wxT("Drop source: format requested: %s"),
                format.GetId().c_str());
@@ -644,10 +648,10 @@ source_drag_data_get  (GtkWidget          *WXUNUSED(widget),
         return;
     }
 
-    drop_source->m_retValue = ConvertFromGTK( context->action );
+    drop_source->m_retValue = ConvertFromGTK(gdk_drag_context_get_selected_action(context));
 
     gtk_selection_data_set( selection_data,
-                            selection_data->target,
+                            gtk_selection_data_get_target(selection_data),
                             8,   // 8-bit
                             d,
                             size );
@@ -677,7 +681,7 @@ extern "C" {
 static gint
 gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxDropSource *source )
 {
-    source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );
+    source->GiveFeedback(ConvertFromGTK(gdk_drag_context_get_selected_action(source->m_dragContext)));
 
     return 0;
 }
@@ -734,11 +738,11 @@ void wxDropSource::SetIcons(const wxIcon &iconCopy,
     m_iconMove = iconMove;
     m_iconNone = iconNone;
 
-    if ( !m_iconCopy.Ok() )
+    if ( !m_iconCopy.IsOk() )
         m_iconCopy = wxIcon(page_xpm);
-    if ( !m_iconMove.Ok() )
+    if ( !m_iconMove.IsOk() )
         m_iconMove = m_iconCopy;
-    if ( !m_iconNone.Ok() )
+    if ( !m_iconNone.IsOk() )
         m_iconNone = m_iconCopy;
 }
 
@@ -757,6 +761,7 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
     else
         icon = &m_iconNone;
 
+#ifndef __WXGTK3__
     GdkBitmap *mask;
     if ( icon->GetMask() )
         mask = icon->GetMask()->GetBitmap();
@@ -765,28 +770,45 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
 
     GdkPixmap *pixmap = icon->GetPixmap();
 
-    gint width,height;
-    gdk_drawable_get_size (pixmap, &width, &height);
-
     GdkColormap *colormap = gtk_widget_get_colormap( m_widget );
     gtk_widget_push_colormap (colormap);
+#endif
 
     m_iconWindow = gtk_window_new (GTK_WINDOW_POPUP);
     gtk_widget_set_events (m_iconWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
     gtk_widget_set_app_paintable (m_iconWindow, TRUE);
 
+#ifdef __WXGTK3__
+    gtk_widget_set_visual(m_iconWindow, gtk_widget_get_visual(m_widget));
+#else
     gtk_widget_pop_colormap ();
+#endif
 
-    gtk_widget_set_size_request (m_iconWindow, width, height);
+    gtk_widget_set_size_request (m_iconWindow, icon->GetWidth(), icon->GetHeight());
     gtk_widget_realize (m_iconWindow);
 
     g_signal_connect (m_iconWindow, "configure_event",
                       G_CALLBACK (gtk_dnd_window_configure_callback), this);
 
-    gdk_window_set_back_pixmap (m_iconWindow->window, pixmap, FALSE);
+#ifdef __WXGTK3__
+    cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(m_iconWindow));
+    icon->SetSourceSurface(cr, 0, 0);
+    cairo_pattern_t* pattern = cairo_get_source(cr);
+    gdk_window_set_background_pattern(gtk_widget_get_window(m_iconWindow), pattern);
+    cairo_destroy(cr);
+    cairo_surface_t* mask = icon->GetMask()->GetBitmap();
+    if (mask)
+    {
+        cairo_region_t* region = gdk_cairo_region_create_from_surface(mask);
+        gtk_widget_shape_combine_region(m_iconWindow, region);
+        cairo_region_destroy(region);
+    }
+#else
+    gdk_window_set_back_pixmap(gtk_widget_get_window(m_iconWindow), pixmap, false);
 
     if (mask)
         gtk_widget_shape_combine_mask (m_iconWindow, mask, 0, 0);
+#endif
 
     gtk_drag_set_icon_widget( context, m_iconWindow, 0, 0 );
 }
@@ -857,6 +879,9 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
     while (m_waiting)
         gtk_main_iteration();
 
+    g_signal_handlers_disconnect_by_func (m_iconWindow,
+                                          (gpointer) gtk_dnd_window_configure_callback, this);
+
     return m_retValue;
 }