From dd38c87578df7a24a491401c943988e2bc89b62b Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Wed, 7 May 2003 17:24:11 +0000 Subject: [PATCH] Implemented wxBitmapDataObject. Implemented generic wxDataObject support in wxClipboard. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20534 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- distrib/msw/tmake/filelist.txt | 1 + docs/changes.txt | 3 + docs/motif/issues.txt | 2 - include/wx/dataobj.h | 2 + include/wx/motif/clipbrd.h | 2 +- include/wx/motif/dataobj2.h | 39 +++ include/wx/x11/bitmap.h | 2 + samples/image/image.cpp | 15 +- src/motif/app.cpp | 1 + src/motif/clipbrd.cpp | 609 +++++++++++++-------------------- src/motif/dataobj.cpp | 70 ++-- src/motif/files.lst | 4 +- src/x11/bitmap.cpp | 40 +++ 13 files changed, 371 insertions(+), 419 deletions(-) create mode 100644 include/wx/motif/dataobj2.h diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index e11f3d5da5..cf1e0e8185 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -1250,6 +1250,7 @@ control.h MotifH cursor.h MotifH dataform.h MotifH dataobj.h MotifH +dataobj2.h MotifH dc.h MotifH dcclient.h MotifH dcmemory.h MotifH diff --git a/docs/changes.txt b/docs/changes.txt index 366a9d2cff..2a8bb95f03 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -137,6 +137,9 @@ wxMotif: - implemented wxToggleButton - wxRadioBox and wxStaticBox now use the default shadow (border) style instead of a sunken border +- implemented wxBitmapDataObject +- finished wxClipboard implementation (it still unconditionally + copies the data) wxUniv: diff --git a/docs/motif/issues.txt b/docs/motif/issues.txt index b0d4fa8edd..f33698f5a6 100644 --- a/docs/motif/issues.txt +++ b/docs/motif/issues.txt @@ -9,8 +9,6 @@ See also: todo.txt. - No wxToolTip (but see wxToolBar for a way of implementing it). -- Limited clipboard support (text only) and no drag and drop. - - Need a way of specifying default settings for colour/font/etc. - More optimisation could be done to reduce X server traffic, etc. diff --git a/include/wx/dataobj.h b/include/wx/dataobj.h index 1cdd0dfe6c..27b38cd456 100644 --- a/include/wx/dataobj.h +++ b/include/wx/dataobj.h @@ -462,6 +462,8 @@ private: #include "wx/gtk/dataobj2.h" #elif defined(__WXX11__) #include "wx/x11/dataobj2.h" + #elif defined(__WXMOTIF__) + #include "wx/motif/dataobj2.h" #elif defined(__WXMAC__) #include "wx/mac/dataobj2.h" #elif defined(__WXPM__) diff --git a/include/wx/motif/clipbrd.h b/include/wx/motif/clipbrd.h index 6b17de1e9f..c1a91626b5 100644 --- a/include/wx/motif/clipbrd.h +++ b/include/wx/motif/clipbrd.h @@ -68,7 +68,7 @@ public: // clears wxTheClipboard and the system's clipboard if possible virtual void Clear(); - virtual void UsePrimarySelection(bool primary = TRUE) + virtual void UsePrimarySelection(bool primary = true) { m_usePrimary = primary; } // implementation from now on diff --git a/include/wx/motif/dataobj2.h b/include/wx/motif/dataobj2.h new file mode 100644 index 0000000000..3bd2a50a3f --- /dev/null +++ b/include/wx/motif/dataobj2.h @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: include/wx/motif/dataobj2.h +// Purpose: declaration of standard wxDataObjectSimple-derived classes +// Author: Mattia Barbon +// Created: 27.04.03 +// RCS-ID: $Id$ +// Copyright: (c) 2003 Mattia Barbon +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MOTIF_DATAOBJ2_H_ +#define _WX_MOTIF_DATAOBJ2_H_ + +#if defined(__GNUG__) && !defined(__APPLE__) + #pragma interface "dataobj.h" +#endif + +// ---------------------------------------------------------------------------- +// wxBitmapDataObject is a specialization of wxDataObject for bitmaps +// ---------------------------------------------------------------------------- + +class wxBitmapDataObject : public wxBitmapDataObjectBase +{ +public: + // ctors + wxBitmapDataObject() + : wxBitmapDataObjectBase() { } + wxBitmapDataObject(const wxBitmap& bitmap) + : wxBitmapDataObjectBase(bitmap) { } + + // implement base class pure virtuals + // ---------------------------------- + virtual size_t GetDataSize() const; + virtual bool GetDataHere(void *buf) const; + virtual bool SetData(size_t len, const void *buf); +}; + +#endif // _WX_MOTIF_DATAOBJ2_H_ + diff --git a/include/wx/x11/bitmap.h b/include/wx/x11/bitmap.h index c9d96ad944..82daf63b50 100644 --- a/include/wx/x11/bitmap.h +++ b/include/wx/x11/bitmap.h @@ -96,6 +96,8 @@ public: bool Create(int width, int height, int depth = -1); bool Create(void* data, wxBitmapType type, int width, int height, int depth = -1); + // create the wxBitmap using a _copy_ of the pixmap + bool Create(WXPixmap pixmap); int GetHeight() const; int GetWidth() const; diff --git a/samples/image/image.cpp b/samples/image/image.cpp index 8661adaaed..734eadf90e 100644 --- a/samples/image/image.cpp +++ b/samples/image/image.cpp @@ -125,7 +125,7 @@ public: #endif // wxHAVE_RAW_BITMAP void OnQuit( wxCommandEvent &event ); -#if wxUSE_CLIPBOARD && !defined(__WXMOTIF_) +#if wxUSE_CLIPBOARD void OnCopy(wxCommandEvent& event); void OnPaste(wxCommandEvent& event); #endif // wxUSE_CLIPBOARD @@ -817,7 +817,7 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame) EVT_MENU (ID_SHOWRAW, MyFrame::OnTestRawBitmap) #endif -#if wxUSE_CLIPBOARD && !defined(__WXMOTIF__) +#if wxUSE_CLIPBOARD EVT_MENU(wxID_COPY, MyFrame::OnCopy) EVT_MENU(wxID_PASTE, MyFrame::OnPaste) #endif // wxUSE_CLIPBOARD @@ -841,7 +841,7 @@ MyFrame::MyFrame() menuImage->Append( ID_QUIT, _T("E&xit\tCtrl-Q")); menu_bar->Append(menuImage, _T("&Image")); -#if wxUSE_CLIPBOARD && !defined(__WXMOTIF__) +#if wxUSE_CLIPBOARD wxMenu *menuClipboard = new wxMenu; menuClipboard->Append(wxID_COPY, _T("&Copy test image\tCtrl-C")); menuClipboard->Append(wxID_PASTE, _T("&Paste image\tCtrl-V")); @@ -898,22 +898,28 @@ void MyFrame::OnTestRawBitmap( wxCommandEvent &event ) #endif // wxHAVE_RAW_BITMAP -#if wxUSE_CLIPBOARD && !defined(__WXMOTIF__) +#if wxUSE_CLIPBOARD void MyFrame::OnCopy(wxCommandEvent& WXUNUSED(event)) { wxBitmapDataObject *dobjBmp = new wxBitmapDataObject; dobjBmp->SetBitmap(*m_canvas->my_horse_png); + wxTheClipboard->Open(); + if ( !wxTheClipboard->SetData(dobjBmp) ) { wxLogError(_T("Failed to copy bitmap to clipboard")); } + + wxTheClipboard->Close(); } void MyFrame::OnPaste(wxCommandEvent& WXUNUSED(event)) { wxBitmapDataObject dobjBmp; + + wxTheClipboard->Open(); if ( !wxTheClipboard->GetData(dobjBmp) ) { wxLogMessage(_T("No bitmap data in the clipboard")); @@ -922,6 +928,7 @@ void MyFrame::OnPaste(wxCommandEvent& WXUNUSED(event)) { (new MyImageFrame(this, dobjBmp.GetBitmap()))->Show(); } + wxTheClipboard->Close(); } #endif // wxUSE_CLIPBOARD diff --git a/src/motif/app.cpp b/src/motif/app.cpp index cc1fad12dd..bd25cba57d 100644 --- a/src/motif/app.cpp +++ b/src/motif/app.cpp @@ -564,6 +564,7 @@ WXWidget wxCreateTopLevelWidget( WXDisplay* display ) applicationShellWidgetClass, (Display*)display, NULL, 0 ); + XtRealizeWidget( tlw ); XtAddCallback( tlw, XmNdestroyCallback, (XtCallbackProc)wxTLWidgetDestroyCallback, diff --git a/src/motif/clipbrd.cpp b/src/motif/clipbrd.cpp index 9bd9307194..17f2e17e27 100644 --- a/src/motif/clipbrd.cpp +++ b/src/motif/clipbrd.cpp @@ -2,7 +2,7 @@ // Name: clipbrd.cpp // Purpose: Clipboard functionality // Author: Julian Smart -// Modified by: +// Modified by: Mattia Barbon (added support for generic wxDataObjects) // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -19,12 +19,11 @@ #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/ptr_scpd.h" #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxDataObjectList); @@ -38,180 +37,94 @@ WX_DEFINE_LIST(wxDataObjectList); #pragma message enable nosimpint #endif -#include - -// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) -// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject) - -static bool gs_clipboardIsOpen = FALSE; +#include "wx/motif/private.h" bool wxOpenClipboard() { - if (!gs_clipboardIsOpen) - { - gs_clipboardIsOpen = TRUE; - return TRUE; - } - else - return FALSE; + return wxTheClipboard->Open(); } bool wxCloseClipboard() { - if (gs_clipboardIsOpen) - { - gs_clipboardIsOpen = FALSE; - return TRUE; - } - else - return FALSE; + wxTheClipboard->Close(); + + return true; } bool wxEmptyClipboard() { - // No equivalent in Motif - return TRUE; + wxTheClipboard->Clear(); + return true; } bool wxClipboardOpen() { - return gs_clipboardIsOpen; + return wxTheClipboard->IsOpened(); } bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat) { - // Only text is supported. - if (dataFormat != wxDF_TEXT) - return FALSE; + return wxTheClipboard->IsSupported( dataFormat ); +} - unsigned long numBytes = 0; - long privateId = 0; - - Window window = (Window) 0; - if (wxTheApp->GetTopWindow()) - window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() ); +bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, + int WXUNUSED(width), int WXUNUSED(height)) +{ + wxDataObject* dobj = NULL; - int success = XmClipboardRetrieve((Display*) wxGetDisplay(), - window, "TEXT", (XtPointer) 0, 0, & numBytes, & privateId) ; + if( dataFormat == wxDF_TEXT ) + { + wxChar* data = (wxChar*)obj; + dobj = new wxTextDataObject( data ); + } + else if( dataFormat = wxDF_BITMAP ) + { + wxBitmap* data = (wxBitmap*)obj; + dobj = new wxBitmapDataObject( *data ); + } - // 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( !dobj ) + return false; -bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int WXUNUSED(width), int WXUNUSED(height)) -{ - if (dataFormat != wxDF_TEXT) - return FALSE; - - char* data = (char*) obj; - - XmString text = XmStringCreateSimple ("CLIPBOARD"); - Window window = (Window) 0; - if (wxTheApp->GetTopWindow()) - window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() ); - - long itemId = 0; - int result = 0; - - while ((result = - XmClipboardStartCopy((Display*) wxGetDisplay(), - window, - text, - XtLastTimestampProcessed((Display*) wxGetDisplay()), - (Widget) 0, - (XmCutPasteProc) 0, - & itemId)) != ClipboardSuccess) - - ; - - XmStringFree (text); - - long dataId = 0; - while ((result = - XmClipboardCopy((Display*) wxGetDisplay(), - window, - itemId, - "TEXT", - (XtPointer) data, - strlen(data) + 1, - 0, - & dataId)) != ClipboardSuccess) - - ; - - while (( result = - XmClipboardEndCopy((Display*) wxGetDisplay(), - window, itemId) ) != ClipboardSuccess) - - ; - - return TRUE; + return wxTheClipboard->SetData( dobj ); } wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len) { - if (dataFormat != wxDF_TEXT) - return (wxObject*) NULL; + wxDataObject* dobj = NULL; + wxTextDataObject* tobj = NULL; + wxBitmapDataObject* bobj = NULL; - 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() ); + if( dataFormat == wxDF_TEXT ) + { + dobj = tobj = new wxTextDataObject; + } + else if( dataFormat = wxDF_BITMAP ) + { + dobj = bobj = new wxBitmapDataObject; + } - int currentDataSize = 256; - char* data = new char[currentDataSize]; + if( !dobj || !wxTheClipboard->GetData( *dobj ) ) + return NULL; - while (!done) + if( tobj ) { - if (result == ClipboardTruncate) - { - 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; - } - } - + wxString text = tobj->GetText(); + wxChar* buf = new wxChar[text.length() + 1]; + + if( len ) *len = text.length(); + return (wxObject*)wxStrcpy( buf, text.c_str() ); + } + else if( bobj ) + { + if( len ) *len = 0; + return new wxBitmap( bobj->GetBitmap() ); } - return NULL; + return NULL; // just in case... } -wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat) +wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat) { // Only wxDF_TEXT supported if (dataFormat == wxDF_TEXT) @@ -220,22 +133,18 @@ wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat) return wxDF_INVALID; } -wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName)) +wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName)) { // Not supported - return (wxDataFormat) wxDF_INVALID; + return wxDF_INVALID; } -bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int WXUNUSED(maxCount)) +bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, + int maxCount) { - // Only wxDF_TEXT supported - if (dataFormat == wxDF_TEXT) - { - strcpy(formatName, "TEXT"); - return TRUE; - } - else - return FALSE; + wxStrncpy( formatName, dataFormat.GetId().c_str(), maxCount ); + + return true; } //----------------------------------------------------------------------------- @@ -246,7 +155,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject) wxClipboard::wxClipboard() { - m_open = FALSE; + m_open = false; } wxClipboard::~wxClipboard() @@ -268,265 +177,231 @@ void wxClipboard::Clear() bool wxClipboard::Open() { - wxCHECK_MSG( !m_open, FALSE, "clipboard already open" ); + wxCHECK_MSG( !m_open, false, "clipboard already open" ); - m_open = TRUE; + 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( data, false, "data is invalid" ); + wxCHECK_MSG( m_open, false, "clipboard not open" ); Clear(); return AddData( data ); } +wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray ); +wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray ); + bool wxClipboard::AddData( wxDataObject *data ) { - wxCHECK_MSG( data, FALSE, "data is invalid" ); - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); + wxCHECK_MSG( data, false, "data is invalid" ); + wxCHECK_MSG( m_open, false, "clipboard not open" ); + + m_data.Append( data ); + + Display* xdisplay = wxGlobalDisplay(); + Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() ); + wxXmString label( wxTheApp->GetAppName() ); + Time timestamp = XtLastTimestampProcessed( xdisplay ); + long itemId; + + int retval; - wxDataFormat::NativeFormat format = data->GetPreferredFormat().GetType(); - switch ( format ) + while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(), + timestamp, (Widget)NULL, + (XmCutPasteProc)NULL, + &itemId ) ) + == XmClipboardLocked ); + if( retval != XmClipboardSuccess ) + return false; + + size_t count = data->GetFormatCount( wxDataObject::Get ); + wxDataFormatScopedArray dfarr( new wxDataFormat[count] ); + data->GetAllFormats( dfarr.get(), wxDataObject::Get ); + + for( size_t i = 0; i < count; ++i ) { - 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; - } -#endif // 0 + size_t size = data->GetDataSize( dfarr[i] ); + wxCharBuffer buffer(size); + + if( !data->GetDataHere( dfarr[i], buffer.data() ) ) + continue; + + wxString id = dfarr[i].GetId(); + + while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId, + wxConstCast(id.c_str(), char), + buffer.data(), size, 0, NULL ) ) + == XmClipboardLocked ); } - - return FALSE; + + while( XmClipboardEndCopy( xdisplay, xwindow, itemId ) + == XmClipboardLocked ); + + return true; } void wxClipboard::Close() { wxCHECK_RET( m_open, "clipboard not open" ); - m_open = FALSE; - wxCloseClipboard(); -} - -bool wxClipboard::IsSupported( const wxDataFormat& format) -{ - return wxIsClipboardFormatAvailable(format); + m_open = false; } -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 ) + Display* xdisplay = wxGlobalDisplay(); + Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() ); + bool isSupported = false; + int retval, count; + unsigned long max_name_length; + wxString id = format.GetId(); + + while( ( retval = XmClipboardLock( xdisplay, xwindow ) ) + == XmClipboardLocked ); + if( retval != XmClipboardSuccess ) + return false; + + if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length ) + == XmClipboardSuccess ) { - 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: + wxCharBuffer buf( max_name_length + 1 ); + unsigned long copied; + + for( int i = 0; i < count; ++i ) { - wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data; - wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetType()); - if (bitmap) + if( XmClipboardInquireFormat( xdisplay, xwindow, i + 1, + (XtPointer)buf.data(), + max_name_length, &copied ) + != XmClipboardSuccess ) + continue; + + buf.data()[copied] = '\0'; + + if( buf == id ) { - bitmapDataObject->SetBitmap(* bitmap); - delete bitmap; - return TRUE; + isSupported = true; + break; } - else - return FALSE; - break; - } -*/ - default: - { -#ifndef __VMS - // VMS complains that this statement is/causes unreachability - return FALSE; -#endif } } - - return FALSE; -} -#if 0 + XmClipboardUnlock( xdisplay, xwindow, False ); -/* -* Old clipboard implementation by Matthew Flatt -*/ - -wxClipboard *wxTheClipboard = NULL; - -void wxInitClipboard() -{ - if (!wxTheClipboard) - wxTheClipboard = new wxClipboard; + return isSupported; } -wxClipboard::wxClipboard() +class wxClipboardEndRetrieve { - clipOwner = NULL; - cbString = NULL; -} - -wxClipboard::~wxClipboard() -{ - if (clipOwner) - clipOwner->BeingReplaced(); - if (cbString) - delete[] cbString; -} +public: + wxClipboardEndRetrieve( Display* display, Window window ) + : m_display( display ), m_window( window ) { } + ~wxClipboardEndRetrieve() + { + while( XmClipboardEndRetrieve( m_display, m_window ) + == XmClipboardLocked ); + } +private: + Display* m_display; + Window m_window; +}; -static int FormatStringToID(char *str) +bool wxClipboard::GetData( wxDataObject& data ) { - if (!strcmp(str, "TEXT")) - return wxDF_TEXT; + wxCHECK_MSG( m_open, false, "clipboard not open" ); + + Display* xdisplay = wxGlobalDisplay(); + Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() ); + Time timestamp = XtLastTimestampProcessed( xdisplay ); + + wxDataFormat chosenFormat; + int retval; + + /////////////////////////////////////////////////////////////////////////// + // determine if the cliboard holds any format we like + /////////////////////////////////////////////////////////////////////////// + while( ( retval = XmClipboardStartRetrieve( xdisplay, xwindow, + timestamp ) ) + == XmClipboardLocked ); + if( retval != XmClipboardSuccess ) + return false; + + wxClipboardEndRetrieve endRetrieve( xdisplay, xwindow ); + + int count; + unsigned long max_name_length; + size_t dfcount = data.GetFormatCount( wxDataObject::Set ); + wxDataFormatScopedArray dfarr( new wxDataFormat[dfcount] ); + data.GetAllFormats( dfarr.get(), wxDataObject::Set ); - return wxRegisterClipboardFormat(str); -} + if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length ) + == XmClipboardSuccess ) + { + wxCharBuffer buf( max_name_length + 1 ); + unsigned long copied; -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; - } -} + for( int i = 0; i < count; ++i ) + { + if( XmClipboardInquireFormat( xdisplay, xwindow, i + 1, + (XtPointer)buf.data(), + max_name_length, &copied ) + != XmClipboardSuccess ) + continue; -wxClipboardClient *wxClipboard::GetClipboardClient() -{ - return clipOwner; -} + buf.data()[copied] = '\0'; -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; - } -} + // try preferred format + if( buf == data.GetPreferredFormat( wxDataObject::Set ).GetId() ) + { + chosenFormat = data.GetPreferredFormat( wxDataObject::Set ); + break; + } -char *wxClipboard::GetClipboardString(long time) -{ - char *str; - long length; - - str = GetClipboardData("TEXT", &length, time); - if (!str) { - str = new char[1]; - *str = 0; + // try all other formats + for( size_t i = 0; i < dfcount; ++i ) + { + if( buf == dfarr[i].GetId() ) + chosenFormat = dfarr[i]; + } + } } - - return str; -} -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; - } + if( chosenFormat == wxDF_INVALID ) + return false; + + /////////////////////////////////////////////////////////////////////////// + // now retrieve the data + /////////////////////////////////////////////////////////////////////////// + unsigned long length, dummy1; + long dummy2; + wxString id = chosenFormat.GetId(); + + while( ( retval = XmClipboardInquireLength( xdisplay, xwindow, + wxConstCast(id.c_str(), char), + &length ) ) + == XmClipboardLocked ); + if( retval != XmClipboardSuccess ) + return false; + + wxCharBuffer buf(length); + + while( ( retval = XmClipboardRetrieve( xdisplay, xwindow, + wxConstCast(id.c_str(), char), + (XtPointer)buf.data(), + length, &dummy1, &dummy2 ) ) + == XmClipboardLocked ); + if( retval != XmClipboardSuccess ) + return false; + + if( !data.SetData( chosenFormat, length, buf.data() ) ) + return false; + + return true; } -#endif #endif // wxUSE_CLIPBOARD diff --git a/src/motif/dataobj.cpp b/src/motif/dataobj.cpp index 8f949396fc..9a21179091 100644 --- a/src/motif/dataobj.cpp +++ b/src/motif/dataobj.cpp @@ -17,6 +17,7 @@ #include "wx/dataobj.h" #include "wx/app.h" +#include "wx/utils.h" #ifdef __VMS__ #pragma message disable nosimpint @@ -25,14 +26,15 @@ #ifdef __VMS__ #pragma message enable nosimpint #endif -#include "wx/utils.h" + +#include "wx/motif/private.h" //------------------------------------------------------------------------- // global data //------------------------------------------------------------------------- Atom g_textAtom = 0; -Atom g_pngAtom = 0; +Atom g_bitmapAtom = 0; Atom g_fileAtom = 0; //------------------------------------------------------------------------- @@ -86,7 +88,7 @@ void wxDataFormat::SetType( wxDataFormatId type ) m_format = g_textAtom; else if (m_type == wxDF_BITMAP) - m_format = g_pngAtom; + m_format = g_bitmapAtom; else if (m_type == wxDF_FILENAME) m_format = g_fileAtom; @@ -118,7 +120,7 @@ void wxDataFormat::SetId( NativeFormat format ) if (m_format == g_textAtom) m_type = wxDF_TEXT; else - if (m_format == g_pngAtom) + if (m_format == g_bitmapAtom) m_type = wxDF_BITMAP; else if (m_format == g_fileAtom) @@ -132,17 +134,18 @@ void wxDataFormat::SetId( const wxChar *id ) PrepareFormats(); m_type = wxDF_PRIVATE; wxString tmp( id ); - m_format = XInternAtom( (Display*) wxGetDisplay(), wxMBSTRINGCAST tmp.mbc_str(), FALSE ); // what is the string cast for? + m_format = XInternAtom( wxGlobalDisplay(), + tmp.mbc_str(), FALSE ); } void wxDataFormat::PrepareFormats() { if (!g_textAtom) - g_textAtom = XInternAtom( (Display*) wxGetDisplay(), "STRING", FALSE ); - if (!g_pngAtom) - g_pngAtom = XInternAtom( (Display*) wxGetDisplay(), "image/png", FALSE ); + g_textAtom = XInternAtom( wxGlobalDisplay(), "STRING", FALSE ); + if (!g_bitmapAtom) + g_bitmapAtom = XInternAtom( wxGlobalDisplay(), "PIXMAP", FALSE ); if (!g_fileAtom) - g_fileAtom = XInternAtom( (Display*) wxGetDisplay(), "file:ALL", FALSE ); + g_fileAtom = XInternAtom( wxGlobalDisplay(), "file:ALL", FALSE ); } // ---------------------------------------------------------------------------- @@ -153,56 +156,35 @@ wxDataObject::~wxDataObject() { } -#if 0 - // ---------------------------------------------------------------------------- -// wxPrivateDataObject +// wxBitmapDataObject // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS( wxPrivateDataObject, wxDataObject ) - -void wxPrivateDataObject::Free() +size_t wxBitmapDataObject::GetDataSize() const { - if ( m_data ) - free(m_data); + return sizeof(Pixmap); } -wxPrivateDataObject::wxPrivateDataObject() +bool wxBitmapDataObject::GetDataHere(void* buf) const { - wxString id = wxT("application/"); - id += wxTheApp->GetAppName(); + if( !GetBitmap().Ok() ) + return false; - m_format.SetId( id ); + (*(Pixmap*)buf) = (Pixmap)GetBitmap().GetDrawable(); - m_size = 0; - m_data = (void *)NULL; + return true; } -void wxPrivateDataObject::SetData( const void *data, size_t size ) +bool wxBitmapDataObject::SetData(size_t len, const void* buf) { - Free(); - - m_size = size; - m_data = malloc(size); - - memcpy( m_data, data, size ); -} + if( len != sizeof(Pixmap) ) + return false; -void wxPrivateDataObject::WriteData( void *dest ) const -{ - WriteData( m_data, dest ); -} + WXPixmap pixmap = (WXPixmap)*(Pixmap*)buf; -size_t wxPrivateDataObject::GetSize() const -{ - return m_size; -} + m_bitmap.Create( pixmap ); -void wxPrivateDataObject::WriteData( const void *data, void *dest ) const -{ - memcpy( dest, data, GetSize() ); + return true; } -#endif // 0 - #endif // wxUSE_CLIPBOARD diff --git a/src/motif/files.lst b/src/motif/files.lst index 8e0dfe314e..0295655a68 100644 --- a/src/motif/files.lst +++ b/src/motif/files.lst @@ -521,6 +521,7 @@ ALL_HEADERS = \ motif/cursor.h \ motif/dataform.h \ motif/dataobj.h \ + motif/dataobj2.h \ motif/dc.h \ motif/dcclient.h \ motif/dcmemory.h \ @@ -625,7 +626,8 @@ ALL_HEADERS = \ protocol/protocol.h \ x11/bitmap.h \ x11/brush.h \ - x11/pen.h + x11/pen.h \ + x11/privx.h COMMONOBJS = \ accesscmn.o \ diff --git a/src/x11/bitmap.cpp b/src/x11/bitmap.cpp index 8f8ba22e1c..1dc3b18684 100644 --- a/src/x11/bitmap.cpp +++ b/src/x11/bitmap.cpp @@ -375,6 +375,46 @@ bool wxBitmap::Create(void *data, wxBitmapType type, return handler->Create(this, data, type, width, height, depth); } +bool wxBitmap::Create(WXPixmap pixmap) +{ + UnRef(); + Pixmap xpixmap = (Pixmap)pixmap; + Display* xdisplay = wxGlobalDisplay(); + int xscreen = DefaultScreen( xdisplay ); + Window xroot = RootWindow( xdisplay, xscreen ); + + // make a copy of the Pixmap + Window root; + Pixmap copy; + int x, y; + unsigned width, height, border, depth; + + XGetGeometry( xdisplay, (Drawable)xpixmap, &root, &x, &y, + &width, &height, &border, &depth ); + copy = XCreatePixmap( xdisplay, xroot, width, height, depth ); + + GC gc = XCreateGC( xdisplay, copy, 0, NULL ); + XCopyArea( xdisplay, xpixmap, copy, gc, 0, 0, width, height, 0, 0 ); + XFreeGC( xdisplay, gc ); + + // fill in ref data + wxBitmapRefData* ref = new wxBitmapRefData(); + + if( depth == 1 ) + ref->m_bitmap = (WXPixmap)copy; + else + ref->m_pixmap = (WXPixmap)copy; + + ref->m_display = (WXDisplay*)xdisplay; + ref->m_width = width; + ref->m_height = height; + ref->m_bpp = depth; + + m_refData = ref; + + return true; +} + bool wxBitmap::CreateFromXpm( const char **bits ) { wxCHECK_MSG( bits, FALSE, _T("NULL pointer in wxBitmap::CreateFromXpm") ); -- 2.45.2