X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/83df96d63a52ebb08b9e32549dc255354b4a18d0..2e14066008229145e2da7b9f05a478ce38631f83:/src/x11/clipbrd.cpp diff --git a/src/x11/clipbrd.cpp b/src/x11/clipbrd.cpp index 41afb324d3..0e5f06f2ac 100644 --- a/src/x11/clipbrd.cpp +++ b/src/x11/clipbrd.cpp @@ -1,240 +1,284 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: clipbrd.cpp +// Name: src/x11/clipbrd.cpp // Purpose: Clipboard functionality -// Author: Julian Smart -// Modified by: -// Created: 17/09/98 +// Author: Robert Roebling +// Created: // RCS-ID: $Id$ -// Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation -#pragma implementation "clipbrd.h" -#endif - -#include "wx/defs.h" +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" #if wxUSE_CLIPBOARD -#include "wx/app.h" -#include "wx/frame.h" -#include "wx/bitmap.h" -#include "wx/utils.h" -#include "wx/metafile.h" #include "wx/clipbrd.h" -#include "wx/dataobj.h" -#ifdef __VMS__ -#pragma message disable nosimpint +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/dataobj.h" #endif -#include -#include -#ifdef __VMS__ -#pragma message enable nosimpint + +#include "wx/x11/private.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +#if !wxUSE_NANOX +Atom g_clipboardAtom = 0; +Atom g_targetsAtom = 0; #endif -#include +// avoid warnings about unused static variable (notice that we still use it +// even in release build if the compiler doesn't support variadic macros) +#if defined(__WXDEBUG__) || !defined(HAVE_VARIADIC_MACROS) -// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) -// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject) +// the trace mask we use with wxLogTrace() - call +// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here +// (there will be a *lot* of them!) +static const wxChar *TRACE_CLIPBOARD = wxT("clipboard"); -static bool gs_clipboardIsOpen = FALSE; +#endif // __WXDEBUG__ -bool wxOpenClipboard() +//----------------------------------------------------------------------------- +// reminder +//----------------------------------------------------------------------------- + +/* The contents of a selection are returned in a GtkSelectionData + structure. selection/target identify the request. + type specifies the type of the return; if length < 0, and + the data should be ignored. This structure has object semantics - + no fields should be modified directly, they should not be created + directly, and pointers to them should not be stored beyond the duration of + a callback. (If the last is changed, we'll need to add reference + counting) + +struct _GtkSelectionData { - if (!gs_clipboardIsOpen) - { - gs_clipboardIsOpen = TRUE; - return TRUE; - } - else - return FALSE; -} + GdkAtom selection; + GdkAtom target; + GdkAtom type; + gint format; + guchar *data; + gint length; +}; + +*/ + +//----------------------------------------------------------------------------- +// "selection_received" for targets +//----------------------------------------------------------------------------- + +#if 0 -bool wxCloseClipboard() +static void +targets_selection_received( GtkWidget *WXUNUSED(widget), + GtkSelectionData *selection_data, +#if (GTK_MINOR_VERSION > 0) + guint32 WXUNUSED(time), +#endif + wxClipboard *clipboard ) { - if (gs_clipboardIsOpen) + if ( wxTheClipboard && selection_data->length > 0 ) { - gs_clipboardIsOpen = FALSE; - return TRUE; - } - else - return FALSE; -} + /* make sure we got the data in the correct form */ + GdkAtom type = selection_data->type; + if ( type != GDK_SELECTION_TYPE_ATOM ) + { + if ( strcmp(gdk_atom_name(type), "TARGETS") ) + { + wxLogTrace( TRACE_CLIPBOARD, + wxT("got unsupported clipboard target") ); -bool wxEmptyClipboard() -{ - // No equivalent in Motif - return TRUE; -} + clipboard->m_waiting = false; + return; + } + } -bool wxClipboardOpen() -{ - return gs_clipboardIsOpen; -} +#ifdef __WXDEBUG__ + wxDataFormat clip( selection_data->selection ); + wxLogTrace( TRACE_CLIPBOARD, + wxT("selection received for targets, clipboard %s"), + clip.GetId().c_str() ); +#endif // __WXDEBUG__ -bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat) -{ - // Only text is supported. - if (dataFormat != wxDF_TEXT) - return FALSE; + // the atoms we received, holding a list of targets (= formats) + GdkAtom *atoms = (GdkAtom *)selection_data->data; - unsigned long numBytes = 0; - long privateId = 0; - - Window window = (Window) 0; - if (wxTheApp->GetTopWindow()) - window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() ); + for (unsigned int i=0; ilength/sizeof(GdkAtom); i++) + { + wxDataFormat format( atoms[i] ); - int success = XmClipboardRetrieve((Display*) wxGetDisplay(), - window, "TEXT", (XtPointer) 0, 0, & numBytes, & privateId) ; + wxLogTrace( TRACE_CLIPBOARD, + wxT("selection received for targets, format %s"), + format.GetId().c_str() ); - // Assume only text is supported. If we have anything at all, - // or the clipboard is locked so we're not sure, we say we support it. - if (success == ClipboardNoData) - return FALSE; - else - return TRUE; -} + if (format == clipboard->m_targetRequested) + { + clipboard->m_waiting = false; + clipboard->m_formatSupported = true; + return; + } + } + } -bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int WXUNUSED(width), int WXUNUSED(height)) -{ - if (dataFormat != wxDF_TEXT) - return FALSE; + clipboard->m_waiting = false; +} - char* data = (char*) obj; +//----------------------------------------------------------------------------- +// "selection_received" for the actual data +//----------------------------------------------------------------------------- - XmString text = XmStringCreateSimple ("CLIPBOARD"); - Window window = (Window) 0; - if (wxTheApp->GetTopWindow()) - window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() ); +static void +selection_received( GtkWidget *WXUNUSED(widget), + GtkSelectionData *selection_data, +#if (GTK_MINOR_VERSION > 0) + guint32 WXUNUSED(time), +#endif + wxClipboard *clipboard ) +{ + if (!wxTheClipboard) + { + clipboard->m_waiting = false; + return; + } - long itemId = 0; - int result = 0; + wxDataObject *data_object = clipboard->m_receivedData; - while ((result = - XmClipboardStartCopy((Display*) wxGetDisplay(), - window, - text, - XtLastTimestampProcessed((Display*) wxGetDisplay()), - (Widget) 0, - (XmCutPasteProc) 0, - & itemId)) != ClipboardSuccess) + if (!data_object) + { + clipboard->m_waiting = false; + return; + } - ; + if (selection_data->length <= 0) + { + clipboard->m_waiting = false; + return; + } - XmStringFree (text); + wxDataFormat format( selection_data->target ); - long dataId = 0; - while ((result = - XmClipboardCopy((Display*) wxGetDisplay(), - window, - itemId, - "TEXT", - (XtPointer) data, - strlen(data) + 1, - 0, - & dataId)) != ClipboardSuccess) + /* make sure we got the data in the correct format */ + if (!data_object->IsSupportedFormat( format ) ) + { + clipboard->m_waiting = false; + return; + } - ; + /* make sure we got the data in the correct form (selection type). + if so, copy data to target object */ + if (selection_data->type != GDK_SELECTION_TYPE_STRING) + { + clipboard->m_waiting = false; + return; + } - while (( result = - XmClipboardEndCopy((Display*) wxGetDisplay(), - window, itemId) ) != ClipboardSuccess) + data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data ); - ; - - return TRUE; + wxTheClipboard->m_formatSupported = true; + clipboard->m_waiting = false; } -wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len) -{ - if (dataFormat != wxDF_TEXT) - return (wxObject*) NULL; +//----------------------------------------------------------------------------- +// "selection_clear" +//----------------------------------------------------------------------------- - bool done = FALSE; - long id = 0; - unsigned long numBytes = 0; - int result = 0; - Window window = (Window) 0; - if (wxTheApp->GetTopWindow()) - window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() ); +static gint +selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event ) +{ + if (!wxTheClipboard) return TRUE; - int currentDataSize = 256; - char* data = new char[currentDataSize]; + if (event->selection == GDK_SELECTION_PRIMARY) + { + wxTheClipboard->m_ownsPrimarySelection = false; + } + else + if (event->selection == g_clipboardAtom) + { + wxTheClipboard->m_ownsClipboard = false; + } + else + { + wxTheClipboard->m_waiting = false; + return FALSE; + } - while (!done) + if ((!wxTheClipboard->m_ownsPrimarySelection) && + (!wxTheClipboard->m_ownsClipboard)) { - if (result == ClipboardTruncate) + /* the clipboard is no longer in our hands. we can the delete clipboard data. */ + if (wxTheClipboard->m_data) { - delete[] data; - currentDataSize = 2*currentDataSize; - data = new char[currentDataSize]; - } - result = XmClipboardRetrieve((Display*) wxGetDisplay(), - window, - "TEXT", - (XtPointer) data, - currentDataSize, - &numBytes, - &id); - - switch (result) - { - case ClipboardSuccess: - { - if (len) - *len = strlen(data) + 1; - return (wxObject*) data; - break; - } - case ClipboardTruncate: - case ClipboardLocked: - { - break; - } - default: - case ClipboardNoData: - { - return (wxObject*) NULL; - break; - } - } - + wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" )); + + wxDELETE(wxTheClipboard->m_data); + } } - return NULL; + wxTheClipboard->m_waiting = false; + return TRUE; } -wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat) -{ - // Only wxDF_TEXT supported - if (dataFormat == wxDF_TEXT) - return wxDF_TEXT; - else - return wxDF_INVALID; -} +//----------------------------------------------------------------------------- +// selection handler for supplying data +//----------------------------------------------------------------------------- -wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName)) +static void +selection_handler( GtkWidget *WXUNUSED(widget), + GtkSelectionData *selection_data, + guint WXUNUSED(info), + guint WXUNUSED(time), + gpointer WXUNUSED(data) ) { - // Not supported - return (wxDataFormat) wxDF_INVALID; -} + if (!wxTheClipboard) return; -bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int WXUNUSED(maxCount)) -{ - // Only wxDF_TEXT supported - if (dataFormat == wxDF_TEXT) + if (!wxTheClipboard->m_data) return; + + wxDataObject *data = wxTheClipboard->m_data; + + wxDataFormat format( selection_data->target ); + + if (!data->IsSupportedFormat( format )) return; + + int size = data->GetDataSize( format ); + + if (size == 0) return; + + void *d = malloc(size); + + data->GetDataHere( selection_data->target, d ); + + // transform Unicode text into multibyte before putting it on clipboard +#if wxUSE_UNICODE + if ( format.GetType() == wxDF_TEXT || format.GetType() == wxDF_UNICODETEXT) { - strcpy(formatName, "TEXT"); - return TRUE; + const wchar_t *wstr = (const wchar_t *)d; + size_t len = wxConvCurrent->WC2MB(NULL, wstr, 0); + char *str = malloc(len + 1); + wxConvCurrent->WC2MB(str, wstr, len); + str[len] = '\0'; + + free(d); + d = str; } - else - return FALSE; +#endif // wxUSE_UNICODE + + gtk_selection_data_set( + selection_data, + GDK_SELECTION_TYPE_STRING, + 8*sizeof(gchar), + (unsigned char*) d, + size ); + + free(d); } +#endif + //----------------------------------------------------------------------------- // wxClipboard //----------------------------------------------------------------------------- @@ -243,39 +287,91 @@ IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject) wxClipboard::wxClipboard() { - m_open = FALSE; + m_open = false; + + m_ownsClipboard = false; + m_ownsPrimarySelection = false; + + m_data = NULL; + m_receivedData = NULL; + + /* we use m_targetsWidget to query what formats are available */ + + /* we use m_clipboardWidget to get and to offer data */ +#if !wxUSE_NANOX + if (!g_clipboardAtom) g_clipboardAtom = XInternAtom( (Display*) wxGetDisplay(), "CLIPBOARD", False ); + if (!g_targetsAtom) g_targetsAtom = XInternAtom( (Display*) wxGetDisplay(), "TARGETS", False ); +#endif + + m_formatSupported = false; + m_targetRequested = 0; } wxClipboard::~wxClipboard() { - Clear(); + Clear(); + +// if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget ); +// if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget ); } void wxClipboard::Clear() { - wxNode* node = m_data.First(); - while (node) + if (m_data) { - wxDataObject* data = (wxDataObject*) node->Data(); - delete data; - node = node->Next(); +#if wxUSE_THREADS + /* disable GUI threads */ +#endif + + /* As we have data we also own the clipboard. Once we no longer own + it, clear_selection is called which will set m_data to zero */ +#if 0 + if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window) + { + m_waiting = true; + + gtk_selection_owner_set( NULL, g_clipboardAtom, + (guint32) GDK_CURRENT_TIME ); + + while (m_waiting) gtk_main_iteration(); + } + + if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window) + { + m_waiting = true; + + gtk_selection_owner_set( NULL, GDK_SELECTION_PRIMARY, + (guint32) GDK_CURRENT_TIME ); + + while (m_waiting) gtk_main_iteration(); + } +#endif + + wxDELETE(m_data); + +#if wxUSE_THREADS + /* re-enable GUI threads */ +#endif } - m_data.Clear(); + + m_targetRequested = 0; + m_formatSupported = false; } bool wxClipboard::Open() { - wxCHECK_MSG( !m_open, FALSE, "clipboard already open" ); - - m_open = TRUE; + wxCHECK_MSG( !m_open, false, wxT("clipboard already open") ); - return wxOpenClipboard(); + m_open = true; + + return true; } bool wxClipboard::SetData( wxDataObject *data ) { - wxCHECK_MSG( data, FALSE, "data is invalid" ); - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); + + wxCHECK_MSG( data, false, wxT("data is invalid") ); Clear(); @@ -284,242 +380,229 @@ bool wxClipboard::SetData( wxDataObject *data ) bool wxClipboard::AddData( wxDataObject *data ) { - wxCHECK_MSG( data, FALSE, "data is invalid" ); - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); +#if wxUSE_NANOX + return false; +#else + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); + + wxCHECK_MSG( data, false, wxT("data is invalid") ); + + /* we can only store one wxDataObject */ + Clear(); + + m_data = data; + + /* get formats from wxDataObjects */ + wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ]; + m_data->GetAllFormats( array ); - wxDataFormat::NativeFormat format = data->GetPreferredFormat().GetType(); - switch ( format ) - { - case wxDF_TEXT: - case wxDF_OEMTEXT: - { - wxTextDataObject* textDataObject = (wxTextDataObject*) data; - wxString str(textDataObject->GetText()); - return wxSetClipboardData(format, (wxObject*) (const char*) str); - } #if 0 - case wxDF_BITMAP: - case wxDF_DIB: - { - wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data; - wxBitmap bitmap(bitmapDataObject->GetBitmap()); - return wxSetClipboardData(data->GetType(), & bitmap); - break; - } + /* primary selection or clipboard */ + Atom clipboard = m_usePrimary ? (Atom) 1 // 1 = primary selection + : g_clipboardAtom; #endif // 0 + + + for (size_t i = 0; i < m_data->GetFormatCount(); i++) + { + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard now supports atom %s"), + array[i].GetId().c_str() ); + +#if 0 + gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget), + clipboard, + array[i], + 0 ); /* what is info ? */ +#endif } - - return FALSE; + + delete[] array; + +#if 0 + gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), + "selection_get", + GTK_SIGNAL_FUNC(selection_handler), + (gpointer) NULL ); +#endif + +#if wxUSE_THREADS + /* disable GUI threads */ +#endif + + bool res = false; +#if 0 + /* Tell the world we offer clipboard data */ + res = (gtk_selection_owner_set( m_clipboardWidget, + clipboard, + (guint32) GDK_CURRENT_TIME )); +#endif + + if (m_usePrimary) + m_ownsPrimarySelection = res; + else + m_ownsClipboard = res; + +#if wxUSE_THREADS + /* re-enable GUI threads */ +#endif + + return res; +#endif } void wxClipboard::Close() { - wxCHECK_RET( m_open, "clipboard not open" ); - - m_open = FALSE; - wxCloseClipboard(); + wxCHECK_RET( m_open, wxT("clipboard not open") ); + + m_open = false; } -bool wxClipboard::IsSupported( const wxDataFormat& format) +bool wxClipboard::IsOpened() const { - return wxIsClipboardFormatAvailable(format); + return m_open; } -bool wxClipboard::GetData( wxDataObject& data ) +bool wxClipboard::IsSupported( const wxDataFormat& format ) { - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); - - wxDataFormat::NativeFormat format = data.GetPreferredFormat().GetType(); - switch ( format ) - { - case wxDF_TEXT: - case wxDF_OEMTEXT: - { - wxTextDataObject& textDataObject = (wxTextDataObject &) data; - char* s = (char*) wxGetClipboardData(format); - if (s) - { - textDataObject.SetText(s); - delete[] s; - return TRUE; - } - else - return FALSE; - break; - } -/* - case wxDF_BITMAP: - case wxDF_DIB: - { - wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data; - wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetType()); - if (bitmap) - { - bitmapDataObject->SetBitmap(* bitmap); - delete bitmap; - return TRUE; - } - else - return FALSE; - break; - } -*/ - default: - { - return FALSE; - } - } - return FALSE; -} + /* reentrance problems */ + if (m_waiting) return false; + + /* store requested format to be asked for by callbacks */ + m_targetRequested = format; + +#if 0 + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard:IsSupported: requested format: %s"), + format.GetId().c_str() ); +#endif + + wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") ); + + m_formatSupported = false; + + /* perform query. this will set m_formatSupported to + true if m_targetRequested is supported. + also, we have to wait for the "answer" from the + clipboard owner which is an asynchronous process. + therefore we set m_waiting = true here and wait + until the callback "targets_selection_received" + sets it to false */ + + m_waiting = true; #if 0 + gtk_selection_convert( m_targetsWidget, + m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY + : g_clipboardAtom, + g_targetsAtom, + (guint32) GDK_CURRENT_TIME ); -/* -* Old clipboard implementation by Matthew Flatt -*/ + while (m_waiting) gtk_main_iteration(); +#endif -wxClipboard *wxTheClipboard = NULL; + if (!m_formatSupported) return false; -void wxInitClipboard() -{ - if (!wxTheClipboard) - wxTheClipboard = new wxClipboard; + return true; } -wxClipboard::wxClipboard() +bool wxClipboard::GetData( wxDataObject& data ) { - clipOwner = NULL; - cbString = NULL; -} + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); -wxClipboard::~wxClipboard() -{ - if (clipOwner) - clipOwner->BeingReplaced(); - if (cbString) - delete[] cbString; -} + /* get formats from wxDataObjects */ + wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ]; + data.GetAllFormats( array ); -static int FormatStringToID(char *str) -{ - if (!strcmp(str, "TEXT")) - return wxDF_TEXT; - - return wxRegisterClipboardFormat(str); -} + for (size_t i = 0; i < data.GetFormatCount(); i++) + { + wxDataFormat format( array[i] ); -void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time) -{ - bool got_selection; - - if (clipOwner) - clipOwner->BeingReplaced(); - clipOwner = client; - if (cbString) { - delete[] cbString; - cbString = NULL; - } - - if (wxOpenClipboard()) { - char **formats, *data; - int i; - int ftype; - long size; - - formats = clipOwner->formats.ListToArray(FALSE); - for (i = clipOwner->formats.Number(); i--; ) { - ftype = FormatStringToID(formats[i]); - data = clipOwner->GetData(formats[i], &size); - if (!wxSetClipboardData(ftype, (wxObject *)data, size, 1)) { - got_selection = FALSE; - break; - } - } - - if (i < 0) - got_selection = wxCloseClipboard(); - } else - got_selection = FALSE; - - got_selection = FALSE; // Assume another process takes over - - if (!got_selection) { - clipOwner->BeingReplaced(); - clipOwner = NULL; - } -} + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard::GetData: requested format: %s"), + format.GetId().c_str() ); -wxClipboardClient *wxClipboard::GetClipboardClient() -{ - return clipOwner; -} + /* is data supported by clipboard ? */ -void wxClipboard::SetClipboardString(char *str, long time) -{ - bool got_selection; - - if (clipOwner) { - clipOwner->BeingReplaced(); - clipOwner = NULL; - } - if (cbString) - delete[] cbString; - - cbString = str; - - if (wxOpenClipboard()) { - if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str)) - got_selection = FALSE; - else - got_selection = wxCloseClipboard(); - } else - got_selection = FALSE; - - got_selection = FALSE; // Assume another process takes over - - if (!got_selection) { - delete[] cbString; - cbString = NULL; - } -} + /* store requested format to be asked for by callbacks */ + m_targetRequested = format; -char *wxClipboard::GetClipboardString(long time) -{ - char *str; - long length; - - str = GetClipboardData("TEXT", &length, time); - if (!str) { - str = new char[1]; - *str = 0; - } - - return str; -} + wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") ); -char *wxClipboard::GetClipboardData(char *format, long *length, long time) -{ - if (clipOwner) { - if (clipOwner->formats.Member(format)) - return clipOwner->GetData(format, length); - else - return NULL; - } else if (cbString) { - if (!strcmp(format, "TEXT")) - return copystring(cbString); - else - return NULL; - } else { - if (wxOpenClipboard()) { - receivedString = (char *)wxGetClipboardData(FormatStringToID(format), - length); - wxCloseClipboard(); - } else - receivedString = NULL; - - return receivedString; + m_formatSupported = false; + + /* perform query. this will set m_formatSupported to + true if m_targetRequested is supported. + also, we have to wait for the "answer" from the + clipboard owner which is an asynchronous process. + therefore we set m_waiting = true here and wait + until the callback "targets_selection_received" + sets it to false */ + + m_waiting = true; + +#if 0 + gtk_selection_convert( m_targetsWidget, + m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY + : g_clipboardAtom, + g_targetsAtom, + (guint32) GDK_CURRENT_TIME ); + + while (m_waiting) gtk_main_iteration(); +#endif + + if (!m_formatSupported) continue; + + /* store pointer to data object to be filled up by callbacks */ + m_receivedData = &data; + + /* store requested format to be asked for by callbacks */ + m_targetRequested = format; + + wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") ); + + /* start query */ + m_formatSupported = false; + + /* ask for clipboard contents. this will set + m_formatSupported to true if m_targetRequested + is supported. + also, we have to wait for the "answer" from the + clipboard owner which is an asynchronous process. + therefore we set m_waiting = true here and wait + until the callback "targets_selection_received" + sets it to false */ + + m_waiting = true; + + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard::GetData: format found, start convert") ); + +#if 0 + gtk_selection_convert( m_clipboardWidget, + m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY + : g_clipboardAtom, + m_targetRequested, + (guint32) GDK_CURRENT_TIME ); + + while (m_waiting) gtk_main_iteration(); +#endif + + /* this is a true error as we checked for the presence of such data before */ + wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") ); + + /* return success */ + delete[] array; + return true; } + + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard::GetData: format not found") ); + + /* return failure */ + delete[] array; + return false; } -#endif -#endif // wxUSE_CLIPBOARD +#endif + // wxUSE_CLIPBOARD