+wxPrivateDropTarget::wxPrivateDropTarget()
+{
+ m_id = wxTheApp->GetAppName();
+}
+
+wxPrivateDropTarget::wxPrivateDropTarget( const wxString &id )
+{
+ m_id = id;
+}
+
+bool wxPrivateDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
+{
+ return IsSupported( m_id );
+}
+
+bool wxPrivateDropTarget::OnDrop( long WXUNUSED(x), long WXUNUSED(y) )
+{
+ if (!IsSupported( m_id ))
+ {
+ RequestData( m_id );
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+bool wxPrivateDropTarget::OnData( long x, long y )
+{
+ if (!IsSupported( m_id )) return FALSE;
+
+ wxPrivateDataObject data;
+ if (!GetData( &data )) return FALSE;
+
+ OnDropData( x, y, data.GetData(), data.GetSize() );
+
+ return TRUE;
+}
+
+//----------------------------------------------------------------------------
+// A drop target which accepts files (dragged from File Manager or Explorer)
+//----------------------------------------------------------------------------
+
+bool wxFileDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
+{
+ return IsSupported( wxDF_FILENAME );
+}
+
+bool wxFileDropTarget::OnDrop( long x, long y )
+{
+ if (IsSupported( wxDF_FILENAME ))
+ {
+ RequestData( wxDF_FILENAME );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool wxFileDropTarget::OnData( long x, long y )
+{
+ wxFileDataObject data;
+ if (!GetData( &data )) return FALSE;
+
+ /* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
+ size_t number = 0;
+ size_t i;
+ size_t size = data.GetFiles().Length();
+ wxChar *text = WXSTRINGCAST data.GetFiles();
+ for ( i = 0; i < size; i++)
+ if (text[i] == 0) number++;
+
+ if (number == 0) return FALSE;
+
+ wxChar **files = new wxChar*[number];
+
+ text = WXSTRINGCAST data.GetFiles();
+ for (i = 0; i < number; i++)
+ {
+ files[i] = text;
+ int len = wxStrlen( text );
+ text += len+1;
+ }
+
+ OnDropFiles( x, y, number, files );
+
+ free( files );
+
+ return TRUE;
+}
+
+//----------------------------------------------------------------------------
+// "drag_data_get"
+//----------------------------------------------------------------------------
+
+static void
+source_drag_data_get (GtkWidget *WXUNUSED(widget),
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint WXUNUSED(info),
+ guint WXUNUSED(time),
+ wxDropSource *drop_source )
+{
+ if (g_isIdle) wxapp_install_idle_handler();
+
+// printf( "Provide data!\n" );
+
+// char *name = gdk_atom_name( selection_data->target );
+// if (name) printf( "Format requested: %s.\n", name );
+
+ wxNode *node = drop_source->m_data->m_dataObjects.First();
+ while (node)
+ {
+ wxDataObject *data_object = (wxDataObject*) node->Data();
+ if (data_object->GetFormat().GetAtom() == selection_data->target)
+ {
+// printf( "format found.\n" );
+
+ size_t data_size = data_object->GetSize();
+
+ if (data_size > 0)
+ {
+// printf( "data size: %d.\n", (int)data_size );
+
+ guchar *buffer = new guchar[data_size];
+ data_object->WriteData( buffer );
+
+ gtk_selection_data_set( selection_data,
+ selection_data->target,
+ 8, // 8-bit
+ buffer,
+ data_size );
+
+ free( buffer );
+
+ /* so far only copy, no moves. TODO. */
+ drop_source->m_retValue = wxDragCopy;
+
+ return;
+ }
+ }
+
+ node = node->Next();
+ }
+
+ drop_source->m_retValue = wxDragCancel;
+}
+
+//----------------------------------------------------------------------------
+// "drag_data_delete"
+//----------------------------------------------------------------------------
+
+static void source_drag_data_delete( GtkWidget *WXUNUSED(widget),
+ GdkDragContext *WXUNUSED(context),
+ wxDropSource *drop_source )
+{
+ if (g_isIdle) wxapp_install_idle_handler();
+
+// printf( "Delete the data!\n" );
+
+ drop_source->m_retValue = wxDragMove;
+}
+
+//----------------------------------------------------------------------------
+// "drag_begin"
+//----------------------------------------------------------------------------
+
+static void source_drag_begin( GtkWidget *WXUNUSED(widget),
+ GdkDragContext *WXUNUSED(context),
+ wxDropSource *WXUNUSED(drop_source) )
+{
+ if (g_isIdle) wxapp_install_idle_handler();
+
+// printf( "drag_begin.\n" );
+}
+
+//----------------------------------------------------------------------------
+// "drag_end"
+//----------------------------------------------------------------------------
+
+static void source_drag_end( GtkWidget *WXUNUSED(widget),
+ GdkDragContext *WXUNUSED(context),
+ wxDropSource *drop_source )
+{
+ if (g_isIdle) wxapp_install_idle_handler();
+
+// printf( "drag_end.\n" );
+
+ drop_source->m_waiting = FALSE;
+}
+
+//---------------------------------------------------------------------------
+// wxDropSource
+//---------------------------------------------------------------------------
+
+wxDropSource::wxDropSource( wxWindow *win, const wxIcon &go, const wxIcon &stop )
+{
+ g_blockEventsOnDrag = TRUE;
+ m_waiting = TRUE;
+
+ m_window = win;
+ m_widget = win->m_widget;
+ if (win->m_wxwindow) m_widget = win->m_wxwindow;
+
+ m_data = (wxDataBroker*) NULL;
+ m_retValue = wxDragCancel;
+
+ m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
+ m_goaheadCursor = wxCursor( wxCURSOR_HAND );
+
+ m_goIcon = go;
+ if (wxNullIcon == go) m_goIcon = wxIcon( page_xpm );
+ m_stopIcon = stop;
+ if (wxNullIcon == stop) m_stopIcon = wxIcon( gv_xpm );
+}
+
+wxDropSource::wxDropSource( wxDataObject *data, wxWindow *win, const wxIcon &go, const wxIcon &stop )
+{
+ m_waiting = TRUE;
+
+ m_window = win;
+ m_widget = win->m_widget;
+ if (win->m_wxwindow) m_widget = win->m_wxwindow;
+ m_retValue = wxDragCancel;
+
+ if (data)
+ {
+ m_data = new wxDataBroker();
+ m_data->Add( data );
+ }
+ else
+ {
+ m_data = (wxDataBroker*) NULL;
+ }
+
+ m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
+ m_goaheadCursor = wxCursor( wxCURSOR_HAND );
+
+ m_goIcon = go;
+ if (wxNullIcon == go) m_goIcon = wxIcon( page_xpm );
+ m_stopIcon = stop;
+ if (wxNullIcon == stop) m_stopIcon = wxIcon( gv_xpm );
+}
+
+wxDropSource::wxDropSource( wxDataBroker *data, wxWindow *win )
+{
+ m_window = win;
+ m_widget = win->m_widget;
+ if (win->m_wxwindow) m_widget = win->m_wxwindow;
+ m_retValue = wxDragCancel;
+
+ m_data = data;
+
+ m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
+ m_goaheadCursor = wxCursor( wxCURSOR_HAND );
+}
+
+void wxDropSource::SetData( wxDataObject *data )
+{
+ if (m_data) delete m_data;
+
+ if (data)
+ {
+ m_data = new wxDataBroker();
+ m_data->Add( data );
+ }
+ else
+ {
+ m_data = (wxDataBroker*) NULL;
+ }
+}
+
+void wxDropSource::SetData( wxDataBroker *data )
+{
+ if (m_data) delete m_data;
+
+ m_data = data;
+}
+
+wxDropSource::~wxDropSource(void)