diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 5b62339e2..57ac76ed9 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1043,6 +1043,11 @@ const char *GetClipboardText(void) return glfwGetClipboardString(platform.handle); } +#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11) + #include + #include +#endif + // Get clipboard image Image GetClipboardImage(void) { @@ -1059,6 +1064,51 @@ Image GetClipboardImage(void) if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize); + +#elif defined(__linux__) && defined(_GLFW_X11) + + // Implementation based on https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c + Display* dpy = XOpenDisplay(NULL); + if (!dpy) return image; + + Window root = DefaultRootWindow(dpy); + Window win = XCreateSimpleWindow( + dpy, // The connection to the X Server + root, // The 'Parent' window (usually the desktop/root) + 0, 0, // X and Y position on the screen + 1, 1, // Width and Height (1x1 pixel) + 0, // Border width + 0, // Border color + 0 // Background color + ); + + Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False); + Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG + Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False); + + // Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER" + XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime); + + // Wait for the SelectionNotify event + XEvent ev; + XNextEvent(dpy, &ev); + + Atom actualType; + int actualFormat; + unsigned long nitems, bytesAfter; + unsigned char* data = NULL; + + // Read the data from our ghost window's property + XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType, + &actualType, &actualFormat, &nitems, &bytesAfter, &data); + + if (data != NULL) { + image = LoadImageFromMemory(".png", data, (int)nitems); + XFree(data); + } + + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); #else TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); #endif // defined(_WIN32) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index ed471645c..651f1206a 100755 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -999,6 +999,9 @@ const char *GetClipboardText(void) #define WINBASE_ALREADY_INCLUDED #define WINGDI_ALREADY_INCLUDED #include "../external/win32_clipboard.h" +#elif defined(__linux__) && defined(DRGFW_X11) + #include + #include #endif #endif @@ -1006,6 +1009,7 @@ const char *GetClipboardText(void) Image GetClipboardImage(void) { Image image = { 0 }; + #if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES #if defined(_WIN32) @@ -1018,6 +1022,51 @@ Image GetClipboardImage(void) if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data"); else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, dataSize); + +#elif defined(__linux__) && defined(DRGFW_X11) + + // Implementation based on https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c + Display* dpy = XOpenDisplay(NULL); + if (!dpy) return image; + + Window root = DefaultRootWindow(dpy); + Window win = XCreateSimpleWindow( + dpy, // The connection to the X Server + root, // The 'Parent' window (usually the desktop/root) + 0, 0, // X and Y position on the screen + 1, 1, // Width and Height (1x1 pixel) + 0, // Border width + 0, // Border color + 0 // Background color + ); + + Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False); + Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG + Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False); + + // Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER" + XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime); + + // Wait for the SelectionNotify event + XEvent ev; + XNextEvent(dpy, &ev); + + Atom actualType; + int actualFormat; + unsigned long nitems, bytesAfter; + unsigned char* data = NULL; + + // Read the data from our ghost window's property + XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType, + &actualType, &actualFormat, &nitems, &bytesAfter, &data); + + if (data != NULL) { + image = LoadImageFromMemory(".png", data, (int)nitems); + XFree(data); + } + + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); #else TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS"); #endif // defined(_WIN32)