clipbrd.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 689 行 · 第 1/2 页
CPP
689 行
/////////////////////////////////////////////////////////////////////////////
// Name: gtk/clipbrd.cpp
// Purpose:
// Author: Robert Roebling
// Id: $Id: clipbrd.cpp,v 1.60.2.4 2006/03/30 01:31:36 RD Exp $
// Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "clipbrd.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/clipbrd.h"
#if wxUSE_CLIPBOARD
#include "wx/dataobj.h"
#include "wx/utils.h"
#include "wx/log.h"
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
//-----------------------------------------------------------------------------
// thread system
//-----------------------------------------------------------------------------
#if wxUSE_THREADS
#endif
//-----------------------------------------------------------------------------
// data
//-----------------------------------------------------------------------------
GdkAtom g_clipboardAtom = 0;
GdkAtom g_targetsAtom = 0;
GdkAtom g_timestampAtom = 0;
#if defined(__WXGTK20__) && wxUSE_UNICODE
extern GdkAtom g_altTextAtom;
#endif
// 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");
//-----------------------------------------------------------------------------
// 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
{
GdkAtom selection;
GdkAtom target;
GdkAtom type;
gint format;
guchar *data;
gint length;
};
*/
//-----------------------------------------------------------------------------
// "selection_received" for targets
//-----------------------------------------------------------------------------
extern "C" {
static void
targets_selection_received( GtkWidget *WXUNUSED(widget),
GtkSelectionData *selection_data,
guint32 WXUNUSED(time),
wxClipboard *clipboard )
{
if ( wxTheClipboard && selection_data->length > 0 )
{
// make sure we got the data in the correct form
GdkAtom type = selection_data->type;
if ( type != GDK_SELECTION_TYPE_ATOM )
{
gchar* atom_name = gdk_atom_name(type);
if ( strcmp(atom_name, "TARGETS") )
{
wxLogTrace( TRACE_CLIPBOARD,
_T("got unsupported clipboard target") );
clipboard->m_waiting = FALSE;
g_free(atom_name);
return;
}
g_free(atom_name);
}
#ifdef __WXDEBUG__
wxDataFormat clip( selection_data->selection );
wxLogTrace( TRACE_CLIPBOARD,
wxT("selection received for targets, clipboard %s"),
clip.GetId().c_str() );
#endif // __WXDEBUG__
// the atoms we received, holding a list of targets (= formats)
GdkAtom *atoms = (GdkAtom *)selection_data->data;
for (unsigned int i=0; i<selection_data->length/sizeof(GdkAtom); i++)
{
wxDataFormat format( atoms[i] );
wxLogTrace( TRACE_CLIPBOARD,
wxT("selection received for targets, format %s"),
format.GetId().c_str() );
// printf( "format %s requested %s\n",
// gdk_atom_name( atoms[i] ),
// gdk_atom_name( clipboard->m_targetRequested ) );
if (format == clipboard->m_targetRequested)
{
clipboard->m_waiting = FALSE;
clipboard->m_formatSupported = TRUE;
return;
}
}
}
clipboard->m_waiting = FALSE;
}
}
//-----------------------------------------------------------------------------
// "selection_received" for the actual data
//-----------------------------------------------------------------------------
extern "C" {
static void
selection_received( GtkWidget *WXUNUSED(widget),
GtkSelectionData *selection_data,
guint32 WXUNUSED(time),
wxClipboard *clipboard )
{
if (!wxTheClipboard)
{
clipboard->m_waiting = FALSE;
return;
}
wxDataObject *data_object = clipboard->m_receivedData;
if (!data_object)
{
clipboard->m_waiting = FALSE;
return;
}
if (selection_data->length <= 0)
{
clipboard->m_waiting = FALSE;
return;
}
wxDataFormat format( selection_data->target );
// make sure we got the data in the correct format
if (!data_object->IsSupportedFormat( format ) )
{
clipboard->m_waiting = FALSE;
return;
}
#if 0
This seems to cause problems somehow
// 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;
}
#endif
data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
wxTheClipboard->m_formatSupported = TRUE;
clipboard->m_waiting = FALSE;
}
}
//-----------------------------------------------------------------------------
// "selection_clear"
//-----------------------------------------------------------------------------
extern "C" {
static gint
selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
{
if (!wxTheClipboard) return TRUE;
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;
}
if ((!wxTheClipboard->m_ownsPrimarySelection) &&
(!wxTheClipboard->m_ownsClipboard))
{
/* the clipboard is no longer in our hands. we can the delete clipboard data. */
if (wxTheClipboard->m_data)
{
wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
delete wxTheClipboard->m_data;
wxTheClipboard->m_data = (wxDataObject*) NULL;
}
}
wxTheClipboard->m_waiting = FALSE;
return TRUE;
}
}
//-----------------------------------------------------------------------------
// selection handler for supplying data
//-----------------------------------------------------------------------------
extern "C" {
static void
selection_handler( GtkWidget *WXUNUSED(widget),
GtkSelectionData *selection_data,
guint WXUNUSED(info),
guint WXUNUSED(time),
gpointer signal_data )
{
if (!wxTheClipboard) return;
if (!wxTheClipboard->m_data) return;
wxDataObject *data = wxTheClipboard->m_data;
// ICCCM says that TIMESTAMP is a required atom.
// In particular, it satisfies Klipper, which polls
// TIMESTAMP to see if the clipboards content has changed.
// It shall return the time which was used to set the data.
if (selection_data->target == g_timestampAtom)
{
uint timestamp = GPOINTER_TO_UINT (signal_data);
gtk_selection_data_set(selection_data,
GDK_SELECTION_TYPE_INTEGER,
32,
(guchar*)&(timestamp),
sizeof(timestamp));
wxLogTrace(TRACE_CLIPBOARD,
_T("Clipboard TIMESTAMP requested, returning timestamp=%u"),
timestamp);
return;
}
wxDataFormat format( selection_data->target );
#ifdef __WXDEBUG__
wxLogTrace(TRACE_CLIPBOARD,
_T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"),
format.GetId().c_str(),
wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(),
wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(),
wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str(),
GPOINTER_TO_UINT( signal_data )
);
#endif
if (!data->IsSupportedFormat( format )) return;
int size = data->GetDataSize( format );
if (size == 0) return;
void *d = malloc(size);
// Text data will be in UTF8 in Unicode mode.
data->GetDataHere( selection_data->target, d );
#ifdef __WXGTK20__
// NB: GTK+ requires special treatment of UTF8_STRING data, the text
// would show as UTF-8 data interpreted as latin1 (?) in other
// GTK+ apps if we used gtk_selection_data_set()
if (format == wxDataFormat(wxDF_UNICODETEXT))
{
gtk_selection_data_set_text(
selection_data,
(const gchar*)d,
size );
}
else
#endif
{
gtk_selection_data_set(
selection_data,
GDK_SELECTION_TYPE_STRING,
8*sizeof(gchar),
(unsigned char*) d,
size );
}
free(d);
}
}
//-----------------------------------------------------------------------------
// wxClipboard
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
wxClipboard::wxClipboard()
{
m_open = FALSE;
m_waiting = FALSE;
m_ownsClipboard = FALSE;
m_ownsPrimarySelection = FALSE;
m_data = (wxDataObject*) NULL;
m_receivedData = (wxDataObject*) NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?