Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/platforms/rcore_desktop_glfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,11 @@ const char *GetClipboardText(void)
return glfwGetClipboardString(platform.handle);
}

#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif

// Get clipboard image
Image GetClipboardImage(void)
{
Expand All @@ -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)
Expand Down
49 changes: 49 additions & 0 deletions src/platforms/rcore_desktop_rgfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,13 +999,17 @@ const char *GetClipboardText(void)
#define WINBASE_ALREADY_INCLUDED
#define WINGDI_ALREADY_INCLUDED
#include "../external/win32_clipboard.h"
#elif defined(__linux__) && defined(DRGFW_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
#endif

// Get clipboard image
Image GetClipboardImage(void)
{
Image image = { 0 };

#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
#if defined(_WIN32)

Expand All @@ -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)
Expand Down
Loading