mirror of https://github.com/libsdl-org/SDL
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.4 KiB
C
181 lines
5.4 KiB
C
/*
|
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely.
|
|
*/
|
|
|
|
#define SDL_MAIN_USE_CALLBACKS 1
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_main.h>
|
|
|
|
#include "icon.h"
|
|
|
|
static SDL_Window *window = NULL;
|
|
static SDL_Renderer *renderer = NULL;
|
|
|
|
static const char *mime_types[] = {
|
|
"text/plain",
|
|
"image/bmp",
|
|
};
|
|
|
|
static const void *ClipboardDataCallback(void *userdata, const char *mime_type, size_t *size)
|
|
{
|
|
if (SDL_strcmp(mime_type, "text/plain") == 0) {
|
|
const char *text = "Hello world!";
|
|
*size = SDL_strlen(text);
|
|
return text;
|
|
} else if (SDL_strcmp(mime_type, "image/bmp") == 0) {
|
|
*size = icon_bmp_len;
|
|
return icon_bmp;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
|
{
|
|
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
|
SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError());
|
|
return SDL_APP_FAILURE;
|
|
}
|
|
|
|
if (!SDL_CreateWindowAndRenderer("testclipboard", 640, 480, 0, &window, &renderer)) {
|
|
SDL_Log("Couldn't create window and renderer: %s\n", SDL_GetError());
|
|
return SDL_APP_FAILURE;
|
|
}
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
|
|
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
|
{
|
|
switch (event->type) {
|
|
case SDL_EVENT_KEY_DOWN:
|
|
if (event->key.key == SDLK_ESCAPE) {
|
|
return SDL_APP_SUCCESS;
|
|
}
|
|
if (event->key.key == SDLK_C && event->key.mod & SDL_KMOD_CTRL) {
|
|
SDL_SetClipboardData(ClipboardDataCallback, NULL, NULL, mime_types, SDL_arraysize(mime_types));
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SDL_EVENT_CLIPBOARD_UPDATE:
|
|
if (event->clipboard.num_mime_types > 0) {
|
|
int i;
|
|
SDL_Log("Clipboard updated:\n");
|
|
for (i = 0; event->clipboard.mime_types[i]; ++i) {
|
|
SDL_Log(" %s\n", event->clipboard.mime_types[i]);
|
|
}
|
|
} else {
|
|
SDL_Log("Clipboard cleared\n");
|
|
}
|
|
break;
|
|
|
|
case SDL_EVENT_QUIT:
|
|
return SDL_APP_SUCCESS;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
static float PrintClipboardText(float x, float y, const char *mime_type)
|
|
{
|
|
void *data = SDL_GetClipboardData(mime_type, NULL);
|
|
if (data) {
|
|
SDL_RenderDebugText(renderer, x, y, (const char *)data);
|
|
SDL_free(data);
|
|
return SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2.0f;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
static float PrintClipboardImage(float x, float y, const char *mime_type)
|
|
{
|
|
/* We don't actually need to read this data each frame, but this is a simple example */
|
|
if (SDL_strcmp(mime_type, "image/bmp") == 0) {
|
|
size_t size;
|
|
void *data = SDL_GetClipboardData(mime_type, &size);
|
|
if (data) {
|
|
float w = 0.0f, h = 0.0f;
|
|
bool rendered = false;
|
|
SDL_IOStream *stream = SDL_IOFromConstMem(data, size);
|
|
if (stream) {
|
|
SDL_Surface *surface = SDL_LoadBMP_IO(stream, false);
|
|
if (surface) {
|
|
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
if (texture) {
|
|
SDL_GetTextureSize(texture, &w, &h);
|
|
|
|
SDL_FRect dst = { x, y, w, h };
|
|
rendered = SDL_RenderTexture(renderer, texture, NULL, &dst);
|
|
SDL_DestroyTexture(texture);
|
|
}
|
|
SDL_DestroySurface(surface);
|
|
}
|
|
SDL_CloseIO(stream);
|
|
}
|
|
if (!rendered) {
|
|
SDL_RenderDebugText(renderer, x, y, SDL_GetError());
|
|
}
|
|
SDL_free(data);
|
|
return h + 2.0f;
|
|
}
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
static void PrintClipboardContents(float x, float y)
|
|
{
|
|
char **clipboard_mime_types = SDL_GetClipboardMimeTypes(NULL);
|
|
if (clipboard_mime_types) {
|
|
int i;
|
|
|
|
for (i = 0; clipboard_mime_types[i]; ++i) {
|
|
const char *mime_type = clipboard_mime_types[i];
|
|
SDL_RenderDebugText(renderer, x, y, mime_type);
|
|
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
|
|
if (SDL_strncmp(mime_type, "text/", 5) == 0) {
|
|
y += PrintClipboardText(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type);
|
|
} else if (SDL_strncmp(mime_type, "image/", 6) == 0) {
|
|
y += PrintClipboardImage(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type);
|
|
}
|
|
}
|
|
SDL_free(clipboard_mime_types);
|
|
}
|
|
}
|
|
|
|
SDL_AppResult SDL_AppIterate(void *appstate)
|
|
{
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
|
float x = 4.0f;
|
|
float y = 4.0f;
|
|
SDL_RenderDebugText(renderer, x, y, "Press Ctrl+C to copy content to the clipboard");
|
|
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2;
|
|
SDL_RenderDebugText(renderer, x, y, "Clipboard contents:");
|
|
x += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2;
|
|
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
|
|
PrintClipboardContents(x, y);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
|
{
|
|
}
|
|
|