#pragma implementation "clipbrd.h"
#endif
+#include "wx/defs.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
+#endif
+#include <Xm/Xm.h>
+#include <Xm/CutPaste.h>
+#ifdef __VMS__
+#pragma message enable nosimpint
+#endif
#include <string.h>
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
-IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
-#endif
+// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
+// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
+
+static bool gs_clipboardIsOpen = FALSE;
bool wxOpenClipboard()
{
- // TODO
- return FALSE;
+ if (!gs_clipboardIsOpen)
+ {
+ gs_clipboardIsOpen = TRUE;
+ return TRUE;
+ }
+ else
+ return FALSE;
}
bool wxCloseClipboard()
{
- // TODO
- return FALSE;
+ if (gs_clipboardIsOpen)
+ {
+ gs_clipboardIsOpen = FALSE;
+ return TRUE;
+ }
+ else
+ return FALSE;
}
bool wxEmptyClipboard()
{
- // TODO
- return FALSE;
+ // No equivalent in Motif
+ return TRUE;
}
bool wxClipboardOpen()
{
- // TODO
- return FALSE;
+ return gs_clipboardIsOpen;
}
-bool wxIsClipboardFormatAvailable(int dataFormat)
+bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
{
- // TODO
- return FALSE;
+ // Only text is supported.
+ if (dataFormat != wxDF_TEXT)
+ return FALSE;
+
+ unsigned long numBytes = 0;
+ long privateId = 0;
+
+ Window window = (Window) 0;
+ if (wxTheApp->GetTopWindow())
+ window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() );
+
+ int success = XmClipboardRetrieve((Display*) wxGetDisplay(),
+ window, "TEXT", (XtPointer) 0, 0, & numBytes, & privateId) ;
+
+ // 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;
}
-bool wxSetClipboardData(int dataFormat, wxObject *obj, int width, int height)
+bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int WXUNUSED(width), int WXUNUSED(height))
{
- // TODO
- return FALSE;
+ 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;
}
-wxObject *wxGetClipboardData(int dataFormat, long *len)
+wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
{
- // TODO
+ if (dataFormat != wxDF_TEXT)
+ return (wxObject*) 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() );
+
+ int currentDataSize = 256;
+ char* data = new char[currentDataSize];
+
+ while (!done)
+ {
+ 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;
+ }
+ }
+
+ }
+
return NULL;
}
-int wxEnumClipboardFormats(int dataFormat)
+wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
{
- // TODO
- return 0;
+ // Only wxDF_TEXT supported
+ if (dataFormat == wxDF_TEXT)
+ return wxDF_TEXT;
+ else
+ return wxDF_INVALID;
}
-int wxRegisterClipboardFormat(char *formatName)
+wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
{
- // TODO
- return 0;
+ // Not supported
+ return (wxDataFormat) wxDF_INVALID;
}
-bool wxGetClipboardFormatName(int dataFormat, char *formatName, int maxCount)
+bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int WXUNUSED(maxCount))
{
- // TODO
- return FALSE;
+ // Only wxDF_TEXT supported
+ if (dataFormat == wxDF_TEXT)
+ {
+ strcpy(formatName, "TEXT");
+ return TRUE;
+ }
+ else
+ return FALSE;
}
-/*
- * Generalized clipboard implementation by Matthew Flatt
- */
+//-----------------------------------------------------------------------------
+// wxClipboard
+//-----------------------------------------------------------------------------
-wxClipboard *wxTheClipboard = NULL;
+IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
-void wxInitClipboard()
+wxClipboard::wxClipboard()
{
- if (!wxTheClipboard)
- wxTheClipboard = new wxClipboard;
+ m_open = FALSE;
}
-wxClipboard::wxClipboard()
+wxClipboard::~wxClipboard()
{
- clipOwner = NULL;
- cbString = NULL;
+ Clear();
}
-wxClipboard::~wxClipboard()
+void wxClipboard::Clear()
{
- if (clipOwner)
- clipOwner->BeingReplaced();
- if (cbString)
- delete[] cbString;
+ wxNode* node = m_data.First();
+ while (node)
+ {
+ wxDataObject* data = (wxDataObject*) node->Data();
+ delete data;
+ node = node->Next();
+ }
+ m_data.Clear();
}
-static int FormatStringToID(char *str)
+bool wxClipboard::Open()
{
- if (!strcmp(str, "TEXT"))
- return wxDF_TEXT;
+ wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
+
+ m_open = TRUE;
- return wxRegisterClipboardFormat(str);
+ return wxOpenClipboard();
}
-void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
+bool wxClipboard::SetData( wxDataObject *data )
{
- bool got_selection;
+ wxCHECK_MSG( data, FALSE, "data is invalid" );
+ wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
- 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;
- }
- }
+ Clear();
+
+ return AddData( data );
+}
- if (i < 0)
- got_selection = wxCloseClipboard();
- } else
- got_selection = FALSE;
+bool wxClipboard::AddData( wxDataObject *data )
+{
+ wxCHECK_MSG( data, FALSE, "data is invalid" );
+ 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;
+ 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
+ }
- got_selection = FALSE; // Assume another process takes over
+ return FALSE;
+}
- if (!got_selection) {
- clipOwner->BeingReplaced();
- clipOwner = NULL;
- }
+void wxClipboard::Close()
+{
+ wxCHECK_RET( m_open, "clipboard not open" );
+
+ m_open = FALSE;
+ wxCloseClipboard();
}
-wxClipboardClient *wxClipboard::GetClipboardClient()
+bool wxClipboard::IsSupported( const wxDataFormat& format)
{
- return clipOwner;
+ return wxIsClipboardFormatAvailable(format);
}
-void wxClipboard::SetClipboardString(char *str, long time)
+bool wxClipboard::GetData( wxDataObject& data )
{
- bool got_selection;
+ 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:
+ {
+#ifndef __VMS
+ // VMS complains that this statement is/causes unreachability
+ return FALSE;
+#endif
+ }
+ }
+
+ return FALSE;
+}
- if (clipOwner) {
- clipOwner->BeingReplaced();
- clipOwner = NULL;
- }
- if (cbString)
- delete[] cbString;
+#if 0
- cbString = str;
+/*
+* Old clipboard implementation by Matthew Flatt
+*/
- if (wxOpenClipboard()) {
- if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
- got_selection = FALSE;
- else
- got_selection = wxCloseClipboard();
- } else
- got_selection = FALSE;
+wxClipboard *wxTheClipboard = NULL;
- got_selection = FALSE; // Assume another process takes over
+void wxInitClipboard()
+{
+ if (!wxTheClipboard)
+ wxTheClipboard = new wxClipboard;
+}
- if (!got_selection) {
- delete[] cbString;
+wxClipboard::wxClipboard()
+{
+ clipOwner = NULL;
cbString = NULL;
- }
}
-char *wxClipboard::GetClipboardString(long time)
+wxClipboard::~wxClipboard()
{
- char *str;
- long length;
+ if (clipOwner)
+ clipOwner->BeingReplaced();
+ if (cbString)
+ delete[] cbString;
+}
- str = GetClipboardData("TEXT", &length, time);
- if (!str) {
- str = new char[1];
- *str = 0;
- }
+static int FormatStringToID(char *str)
+{
+ if (!strcmp(str, "TEXT"))
+ return wxDF_TEXT;
+
+ return wxRegisterClipboardFormat(str);
+}
- return str;
+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;
+ }
}
-char *wxClipboard::GetClipboardData(char *format, long *length, long time)
+wxClipboardClient *wxClipboard::GetClipboardClient()
{
- 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 {
+ return clipOwner;
+}
+
+void wxClipboard::SetClipboardString(char *str, long time)
+{
+ bool got_selection;
+
+ if (clipOwner) {
+ clipOwner->BeingReplaced();
+ clipOwner = NULL;
+ }
+ if (cbString)
+ delete[] cbString;
+
+ cbString = str;
+
if (wxOpenClipboard()) {
- receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
- length);
- wxCloseClipboard();
+ if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
+ got_selection = FALSE;
+ else
+ got_selection = wxCloseClipboard();
} else
- receivedString = NULL;
+ got_selection = FALSE;
+
+ got_selection = FALSE; // Assume another process takes over
+
+ if (!got_selection) {
+ delete[] cbString;
+ cbString = NULL;
+ }
+}
- return receivedString;
- }
+char *wxClipboard::GetClipboardString(long time)
+{
+ char *str;
+ long length;
+
+ str = GetClipboardData("TEXT", &length, time);
+ if (!str) {
+ str = new char[1];
+ *str = 0;
+ }
+
+ 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;
+ }
+}
+#endif
+
+#endif // wxUSE_CLIPBOARD