X11 implementation of clipboard pasting.

This commit is contained in:
Ralph Eastwood
2011-09-21 15:43:28 +01:00
parent 31c91545be
commit 57522db6e2
7 changed files with 147 additions and 5 deletions
+105 -2
View File
@@ -29,28 +29,131 @@
#include "internal.h"
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Get the corresponding X11 format for a given GLFW format.
//========================================================================
static Atom *getInternalFormat(int fmt)
{
// Get the necessary atoms
switch (fmt)
{
case GLFW_CLIPBOARD_FORMAT_STRING:
return _glfwLibrary.X11.selection.stringatoms;
default:
return 0;
}
}
//========================================================================
// Set the clipboard contents
//========================================================================
void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
{
}
//========================================================================
// Return the current clipboard contents
// TODO: Incremental support? Overkill perhaps.
//========================================================================
size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
{
return 0;
size_t len, rembytes, dummy;
unsigned char *d;
int fmt;
Window window;
Atom *xfmt, type;
// Try different formats that relate to the GLFW format with preference
// for better formats first
for (xfmt = getInternalFormat(format); *xfmt; xfmt++)
{
// Specify the format we would like.
_glfwLibrary.X11.selection.request = *xfmt;
// Convert the selection into a format we would like.
window = _glfwLibrary.activeWindow->X11.handle;
XConvertSelection(_glfwLibrary.X11.display, XA_PRIMARY,
*xfmt, None, window,
CurrentTime);
XFlush(_glfwLibrary.X11.display);
// Process pending events until we get a SelectionNotify.
while (!_glfwLibrary.X11.selection.converted)
_glfwPlatformWaitEvents();
// If there is no owner to the selection/wrong request, bail out.
if (_glfwLibrary.X11.selection.converted == 2)
{
_glfwLibrary.X11.selection.converted = 0;
_glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
"X11/GLX: Unavailable clipboard format");
return 0;
}
else // Right format, stop checking
{
_glfwLibrary.X11.selection.converted = 0;
break;
}
}
// Reset for the next selection
_glfwLibrary.X11.selection.converted = 0;
// Check the length of data to receive
XGetWindowProperty(_glfwLibrary.X11.display,
window,
*xfmt,
0, 0,
0,
AnyPropertyType,
&type,
&fmt,
&len, &rembytes,
&d);
// The number of bytes remaining (which is all of them)
if (rembytes > 0)
{
int result = XGetWindowProperty(_glfwLibrary.X11.display, window,
*xfmt, 0, rembytes, 0,
AnyPropertyType, &type, &fmt,
&len, &dummy, &d);
if (result == Success)
{
size_t s = size - 1 > rembytes ? rembytes : size - 1;
// Copy the data out.
memcpy(data, d, s);
// Null-terminate strings.
if (format == GLFW_CLIPBOARD_FORMAT_STRING)
{
((char *)data)[s] = '\0';
}
// Free the data allocated using X11.
XFree(d);
// Return the actual number of bytes.
return rembytes;
}
else
{
// Free the data allocated using X11.
XFree(d);
return 0;
}
}
return 0;
}