mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-01 18:50:16 +03:00
Add SDL3 non-text clipboard data support
Expose MIME-based clipboard data operations through the Clipboard interface, with unsupported defaults for SDL2. Implement lazy data providers, cleanup callbacks, MIME type enumeration, data retrieval, availability checks, and clipboard clearing for SDL3.
This commit is contained in:
@@ -7,6 +7,10 @@ namespace EE { namespace Window {
|
||||
|
||||
class EE_API Clipboard {
|
||||
public:
|
||||
using Data = std::vector<Uint8>;
|
||||
using DataCallback = std::function<const void*( const char* mimeType, size_t* size )>;
|
||||
using CleanupCallback = std::function<void()>;
|
||||
|
||||
virtual ~Clipboard();
|
||||
|
||||
/** @return The Clipboard Text if available */
|
||||
@@ -30,6 +34,29 @@ class EE_API Clipboard {
|
||||
/** Set the current clipboard primary selection text */
|
||||
virtual void setPrimarySelectionText( const std::string& text ) {}
|
||||
|
||||
/**
|
||||
* Offer non-text clipboard data in one or more MIME types. The data callback is invoked lazily
|
||||
* when the operating system requests a format, and with a null MIME type when the offer is
|
||||
* cleared or replaced. The returned data must remain valid until the cleanup callback is
|
||||
* invoked. Only implemented by the SDL3 backend.
|
||||
*/
|
||||
virtual bool setData( DataCallback callback, CleanupCallback cleanup,
|
||||
const std::vector<std::string>& mimeTypes ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Clear all clipboard data. Only implemented by the SDL3 backend. */
|
||||
virtual bool clearData() { return false; }
|
||||
|
||||
/** Get clipboard data for a MIME type. Only implemented by the SDL3 backend. */
|
||||
virtual Data getData( const std::string& mimeType ) { return {}; }
|
||||
|
||||
/** @return The MIME types currently offered by the clipboard. SDL3 backend only. */
|
||||
virtual std::vector<std::string> getMimeTypes() { return {}; }
|
||||
|
||||
/** @return Whether clipboard data is available for a MIME type. SDL3 backend only. */
|
||||
virtual bool hasData( const std::string& mimeType ) const { return false; }
|
||||
|
||||
protected:
|
||||
friend class Window;
|
||||
|
||||
|
||||
@@ -2,10 +2,32 @@
|
||||
#include <eepp/window/backend/SDL3/clipboardsdl3.hpp>
|
||||
#include <eepp/window/backend/SDL3/windowsdl3.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef EE_BACKEND_SDL3
|
||||
|
||||
namespace EE { namespace Window { namespace Backend { namespace SDL3 {
|
||||
|
||||
namespace {
|
||||
|
||||
struct ClipboardDataContext {
|
||||
Clipboard::DataCallback callback;
|
||||
Clipboard::CleanupCallback cleanup;
|
||||
};
|
||||
|
||||
const void* SDLCALL clipboardDataCallback( void* userdata, const char* mimeType, size_t* size ) {
|
||||
auto context = static_cast<ClipboardDataContext*>( userdata );
|
||||
return context->callback( mimeType, size );
|
||||
}
|
||||
|
||||
void SDLCALL clipboardCleanupCallback( void* userdata ) {
|
||||
std::unique_ptr<ClipboardDataContext> context( static_cast<ClipboardDataContext*>( userdata ) );
|
||||
if ( context->cleanup )
|
||||
context->cleanup();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ClipboardSDL::ClipboardSDL( EE::Window::Window* window ) : Clipboard( window ) {}
|
||||
|
||||
ClipboardSDL::~ClipboardSDL() {}
|
||||
@@ -40,6 +62,60 @@ String ClipboardSDL::getWideText() {
|
||||
return String::fromUtf8( getText() );
|
||||
}
|
||||
|
||||
bool ClipboardSDL::setData( DataCallback callback, CleanupCallback cleanup,
|
||||
const std::vector<std::string>& mimeTypes ) {
|
||||
if ( !callback || mimeTypes.empty() )
|
||||
return false;
|
||||
|
||||
std::vector<const char*> mimeTypePointers;
|
||||
mimeTypePointers.reserve( mimeTypes.size() );
|
||||
for ( const auto& mimeType : mimeTypes )
|
||||
mimeTypePointers.emplace_back( mimeType.c_str() );
|
||||
|
||||
auto context = std::make_unique<ClipboardDataContext>(
|
||||
ClipboardDataContext{ std::move( callback ), std::move( cleanup ) } );
|
||||
if ( !SDL_SetClipboardData( clipboardDataCallback, clipboardCleanupCallback, context.get(),
|
||||
mimeTypePointers.data(), mimeTypePointers.size() ) )
|
||||
return false;
|
||||
|
||||
context.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClipboardSDL::clearData() {
|
||||
return SDL_ClearClipboardData();
|
||||
}
|
||||
|
||||
Clipboard::Data ClipboardSDL::getData( const std::string& mimeType ) {
|
||||
size_t size = 0;
|
||||
void* data = SDL_GetClipboardData( mimeType.c_str(), &size );
|
||||
if ( !data )
|
||||
return {};
|
||||
|
||||
const auto bytes = static_cast<const Uint8*>( data );
|
||||
Data result( bytes, bytes + size );
|
||||
SDL_free( data );
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> ClipboardSDL::getMimeTypes() {
|
||||
size_t count = 0;
|
||||
char** mimeTypes = SDL_GetClipboardMimeTypes( &count );
|
||||
if ( !mimeTypes )
|
||||
return {};
|
||||
|
||||
std::vector<std::string> result;
|
||||
result.reserve( count );
|
||||
for ( size_t i = 0; i < count; ++i )
|
||||
result.emplace_back( mimeTypes[i] );
|
||||
SDL_free( mimeTypes );
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ClipboardSDL::hasData( const std::string& mimeType ) const {
|
||||
return SDL_HasClipboardData( mimeType.c_str() );
|
||||
}
|
||||
|
||||
}}}} // namespace EE::Window::Backend::SDL3
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,17 @@ class EE_API ClipboardSDL : public Clipboard {
|
||||
|
||||
void setPrimarySelectionText( const std::string& text );
|
||||
|
||||
bool setData( DataCallback callback, CleanupCallback cleanup,
|
||||
const std::vector<std::string>& mimeTypes );
|
||||
|
||||
bool clearData();
|
||||
|
||||
Data getData( const std::string& mimeType );
|
||||
|
||||
std::vector<std::string> getMimeTypes();
|
||||
|
||||
bool hasData( const std::string& mimeType ) const;
|
||||
|
||||
protected:
|
||||
friend class WindowSDL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user