Atlas - testclipboard.c
Home / ext / SDL / test Lines: 1 | Size: 7096 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11*/ 12 13#define SDL_MAIN_USE_CALLBACKS 1 14#include <SDL3/SDL.h> 15#include <SDL3/SDL_main.h> 16 17#include "icon.h" 18 19static SDL_Window *window = NULL; 20static SDL_Renderer *renderer = NULL; 21 22static const char *mime_types[] = { 23 "text/plain", 24 "image/png", 25}; 26 27static const void *ClipboardDataCallback(void *userdata, const char *mime_type, size_t *size) 28{ 29 if (SDL_strcmp(mime_type, "text/plain") == 0) { 30 const char *text = "Hello world!"; 31 *size = SDL_strlen(text); 32 return text; 33 } else if (SDL_strcmp(mime_type, "image/png") == 0) { 34 *size = icon_png_len; 35 return icon_png; 36 } else { 37 SDL_Log("Called with unexpected mime type: %s", mime_type); 38 return NULL; 39 } 40} 41 42SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) 43{ 44 if (!SDL_Init(SDL_INIT_VIDEO)) { 45 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); 46 return SDL_APP_FAILURE; 47 } 48 49 if (!SDL_CreateWindowAndRenderer("testclipboard", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) { 50 SDL_Log("Couldn't create window and renderer: %s", SDL_GetError()); 51 return SDL_APP_FAILURE; 52 } 53 return SDL_APP_CONTINUE; 54} 55 56 57SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) 58{ 59 switch (event->type) { 60 case SDL_EVENT_KEY_DOWN: 61 if (event->key.key == SDLK_ESCAPE) { 62 return SDL_APP_SUCCESS; 63 } 64 if (event->key.key == SDLK_C) { 65 if (event->key.mod & SDL_KMOD_CTRL) { 66 SDL_SetClipboardData(ClipboardDataCallback, NULL, NULL, mime_types, SDL_arraysize(mime_types)); 67 } else if (event->key.mod & SDL_KMOD_ALT) { 68 SDL_ClearClipboardData(); 69 } 70 } else if (event->key.key == SDLK_P) { 71 if (event->key.mod & SDL_KMOD_CTRL) { 72 SDL_SetPrimarySelectionText("SDL Primary Selection Text!"); 73 } else if (event->key.mod & SDL_KMOD_ALT) { 74 SDL_SetPrimarySelectionText(NULL); 75 } 76 } 77 break; 78 79 case SDL_EVENT_CLIPBOARD_UPDATE: 80 if (event->clipboard.num_mime_types > 0) { 81 int i; 82 SDL_Log("Clipboard updated:"); 83 for (i = 0; event->clipboard.mime_types[i]; ++i) { 84 SDL_Log(" %s", event->clipboard.mime_types[i]); 85 } 86 } else { 87 SDL_Log("Clipboard cleared"); 88 } 89 break; 90 91 case SDL_EVENT_QUIT: 92 return SDL_APP_SUCCESS; 93 94 default: 95 break; 96 } 97 98 return SDL_APP_CONTINUE; 99} 100 101static float PrintClipboardText(float x, float y, const char *mime_type) 102{ 103 size_t size; 104 void *data = SDL_GetClipboardData(mime_type, &size); 105 if (data) { 106 char *text = (char *)data; 107 if (size > 2 && text[2] == '\0') { 108 /* UCS-4 data */ 109 text = (char *)SDL_iconv_string("UTF-8", "UCS-4", data, size+4); 110 } else if (size > 1 && text[1] == '\0') { 111 /* UCS-2 data */ 112 text = (char *)SDL_iconv_string("UTF-8", "UCS-2", data, size+2); 113 } 114 if (text) { 115 SDL_RenderDebugText(renderer, x, y, text); 116 } 117 if (text != data) { 118 SDL_free(text); 119 } 120 SDL_free(data); 121 return SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2.0f; 122 } 123 return 0.0f; 124} 125 126static float PrintPrimarySelectionText(float x, float y) 127{ 128 if (SDL_HasPrimarySelectionText()) { 129 SDL_RenderDebugText(renderer, x, y, SDL_GetPrimarySelectionText()); 130 return SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2.0f; 131 } 132 return 0.0f; 133} 134 135static float PrintClipboardImage(float x, float y, const char *mime_type) 136{ 137 /* We don't actually need to read this data each frame, but this is a simple example */ 138 size_t size; 139 void *data = SDL_GetClipboardData(mime_type, &size); 140 if (data) { 141 float w = 0.0f, h = 0.0f; 142 bool rendered = false; 143 SDL_IOStream *stream = SDL_IOFromConstMem(data, size); 144 if (stream) { 145 SDL_Surface *surface = SDL_LoadSurface_IO(stream, false); 146 if (surface) { 147 SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); 148 if (texture) { 149 SDL_GetTextureSize(texture, &w, &h); 150 151 SDL_FRect dst = { x, y, w, h }; 152 rendered = SDL_RenderTexture(renderer, texture, NULL, &dst); 153 SDL_DestroyTexture(texture); 154 } 155 SDL_DestroySurface(surface); 156 } 157 SDL_CloseIO(stream); 158 } 159 if (!rendered) { 160 SDL_RenderDebugText(renderer, x, y, SDL_GetError()); 161 } 162 SDL_free(data); 163 return h + 2.0f; 164 } 165 return 0.0f; 166} 167 168static float PrintClipboardContents(float x, float y) 169{ 170 char **clipboard_mime_types = SDL_GetClipboardMimeTypes(NULL); 171 if (clipboard_mime_types) { 172 int i; 173 174 for (i = 0; clipboard_mime_types[i]; ++i) { 175 const char *mime_type = clipboard_mime_types[i]; 176 SDL_RenderDebugText(renderer, x, y, mime_type); 177 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2; 178 if (SDL_strncmp(mime_type, "text/", 5) == 0) { 179 y += PrintClipboardText(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type); 180 } else if (SDL_strncmp(mime_type, "image/", 6) == 0) { 181 y += PrintClipboardImage(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type); 182 } 183 } 184 SDL_free(clipboard_mime_types); 185 } 186 187 return y; 188} 189 190SDL_AppResult SDL_AppIterate(void *appstate) 191{ 192 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 193 SDL_RenderClear(renderer); 194 195 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 196 float x = 4.0f; 197 float y = 4.0f; 198 SDL_RenderDebugText(renderer, x, y, "Press Ctrl+C to copy content to the clipboard (Alt+C to clear)"); 199 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2; 200 SDL_RenderDebugText(renderer, x, y, "Press Ctrl+P to set the primary selection text (Alt+P to clear)"); 201 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2; 202 SDL_RenderDebugText(renderer, x, y, "Clipboard contents:"); 203 x += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2; 204 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2; 205 y = PrintClipboardContents(x, y); 206 if (SDL_HasPrimarySelectionText()) { 207 x = 4.0f; 208 SDL_RenderDebugText(renderer, x, y, "Primary selection text contents:"); 209 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2; 210 PrintPrimarySelectionText(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y); 211 } 212 213 SDL_RenderPresent(renderer); 214 215 return SDL_APP_CONTINUE; 216} 217 218void SDL_AppQuit(void *appstate, SDL_AppResult result) 219{ 220} 221 222[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.