mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 06:14:35 +00:00
X11 implementation of clipboard pasting.
This commit is contained in:
parent
31c91545be
commit
57522db6e2
@ -465,6 +465,7 @@ extern "C" {
|
|||||||
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
||||||
#define GLFW_PLATFORM_ERROR 0x00070008
|
#define GLFW_PLATFORM_ERROR 0x00070008
|
||||||
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
||||||
|
#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
|
||||||
|
|
||||||
/* Gamma ramps */
|
/* Gamma ramps */
|
||||||
#define GLFW_GAMMA_RAMP_SIZE 256
|
#define GLFW_GAMMA_RAMP_SIZE 256
|
||||||
|
@ -48,6 +48,10 @@ GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format)
|
|||||||
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (format == GLFW_CLIPBOARD_FORMAT_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
_glfwPlatformSetClipboardData(data, size, format);
|
_glfwPlatformSetClipboardData(data, size, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,5 +68,8 @@ GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (format == GLFW_CLIPBOARD_FORMAT_NONE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return _glfwPlatformGetClipboardData(data, size, format);
|
return _glfwPlatformGetClipboardData(data, size, format);
|
||||||
}
|
}
|
||||||
|
@ -29,28 +29,131 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// 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
|
// Set the clipboard contents
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
|
void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Return the current clipboard contents
|
// Return the current clipboard contents
|
||||||
|
// TODO: Incremental support? Overkill perhaps.
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
|
size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
|
||||||
{
|
{
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +446,14 @@ static GLboolean initDisplay(void)
|
|||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
updateKeyCodeLUT();
|
updateKeyCodeLUT();
|
||||||
|
|
||||||
|
// Find or create selection atoms
|
||||||
|
_glfwLibrary.X11.selection.stringatoms[0] =
|
||||||
|
XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
|
||||||
|
_glfwLibrary.X11.selection.stringatoms[1] =
|
||||||
|
XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
|
||||||
|
_glfwLibrary.X11.selection.stringatoms[2] = XA_STRING;
|
||||||
|
_glfwLibrary.X11.selection.stringatoms[3] = 0;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@
|
|||||||
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
||||||
|
|
||||||
|
// Number of string atoms that will be checked
|
||||||
|
#define _GLFW_STRING_ATOMS_COUNT 4
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW platform specific types
|
// GLFW platform specific types
|
||||||
@ -225,6 +227,13 @@ typedef struct _GLFWlibraryX11
|
|||||||
uint64_t t0;
|
uint64_t t0;
|
||||||
} timer;
|
} timer;
|
||||||
|
|
||||||
|
// Selection data
|
||||||
|
struct {
|
||||||
|
Atom stringatoms[_GLFW_STRING_ATOMS_COUNT];
|
||||||
|
Atom request;
|
||||||
|
int converted;
|
||||||
|
} selection;
|
||||||
|
|
||||||
#if defined(_GLFW_DLOPEN_LIBGL)
|
#if defined(_GLFW_DLOPEN_LIBGL)
|
||||||
void* libGL; // dlopen handle for libGL.so
|
void* libGL; // dlopen handle for libGL.so
|
||||||
#endif
|
#endif
|
||||||
|
@ -1381,6 +1381,19 @@ static void processSingleEvent(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
// Selection notification triggered by the XConvertSelection
|
||||||
|
|
||||||
|
// Check if the notification property matches the request
|
||||||
|
if (event.xselection.property != _glfwLibrary.X11.selection.request)
|
||||||
|
_glfwLibrary.X11.selection.converted = 2;
|
||||||
|
else // It was successful
|
||||||
|
_glfwLibrary.X11.selection.converted = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Was the window destroyed?
|
// Was the window destroyed?
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
return;
|
return;
|
||||||
|
@ -5,6 +5,7 @@ include_directories(${GLFW_SOURCE_DIR}/include
|
|||||||
${GLFW_SOURCE_DIR}/support
|
${GLFW_SOURCE_DIR}/support
|
||||||
${OPENGL_INCLUDE_DIR})
|
${OPENGL_INCLUDE_DIR})
|
||||||
|
|
||||||
|
add_executable(clipboard clipboard.c)
|
||||||
add_executable(defaults defaults.c)
|
add_executable(defaults defaults.c)
|
||||||
add_executable(events events.c)
|
add_executable(events events.c)
|
||||||
add_executable(fsaa fsaa.c getopt.c)
|
add_executable(fsaa fsaa.c getopt.c)
|
||||||
@ -32,8 +33,8 @@ else()
|
|||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
set(WINDOWS_BINARIES accuracy sharing tearing windows)
|
set(WINDOWS_BINARIES accuracy sharing tearing windows)
|
||||||
set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma iconify joysticks
|
set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma iconify
|
||||||
listmodes peter reopen version)
|
joysticks listmodes peter reopen version)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
||||||
|
Loading…
Reference in New Issue
Block a user