]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/dnd.cpp
Sorry, I went and removed consts as per the style guide :-)
[wxWidgets.git] / src / gtk / dnd.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: dnd.cpp
3 // Purpose: wxDropTarget class
4 // Author: Robert Roebling
5 // Copyright: Robert Roebling
6 // Licence: wxWindows license
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation "dnd.h"
11 #endif
12
13 #include "wx/dnd.h"
14 #include "wx/window.h"
15 #include "wx/app.h"
16 #include "wx/gdicmn.h"
17
18 #include "gdk/gdkprivate.h"
19
20 #include <X11/Xlib.h>
21
22 // ----------------------------------------------------------------------------
23 // global
24 // ----------------------------------------------------------------------------
25
26 extern bool g_blockEventsOnDrag;
27
28 // ----------------------------------------------------------------------------
29 // wxDropTarget
30 // ----------------------------------------------------------------------------
31
32 wxDropTarget::wxDropTarget()
33 {
34 };
35
36 wxDropTarget::~wxDropTarget()
37 {
38 };
39
40 void wxDropTarget::Drop( GdkEvent *event, int x, int y )
41 {
42 printf( "Drop data is of type %s.\n", event->dropdataavailable.data_type );
43
44 OnDrop( x, y, (char *)event->dropdataavailable.data);
45 };
46
47 void wxDropTarget::UnregisterWidget( GtkWidget *widget )
48 {
49 gtk_widget_dnd_drop_set( widget, FALSE, NULL, 0, FALSE );
50 };
51
52 // ----------------------------------------------------------------------------
53 // wxTextDropTarget
54 // ----------------------------------------------------------------------------
55
56 bool wxTextDropTarget::OnDrop( long x, long y, const void *pData )
57 {
58 OnDropText( x, y, (const char*)pData );
59 return TRUE;
60 };
61
62 bool wxTextDropTarget::OnDropText( long x, long y, const char *psz )
63 {
64 printf( "Got dropped text: %s.\n", psz );
65 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
66 return TRUE;
67 };
68
69 void wxTextDropTarget::RegisterWidget( GtkWidget *widget )
70 {
71 char *accepted_drop_types[] = { "text/plain" };
72 gtk_widget_dnd_drop_set( widget, TRUE, accepted_drop_types, 1, FALSE );
73 };
74
75 //-------------------------------------------------------------------------
76 // wxDragSource
77 //-------------------------------------------------------------------------
78
79 //-----------------------------------------------------------------------------
80 // drag request
81
82 void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDragSource *drag )
83 {
84 printf( "OnDragRequest.\n" );
85
86 gtk_widget_dnd_data_set( widget, event, drag->m_data, drag->m_size );
87 };
88
89 wxDragSource::wxDragSource( wxWindow *win )
90 {
91 g_blockEventsOnDrag = TRUE;
92
93 m_window = win;
94 m_widget = win->m_widget;
95 if (win->m_wxwindow) m_widget = win->m_wxwindow;
96
97 m_data = NULL;
98 m_size = 0;
99
100 m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
101 m_goaheadCursor = wxCursor( wxCURSOR_HAND );
102 };
103
104 wxDragSource::~wxDragSource(void)
105 {
106 g_blockEventsOnDrag = FALSE;
107 };
108
109 void wxDragSource::SetData( char *data, long size )
110 {
111 m_size = size;
112 m_data = data;
113 };
114
115 void wxDragSource::Start( int x, int y )
116 {
117 if (gdk_dnd.dnd_grabbed) return;
118 if (gdk_dnd.drag_really) return;
119 if (m_size == 0) return;
120 if (!m_data) return;
121
122 GdkWindowPrivate *wp = (GdkWindowPrivate*) m_widget->window;
123
124 RegisterWindow();
125 ConnectWindow();
126
127 gdk_dnd.drag_perhaps = TRUE;
128
129 gdk_dnd.dnd_drag_start.x = 5;
130 gdk_dnd.dnd_drag_start.y = 5;
131 gdk_dnd.real_sw = wp;
132
133 if (gdk_dnd.drag_startwindows)
134 {
135 g_free( gdk_dnd.drag_startwindows );
136 gdk_dnd.drag_startwindows = NULL;
137 };
138 gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
139
140 XWindowAttributes dnd_winattr;
141 XGetWindowAttributes( gdk_display, wp->xwindow, &dnd_winattr );
142 wp->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
143
144 gdk_dnd_drag_addwindow( m_widget->window );
145
146 GdkEventDragBegin ev;
147 ev.type = GDK_DRAG_BEGIN;
148 ev.window = m_widget->window;
149 ev.u.allflags = 0;
150 ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
151
152 gdk_event_put( (GdkEvent*)&ev );
153
154 XGrabPointer( gdk_display, wp->xwindow, False,
155 ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
156 GrabModeAsync, GrabModeAsync, gdk_root_window, None, CurrentTime );
157
158 gdk_dnd_set_drag_cursors( m_defaultCursor.GetCursor(), m_goaheadCursor.GetCursor() );
159
160 gdk_dnd.dnd_grabbed = TRUE;
161 gdk_dnd.drag_really = 1;
162 gdk_dnd_display_drag_cursor( x, y, FALSE, TRUE );
163
164 while (gdk_dnd.drag_really || gdk_dnd.drag_perhaps) wxYield();
165
166 UnconnectWindow();
167 UnregisterWindow();
168 };
169
170 void wxDragSource::ConnectWindow(void)
171 {
172 gtk_signal_connect( GTK_OBJECT(m_widget), "drag_request_event",
173 GTK_SIGNAL_FUNC(gtk_drag_callback), (gpointer)this );
174 };
175
176 void wxDragSource::UnconnectWindow(void)
177 {
178 if (!m_widget) return;
179
180 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget), (gpointer)this );
181 };
182
183 void wxDragSource::UnregisterWindow(void)
184 {
185 if (!m_widget) return;
186
187 gtk_widget_dnd_drag_set( m_widget, FALSE, NULL, 0 );
188 };
189
190 //-------------------------------------------------------------------------
191 // wxTextDragSource
192 //-------------------------------------------------------------------------
193
194 void wxTextDragSource::SetTextData( const wxString &text )
195 {
196 m_tmp = text;
197 SetData( WXSTRINGCAST(m_tmp), m_tmp.Length()+1 );
198 };
199
200 void wxTextDragSource::RegisterWindow(void)
201 {
202 if (!m_widget) return;
203
204 char *accepted_drop_types[] = { "text/plain" };
205 gtk_widget_dnd_drag_set( m_widget, TRUE, accepted_drop_types, 1 );
206 };
207