From 2501218801437ea413091007b535d7c097801713 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 22 May 2022 12:24:59 -0400 Subject: Add rich clipboard support This implements a more powerful protocol for working with clipboards, which supports datatype negotiation, and fixes various issues by mapping more directly to how things work on X11. --- examples/pugl_clipboard_demo.c | 50 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/pugl_clipboard_demo.c b/examples/pugl_clipboard_demo.c index 76e42f8..9b5fb28 100644 --- a/examples/pugl_clipboard_demo.c +++ b/examples/pugl_clipboard_demo.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -64,15 +65,50 @@ onKeyPress(PuglView* const view, const PuglKeyEvent* const event) if (event->key == 'q' || event->key == PUGL_KEY_ESCAPE) { app->quit = 1; } else if ((event->state & PUGL_MOD_CTRL) && event->key == 'c') { - puglSetClipboard(view, NULL, copyString, strlen(copyString) + 1); + puglSetClipboard(view, "text/plain", copyString, strlen(copyString)); fprintf(stderr, "Copy \"%s\"\n", copyString); } else if ((event->state & PUGL_MOD_CTRL) && event->key == 'v') { - const char* type = NULL; + puglPaste(view); + } +} + +static void +onDataOffer(PuglView* view, const PuglDataOfferEvent* event) +{ + const uint32_t numTypes = puglGetNumClipboardTypes(view); + + // Print all offered types to be useful as a testing program + fprintf(stderr, "Offered %u types:\n", numTypes); + for (uint32_t t = 0; t < numTypes; ++t) { + const char* type = puglGetClipboardType(view, t); + fprintf(stderr, "\t%s\n", type); + } + + // Accept the first type found that we support (namely text) + for (uint32_t t = 0; t < numTypes; ++t) { + const char* type = puglGetClipboardType(view, t); + if (!strncmp(type, "text/", 5)) { + puglAcceptOffer(view, event, t); + return; + } + } +} + +static void +onData(PuglView* view, const PuglDataEvent* event) +{ + const uint32_t typeIndex = event->typeIndex; + + const char* const type = puglGetClipboardType(view, typeIndex); + + fprintf(stderr, "Received data type: %s\n", type); + if (!strncmp(type, "text/", 5)) { + // Accept any text type size_t len = 0; - const char* text = (const char*)puglGetClipboard(view, &type, &len); + const void* data = puglGetClipboard(view, typeIndex, &len); - fprintf(stderr, "Paste \"%s\"\n", text); + fprintf(stderr, "Data:\n%s\n", (const char*)data); } } @@ -143,6 +179,12 @@ onEvent(PuglView* view, const PuglEvent* event) case PUGL_FOCUS_OUT: redisplayView(app, view); break; + case PUGL_DATA_OFFER: + onDataOffer(view, &event->offer); + break; + case PUGL_DATA: + onData(view, &event->data); + break; default: break; } -- cgit v1.2.1