Cross-platform copy & paste support comes up once in a blue moon on the SDL mailing list.
Sam Lantinga (the main author of SDL) implemented a demo piece called SDL_scrap some years ago. Several years ago, I tried the code and decided to modify it because it didn't meet my needs.
First, it completely lacked a native Mac OS X implementation, so I implemented that.
Second, Sam's demo relied on inventing custom types for clipboards so it was useless for sharing data between other applications that didn't use SDL_scrap. For example, if I wanted to copy/paste text with Notepad.exe or an image with MS Paint , this was impossible because SDL_Scrap didn't leverage native known types in the underlying clipboard implementations.
So I implemented the Mac version around my needs and then made a bunch of changes to the Windows implementation to support this. I tried to tweak the X11 implementation, but I never got it to fully work right for me, though I am not sure if part of my problem is if there is a conflict between KDE's clipboard system and X11.
My implementation satisfied my own needs and then I moved on. On the SDL mailing, we occasionally talked about launching a new formal clipboard project, though we never followed through.
More recently with SDL 1.3 approaching, Sam asked me if I wanted to propose a new clipboard API for SDL. So I have taken my old work, cleaned up the public APIs a bit, wrote a good test/demo program, and pushed it up to a public repository.
So for review, you can find my prototype clipboard API for SDL at:
A few things to note:
- It is implemented against SDL 1.2, not 1.3. If feedback is positive, the goal will be to integrate this as part of the SDL core for SDL 1.3. (Volunteers welcome.)
- The core library only requires SDL, but my test/demo program additionally relies on SDL_ttf.
- A CMake build system is included.
- Currently only BMP images are supported as "images". (On Mac, other image types may work, but other implementations are not guaranteed to work.)
- The Mac and Windows implementations are finished. As I mentioned, I am having trouble with X11. And my changes completely broke the QNX implementation.
- There is an API called SDLScrap_Lost(), which is a left-over from SDL_scrap. I never understood what it was supposed to do and I don't think it makes any sense for Mac and Windows. I would like to remove this API completely if possible.
- Some of my API functions are prefixed with "SDLScrap_". These will be renamed if integrated into SDL.
- There is a set of utility functions to help make serializing and de-serializing buffers to/from SDL_Surfaces easy. I tried to keep these separate from the core clipboard implementation, but I propose these functions also be included in the main clipboard API because they are really handy.
- To paste an image from the pasteboard on Mac OS X, you need to patch SDL (currently 1.2.13). There is a bug in SDL's BMP handler that does not handle negative height values in the BMP headers. Apple appears to use this to denote an image is inverted. Without the patch, pasting an image from the pasteboard will result in a crash. (SDL bug: 724). I include a fixed version of SDL_bmp.c in the repository. Just replace the existing file in the SDL source with mine and compile SDL.
There are really only 2 API functions for the clipboard itself. These are:
void SDLScrap_CopyToClipboard(SDLScrap_DataType* clipboard_type, size_t src_len, const char* src_data);
void SDLScrap_PasteFromClipboard(SDLScrap_DataType* clipboard_type, size_t* dst_len, char** dst_data);
The first parameter represents the type of data you want to exchange with the clipboard. I provide 2 predefined constants you can use.
The remaining parameters are just passing byte arrays and the array size.
There are helper functions in SDL_SurfaceUtils to help you convert SDL_Surfaces to/from byte arrays.
Please see the test program source code for usage examples.
Running the Test Program:
The test program is pretty simple. The window is divided into 4 clickable regions. The text describes what each region does. Any key press will quit the program.
So for example, if I go to my web browser and copy some text such as the link: "http://www.libsdl.org/images/SDL_logo.png", and then click in the left-bottom corner, the text should appear there. (Note if the string has a newline character at the end, you may see a box outline as a placeholder for the newline character because that's what SDL_ttf seems to do.)
Then if I find a BMP image in my web browser and copy the to the image to the clipboard, and then click in the bottom-right corner, the image will appear.
Your screen may look something like this:
(Note, I cheated a little and used a PNG which works fine on OS X, but will probably not work on Windows. You need a true BMP image on Windows.)
Next if you click the top-right corner, it will basically do a screen capture of your window contents and copy the image to the clipboard. If you open a program that lets you paste images, such as MS Paint on Windows or TextEdit on Mac, you can try pasting the image.
Finally if you click on the top-left corner, the program copies the current date and time as a string to the clipboard. Paste into Notepad on Windows or TextEdit on Mac and you can see the result.
Areas I need help with:
- I need help with getting X11 fully working
- Fix QNX support?
- Ideas and implementations on getting different window manager support such as Gnome and KDE are welcome
- Ideas on what other data types we should and can support out of the box
- Ideas on how we can open up the DataTypes so users can invent new types or hook into platform specific, but SDL unsupported types. (For example, the current implementation uses strings as type identifiers which maps directly to the Cocoa implementation so if you pass the correct string value, e.g. "Apple PDF pasteboard type", you could get PDF support. It would be nice if we can extend this idea to other platforms
- Can we drop the Lost() API?
Feedback is welcome here or on the SDL mailing list.