1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDropTarget class
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "dnd.h"
16 #if wxUSE_DRAG_AND_DROP
18 #include "wx/window.h"
20 #include "wx/gdicmn.h"
26 #include "gdk/gdkprivate.h"
30 // ----------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------
34 extern bool g_blockEventsOnDrag
;
36 #if (GTK_MINOR_VERSION > 0)
38 #include "gtk/gtkdnd.h"
39 #include "gtk/gtkselection.h"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 static void target_drag_leave( GtkWidget
*WXUNUSED(widget
),
46 GdkDragContext
*context
,
50 dt
->SetDragContext( context
);
52 dt
->SetDragContext( (GdkDragContext
*) NULL
);
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 static gboolean
target_drag_motion( GtkWidget
*WXUNUSED(widget
),
60 GdkDragContext
*context
,
66 dt
->SetDragContext( context
);
68 if (dt
->OnMove( x
, y
))
70 gdk_drag_status( context
, context
->suggested_action
, time
);
74 gdk_drag_status( context
, (GdkDragAction
)0, time
);
77 dt
->SetDragContext( (GdkDragContext
*) NULL
);
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 static gboolean
target_drag_drop( GtkWidget
*widget
,
86 GdkDragContext
*context
,
91 printf( "drop at: %d,%d.\n", x
, y
);
95 gtk_drag_get_data( widget
,
97 GPOINTER_TO_INT (context
->targets
->data
),
103 // ----------------------------------------------------------------------------
104 // "drag_data_received"
105 // ----------------------------------------------------------------------------
107 static void target_drag_data_received( GtkWidget
*WXUNUSED(widget
),
108 GdkDragContext
*context
,
111 GtkSelectionData
*data
,
112 guint
WXUNUSED(info
),
115 printf( "data receive at: %d,%d.\n", x
, y
);
117 if ((data
->length
>= 0) && (data
->format
== 8))
119 wxString str
= (const char*)data
->data
;
120 printf( "Received %s\n.", WXSTRINGCAST str
);
121 gtk_drag_finish( context
, TRUE
, FALSE
, time
);
125 gtk_drag_finish (context
, FALSE
, FALSE
, time
);
128 // ----------------------------------------------------------------------------
130 // ----------------------------------------------------------------------------
132 wxDropTarget::wxDropTarget()
136 wxDropTarget::~wxDropTarget()
140 void wxDropTarget::OnEnter()
144 void wxDropTarget::OnLeave()
148 bool wxDropTarget::OnMove( int x
, int y
)
150 printf( "mouse move %d %d.\n", x
, y
);
154 bool wxDropTarget::OnDrop( int x
, int y
)
156 printf( "mouse move %d %d.\n", x
, y
);
160 bool wxDropTarget::IsSupported( wxDataFormat format
)
165 bool wxDropTarget::GetData( wxDataObject
*data
)
170 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
172 wxCHECK_RET( widget
!= NULL
, "unregister widget is NULL" );
174 gtk_drag_dest_set( widget
,
176 (GtkTargetEntry
*) NULL
,
180 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
181 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
183 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
184 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
186 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
187 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
189 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
190 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
193 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
195 wxCHECK_RET( widget
!= NULL
, "register widget is NULL" );
197 GtkTargetEntry format
;
201 strcpy( buf
, "text/plain" );
203 gtk_drag_dest_set( widget
,
204 GTK_DEST_DEFAULT_ALL
,
207 (GdkDragAction
)(GDK_ACTION_COPY
| GDK_ACTION_MOVE
) );
209 gtk_signal_connect( GTK_OBJECT(widget
), "drag_leave",
210 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
212 gtk_signal_connect( GTK_OBJECT(widget
), "drag_motion",
213 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
215 gtk_signal_connect( GTK_OBJECT(widget
), "drag_drop",
216 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
218 gtk_signal_connect( GTK_OBJECT(widget
), "drag_data_received",
219 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
222 //-------------------------------------------------------------------------
224 //-------------------------------------------------------------------------
226 bool wxTextDropTarget::OnMove( int WXUNUSED(x
), int WXUNUSED(y
) )
228 return IsSupported( wxDF_TEXT
); // same as "TEXT"
231 bool wxTextDropTarget::OnDrop( int x
, int y
)
233 if (!IsSupported( wxDF_TEXT
)) return FALSE
;
235 wxTextDataObject data
;
236 if (!GetData( &data
)) return FALSE
;
238 return OnDropText( x
, y
, data
.GetText() );
241 //-------------------------------------------------------------------------
242 // wxPrivateDropTarget
243 //-------------------------------------------------------------------------
245 wxPrivateDropTarget::wxPrivateDropTarget()
247 m_id
= wxTheApp
->GetAppName();
250 wxPrivateDropTarget::wxPrivateDropTarget( const wxString
&id
)
255 bool wxPrivateDropTarget::OnMove( int WXUNUSED(x
), int WXUNUSED(y
) )
257 return IsSupported( m_id
);
260 bool wxPrivateDropTarget::OnDrop( int x
, int y
)
262 if (!IsSupported( m_id
)) return FALSE
;
264 wxPrivateDataObject data
;
265 if (!GetData( &data
)) return FALSE
;
267 return OnDropData( x
, y
, data
.GetData(), data
.GetSize() );
270 //----------------------------------------------------------------------------
271 // A drop target which accepts files (dragged from File Manager or Explorer)
272 //----------------------------------------------------------------------------
274 bool wxFileDropTarget::OnMove( int WXUNUSED(x
), int WXUNUSED(y
) )
276 return IsSupported( wxDF_FILENAME
); // same as "file:ALL"
279 bool wxFileDropTarget::OnDrop( int x
, int y
)
281 if (!IsSupported( wxDF_FILENAME
)) return FALSE
;
283 wxFileDataObject data
;
284 if (!GetData( &data
)) return FALSE
;
286 /* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
289 size_t size
= data
.GetFiles().Length();
290 char *text
= WXSTRINGCAST data
.GetFiles();
291 for ( i
= 0; i
< size
; i
++)
292 if (text
[i
] == 0) number
++;
294 if (number
== 0) return TRUE
;
296 char **files
= new char*[number
];
298 text
= WXSTRINGCAST data
.GetFiles();
299 for (i
= 0; i
< number
; i
++)
302 int len
= strlen( text
);
306 bool ret
= OnDropFiles( x
, y
, number
, files
);
313 //-------------------------------------------------------------------------
315 //-------------------------------------------------------------------------
319 GtkWidget
*shape_create_icon ( const wxIcon
&shape
,
327 static char * gv_xpm
[] = {
339 " .XXXXXXXXXXXXXX. ",
340 " .XXX..XXXX..XXX. ",
341 " ....XX....XX....XX. ",
342 " .XXX.XXX..XXXX..XXX.... ",
343 " .XXXXXXXXXXXXXXXXXXX.XXX. ",
344 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
345 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
346 " ..XXXXXXXXXXXXXXXXXXXXXX. ",
347 " .XXXXXXXXXXXXXXXXXX... ",
348 " ..XXXXXXXXXXXXXXXX. ",
349 " .XXXXXXXXXXXXXXXX. ",
350 " .XXXXXXXXXXXXXXXX. ",
351 " .XXXXXXXXXXXXXXXXX. ",
352 " .XXXXXXXXXXXXXXXXX. ",
353 " .XXXXXXXXXXXXXXXXXX. ",
354 " .XXXXXXXXXXXXXXXXXXX. ",
355 " .XXXXXXXXXXXXXXXXXXXXX. ",
356 " .XXXXXXXXXXXXXX.XXXXXXX. ",
357 " .XXXXXXX.XXXXXXX.XXXXXXX. ",
358 " .XXXXXXXX.XXXXXXX.XXXXXXX. ",
359 " .XXXXXXX...XXXXX...XXXXX. ",
360 " .XXXXXXX. ..... ..... ",
368 static char * page_xpm
[] = {
369 /* width height ncolors chars_per_pixel */
378 " ................... ",
379 " .XXXXXXXXXXXXXXXXX.. ",
380 " .XXXXXXXXXXXXXXXXX.o. ",
381 " .XXXXXXXXXXXXXXXXX.oo. ",
382 " .XXXXXXXXXXXXXXXXX.ooo. ",
383 " .XXXXXXXXXXXXXXXXX.oooo. ",
384 " .XXXXXXXXXXXXXXXXX....... ",
385 " .XXXXXOOOOOOOOOOXXXooooo. ",
386 " .XXXXXXXXXXXXXXXXXXooooo. ",
387 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
388 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
389 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
390 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
391 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
392 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
393 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
394 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
395 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
396 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
397 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
398 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
399 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
400 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
401 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
402 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
403 " .XXXXXOOOOOOOXXXXXXXXXXX. ",
404 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
405 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
406 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
407 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
408 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
409 " ......................... "};
412 //-----------------------------------------------------------------------------
414 //-----------------------------------------------------------------------------
416 wxDropSource
*gs_currentDropSource
= (wxDropSource
*) NULL
;
418 //-----------------------------------------------------------------------------
419 // "drop_enter_event"
420 //-----------------------------------------------------------------------------
422 static void gtk_target_enter_callback( GtkWidget
*WXUNUSED(widget
),
423 GdkEventDropEnter
*WXUNUSED(event
),
424 wxDropTarget
*target
)
430 //-----------------------------------------------------------------------------
431 // "drop_leave_event"
432 //-----------------------------------------------------------------------------
434 static void gtk_target_leave_callback( GtkWidget
*WXUNUSED(widget
),
435 GdkEventDropLeave
*WXUNUSED(event
),
436 wxDropTarget
*target
)
442 //-----------------------------------------------------------------------------
443 // "drop_data_available_event"
444 //-----------------------------------------------------------------------------
446 static void gtk_target_callback( GtkWidget
*widget
,
447 GdkEventDropDataAvailable
*event
,
448 wxDropTarget
*target
)
454 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
456 printf( "Drop data is of type %s.\n", event->data_type );
458 target
->OnDrop( x
, y
, (const void*)event
->data
, (size_t)event
->data_numbytes
);
462 g_free (event->data);
463 g_free (event->data_type);
467 // ----------------------------------------------------------------------------
469 // ----------------------------------------------------------------------------
471 wxDropTarget::wxDropTarget()
473 m_format
= (wxDataFormat
*) NULL
;
476 wxDropTarget::~wxDropTarget()
478 if (m_format
) delete m_format
;
481 wxDataFormat
&wxDropTarget::GetFormat(size_t n
) const
486 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
490 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
491 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
493 gtk_widget_dnd_drop_set( widget
, FALSE
, (gchar
**) NULL
, 0, FALSE
);
496 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
501 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
503 switch (GetFormat(i
).GetType())
507 if (i
> 0) formats
+= ";";
508 formats
+= "text/plain";
514 if (i
> 0) formats
+= ";";
515 formats
+= "file:ALL";
521 if (i
> 0) formats
+= ";";
522 wxPrivateDropTarget
*pdt
= (wxPrivateDropTarget
*)this;
523 formats
+= pdt
->GetId();
532 char *str
= WXSTRINGCAST formats
;
534 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
536 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
537 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
539 gtk_signal_connect( GTK_OBJECT(widget
), "drop_enter_event",
540 GTK_SIGNAL_FUNC(gtk_target_enter_callback
), (gpointer
) this );
542 gtk_signal_connect( GTK_OBJECT(widget
), "drop_leave_event",
543 GTK_SIGNAL_FUNC(gtk_target_leave_callback
), (gpointer
) this );
546 // ----------------------------------------------------------------------------
548 // ----------------------------------------------------------------------------
550 wxTextDropTarget::wxTextDropTarget()
552 m_format
= new wxDataFormat( wxDF_TEXT
);
555 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
557 OnDropText( x
, y
, (const char*)data
);
561 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
564 printf( "Got dropped text: %s.\n", psz );
565 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
570 size_t wxTextDropTarget::GetFormatCount() const
575 // ----------------------------------------------------------------------------
576 // wxPrivateDropTarget
577 // ----------------------------------------------------------------------------
579 wxPrivateDropTarget::wxPrivateDropTarget()
581 m_id
= wxTheApp
->GetAppName();
582 m_format
= new wxDataFormat( m_id
);
585 void wxPrivateDropTarget::SetId( const wxString
& id
)
588 m_format
->SetId( id
);
591 size_t wxPrivateDropTarget::GetFormatCount() const
596 // ----------------------------------------------------------------------------
598 // ----------------------------------------------------------------------------
600 wxFileDropTarget::wxFileDropTarget()
602 m_format
= new wxDataFormat( wxDF_FILENAME
);
605 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
607 printf( "Got %d dropped files.\n", (int)nFiles
);
608 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
610 for (size_t i
= 0; i
< nFiles
; i
++)
612 printf( aszFiles
[i
] );
619 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
623 char *text
= (char*) data
;
624 for ( i
= 0; i
< size
; i
++)
625 if (text
[i
] == 0) number
++;
627 if (number
== 0) return TRUE
;
629 char **files
= new char*[number
];
632 for (i
= 0; i
< number
; i
++)
635 int len
= strlen( text
);
639 bool ret
= OnDropFiles( x
, y
, 1, files
);
646 size_t wxFileDropTarget::GetFormatCount() const
651 //-------------------------------------------------------------------------
653 //-------------------------------------------------------------------------
656 shape_motion (GtkWidget
*widget
,
657 GdkEventMotion
* /*event*/);
659 //-----------------------------------------------------------------------------
660 // "drag_request_event"
661 //-----------------------------------------------------------------------------
663 void gtk_drag_callback( GtkWidget
*widget
, GdkEventDragRequest
*event
, wxDropSource
*source
)
665 wxDataBroker
*data
= source
->m_data
;
669 wxNode
*node
= data
->m_dataObjects
.First();
671 wxDataObject
*dobj
= (wxDataObject
*) node
->Data();
673 if ((strcmp(event
->data_type
,"file:ALL") == 0) &&
674 (dobj
->GetFormat().GetType() == wxDF_FILENAME
))
676 wxFileDataObject
*file_object
= (wxFileDataObject
*) dobj
;
678 wxString text
= file_object
->GetFiles();
680 char *s
= WXSTRINGCAST text
;
682 gtk_widget_dnd_data_set( widget
,
685 (int) text
.Length()+1 );
687 source
->m_retValue
= wxDragCopy
;
692 if ((strcmp(event
->data_type
,"text/plain") == 0) &&
693 (dobj
->GetFormat().GetType() == wxDF_TEXT
))
695 wxTextDataObject
*text_object
= (wxTextDataObject
*) dobj
;
697 wxString text
= text_object
->GetText();
699 char *s
= WXSTRINGCAST text
;
701 gtk_widget_dnd_data_set( widget
,
704 (int) text
.Length()+1 );
706 source
->m_retValue
= wxDragCopy
;
711 if (dobj
->GetFormat().GetType() == wxDF_PRIVATE
)
713 wxPrivateDataObject
*pdo
= (wxPrivateDataObject
*) dobj
;
715 if (pdo
->GetId() == event
->data_type
)
717 gtk_widget_dnd_data_set( widget
,
719 (unsigned char*) pdo
->GetData(),
720 (int) pdo
->GetSize() );
722 source
->m_retValue
= wxDragCopy
;
732 wxDropSource::wxDropSource( wxWindow
*win
, const wxIcon
&go
, const wxIcon
&stop
)
734 g_blockEventsOnDrag
= TRUE
;
737 m_widget
= win
->m_widget
;
738 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
740 m_data
= (wxDataBroker
*) NULL
;
741 m_retValue
= wxDragCancel
;
743 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
744 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
747 if (wxNullIcon
== go
) m_goIcon
= wxIcon( page_xpm
);
749 if (wxNullIcon
== stop
) m_stopIcon
= wxIcon( gv_xpm
);
752 wxDropSource::wxDropSource( wxDataObject
*data
, wxWindow
*win
, const wxIcon
&go
, const wxIcon
&stop
)
754 g_blockEventsOnDrag
= TRUE
;
757 m_widget
= win
->m_widget
;
758 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
759 m_retValue
= wxDragCancel
;
763 m_data
= new wxDataBroker();
768 m_data
= (wxDataBroker
*) NULL
;
771 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
772 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
775 if (wxNullIcon
== go
) m_goIcon
= wxIcon( page_xpm
);
777 if (wxNullIcon
== stop
) m_stopIcon
= wxIcon( gv_xpm
);
780 wxDropSource::wxDropSource( wxDataBroker
*data
, wxWindow
*win
)
782 g_blockEventsOnDrag
= TRUE
;
785 m_widget
= win
->m_widget
;
786 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
787 m_retValue
= wxDragCancel
;
791 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
792 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
795 void wxDropSource::SetData( wxDataObject
*data
)
797 if (m_data
) delete m_data
;
801 m_data
= new wxDataBroker();
806 m_data
= (wxDataBroker
*) NULL
;
810 void wxDropSource::SetData( wxDataBroker
*data
)
812 if (m_data
) delete m_data
;
817 wxDropSource::~wxDropSource(void)
819 if (m_data
) delete m_data
;
821 g_blockEventsOnDrag
= FALSE
;
824 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
826 if (gdk_dnd
.dnd_grabbed
) return (wxDragResult
) wxDragNone
;
827 if (gdk_dnd
.drag_really
) return (wxDragResult
) wxDragNone
;
829 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
831 if (!m_data
) return (wxDragResult
) wxDragNone
;
833 static GtkWidget
*drag_icon
= (GtkWidget
*) NULL
;
834 static GtkWidget
*drop_icon
= (GtkWidget
*) NULL
;
836 GdkPoint hotspot_1
= {0,-5 };
840 drag_icon
= shape_create_icon ( m_stopIcon
,
841 440, 140, 0,0, GTK_WINDOW_POPUP
);
843 gtk_signal_connect (GTK_OBJECT (drag_icon
), "destroy",
844 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
847 gtk_widget_hide (drag_icon
);
850 GdkPoint hotspot_2
= {-5,-5};
854 drop_icon
= shape_create_icon ( m_goIcon
,
855 440, 140, 0,0, GTK_WINDOW_POPUP
);
857 gtk_signal_connect (GTK_OBJECT (drop_icon
), "destroy",
858 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
861 gtk_widget_hide (drop_icon
);
865 gdk_dnd_set_drag_shape( drag_icon
->window
,
871 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
875 gdk_dnd
.drag_perhaps
= TRUE
;
877 gdk_dnd
.dnd_drag_start
.x
= 5;
878 gdk_dnd
.dnd_drag_start
.y
= 5;
879 gdk_dnd
.real_sw
= wp
;
881 if (gdk_dnd
.drag_startwindows
)
883 g_free( gdk_dnd
.drag_startwindows
);
884 gdk_dnd
.drag_startwindows
= (GdkWindow
**) NULL
;
886 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
888 XWindowAttributes dnd_winattr
;
889 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
890 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
892 gdk_dnd_drag_addwindow( m_widget
->window
);
894 GdkEventDragBegin ev
;
895 ev
.type
= GDK_DRAG_BEGIN
;
896 ev
.window
= m_widget
->window
;
898 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
900 gdk_event_put( (GdkEvent
*)&ev
);
902 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
903 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
904 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
906 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
908 gdk_dnd
.dnd_grabbed
= TRUE
;
909 gdk_dnd
.drag_really
= 1;
913 wxGetMousePosition( &x
, &y
);
915 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
917 gs_currentDropSource
= this;
919 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
921 gs_currentDropSource
= (wxDropSource
*) NULL
;
925 g_blockEventsOnDrag
= FALSE
;
930 void wxDropSource::RegisterWindow(void)
936 wxNode
*node
= m_data
->m_dataObjects
.First();
939 wxDataObject
* dobj
= (wxDataObject
*) node
->Data();
941 switch (dobj
->GetFormat().GetType())
945 formats
+= "text/plain";
950 formats
+= "file:ALL";
955 wxPrivateDataObject
* pdo
= (wxPrivateDataObject
*) m_data
;
956 formats
+= pdo
->GetId();
965 char *str
= WXSTRINGCAST formats
;
967 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
969 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
970 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
973 void wxDropSource::UnregisterWindow(void)
975 if (!m_widget
) return;
977 gtk_widget_dnd_drag_set( m_widget
, FALSE
, (gchar
**) NULL
, 0 );
979 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );
986 static GdkWindow
*root_win
= (GdkWindow
*) NULL
;
988 typedef struct _cursoroffset
{gint x
,y
;} CursorOffset
;
991 shape_pressed (GtkWidget
*widget
, GdkEventButton
*event
)
995 /* ignore double and triple click */
996 if (event
->type
!= GDK_BUTTON_PRESS
)
999 p
= (CursorOffset
*)gtk_object_get_user_data (GTK_OBJECT(widget
));
1000 p
->x
= (int) event
->x
;
1001 p
->y
= (int) event
->y
;
1003 gtk_grab_add (widget
);
1004 gdk_pointer_grab (widget
->window
, TRUE
,
1006 (GDK_BUTTON_RELEASE_MASK
|
1007 GDK_BUTTON_MOTION_MASK
|
1008 GDK_POINTER_MOTION_HINT_MASK
),
1010 (GdkCursor
*) NULL
, 0);
1015 shape_released (GtkWidget
*widget
)
1017 gtk_grab_remove (widget
);
1018 gdk_pointer_ungrab (0);
1022 shape_motion (GtkWidget
*widget
,
1023 GdkEventMotion
* /*event*/ )
1027 GdkModifierType mask
;
1029 p
= (CursorOffset
*)gtk_object_get_user_data (GTK_OBJECT (widget
));
1032 * Can't use event->x / event->y here
1033 * because I need absolute coordinates.
1036 gdk_window_get_pointer (root_win
, &xp
, &yp
, &mask
);
1037 gtk_widget_set_uposition (widget
, xp
- p
->x
, yp
- p
->y
);
1039 if (gs_currentDropSource
) gs_currentDropSource
->GiveFeedback( wxDragCopy
, FALSE
);
1043 shape_create_icon (const wxIcon
&shape
,
1051 * GDK_WINDOW_TOPLEVEL works also, giving you a title border
1053 GtkWidget
*window
= gtk_window_new ((GtkWindowType
)window_type
);
1055 GtkWidget
*fixed
= gtk_fixed_new ();
1056 gtk_widget_set_usize (fixed
, 100,100);
1057 gtk_container_add (GTK_CONTAINER (window
), fixed
);
1058 gtk_widget_show (fixed
);
1060 gtk_widget_set_events (window
,
1061 gtk_widget_get_events (window
) |
1062 GDK_BUTTON_MOTION_MASK
|
1063 GDK_POINTER_MOTION_HINT_MASK
|
1064 GDK_BUTTON_PRESS_MASK
);
1066 gtk_widget_realize (window
);
1068 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
1069 if (shape
.GetMask()) mask
= shape
.GetMask()->GetBitmap();
1071 GtkWidget
*pixmap
= gtk_pixmap_new (shape
.GetPixmap(), mask
);
1072 gtk_fixed_put (GTK_FIXED (fixed
), pixmap
, px
,py
);
1073 gtk_widget_show (pixmap
);
1075 gtk_widget_shape_combine_mask (window
, mask
, px
,py
);
1078 gtk_signal_connect (GTK_OBJECT (window
), "button_press_event",
1079 GTK_SIGNAL_FUNC (shape_pressed
),NULL
);
1080 gtk_signal_connect (GTK_OBJECT (window
), "button_release_event",
1081 GTK_SIGNAL_FUNC (shape_released
),NULL
);
1082 gtk_signal_connect (GTK_OBJECT (window
), "motion_notify_event",
1083 GTK_SIGNAL_FUNC (shape_motion
),NULL
);
1085 CursorOffset
*icon_pos
= g_new (CursorOffset
, 1);
1086 gtk_object_set_user_data(GTK_OBJECT(window
), icon_pos
);
1088 gtk_widget_set_uposition (window
, x
, y
);
1089 gtk_widget_show (window
);
1099 // wxUSE_DRAG_AND_DROP