1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "clipbrd.h"
14 #include "wx/clipbrd.h"
16 //-----------------------------------------------------------------------------
18 //-----------------------------------------------------------------------------
20 wxClipboard
*wxTheClipboard
= (wxClipboard
*) NULL
;
22 GdkAtom g_textAtom
= 0;
23 GdkAtom g_clipboardAtom
= 0;
24 GdkAtom g_targetsAtom
= 0;
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30 /* The contents of a selection are returned in a GtkSelectionData
31 structure. selection/target identify the request.
32 type specifies the type of the return; if length < 0, and
33 the data should be ignored. This structure has object semantics -
34 no fields should be modified directly, they should not be created
35 directly, and pointers to them should not be stored beyond the duration of
36 a callback. (If the last is changed, we'll need to add reference
39 struct _GtkSelectionData
51 //-----------------------------------------------------------------------------
52 // "selection_received" for targets
53 //-----------------------------------------------------------------------------
56 targets_selection_received( GtkWidget
*WXUNUSED(widget
),
57 GtkSelectionData
*selection_data
,
58 wxClipboard
*clipboard
)
60 if (!wxTheClipboard
) return;
62 if (selection_data
->length
<= 0) return;
64 // make sure we got the data in the correct form
65 if (selection_data
->type
!= GDK_SELECTION_TYPE_ATOM
) return;
67 // the atoms we received, holding a list of targets (= formats)
68 GdkAtom
*atoms
= (GdkAtom
*)selection_data
->data
;
70 for (unsigned int i
=0; i
<selection_data
->length
/sizeof(GdkAtom
); i
++)
72 if (atoms
[i
] == clipboard
->m_targetRequested
)
74 clipboard
->m_formatSupported
= TRUE
;
82 //-----------------------------------------------------------------------------
83 // "selection_received" for the actual data
84 //-----------------------------------------------------------------------------
87 selection_received( GtkWidget
*WXUNUSED(widget
),
88 GtkSelectionData
*selection_data
,
89 wxClipboard
*clipboard
)
91 if (!wxTheClipboard
) return;
93 if (selection_data
->length
<= 0) return;
95 size_t size
= (size_t) selection_data
->length
;
97 // make sure we got the data in the correct form
98 if (selection_data
->type
!= GDK_SELECTION_TYPE_STRING
) return;
100 clipboard
->m_receivedSize
= size
;
102 clipboard
->m_receivedData
= new char[size
+1];
104 memcpy( clipboard
->m_receivedData
, selection_data
->data
, size
);
107 //-----------------------------------------------------------------------------
109 //-----------------------------------------------------------------------------
112 selection_clear( GtkWidget
*WXUNUSED(widget
), GdkEventSelection
*WXUNUSED(event
) )
114 if (!wxTheClipboard
) return TRUE
;
116 /* the clipboard is no longer in our hands. we can delete the
117 * clipboard data. I hope I got that one right... */
119 wxTheClipboard
->SetData( (wxDataObject
*) NULL
);
124 //-----------------------------------------------------------------------------
125 // selection handler for supplying data
126 //-----------------------------------------------------------------------------
129 selection_handler( GtkWidget
*WXUNUSED(widget
), GtkSelectionData
*selection_data
, gpointer
WXUNUSED(data
) )
131 if (!wxTheClipboard
) return;
133 wxDataObject
*data_object
= wxTheClipboard
->m_data
;
135 if (!data_object
) return;
137 if (data_object
->GetDataSize() == 0) return;
141 gint len
= data_object
->GetDataSize();
142 guchar
*bin_data
= (guchar
*) malloc( len
);
143 data_object
->GetDataHere( (void*)bin_data
);
145 if (selection_data
->target
== GDK_TARGET_STRING
)
147 gtk_selection_data_set(
148 selection_data
, GDK_SELECTION_TYPE_STRING
, 8*sizeof(gchar
), bin_data
, len
);
151 else if (selection_data->target == g_textAtom)
153 gtk_selection_data_set(
154 selection_data, g_textAtom, 8*sizeof(gchar), bin_data, len );
160 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
164 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
,wxObject
)
166 wxClipboard::wxClipboard()
168 m_data
= (wxDataObject
*) NULL
;
170 m_clipboardWidget
= gtk_window_new( GTK_WINDOW_POPUP
);
171 gtk_widget_realize( m_clipboardWidget
);
173 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget
),
174 "selection_clear_event",
175 GTK_SIGNAL_FUNC( selection_clear
),
178 if (!g_clipboardAtom
) g_clipboardAtom
= gdk_atom_intern( "CLIPBOARD", FALSE
);
179 if (!g_textAtom
) g_textAtom
= gdk_atom_intern( "TEXT", FALSE
);
180 if (!g_targetsAtom
) g_targetsAtom
= gdk_atom_intern ("TARGETS", FALSE
);
182 m_receivedData
= (char*)NULL
;
184 m_formatSupported
= FALSE
;
185 m_targetRequested
= 0;
188 wxClipboard::~wxClipboard()
192 if (m_clipboardWidget
) gtk_widget_destroy( m_clipboardWidget
);
195 void wxClipboard::Clear()
197 /* As we have data we also own the clipboard. Once we no longer own
198 it, clear_selection is called which will set m_data to zero */
202 if (gdk_selection_owner_get( g_clipboardAtom
) == m_clipboardWidget
->window
)
204 gtk_selection_owner_set( (GtkWidget
*) NULL
, g_clipboardAtom
, GDK_CURRENT_TIME
);
208 m_data
= (wxDataObject
*) NULL
;
215 delete[] m_receivedData
;
216 m_receivedData
= (char*) NULL
;
219 m_targetRequested
= 0;
221 m_formatSupported
= FALSE
;
224 void wxClipboard::SetData( wxDataObject
*data
)
229 GTK 1.0.X cannot remove a target from a widget so if a widget
230 at first offers text and then a bitmap (and no longer text) to
231 the clipboard, we seem too have to delete it.
234 if (m_clipboardWidget
) gtk_widget_destroy( m_clipboardWidget
);
236 m_clipboardWidget
= gtk_window_new( GTK_WINDOW_POPUP
);
237 gtk_widget_realize( m_clipboardWidget
);
239 if (m_data
) delete m_data
;
243 if (!gtk_selection_owner_set( m_clipboardWidget
,
248 m_data
= (wxDataObject
*) NULL
;
252 switch (m_data
->GetPreferredFormat())
255 gtk_selection_add_handler( m_clipboardWidget
,
267 bool wxClipboard::IsSupportedFormat( wxDataFormat format
)
269 m_targetRequested
= 0;
271 if (format
== wxDF_TEXT
)
273 // m_targetRequested = g_textAtom;
274 m_targetRequested
= GDK_TARGET_STRING
;
277 if (m_targetRequested
== 0) return FALSE
;
279 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget
),
280 "selection_received",
281 GTK_SIGNAL_FUNC( targets_selection_received
),
284 m_formatSupported
= FALSE
;
286 gtk_selection_convert( m_clipboardWidget
,
291 gtk_signal_disconnect_by_func( GTK_OBJECT(m_clipboardWidget
),
292 GTK_SIGNAL_FUNC( targets_selection_received
),
295 if (!m_formatSupported
) return FALSE
;
300 bool wxClipboard::ObtainData( wxDataFormat format
)
306 delete[] m_receivedData
;
307 m_receivedData
= (char*) NULL
;
310 m_targetRequested
= 0;
312 if (format
== wxDF_TEXT
)
314 // m_targetRequested = g_textAtom;
315 m_targetRequested
= GDK_TARGET_STRING
;
318 if (m_targetRequested
== 0) return FALSE
;
320 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget
),
321 "selection_received",
322 GTK_SIGNAL_FUNC( selection_received
),
325 gtk_selection_convert( m_clipboardWidget
,
330 gtk_signal_disconnect_by_func( GTK_OBJECT(m_clipboardWidget
),
331 GTK_SIGNAL_FUNC( selection_received
),
334 if (m_receivedSize
== 0) return FALSE
;
339 size_t wxClipboard::GetDataSize() const
341 return m_receivedSize
;
344 void wxClipboard::GetDataHere( void *data
) const
346 memcpy(data
, m_receivedData
, m_receivedSize
);
349 //-----------------------------------------------------------------------------
351 //-----------------------------------------------------------------------------
353 IMPLEMENT_DYNAMIC_CLASS(wxClipboardModule
,wxModule
)
355 bool wxClipboardModule::OnInit()
357 wxTheClipboard
= new wxClipboard();
362 void wxClipboardModule::OnExit()
364 if (wxTheClipboard
) delete wxTheClipboard
;
365 wxTheClipboard
= (wxClipboard
*) NULL
;