From: Robert Roebling Date: Sat, 23 Feb 2002 21:26:16 +0000 (+0000) Subject: Implemented a simple modality under X11. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9691c806e6fbb08b01c9eec9998ad1e8242c7df3 Implemented a simple modality under X11. Filled wxDataFormat and wxDataObject etc. Added skeleton for X11 clipboard. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14370 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/configure b/configure index 09e2d2230a..a71f11ee89 100755 --- a/configure +++ b/configure @@ -19604,22 +19604,15 @@ EOF fi if test "$wxUSE_CLIPBOARD" = "yes"; then - if test "$wxUSE_X11" = 1; then - echo "configure: warning: Clipboard not yet supported under X11... disabled" 1>&2 - wxUSE_CLIPBOARD=no - fi - - if test "$wxUSE_CLIPBOARD" = "yes"; then - cat >> confdefs.h <<\EOF + cat >> confdefs.h <<\EOF #define wxUSE_CLIPBOARD 1 EOF - cat >> confdefs.h <<\EOF + cat >> confdefs.h <<\EOF #define wxUSE_DATAOBJ 1 EOF - fi fi if test "$wxUSE_DRAG_AND_DROP" = "yes" ; then @@ -20509,7 +20502,7 @@ SAMPLES_SUBDIRS="`echo $SAMPLES_SUBDIRS | tr -s ' ' | tr ' ' '\n' | sort | uniq echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:20513: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:20506: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 diff --git a/configure.in b/configure.in index 3c503999c2..6c33b87e55 100644 --- a/configure.in +++ b/configure.in @@ -4115,17 +4115,10 @@ if test "$wxUSE_IPC" = "yes"; then fi if test "$wxUSE_CLIPBOARD" = "yes"; then - if test "$wxUSE_X11" = 1; then - AC_MSG_WARN([Clipboard not yet supported under X11... disabled]) - wxUSE_CLIPBOARD=no - fi + AC_DEFINE(wxUSE_CLIPBOARD) - if test "$wxUSE_CLIPBOARD" = "yes"; then - AC_DEFINE(wxUSE_CLIPBOARD) - - dnl required by clipboard code in configuration check - AC_DEFINE(wxUSE_DATAOBJ) - fi + dnl required by clipboard code in configuration check + AC_DEFINE(wxUSE_DATAOBJ) fi if test "$wxUSE_DRAG_AND_DROP" = "yes" ; then diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index 8f3c52b261..2c294e8d73 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -1186,6 +1186,7 @@ colour.h X11H cursor.h X11H dataform.h X11H dataobj.h X11H +dataobj2.h X11H dc.h X11H dcclient.h X11H dcmemory.h X11H diff --git a/include/wx/dataobj.h b/include/wx/dataobj.h index 82c501598f..e367c29194 100644 --- a/include/wx/dataobj.h +++ b/include/wx/dataobj.h @@ -460,6 +460,8 @@ private: #else // !__WXMSW__ #if defined(__WXGTK__) #include "wx/gtk/dataobj2.h" + #elif defined(__WXX11__) + #include "wx/x11/dataobj2.h" #elif defined(__WXMAC__) #include "wx/mac/dataobj2.h" #elif defined(__WXPM__) diff --git a/include/wx/x11/clipbrd.h b/include/wx/x11/clipbrd.h index 848bfe6565..1a42d17cb6 100644 --- a/include/wx/x11/clipbrd.h +++ b/include/wx/x11/clipbrd.h @@ -1,84 +1,88 @@ ///////////////////////////////////////////////////////////////////////////// // Name: clipbrd.h // Purpose: Clipboard functionality. -// Author: Julian Smart -// Modified by: +// Author: Robert Roebling // Created: 17/09/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_CLIPBRD_H_ -#define _WX_CLIPBRD_H_ +#ifndef __X11CLIPBOARDH__ +#define __X11CLIPBOARDH__ #ifdef __GNUG__ -#pragma interface "clipbrd.h" +#pragma interface #endif #if wxUSE_CLIPBOARD +#include "wx/object.h" #include "wx/list.h" +#include "wx/dataobj.h" +#include "wx/control.h" +#include "wx/module.h" -bool WXDLLEXPORT wxOpenClipboard(); -bool WXDLLEXPORT wxClipboardOpen(); -bool WXDLLEXPORT wxCloseClipboard(); -bool WXDLLEXPORT wxEmptyClipboard(); -bool WXDLLEXPORT wxIsClipboardFormatAvailable(wxDataFormat dataFormat); -bool WXDLLEXPORT wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int width = 0, int height = 0); -wxObject* WXDLLEXPORT wxGetClipboardData(wxDataFormat dataFormat, long *len = NULL); -wxDataFormat WXDLLEXPORT wxEnumClipboardFormats(wxDataFormat dataFormat); -wxDataFormat WXDLLEXPORT wxRegisterClipboardFormat(char *formatName); -bool WXDLLEXPORT wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int maxCount); - -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxClipboard -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- class wxClipboard : public wxClipboardBase { public: wxClipboard(); ~wxClipboard(); - + // open the clipboard before SetData() and GetData() virtual bool Open(); - + // close the clipboard after SetData() and GetData() virtual void Close(); - - // opened? - virtual bool IsOpened() const { return m_open; } - - // replaces the data on the clipboard with data + + // query whether the clipboard is opened + virtual bool IsOpened() const; + + // set the clipboard data. all other formats will be deleted. virtual bool SetData( wxDataObject *data ); - - // adds data to the clipboard + + // add to the clipboard data. virtual bool AddData( wxDataObject *data ); - - // format available on the clipboard ? + + // ask if data in correct format is available virtual bool IsSupported( const wxDataFormat& format ); - + // fill data with data on the clipboard (if available) virtual bool GetData( wxDataObject& data ); - + // clears wxTheClipboard and the system's clipboard if possible virtual void Clear(); - + + // If primary == TRUE, use primary selection in all further ops, + // primary == FALSE resets it. virtual void UsePrimarySelection(bool primary = TRUE) - { m_usePrimary = primary; } + { m_usePrimary = primary; } // implementation from now on - bool m_open; - wxList m_data; + bool m_ownsClipboard; + bool m_ownsPrimarySelection; + wxDataObject *m_data; + + WXWindow m_clipboardWidget; /* for getting and offering data */ + WXWindow m_targetsWidget; /* for getting list of supported formats */ + bool m_waiting; /* querying data or formats is asynchronous */ + + bool m_formatSupported; + Atom m_targetRequested; bool m_usePrimary; - + wxDataObject *m_receivedData; + private: DECLARE_DYNAMIC_CLASS(wxClipboard) }; -#endif // wxUSE_CLIPBOARD +#endif + // wxUSE_CLIPBOARD #endif -// _WX_CLIPBRD_H_ + // __X11CLIPBOARDH__ diff --git a/include/wx/x11/dataform.h b/include/wx/x11/dataform.h index eebf507e23..006f7b0e38 100644 --- a/include/wx/x11/dataform.h +++ b/include/wx/x11/dataform.h @@ -9,8 +9,8 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_MOTIF_DATAFORM_H -#define _WX_MOTIF_DATAFORM_H +#ifndef _WX_X11_DATAFORM_H +#define _WX_X11_DATAFORM_H class wxDataFormat { @@ -25,17 +25,17 @@ public: wxDataFormat( NativeFormat format ); wxDataFormat& operator=(NativeFormat format) - { SetId(format); return *this; } + { SetId(format); return *this; } // comparison (must have both versions) bool operator==(NativeFormat format) const - { return m_format == (NativeFormat)format; } + { return m_format == (NativeFormat)format; } bool operator!=(NativeFormat format) const - { return m_format != (NativeFormat)format; } + { return m_format != (NativeFormat)format; } bool operator==(wxDataFormatId format) const - { return m_type == (wxDataFormatId)format; } + { return m_type == (wxDataFormatId)format; } bool operator!=(wxDataFormatId format) const - { return m_type != (wxDataFormatId)format; } + { return m_type != (wxDataFormatId)format; } // explicit and implicit conversions to NativeFormat which is one of // standard data types (implicit conversion is useful for preserving the @@ -62,5 +62,5 @@ private: }; -#endif // _WX_MOTIF_DATAFORM_H +#endif // _WX_X11_DATAFORM_H diff --git a/include/wx/x11/dataobj.h b/include/wx/x11/dataobj.h index 77064e648d..6dc89e60e4 100644 --- a/include/wx/x11/dataobj.h +++ b/include/wx/x11/dataobj.h @@ -3,12 +3,12 @@ // Purpose: declaration of the wxDataObject class for Motif // Author: Julian Smart // RCS-ID: $Id$ -// Copyright: (c) 1998 Julian Smart +// Copyright: (c) 1998 Robert Roebling // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_MOTIF_DATAOBJ_H_ -#define _WX_MOTIF_DATAOBJ_H_ +#ifndef _WX_X11_DATAOBJ_H_ +#define _WX_X11_DATAOBJ_H_ #ifdef __GNUG__ #pragma interface "dataobj.h" @@ -21,10 +21,14 @@ class wxDataObject : public wxDataObjectBase { public: + wxDataObject(); + #ifdef __DARWIN__ ~wxDataObject() { } #endif + + virtual bool IsSupportedFormat( const wxDataFormat& format, Direction dir = Get ) const; }; -#endif //_WX_MOTIF_DATAOBJ_H_ +#endif //_WX_X11_DATAOBJ_H_ diff --git a/include/wx/x11/dataobj2.h b/include/wx/x11/dataobj2.h new file mode 100644 index 0000000000..74562e6d79 --- /dev/null +++ b/include/wx/x11/dataobj2.h @@ -0,0 +1,89 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: gtk/dataobj2.h +// Purpose: declaration of standard wxDataObjectSimple-derived classes +// Author: Robert Roebling +// Created: 19.10.99 (extracted from gtk/dataobj.h) +// RCS-ID: $Id$ +// Copyright: (c) 1998, 1999 Vadim Zeitlin, Robert Roebling +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_X11_DATAOBJ2_H_ +#define _WX_X11_DATAOBJ2_H_ + +#ifdef __GNUG__ + #pragma interface "dataobj.h" +#endif + +// ---------------------------------------------------------------------------- +// wxBitmapDataObject is a specialization of wxDataObject for bitmaps +// ---------------------------------------------------------------------------- + +class wxBitmapDataObject : public wxBitmapDataObjectBase +{ +public: + // ctors + wxBitmapDataObject(); + wxBitmapDataObject(const wxBitmap& bitmap); + + // destr + ~wxBitmapDataObject(); + + // override base class virtual to update PNG data too + virtual void SetBitmap(const wxBitmap& bitmap); + + // implement base class pure virtuals + // ---------------------------------- + + virtual size_t GetDataSize() const { return m_pngSize; } + virtual bool GetDataHere(void *buf) const; + virtual bool SetData(size_t len, const void *buf); + +protected: + void Init() { m_pngData = (void *)NULL; m_pngSize = 0; } + void Clear() { free(m_pngData); } + void ClearAll() { Clear(); Init(); } + + size_t m_pngSize; + void *m_pngData; + + void DoConvertToPng(); + +private: + // virtual function hiding supression + size_t GetDataSize(const wxDataFormat& format) const + { return(wxDataObjectSimple::GetDataSize(format)); } + bool GetDataHere(const wxDataFormat& format, void* pBuf) const + { return(wxDataObjectSimple::GetDataHere(format, pBuf)); } + bool SetData(const wxDataFormat& format, size_t nLen, const void* pBuf) + { return(wxDataObjectSimple::SetData(format, nLen, pBuf)); } +}; + +// ---------------------------------------------------------------------------- +// wxFileDataObject is a specialization of wxDataObject for file names +// ---------------------------------------------------------------------------- + +class wxFileDataObject : public wxFileDataObjectBase +{ +public: + // implement base class pure virtuals + // ---------------------------------- + + void AddFile( const wxString &filename ); + + virtual size_t GetDataSize() const; + virtual bool GetDataHere(void *buf) const; + virtual bool SetData(size_t len, const void *buf); + +private: + // virtual function hiding supression + size_t GetDataSize(const wxDataFormat& format) const + { return(wxDataObjectSimple::GetDataSize(format)); } + bool GetDataHere(const wxDataFormat& format, void* pBuf) const + { return(wxDataObjectSimple::GetDataHere(format, pBuf)); } + bool SetData(const wxDataFormat& format, size_t nLen, const void* pBuf) + { return(wxDataObjectSimple::SetData(format, nLen, pBuf)); } +}; + +#endif // _WX_X11_DATAOBJ2_H_ + diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp index b077830509..5ba383e3c3 100644 --- a/samples/minimal/minimal.cpp +++ b/samples/minimal/minimal.cpp @@ -174,9 +174,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { - char *test = NULL; - *test = 0; - // TRUE is to force the frame to close Close(TRUE); } diff --git a/src/x11/app.cpp b/src/x11/app.cpp index c84e7fb90e..39f1eb2d53 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -435,7 +435,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) wxKeyEvent keyEvent(wxEVT_KEY_DOWN); wxTranslateKeyEvent(keyEvent, win, window, event); - wxLogDebug( "OnKey from %s", win->GetName().c_str() ); + // wxLogDebug( "OnKey from %s", win->GetName().c_str() ); // We didn't process wxEVT_KEY_DOWN, so send // wxEVT_CHAR @@ -598,14 +598,20 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (!win->IsEnabled()) return; + + // Here we check if the top level window is + // disabled, which is one aspect of modality. + wxWindow *tlw = win; + while (tlw && !tlw->IsTopLevel()) + tlw = tlw->GetParent(); + if (tlw && !tlw->IsEnabled()) + return; -#if 1 if (event->type == ButtonPress) { if ((win != wxWindow::FindFocus()) && win->AcceptsFocus()) win->SetFocus(); } -#endif wxMouseEvent wxevent; wxTranslateMouseEvent(wxevent, win, window, event); @@ -618,7 +624,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (win && event->xfocus.detail != NotifyPointer) #endif { - wxLogDebug( "FocusIn from %s", win->GetName().c_str() ); + // wxLogDebug( "FocusIn from %s", win->GetName().c_str() ); wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId()); focusEvent.SetEventObject(win); @@ -632,7 +638,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (win && event->xfocus.detail != NotifyPointer) #endif { - wxLogDebug( "FocusOut from %s", win->GetName().c_str() ); + // wxLogDebug( "FocusOut from %s", win->GetName().c_str() ); wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId()); focusEvent.SetEventObject(win); diff --git a/src/x11/clipbrd.cpp b/src/x11/clipbrd.cpp index 42446b71af..0e57fb9ba2 100644 --- a/src/x11/clipbrd.cpp +++ b/src/x11/clipbrd.cpp @@ -1,252 +1,276 @@ ///////////////////////////////////////////////////////////////////////////// // Name: 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 +// Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -#pragma implementation #pragma implementation "clipbrd.h" #endif -#include "wx/defs.h" +#include "wx/clipbrd.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" +#include "wx/utils.h" +#include "wx/log.h" -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#include -#include -#ifdef __VMS__ -#pragma message enable nosimpint -#endif +#include "wx/x11/private.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +Atom g_clipboardAtom = 0; +Atom g_targetsAtom = 0; -#include +// 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 = _T("clipboard"); -// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) -// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject) +//----------------------------------------------------------------------------- +// reminder +//----------------------------------------------------------------------------- -static bool gs_clipboardIsOpen = FALSE; +/* 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) -bool wxOpenClipboard() +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, + _T("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) -{ - // TODO - return FALSE; -#if 0 - // 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()->GetTopWindow() ); + 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; -#endif -} + 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)) -{ - // TODO - return FALSE; -#if 0 - 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; -#endif + wxTheClipboard->m_formatSupported = TRUE; + clipboard->m_waiting = FALSE; } -wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len) -{ - // TODO - return FALSE; -#if 0 - 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" )); + + delete wxTheClipboard->m_data; + wxTheClipboard->m_data = (wxDataObject*) NULL; + } } - return NULL; -#endif + 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 ) { - 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 //----------------------------------------------------------------------------- @@ -256,38 +280,95 @@ IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject) wxClipboard::wxClipboard() { m_open = FALSE; + + m_ownsClipboard = FALSE; + m_ownsPrimarySelection = FALSE; + + m_data = (wxDataObject*) NULL; + m_receivedData = (wxDataObject*) NULL; + + /* we use m_targetsWidget to query what formats are available */ + + /* we use m_clipboardWidget to get and to offer data */ + + if (!g_clipboardAtom) g_clipboardAtom = XInternAtom( (Display*) wxGetDisplay(), "CLIPBOARD", False ); + if (!g_targetsAtom) g_targetsAtom = XInternAtom( (Display*) wxGetDisplay(), "TARGETS", False ); + + m_formatSupported = FALSE; + m_targetRequested = 0; + + m_usePrimary = FALSE; } 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( (GtkWidget*) 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( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY, + (guint32) GDK_CURRENT_TIME ); + + while (m_waiting) gtk_main_iteration(); + } +#endif + + if (m_data) + { + delete m_data; + m_data = (wxDataObject*) NULL; + } + +#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" ); - + wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") ); + m_open = TRUE; - return wxOpenClipboard(); + 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(); @@ -296,242 +377,224 @@ 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" ); + 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 ) + /* primary selection or clipboard */ + Atom clipboard = m_usePrimary ? (Atom) 1 // 1 = primary selection + : g_clipboardAtom; + + + for (size_t i = 0; i < m_data->GetFormatCount(); i++) { - case wxDF_TEXT: - case wxDF_OEMTEXT: - { - wxTextDataObject* textDataObject = (wxTextDataObject*) data; - wxString str(textDataObject->GetText()); - return wxSetClipboardData(format, (wxObject*) (const char*) str); - } + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard now supports atom %s"), + array[i].GetId().c_str() ); + #if 0 - case wxDF_BITMAP: - case wxDF_DIB: - { - wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data; - wxBitmap bitmap(bitmapDataObject->GetBitmap()); - return wxSetClipboardData(data->GetType(), & bitmap); - break; - } -#endif // 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; } void wxClipboard::Close() { - wxCHECK_RET( m_open, "clipboard not open" ); - + wxCHECK_RET( m_open, wxT("clipboard not open") ); + m_open = FALSE; - wxCloseClipboard(); } -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 -/* -* Old clipboard implementation by Matthew Flatt -*/ + wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") ); -wxClipboard *wxTheClipboard = NULL; + m_formatSupported = FALSE; -void wxInitClipboard() -{ - if (!wxTheClipboard) - wxTheClipboard = new wxClipboard; -} + /* 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 */ -wxClipboard::wxClipboard() -{ - clipOwner = NULL; - cbString = NULL; -} + m_waiting = TRUE; -wxClipboard::~wxClipboard() -{ - if (clipOwner) - clipOwner->BeingReplaced(); - if (cbString) - delete[] cbString; -} +#if 0 + gtk_selection_convert( m_targetsWidget, + m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY + : g_clipboardAtom, + g_targetsAtom, + (guint32) GDK_CURRENT_TIME ); -static int FormatStringToID(char *str) -{ - if (!strcmp(str, "TEXT")) - return wxDF_TEXT; - - return wxRegisterClipboardFormat(str); -} + while (m_waiting) gtk_main_iteration(); +#endif -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; - } -} + if (!m_formatSupported) return FALSE; -wxClipboardClient *wxClipboard::GetClipboardClient() -{ - return clipOwner; + return TRUE; } -void wxClipboard::SetClipboardString(char *str, long time) +bool wxClipboard::GetData( wxDataObject& data ) { - 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; - } -} + wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") ); -char *wxClipboard::GetClipboardString(long time) -{ - char *str; - long length; - - str = GetClipboardData("TEXT", &length, time); - if (!str) { - str = new char[1]; - *str = 0; - } - - return str; -} + /* get formats from wxDataObjects */ + wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ]; + data.GetAllFormats( array ); -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; + for (size_t i = 0; i < data.GetFormatCount(); i++) + { + wxDataFormat format( array[i] ); + + wxLogTrace( TRACE_CLIPBOARD, + wxT("wxClipboard::GetData: requested format: %s"), + format.GetId().c_str() ); + + /* is data supported by clipboard ? */ + + /* store requested format to be asked for by callbacks */ + m_targetRequested = format; + + 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 ); + + 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 + // wxUSE_CLIPBOARD -#endif // wxUSE_CLIPBOARD diff --git a/src/x11/data.cpp b/src/x11/data.cpp index 0387862c7b..b094b7389e 100644 --- a/src/x11/data.cpp +++ b/src/x11/data.cpp @@ -120,8 +120,6 @@ const char *wxGetTextFromUserPromptStr = "Input Text"; const char *wxMessageBoxCaptionStr = "Message"; const char *wxFileSelectorPromptStr = "Select a file"; const char *wxFileSelectorDefaultWildcardStr = "*.*"; -const char *wxInternalErrorStr = "wxWindows Internal Error"; -const char *wxFatalErrorStr = "wxWindows Fatal Error"; const char *wxDirDialogNameStr = "wxDirCtrl"; const char *wxDirDialogDefaultFolderStr = "/"; const wxChar *wxTreeCtrlNameStr = wxT("wxTreeCtrl"); diff --git a/src/x11/dataobj.cpp b/src/x11/dataobj.cpp index ebc3d70da1..75028159fe 100644 --- a/src/x11/dataobj.cpp +++ b/src/x11/dataobj.cpp @@ -8,22 +8,16 @@ /////////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -#pragma implementation "dataobj.h" + #pragma implementation "dataobj.h" #endif #include "wx/defs.h" -#if wxUSE_CLIPBOARD - #include "wx/dataobj.h" +#include "wx/mstream.h" #include "wx/app.h" +#include "wx/image.h" -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#ifdef __VMS__ -#pragma message enable nosimpint -#endif #include "wx/utils.h" #include "wx/x11/private.h" @@ -142,59 +136,237 @@ void wxDataFormat::PrepareFormats() if (!g_pngAtom) g_pngAtom = XInternAtom( (Display*) wxGetDisplay(), "image/png", FALSE ); if (!g_fileAtom) - g_fileAtom = XInternAtom( (Display*) wxGetDisplay(), "file:ALL", FALSE ); + g_fileAtom = XInternAtom( (Display*) wxGetDisplay(), "text/uri-list", FALSE ); } -#if 0 +//------------------------------------------------------------------------- +// wxDataObject +//------------------------------------------------------------------------- + +wxDataObject::wxDataObject() +{ +} + +bool wxDataObject::IsSupportedFormat(const wxDataFormat& format, Direction dir) const +{ + size_t nFormatCount = GetFormatCount(dir); + if ( nFormatCount == 1 ) + { + return format == GetPreferredFormat(); + } + else + { + wxDataFormat *formats = new wxDataFormat[nFormatCount]; + GetAllFormats(formats,dir); + + size_t n; + for ( n = 0; n < nFormatCount; n++ ) + { + if ( formats[n] == format ) + break; + } + + delete [] formats; + + // found? + return n < nFormatCount; + } +} // ---------------------------------------------------------------------------- -// wxPrivateDataObject +// wxFileDataObject // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS( wxPrivateDataObject, wxDataObject ) +bool wxFileDataObject::GetDataHere(void *buf) const +{ + wxString filenames; + + for (size_t i = 0; i < m_filenames.GetCount(); i++) + { + filenames += m_filenames[i]; + filenames += (wxChar) 0; + } + + memcpy( buf, filenames.mbc_str(), filenames.Len() + 1 ); + + return TRUE; +} -void wxPrivateDataObject::Free() +size_t wxFileDataObject::GetDataSize() const { - if ( m_data ) - free(m_data); + size_t res = 0; + + for (size_t i = 0; i < m_filenames.GetCount(); i++) + { + res += m_filenames[i].Len(); + res += 1; + } + + return res + 1; } -wxPrivateDataObject::wxPrivateDataObject() +bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *buf) { - wxString id = wxT("application/"); - id += wxTheApp->GetAppName(); + // VZ: old format +#if 0 + // filenames are stores as a string with #0 as deliminators + const char *filenames = (const char*) buf; + size_t pos = 0; + for(;;) + { + if (filenames[0] == 0) + break; + if (pos >= size) + break; + wxString file( filenames ); // this returns the first file + AddFile( file ); + pos += file.Len()+1; + filenames += file.Len()+1; + } +#else // 1 + m_filenames.Empty(); + + // the text/uri-list format is a sequence of URIs (filenames prefixed by + // "file:" as far as I see) delimited by "\r\n" of total length size + // (I wonder what happens if the file has '\n' in its filename??) + wxString filename; + for ( const char *p = (const char *)buf; ; p++ ) + { + // some broken programs (testdnd GTK+ sample!) omit the trailing + // "\r\n", so check for '\0' explicitly here instead of doing it in + // the loop statement to account for it + if ( (*p == '\r' && *(p+1) == '\n') || !*p ) + { + size_t lenPrefix = 5; // strlen("file:") + if ( filename.Left(lenPrefix).MakeLower() == _T("file:") ) + { + // sometimes the syntax is "file:filename", sometimes it's + // URL-like: "file://filename" - deal with both + if ( filename[lenPrefix] == _T('/') && + filename[lenPrefix + 1] == _T('/') ) + { + // skip the slashes + lenPrefix += 2; + } + + AddFile(filename.c_str() + lenPrefix); + filename.Empty(); + } + else + { + wxLogDebug(_T("Unsupported URI '%s' in wxFileDataObject"), + filename.c_str()); + } + + if ( !*p ) + break; + + // skip '\r' + p++; + } + else + { + filename += *p; + } + } +#endif // 0/1 - m_format.SetId( id ); + return TRUE; +} - m_size = 0; - m_data = (void *)NULL; +void wxFileDataObject::AddFile( const wxString &filename ) +{ + m_filenames.Add( filename ); } -void wxPrivateDataObject::SetData( const void *data, size_t size ) +// ---------------------------------------------------------------------------- +// wxBitmapDataObject +// ---------------------------------------------------------------------------- + +wxBitmapDataObject::wxBitmapDataObject() { - Free(); + Init(); +} - m_size = size; - m_data = malloc(size); +wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap ) + : wxBitmapDataObjectBase(bitmap) +{ + Init(); - memcpy( m_data, data, size ); + DoConvertToPng(); } -void wxPrivateDataObject::WriteData( void *dest ) const +wxBitmapDataObject::~wxBitmapDataObject() { - WriteData( m_data, dest ); + Clear(); } -size_t wxPrivateDataObject::GetSize() const +void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap ) { - return m_size; + ClearAll(); + + wxBitmapDataObjectBase::SetBitmap(bitmap); + + DoConvertToPng(); } -void wxPrivateDataObject::WriteData( const void *data, void *dest ) const +bool wxBitmapDataObject::GetDataHere(void *buf) const { - memcpy( dest, data, GetSize() ); + if ( !m_pngSize ) + { + wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") ); + + return FALSE; + } + + memcpy(buf, m_pngData, m_pngSize); + + return TRUE; } -#endif // 0 +bool wxBitmapDataObject::SetData(size_t size, const void *buf) +{ + Clear(); + +#if wxUSE_LIBPNG + m_pngSize = size; + m_pngData = malloc(m_pngSize); + + memcpy( m_pngData, buf, m_pngSize ); + + wxMemoryInputStream mstream( (char*) m_pngData, m_pngSize ); + wxImage image; + wxPNGHandler handler; + if ( !handler.LoadFile( &image, mstream ) ) + { + return FALSE; + } + + m_bitmap = image.ConvertToBitmap(); + + return m_bitmap.Ok(); +#else + return FALSE; +#endif +} + +void wxBitmapDataObject::DoConvertToPng() +{ +#if wxUSE_LIBPNG + if (!m_bitmap.Ok()) + return; + + wxImage image( m_bitmap ); + wxPNGHandler handler; + + wxCountingOutputStream count; + handler.SaveFile( &image, count ); + + m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ??? + m_pngData = malloc(m_pngSize); + + wxMemoryOutputStream mstream( (char*) m_pngData, m_pngSize ); + handler.SaveFile( &image, mstream ); +#endif +} -#endif // wxUSE_CLIPBOARD diff --git a/src/x11/files.lst b/src/x11/files.lst index e2c29117d2..96c5323cf2 100644 --- a/src/x11/files.lst +++ b/src/x11/files.lst @@ -473,6 +473,7 @@ ALL_HEADERS = \ x11/cursor.h \ x11/dataform.h \ x11/dataobj.h \ + x11/dataobj2.h \ x11/dc.h \ x11/dcclient.h \ x11/dcmemory.h \ diff --git a/src/x11/toplevel.cpp b/src/x11/toplevel.cpp index 9019174594..400891ac1d 100644 --- a/src/x11/toplevel.cpp +++ b/src/x11/toplevel.cpp @@ -447,14 +447,14 @@ bool wxSetWMDecorations(Window w, long style) if (style & wxRESIZE_BORDER) { - wxLogDebug("MWM_DECOR_RESIZEH"); + // wxLogDebug("MWM_DECOR_RESIZEH"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_RESIZEH; } if (style & wxSYSTEM_MENU) { - wxLogDebug("MWM_DECOR_MENU"); + // wxLogDebug("MWM_DECOR_MENU"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_MENU; } @@ -463,28 +463,28 @@ bool wxSetWMDecorations(Window w, long style) (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)) { - wxLogDebug("MWM_DECOR_TITLE"); + // wxLogDebug("MWM_DECOR_TITLE"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_TITLE; } if ((style & wxTHICK_FRAME) || (style & wxSIMPLE_BORDER) || (style & wxCAPTION)) { - wxLogDebug("MWM_DECOR_BORDER"); + // wxLogDebug("MWM_DECOR_BORDER"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_BORDER; } if (style & wxMINIMIZE_BOX) { - wxLogDebug("MWM_DECOR_MINIMIZE"); + // wxLogDebug("MWM_DECOR_MINIMIZE"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_MINIMIZE; } if (style & wxMAXIMIZE_BOX) { - wxLogDebug("MWM_DECOR_MAXIMIZE"); + // wxLogDebug("MWM_DECOR_MAXIMIZE"); hints.flags |= MWM_HINTS_DECORATIONS; hints.decorations |= MWM_DECOR_MAXIMIZE; } @@ -585,14 +585,11 @@ void wxTopLevelWindowX11::DoSetClientSize(int width, int height) void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - wxString msg; - msg.Printf("Setting pos: %d, %d", x, y); - wxLogDebug(msg); + wxLogDebug( "Setting pos: %d, %d", x, y ); wxWindowX11::DoSetSize(x, y, width, height, sizeFlags); wxPoint pt = GetPosition(); - msg.Printf("After, pos: %d, %d", pt.x, pt.y); - wxLogDebug(msg); + wxLogDebug( "After, pos: %d, %d", pt.x, pt.y ); #if 0 XSync(wxGlobalDisplay(), False); int w, h; @@ -646,8 +643,8 @@ void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const Window window = (Window) m_mainWidget; if (window) { - int offsetX = 0; - int offsetY = 0; + int offsetX = 0; + int offsetY = 0; #if !wxUSE_NANOX wxLogDebug("Translating..."); @@ -655,9 +652,7 @@ void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const XTranslateCoordinates(wxGlobalDisplay(), window, XDefaultRootWindow(wxGlobalDisplay()), 0, 0, & offsetX, & offsetY, & childWindow); - wxString msg; - msg.Printf("Offset: %d, %d", offsetX, offsetY); - wxLogDebug(msg); + wxLogDebug("Offset: %d, %d", offsetX, offsetY); #endif XWindowAttributes attr; diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 13a199db53..836d5c2202 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -383,7 +383,7 @@ void wxWindowX11::DoCaptureMouse() return; } - wxLogDebug("Grabbed pointer in %s", GetName().c_str() ); + // wxLogDebug("Grabbed pointer in %s", GetName().c_str() ); #if 0 res = XGrabButton(wxGlobalDisplay(), AnyButton, AnyModifier, @@ -443,7 +443,7 @@ void wxWindowX11::DoReleaseMouse() #endif } - wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() ); + // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() ); m_winCaptured = FALSE; }