From 31c91545be9c65c7ad3701c71286102e07186bb8 Mon Sep 17 00:00:00 2001
From: Ralph Eastwood
Date: Wed, 21 Sep 2011 10:09:47 +0100
Subject: [PATCH 01/37] Added clipboard stubs.
---
include/GL/glfw3.h | 8 +++++
src/CMakeLists.txt | 11 ++++---
src/clipboard.c | 68 +++++++++++++++++++++++++++++++++++++++++++
src/cocoa_clipboard.m | 56 +++++++++++++++++++++++++++++++++++
src/internal.h | 4 +++
src/win32_clipboard.c | 56 +++++++++++++++++++++++++++++++++++
src/x11_clipboard.c | 56 +++++++++++++++++++++++++++++++++++
7 files changed, 255 insertions(+), 4 deletions(-)
create mode 100644 src/clipboard.c
create mode 100644 src/cocoa_clipboard.m
create mode 100644 src/win32_clipboard.c
create mode 100644 src/x11_clipboard.c
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 1f52e742..e3687b5c 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -469,6 +469,10 @@ extern "C" {
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
+/* Clipboard formats */
+#define GLFW_CLIPBOARD_FORMAT_NONE 0
+#define GLFW_CLIPBOARD_FORMAT_STRING 1
+
/*************************************************************************
* Typedefs
*************************************************************************/
@@ -591,6 +595,10 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param);
GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
+/* Clipboard */
+GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format);
+GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format);
+
/* Time */
GLFWAPI double glfwGetTime(void);
GLFWAPI void glfwSetTime(double time);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cd50b41d..08ce8365 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,23 +27,26 @@ include_directories(${GLFW_SOURCE_DIR}/src
${GLFW_BINARY_DIR}/src
${GLFW_INCLUDE_DIR})
-set(common_SOURCES enable.c error.c fullscreen.c gamma.c init.c input.c
+set(common_SOURCES clipboard.c enable.c error.c fullscreen.c gamma.c init.c input.c
joystick.c opengl.c time.c window.c)
if(_GLFW_COCOA_NSGL)
- set(libglfw_SOURCES ${common_SOURCES} cocoa_enable.m cocoa_fullscreen.m
+ set(libglfw_SOURCES ${common_SOURCES} cocoa_clipboard.c
+ cocoa_enable.m cocoa_fullscreen.m
cocoa_gamma.m cocoa_init.m cocoa_joystick.m
cocoa_opengl.m cocoa_time.m cocoa_window.m)
# For some reason, CMake doesn't know about .m
set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C)
elseif(_GLFW_WIN32_WGL)
- set(libglfw_SOURCES ${common_SOURCES} win32_enable.c win32_fullscreen.c
+ set(libglfw_SOURCES ${common_SOURCES} win32_clipboard.c
+ win32_enable.c win32_fullscreen.c
win32_gamma.c win32_init.c win32_joystick.c
win32_opengl.c win32_time.c win32_window.c
win32_dllmain.c)
elseif(_GLFW_X11_GLX)
- set(libglfw_SOURCES ${common_SOURCES} x11_enable.c x11_fullscreen.c
+ set(libglfw_SOURCES ${common_SOURCES} x11_clipboard.c
+ x11_enable.c x11_fullscreen.c
x11_gamma.c x11_init.c x11_joystick.c
x11_keysym2unicode.c x11_opengl.c x11_time.c
x11_window.c)
diff --git a/src/clipboard.c b/src/clipboard.c
new file mode 100644
index 00000000..5e38904f
--- /dev/null
+++ b/src/clipboard.c
@@ -0,0 +1,68 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Any
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format)
+{
+ if (!_glfwInitialized)
+ {
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return;
+ }
+ _glfwPlatformSetClipboardData(data, size, format);
+}
+
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
+{
+ if (!_glfwInitialized)
+ {
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return 0;
+ }
+
+ return _glfwPlatformGetClipboardData(data, size, format);
+}
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
new file mode 100644
index 00000000..0f78cf21
--- /dev/null
+++ b/src/cocoa_clipboard.m
@@ -0,0 +1,56 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Cocoa/NSOpenGL
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+{
+}
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
+{
+ return 0;
+}
+
diff --git a/src/internal.h b/src/internal.h
index 83559ecc..3b82d47e 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -284,6 +284,10 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
+// Clipboard
+void _glfwPlatformSetClipboardData(void *data, size_t size, int format);
+size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format);
+
// Joystick
int _glfwPlatformGetJoystickParam(int joy, int param);
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes);
diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c
new file mode 100644
index 00000000..b16c51c4
--- /dev/null
+++ b/src/win32_clipboard.c
@@ -0,0 +1,56 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Win32/WGL
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+{
+}
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
+{
+ return 0;
+}
+
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
new file mode 100644
index 00000000..164bad49
--- /dev/null
+++ b/src/x11_clipboard.c
@@ -0,0 +1,56 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: X11/GLX
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+{
+}
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
+{
+ return 0;
+}
+
From 57522db6e2919406efd0d44a170962ed8f480f2f Mon Sep 17 00:00:00 2001
From: Ralph Eastwood
Date: Wed, 21 Sep 2011 15:43:28 +0100
Subject: [PATCH 02/37] X11 implementation of clipboard pasting.
---
include/GL/glfw3.h | 1 +
src/clipboard.c | 9 +++-
src/x11_clipboard.c | 107 ++++++++++++++++++++++++++++++++++++++++++-
src/x11_init.c | 8 ++++
src/x11_platform.h | 9 ++++
src/x11_window.c | 13 ++++++
tests/CMakeLists.txt | 5 +-
7 files changed, 147 insertions(+), 5 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index e3687b5c..21ed049a 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -465,6 +465,7 @@ extern "C" {
#define GLFW_VERSION_UNAVAILABLE 0x00070007
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
+#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
diff --git a/src/clipboard.c b/src/clipboard.c
index 5e38904f..79cf680c 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -48,6 +48,10 @@ GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format)
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
+
+ if (format == GLFW_CLIPBOARD_FORMAT_NONE)
+ return;
+
_glfwPlatformSetClipboardData(data, size, format);
}
@@ -61,8 +65,11 @@ GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
- return 0;
+ return 0;
}
+ if (format == GLFW_CLIPBOARD_FORMAT_NONE)
+ return 0;
+
return _glfwPlatformGetClipboardData(data, size, format);
}
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 164bad49..467a0d52 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -29,28 +29,131 @@
#include "internal.h"
+#include
#include
#include
-
+#include
//////////////////////////////////////////////////////////////////////////
////// 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;
}
diff --git a/src/x11_init.c b/src/x11_init.c
index 9af7783e..a824528b 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -446,6 +446,14 @@ static GLboolean initDisplay(void)
// the keyboard mapping.
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;
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index b3cf642e..90b6e75c 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -89,6 +89,8 @@
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#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
@@ -225,6 +227,13 @@ typedef struct _GLFWlibraryX11
uint64_t t0;
} timer;
+ // Selection data
+ struct {
+ Atom stringatoms[_GLFW_STRING_ATOMS_COUNT];
+ Atom request;
+ int converted;
+ } selection;
+
#if defined(_GLFW_DLOPEN_LIBGL)
void* libGL; // dlopen handle for libGL.so
#endif
diff --git a/src/x11_window.c b/src/x11_window.c
index a05b121c..ff54a11b 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -1381,6 +1381,19 @@ static void processSingleEvent(void)
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?
case DestroyNotify:
return;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9ef07acc..23a1ebd0 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories(${GLFW_SOURCE_DIR}/include
${GLFW_SOURCE_DIR}/support
${OPENGL_INCLUDE_DIR})
+add_executable(clipboard clipboard.c)
add_executable(defaults defaults.c)
add_executable(events events.c)
add_executable(fsaa fsaa.c getopt.c)
@@ -32,8 +33,8 @@ else()
endif(APPLE)
set(WINDOWS_BINARIES accuracy sharing tearing windows)
-set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma iconify joysticks
- listmodes peter reopen version)
+set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma iconify
+ joysticks listmodes peter reopen version)
if(MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
From 9f41e5b67a89dbd93f96e39d2d1d7d6c79a872c2 Mon Sep 17 00:00:00 2001
From: Ralph Eastwood
Date: Thu, 22 Sep 2011 12:03:45 +0100
Subject: [PATCH 03/37] X11 copying code and support PRIMARY & CLIPBOARD
clipboards.
---
include/GL/glfw3.h | 1 +
src/clipboard.c | 3 +
src/x11_clipboard.c | 149 +++++++++++++++++++++++++++++++++++---------
src/x11_init.c | 19 ++++--
src/x11_platform.h | 26 ++++++--
src/x11_window.c | 21 ++++++-
6 files changed, 179 insertions(+), 40 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 21ed049a..7f054e5f 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -466,6 +466,7 @@ extern "C" {
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
+#define GLFW_CLIPBOARD_CANNOT_OWN 0x00070011
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
diff --git a/src/clipboard.c b/src/clipboard.c
index 79cf680c..b055c168 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -71,5 +71,8 @@ GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
if (format == GLFW_CLIPBOARD_FORMAT_NONE)
return 0;
+ if (!data || !size)
+ return 0;
+
return _glfwPlatformGetClipboardData(data, size, format);
}
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 467a0d52..1be0ac23 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -27,6 +27,8 @@
//
//========================================================================
+// TODO: Incremental support? Overkill perhaps.
+
#include "internal.h"
#include
@@ -45,28 +47,101 @@
static Atom *getInternalFormat(int fmt)
{
// Get the necessary atoms
-
switch (fmt)
{
case GLFW_CLIPBOARD_FORMAT_STRING:
- return _glfwLibrary.X11.selection.stringatoms;
+ return _glfwLibrary.X11.selection.atoms.string;
default:
return 0;
}
}
+//========================================================================
+// X11 selection request event
+//========================================================================
+
+Atom _glfwSelectionRequest(XSelectionRequestEvent *request)
+{
+ Atom *atoms = _glfwLibrary.X11.selection.atoms.string;
+ if (request->target == XA_STRING)
+ {
+ // TODO: ISO Latin-1 specific characters don't get converted
+ // (yet). For cleanliness, would we need something like iconv?
+ XChangeProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ request->target,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char *)_glfwLibrary.X11.selection.clipboard.string,
+ 8);
+ }
+ else if (request->target == atoms[_GLFW_STRING_ATOM_COMPOUND] ||
+ request->target == atoms[_GLFW_STRING_ATOM_UTF8])
+ {
+ XChangeProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ request->target,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char *)_glfwLibrary.X11.selection.clipboard.string,
+ _glfwLibrary.X11.selection.clipboard.stringlen);
+ }
+ else
+ {
+ // TODO: Should we set an error? Probably not.
+ return None;
+ }
+ return request->target;
+}
+
//========================================================================
// Set the clipboard contents
//========================================================================
void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
{
+ switch (format)
+ {
+ case GLFW_CLIPBOARD_FORMAT_STRING:
+ {
+ // Allocate memory to keep track of the clipboard
+ char *cb = malloc(size+1);
+ // Copy the clipboard data
+ memcpy(cb, data, size);
+
+ // Set the string length
+ _glfwLibrary.X11.selection.clipboard.stringlen = size;
+
+ // Check if existing clipboard memory needs to be freed
+ if (_glfwLibrary.X11.selection.clipboard.string)
+ free(_glfwLibrary.X11.selection.clipboard.string);
+
+ // Now set the clipboard (awaiting the event SelectionRequest)
+ _glfwLibrary.X11.selection.clipboard.string = cb;
+ break;
+ }
+
+ default:
+ _glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
+ "X11/GLX: Unavailable clipboard format");
+ return;
+ }
+
+ // Set the selection owner to our active window
+ XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
+ _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ XSetSelectionOwner(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.selection.atoms.clipboard
+ [_GLFW_CLIPBOARD_ATOM_CLIPBOARD],
+ _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ XFlush(_glfwLibrary.X11.display);
}
//========================================================================
// Return the current clipboard contents
-// TODO: Incremental support? Overkill perhaps.
//========================================================================
size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
@@ -74,46 +149,60 @@ 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;
+ Atom type;
- // Try different formats that relate to the GLFW format with preference
- // for better formats first
- for (xfmt = getInternalFormat(format); *xfmt; xfmt++)
+ // Try different clipboards and formats that relate to the GLFW
+ // format with preference for more appropriate formats first
+ Atom *xcbrd = _glfwLibrary.X11.selection.atoms.clipboard;
+ Atom *xcbrdend = _glfwLibrary.X11.selection.atoms.clipboard +
+ _GLFW_CLIPBOARD_ATOM_COUNT;
+ Atom *xfmt = getInternalFormat(format);
+ Atom *xfmtend = xfmt + _GLFW_STRING_ATOM_COUNT;
+
+ // Get the currently active window
+ Window window = _glfwLibrary.activeWindow->X11.handle;
+
+ for (; xcbrd != xcbrdend; xcbrd++)
{
- // 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)
+ for (; xfmt != xfmtend; xfmt++)
{
- _glfwLibrary.X11.selection.converted = 0;
- _glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
- "X11/GLX: Unavailable clipboard format");
- return 0;
+ // Specify the format we would like.
+ _glfwLibrary.X11.selection.request = *xfmt;
+
+ // Convert the selection into a format we would like.
+ XConvertSelection(_glfwLibrary.X11.display, *xcbrd,
+ *xfmt, None, window, CurrentTime);
+ XFlush(_glfwLibrary.X11.display);
+
+ // Process pending events until we get a SelectionNotify.
+ while (!_glfwLibrary.X11.selection.converted)
+ _glfwPlatformWaitEvents();
+
+ // Successful?
+ if (_glfwLibrary.X11.selection.converted == 1)
+ break;
}
- else // Right format, stop checking
+
+ // Successful?
+ if (_glfwLibrary.X11.selection.converted == 1)
{
_glfwLibrary.X11.selection.converted = 0;
break;
}
}
+ // Unsuccessful conversion, bail with no clipboard data
+ if (_glfwLibrary.X11.selection.converted)
+ {
+ _glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
+ "X11/GLX: Unavailable clipboard format");
+ return 0;
+ }
+
// Reset for the next selection
_glfwLibrary.X11.selection.converted = 0;
- // Check the length of data to receive
+ // Check the length of data to receive (rembytes)
XGetWindowProperty(_glfwLibrary.X11.display,
window,
*xfmt,
diff --git a/src/x11_init.c b/src/x11_init.c
index a824528b..1fa549bd 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -446,13 +446,20 @@ static GLboolean initDisplay(void)
// the keyboard mapping.
updateKeyCodeLUT();
+ // Find or create clipboard atoms
+ _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_PRIMARY] =
+ XA_PRIMARY;
+ _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_CLIPBOARD] =
+ XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);
+ _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_SECONDARY] =
+ XA_SECONDARY;
+
// Find or create selection atoms
- _glfwLibrary.X11.selection.stringatoms[0] =
+ _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_UTF8] =
XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
- _glfwLibrary.X11.selection.stringatoms[1] =
+ _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_COMPOUND] =
XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
- _glfwLibrary.X11.selection.stringatoms[2] = XA_STRING;
- _glfwLibrary.X11.selection.stringatoms[3] = 0;
+ _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_STRING] = XA_STRING;
return GL_TRUE;
}
@@ -616,6 +623,10 @@ int _glfwPlatformTerminate(void)
}
#endif
+ // Free clipboard memory
+ if (_glfwLibrary.X11.selection.clipboard.string)
+ free(_glfwLibrary.X11.selection.clipboard.string);
+
return GL_TRUE;
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 90b6e75c..6f1bf6a5 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -89,8 +89,17 @@
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
-// Number of string atoms that will be checked
-#define _GLFW_STRING_ATOMS_COUNT 4
+// Clipboard atoms
+#define _GLFW_CLIPBOARD_ATOM_PRIMARY 0
+#define _GLFW_CLIPBOARD_ATOM_CLIPBOARD 1
+#define _GLFW_CLIPBOARD_ATOM_SECONDARY 2
+#define _GLFW_CLIPBOARD_ATOM_COUNT 3
+
+// String atoms
+#define _GLFW_STRING_ATOM_UTF8 0
+#define _GLFW_STRING_ATOM_COMPOUND 1
+#define _GLFW_STRING_ATOM_STRING 2
+#define _GLFW_STRING_ATOM_COUNT 3
//========================================================================
// GLFW platform specific types
@@ -229,8 +238,15 @@ typedef struct _GLFWlibraryX11
// Selection data
struct {
- Atom stringatoms[_GLFW_STRING_ATOMS_COUNT];
- Atom request;
+ struct {
+ Atom clipboard[_GLFW_CLIPBOARD_ATOM_COUNT];
+ Atom string[_GLFW_STRING_ATOM_COUNT];
+ } atoms;
+ struct {
+ size_t stringlen;
+ char *string;
+ } clipboard;
+ Atom request;
int converted;
} selection;
@@ -273,5 +289,7 @@ void _glfwTerminateJoysticks(void);
// Unicode support
long _glfwKeySym2Unicode(KeySym keysym);
+// Clipboard handling
+Atom _glfwSelectionRequest(XSelectionRequestEvent *request);
#endif // _platform_h_
diff --git a/src/x11_window.c b/src/x11_window.c
index ff54a11b..cfb19980 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -41,8 +41,8 @@
#define _NET_WM_STATE_TOGGLE 2
// Additional mouse button names for XButtonEvent
-#define Button6 6
-#define Button7 7
+#define Button6 6
+#define Button7 7
//========================================================================
// Error handler for BadMatch errors when requesting context with
@@ -1394,6 +1394,23 @@ static void processSingleEvent(void)
break;
}
+ case SelectionRequest:
+ {
+ XSelectionRequestEvent *request = &event.xselectionrequest;
+ // Construct the response
+ XEvent response;
+ response.xselection.property = _glfwSelectionRequest(request);
+ response.xselection.type = SelectionNotify;
+ response.xselection.display = request->display;
+ response.xselection.requestor = request->requestor;
+ response.xselection.selection = request->selection;
+ response.xselection.target = request->target;
+ response.xselection.time = request->time;
+ // Send off the event
+ XSendEvent(_glfwLibrary.X11.display, request->requestor, 0, 0, &response);
+ break;
+ }
+
// Was the window destroyed?
case DestroyNotify:
return;
From a2ffa80e82729afcca0b0929a03b21661c2d00d7 Mon Sep 17 00:00:00 2001
From: Ralph Eastwood
Date: Thu, 22 Sep 2011 12:09:01 +0100
Subject: [PATCH 04/37] Some reformatting with new X11 SelectionRequest event.
---
src/x11_window.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/x11_window.c b/src/x11_window.c
index cfb19980..0fe4db83 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -1396,7 +1396,10 @@ static void processSingleEvent(void)
case SelectionRequest:
{
+ // Selection request triggered by someone wanting data from the
+ // X11 clipboard
XSelectionRequestEvent *request = &event.xselectionrequest;
+
// Construct the response
XEvent response;
response.xselection.property = _glfwSelectionRequest(request);
@@ -1406,8 +1409,10 @@ static void processSingleEvent(void)
response.xselection.selection = request->selection;
response.xselection.target = request->target;
response.xselection.time = request->time;
+
// Send off the event
XSendEvent(_glfwLibrary.X11.display, request->requestor, 0, 0, &response);
+
break;
}
From f332e0009d46f71ee23e91eafc50821dcc2a0acd Mon Sep 17 00:00:00 2001
From: Tai Chi Minh Ralph Eastwood
Date: Sun, 19 Feb 2012 05:39:21 +0000
Subject: [PATCH 05/37] Add mising clipboard test program.
---
tests/clipboard.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
create mode 100644 tests/clipboard.c
diff --git a/tests/clipboard.c b/tests/clipboard.c
new file mode 100644
index 00000000..cdbba6d2
--- /dev/null
+++ b/tests/clipboard.c
@@ -0,0 +1,147 @@
+//========================================================================
+// Gamma correction test program
+// Copyright (c) Camilla Berglund
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+//
+// This program is used to test the clipboard functionality.
+//
+//========================================================================
+
+#include
+
+#include
+#include
+
+#include "getopt.h"
+
+static void usage(void)
+{
+ printf("Usage: clipboard [-h]\n");
+}
+
+static void key_callback(GLFWwindow window, int key, int action)
+{
+ static int control = GL_FALSE;
+ if (key == GLFW_KEY_LEFT_CONTROL)
+ {
+ control = (action == GLFW_PRESS);
+ return;
+ }
+
+ if (action != GLFW_PRESS)
+ return;
+
+ switch (key)
+ {
+ case GLFW_KEY_ESCAPE:
+ glfwCloseWindow(window);
+ break;
+ case GLFW_KEY_V:
+ if (control)
+ {
+ char buffer[4096];
+ size_t size;
+ printf("Paste test.\n");
+ size = glfwGetClipboardData(buffer, sizeof(buffer), GLFW_CLIPBOARD_FORMAT_STRING);
+ if (size >= sizeof(buffer))
+ {
+ printf("Buffer wasn't big enough to hold clipboard data.\n");
+ }
+ printf("[%ld]: %s\n", size, buffer);
+ }
+ break;
+ case GLFW_KEY_C:
+ if (control)
+ {
+ glfwSetClipboardData("Hello GLFW World!", sizeof("Hello GLFW World!"),
+ GLFW_CLIPBOARD_FORMAT_STRING);
+ printf("Setting clipboard to: %s\n", "Hello GLFW World!");
+ }
+ break;
+ }
+}
+
+static void size_callback(GLFWwindow window, int width, int height)
+{
+ glViewport(0, 0, width, height);
+}
+
+int main(int argc, char** argv)
+{
+ int ch;
+ GLFWwindow window;
+
+ while ((ch = getopt(argc, argv, "h")) != -1)
+ {
+ switch (ch)
+ {
+ case 'h':
+ usage();
+ exit(EXIT_SUCCESS);
+
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (!glfwInit())
+ {
+ fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
+ exit(EXIT_FAILURE);
+ }
+
+ window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Clipboard Test", NULL);
+ if (!window)
+ {
+ glfwTerminate();
+
+ fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
+ exit(EXIT_FAILURE);
+ }
+
+ glfwSwapInterval(1);
+ glfwSetKeyCallback(key_callback);
+ glfwSetWindowSizeCallback(size_callback);
+
+ glMatrixMode(GL_PROJECTION);
+ glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
+ glMatrixMode(GL_MODELVIEW);
+
+ glClearColor(0.5f, 0.5f, 0.5f, 0);
+
+ while (glfwIsWindow(window))
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8f, 0.2f, 0.4f);
+ glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
+
+ glfwSwapBuffers();
+ glfwPollEvents();
+ }
+
+ glfwTerminate();
+ exit(EXIT_SUCCESS);
+}
+
From a3430c2dec9991cc9ed2aef2019dd7ce95f4591e Mon Sep 17 00:00:00 2001
From: Tai Chi Minh Ralph Eastwood
Date: Sun, 19 Feb 2012 05:40:11 +0000
Subject: [PATCH 06/37] No idea why this file changed... or should it be
changed at all.
---
src/libglfw.pc.cmake | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libglfw.pc.cmake b/src/libglfw.pc.cmake
index 47cfb4f5..7538b885 100644
--- a/src/libglfw.pc.cmake
+++ b/src/libglfw.pc.cmake
@@ -9,4 +9,5 @@ Version: 3.0.0
URL: http://www.glfw.org/
Requires.private: gl x11 @GLFW_PKGLIBS@
Libs: -L${libdir} -lglfw
+Libs.private: @GLFW_LIBRARIES@
Cflags: -I${includedir}
From 8b7fc5d6013bf99af5c538dd73d24a38d835cd32 Mon Sep 17 00:00:00 2001
From: Tai Chi Minh Ralph Eastwood
Date: Sun, 19 Feb 2012 06:30:45 +0000
Subject: [PATCH 07/37] Trailing whitespace.
---
src/libglfw.pc.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libglfw.pc.cmake b/src/libglfw.pc.cmake
index 7538b885..1a712d9d 100644
--- a/src/libglfw.pc.cmake
+++ b/src/libglfw.pc.cmake
@@ -8,6 +8,6 @@ Description: A portable library for OpenGL, window and input
Version: 3.0.0
URL: http://www.glfw.org/
Requires.private: gl x11 @GLFW_PKGLIBS@
-Libs: -L${libdir} -lglfw
+Libs: -L${libdir} -lglfw
Libs.private: @GLFW_LIBRARIES@
Cflags: -I${includedir}
From 7f470065fc3b0a2c8c9fe72a146d7346d965ef98 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Wed, 28 Mar 2012 15:05:17 +0200
Subject: [PATCH 08/37] Applied coding conventions.
---
src/clipboard.c | 1 +
src/x11_clipboard.c | 54 +++++++++++++++++++++++++++------------------
2 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/src/clipboard.c b/src/clipboard.c
index b055c168..480bad8e 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -76,3 +76,4 @@ GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
return _glfwPlatformGetClipboardData(data, size, format);
}
+
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 1be0ac23..71f2f7c9 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -36,18 +36,15 @@
#include
#include
-//////////////////////////////////////////////////////////////////////////
-////// GLFW platform API //////
-//////////////////////////////////////////////////////////////////////////
//========================================================================
// Get the corresponding X11 format for a given GLFW format.
//========================================================================
-static Atom *getInternalFormat(int fmt)
+static Atom* getInternalFormat(int format)
{
// Get the necessary atoms
- switch (fmt)
+ switch (format)
{
case GLFW_CLIPBOARD_FORMAT_STRING:
return _glfwLibrary.X11.selection.atoms.string;
@@ -56,13 +53,18 @@ static Atom *getInternalFormat(int fmt)
}
}
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
//========================================================================
// X11 selection request event
//========================================================================
-Atom _glfwSelectionRequest(XSelectionRequestEvent *request)
+Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
{
- Atom *atoms = _glfwLibrary.X11.selection.atoms.string;
+ Atom* atoms = _glfwLibrary.X11.selection.atoms.string;
if (request->target == XA_STRING)
{
// TODO: ISO Latin-1 specific characters don't get converted
@@ -73,7 +75,7 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent *request)
request->target,
8,
PropModeReplace,
- (unsigned char *)_glfwLibrary.X11.selection.clipboard.string,
+ (unsigned char*) _glfwLibrary.X11.selection.clipboard.string,
8);
}
else if (request->target == atoms[_GLFW_STRING_ATOM_COMPOUND] ||
@@ -85,7 +87,7 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent *request)
request->target,
8,
PropModeReplace,
- (unsigned char *)_glfwLibrary.X11.selection.clipboard.string,
+ (unsigned char*) _glfwLibrary.X11.selection.clipboard.string,
_glfwLibrary.X11.selection.clipboard.stringlen);
}
else
@@ -93,9 +95,15 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent *request)
// TODO: Should we set an error? Probably not.
return None;
}
+
return request->target;
}
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
//========================================================================
// Set the clipboard contents
//========================================================================
@@ -132,14 +140,15 @@ void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
// Set the selection owner to our active window
XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
- _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ _glfwLibrary.activeWindow->X11.handle, CurrentTime);
XSetSelectionOwner(_glfwLibrary.X11.display,
- _glfwLibrary.X11.selection.atoms.clipboard
- [_GLFW_CLIPBOARD_ATOM_CLIPBOARD],
- _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ _glfwLibrary.X11.selection.atoms.clipboard
+ [_GLFW_CLIPBOARD_ATOM_CLIPBOARD],
+ _glfwLibrary.activeWindow->X11.handle, CurrentTime);
XFlush(_glfwLibrary.X11.display);
}
+
//========================================================================
// Return the current clipboard contents
//========================================================================
@@ -155,16 +164,16 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
// format with preference for more appropriate formats first
Atom *xcbrd = _glfwLibrary.X11.selection.atoms.clipboard;
Atom *xcbrdend = _glfwLibrary.X11.selection.atoms.clipboard +
- _GLFW_CLIPBOARD_ATOM_COUNT;
+ _GLFW_CLIPBOARD_ATOM_COUNT;
Atom *xfmt = getInternalFormat(format);
Atom *xfmtend = xfmt + _GLFW_STRING_ATOM_COUNT;
// Get the currently active window
Window window = _glfwLibrary.activeWindow->X11.handle;
- for (; xcbrd != xcbrdend; xcbrd++)
+ for ( ; xcbrd != xcbrdend; xcbrd++)
{
- for (; xfmt != xfmtend; xfmt++)
+ for ( ; xfmt != xfmtend; xfmt++)
{
// Specify the format we would like.
_glfwLibrary.X11.selection.request = *xfmt;
@@ -218,21 +227,23 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
if (rembytes > 0)
{
int result = XGetWindowProperty(_glfwLibrary.X11.display, window,
- *xfmt, 0, rembytes, 0,
- AnyPropertyType, &type, &fmt,
- &len, &dummy, &d);
+ *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;
}
@@ -243,6 +254,7 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
return 0;
}
}
+
return 0;
}
From a1d5fc039d39ee1a925874ce3abbed0a821133f1 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Wed, 28 Mar 2012 15:07:47 +0200
Subject: [PATCH 09/37] Added support for right control key.
---
tests/clipboard.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/tests/clipboard.c b/tests/clipboard.c
index cdbba6d2..16249f8a 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -39,15 +39,14 @@ static void usage(void)
printf("Usage: clipboard [-h]\n");
}
+static GLboolean control_is_down(void)
+{
+ return glfwGetKey(GLFW_KEY_LEFT_CONTROL) ||
+ glfwGetKey(GLFW_KEY_RIGHT_CONTROL);
+}
+
static void key_callback(GLFWwindow window, int key, int action)
{
- static int control = GL_FALSE;
- if (key == GLFW_KEY_LEFT_CONTROL)
- {
- control = (action == GLFW_PRESS);
- return;
- }
-
if (action != GLFW_PRESS)
return;
@@ -57,7 +56,7 @@ static void key_callback(GLFWwindow window, int key, int action)
glfwCloseWindow(window);
break;
case GLFW_KEY_V:
- if (control)
+ if (control_is_down())
{
char buffer[4096];
size_t size;
@@ -71,7 +70,7 @@ static void key_callback(GLFWwindow window, int key, int action)
}
break;
case GLFW_KEY_C:
- if (control)
+ if (control_is_down())
{
glfwSetClipboardData("Hello GLFW World!", sizeof("Hello GLFW World!"),
GLFW_CLIPBOARD_FORMAT_STRING);
From e4328af790de86d14811a10a1f266c30f08f9a33 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Wed, 28 Mar 2012 16:08:55 +0200
Subject: [PATCH 10/37] Formatting.
---
src/x11_platform.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/x11_platform.h b/src/x11_platform.h
index c6be6db3..2e6bbc21 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -236,15 +236,15 @@ typedef struct _GLFWlibraryX11
// Selection data
struct {
- struct {
- Atom clipboard[_GLFW_CLIPBOARD_ATOM_COUNT];
- Atom string[_GLFW_STRING_ATOM_COUNT];
- } atoms;
- struct {
- size_t stringlen;
- char *string;
- } clipboard;
- Atom request;
+ struct {
+ Atom clipboard[_GLFW_CLIPBOARD_ATOM_COUNT];
+ Atom string[_GLFW_STRING_ATOM_COUNT];
+ } atoms;
+ struct {
+ size_t stringlen;
+ char *string;
+ } clipboard;
+ Atom request;
int converted;
} selection;
From e49f1b88011838fafe705a8fd00d54f280f27f4a Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Thu, 29 Mar 2012 13:30:40 +0200
Subject: [PATCH 11/37] Fixed broken example.
---
tests/clipboard.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/clipboard.c b/tests/clipboard.c
index 16249f8a..5388ba4d 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -39,10 +39,10 @@ static void usage(void)
printf("Usage: clipboard [-h]\n");
}
-static GLboolean control_is_down(void)
+static GLboolean control_is_down(GLFWwindow window)
{
- return glfwGetKey(GLFW_KEY_LEFT_CONTROL) ||
- glfwGetKey(GLFW_KEY_RIGHT_CONTROL);
+ return glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) ||
+ glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL);
}
static void key_callback(GLFWwindow window, int key, int action)
@@ -56,7 +56,7 @@ static void key_callback(GLFWwindow window, int key, int action)
glfwCloseWindow(window);
break;
case GLFW_KEY_V:
- if (control_is_down())
+ if (control_is_down(window))
{
char buffer[4096];
size_t size;
@@ -66,11 +66,11 @@ static void key_callback(GLFWwindow window, int key, int action)
{
printf("Buffer wasn't big enough to hold clipboard data.\n");
}
- printf("[%ld]: %s\n", size, buffer);
+ printf("[%lu]: %s\n", (unsigned long) size, buffer);
}
break;
case GLFW_KEY_C:
- if (control_is_down())
+ if (control_is_down(window))
{
glfwSetClipboardData("Hello GLFW World!", sizeof("Hello GLFW World!"),
GLFW_CLIPBOARD_FORMAT_STRING);
From cca6b521208bcdc693dffc28922713064d647d6b Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Thu, 29 Mar 2012 13:31:19 +0200
Subject: [PATCH 12/37] Formatting.
---
tests/clipboard.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/clipboard.c b/tests/clipboard.c
index 5388ba4d..0065e0a6 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -60,12 +60,13 @@ static void key_callback(GLFWwindow window, int key, int action)
{
char buffer[4096];
size_t size;
+
printf("Paste test.\n");
+
size = glfwGetClipboardData(buffer, sizeof(buffer), GLFW_CLIPBOARD_FORMAT_STRING);
if (size >= sizeof(buffer))
- {
printf("Buffer wasn't big enough to hold clipboard data.\n");
- }
+
printf("[%lu]: %s\n", (unsigned long) size, buffer);
}
break;
From 2ad5764f0627b6a949ac7e69f21f177a5d58db0b Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Thu, 29 Mar 2012 13:44:55 +0200
Subject: [PATCH 13/37] Formatting.
---
tests/clipboard.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/clipboard.c b/tests/clipboard.c
index 0065e0a6..1960d6ec 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -55,6 +55,7 @@ static void key_callback(GLFWwindow window, int key, int action)
case GLFW_KEY_ESCAPE:
glfwCloseWindow(window);
break;
+
case GLFW_KEY_V:
if (control_is_down(window))
{
@@ -70,6 +71,7 @@ static void key_callback(GLFWwindow window, int key, int action)
printf("[%lu]: %s\n", (unsigned long) size, buffer);
}
break;
+
case GLFW_KEY_C:
if (control_is_down(window))
{
From d55616661d7a2b27807fe94c37dfcb546fa42f0d Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:00:52 +0200
Subject: [PATCH 14/37] Removed support for primary and secondary selections.
---
src/x11_clipboard.c | 41 ++++++++++++++++-------------------------
src/x11_init.c | 8 ++------
src/x11_platform.h | 8 +-------
3 files changed, 19 insertions(+), 38 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 71f2f7c9..a0640873 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -142,8 +142,7 @@ void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
_glfwLibrary.activeWindow->X11.handle, CurrentTime);
XSetSelectionOwner(_glfwLibrary.X11.display,
- _glfwLibrary.X11.selection.atoms.clipboard
- [_GLFW_CLIPBOARD_ATOM_CLIPBOARD],
+ _glfwLibrary.X11.selection.atom,
_glfwLibrary.activeWindow->X11.handle, CurrentTime);
XFlush(_glfwLibrary.X11.display);
}
@@ -162,44 +161,36 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
// Try different clipboards and formats that relate to the GLFW
// format with preference for more appropriate formats first
- Atom *xcbrd = _glfwLibrary.X11.selection.atoms.clipboard;
- Atom *xcbrdend = _glfwLibrary.X11.selection.atoms.clipboard +
- _GLFW_CLIPBOARD_ATOM_COUNT;
Atom *xfmt = getInternalFormat(format);
Atom *xfmtend = xfmt + _GLFW_STRING_ATOM_COUNT;
// Get the currently active window
Window window = _glfwLibrary.activeWindow->X11.handle;
- for ( ; xcbrd != xcbrdend; xcbrd++)
+ for ( ; xfmt != xfmtend; xfmt++)
{
- for ( ; xfmt != xfmtend; xfmt++)
- {
- // Specify the format we would like.
- _glfwLibrary.X11.selection.request = *xfmt;
+ // Specify the format we would like.
+ _glfwLibrary.X11.selection.request = *xfmt;
- // Convert the selection into a format we would like.
- XConvertSelection(_glfwLibrary.X11.display, *xcbrd,
- *xfmt, None, window, CurrentTime);
- XFlush(_glfwLibrary.X11.display);
+ // Convert the selection into a format we would like.
+ XConvertSelection(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.selection.atom,
+ *xfmt, None, window, CurrentTime);
+ XFlush(_glfwLibrary.X11.display);
- // Process pending events until we get a SelectionNotify.
- while (!_glfwLibrary.X11.selection.converted)
- _glfwPlatformWaitEvents();
-
- // Successful?
- if (_glfwLibrary.X11.selection.converted == 1)
- break;
- }
+ // Process pending events until we get a SelectionNotify.
+ while (!_glfwLibrary.X11.selection.converted)
+ _glfwPlatformWaitEvents();
// Successful?
if (_glfwLibrary.X11.selection.converted == 1)
- {
- _glfwLibrary.X11.selection.converted = 0;
break;
- }
}
+ // Successful?
+ if (_glfwLibrary.X11.selection.converted == 1)
+ _glfwLibrary.X11.selection.converted = 0;
+
// Unsuccessful conversion, bail with no clipboard data
if (_glfwLibrary.X11.selection.converted)
{
diff --git a/src/x11_init.c b/src/x11_init.c
index 8b832d52..f9adc7f5 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -456,13 +456,9 @@ static GLboolean initDisplay(void)
// the keyboard mapping.
updateKeyCodeLUT();
- // Find or create clipboard atoms
- _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_PRIMARY] =
- XA_PRIMARY;
- _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_CLIPBOARD] =
+ // Find or create clipboard atom
+ _glfwLibrary.X11.selection.atom =
XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);
- _glfwLibrary.X11.selection.atoms.clipboard[_GLFW_CLIPBOARD_ATOM_SECONDARY] =
- XA_SECONDARY;
// Find or create selection atoms
_glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_UTF8] =
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 2e6bbc21..163fcd19 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -85,12 +85,6 @@
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
-// Clipboard atoms
-#define _GLFW_CLIPBOARD_ATOM_PRIMARY 0
-#define _GLFW_CLIPBOARD_ATOM_CLIPBOARD 1
-#define _GLFW_CLIPBOARD_ATOM_SECONDARY 2
-#define _GLFW_CLIPBOARD_ATOM_COUNT 3
-
// String atoms
#define _GLFW_STRING_ATOM_UTF8 0
#define _GLFW_STRING_ATOM_COMPOUND 1
@@ -236,8 +230,8 @@ typedef struct _GLFWlibraryX11
// Selection data
struct {
+ Atom atom;
struct {
- Atom clipboard[_GLFW_CLIPBOARD_ATOM_COUNT];
Atom string[_GLFW_STRING_ATOM_COUNT];
} atoms;
struct {
From 508207ae04b06bee853adfba89033e8e95349662 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:04:14 +0200
Subject: [PATCH 15/37] Removed superfluous function.
---
src/x11_clipboard.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index a0640873..ab2a5c1d 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -37,23 +37,6 @@
#include
-//========================================================================
-// Get the corresponding X11 format for a given GLFW format.
-//========================================================================
-
-static Atom* getInternalFormat(int format)
-{
- // Get the necessary atoms
- switch (format)
- {
- case GLFW_CLIPBOARD_FORMAT_STRING:
- return _glfwLibrary.X11.selection.atoms.string;
- default:
- return 0;
- }
-}
-
-
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
@@ -161,7 +144,7 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
// Try different clipboards and formats that relate to the GLFW
// format with preference for more appropriate formats first
- Atom *xfmt = getInternalFormat(format);
+ Atom *xfmt = _glfwLibrary.X11.selection.atoms.string;
Atom *xfmtend = xfmt + _GLFW_STRING_ATOM_COUNT;
// Get the currently active window
From 168aba78d4f8f6cd7058627c9095b33ef056c393 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:12:59 +0200
Subject: [PATCH 16/37] Formatting.
---
src/x11_clipboard.c | 69 +++++++++++++++++++++++++++------------------
1 file changed, 41 insertions(+), 28 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index ab2a5c1d..c46b0dd1 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -47,31 +47,33 @@
Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
{
- Atom* atoms = _glfwLibrary.X11.selection.atoms.string;
+ Atom* formats = _glfwLibrary.X11.selection.atoms.string;
+ char* target = _glfwLibrary.X11.selection.clipboard.string;
+
if (request->target == XA_STRING)
{
// TODO: ISO Latin-1 specific characters don't get converted
// (yet). For cleanliness, would we need something like iconv?
XChangeProperty(_glfwLibrary.X11.display,
- request->requestor,
- request->target,
- request->target,
- 8,
- PropModeReplace,
- (unsigned char*) _glfwLibrary.X11.selection.clipboard.string,
- 8);
+ request->requestor,
+ request->target,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char*) target,
+ 8);
}
- else if (request->target == atoms[_GLFW_STRING_ATOM_COMPOUND] ||
- request->target == atoms[_GLFW_STRING_ATOM_UTF8])
+ else if (request->target == formats[_GLFW_STRING_ATOM_COMPOUND] ||
+ request->target == formats[_GLFW_STRING_ATOM_UTF8])
{
XChangeProperty(_glfwLibrary.X11.display,
- request->requestor,
- request->target,
- request->target,
- 8,
- PropModeReplace,
- (unsigned char*) _glfwLibrary.X11.selection.clipboard.string,
- _glfwLibrary.X11.selection.clipboard.stringlen);
+ request->requestor,
+ request->target,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char*) target,
+ _glfwLibrary.X11.selection.clipboard.stringlen);
}
else
{
@@ -91,14 +93,14 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
// Set the clipboard contents
//========================================================================
-void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+void _glfwPlatformSetClipboardData(void* data, size_t size, int format)
{
switch (format)
{
case GLFW_CLIPBOARD_FORMAT_STRING:
{
// Allocate memory to keep track of the clipboard
- char *cb = malloc(size+1);
+ char* cb = malloc(size + 1);
// Copy the clipboard data
memcpy(cb, data, size);
@@ -135,10 +137,10 @@ void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-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;
+ unsigned char* d;
int fmt;
Atom type;
@@ -158,7 +160,7 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
// Convert the selection into a format we would like.
XConvertSelection(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
- *xfmt, None, window, CurrentTime);
+ *xfmt, None, window, CurrentTime);
XFlush(_glfwLibrary.X11.display);
// Process pending events until we get a SelectionNotify.
@@ -200,20 +202,31 @@ size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
// 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);
+ 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;
+ size_t s;
+
+ if (rembytes < size - 1)
+ s = rembytes;
+ else
+ s = size - 1;
// Copy the data out.
memcpy(data, d, s);
// Null-terminate strings.
if (format == GLFW_CLIPBOARD_FORMAT_STRING)
- ((char *)data)[s] = '\0';
+ ((char*) data)[s] = '\0';
// Free the data allocated using X11.
XFree(d);
From 3252829fe007ac27aab89d6a3aad571a9f1af079 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:16:56 +0200
Subject: [PATCH 17/37] Replaced iterators with index.
---
src/x11_clipboard.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index c46b0dd1..c5d00deb 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -141,26 +141,23 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
{
size_t len, rembytes, dummy;
unsigned char* d;
- int fmt;
+ int i, fmt;
Atom type;
- // Try different clipboards and formats that relate to the GLFW
- // format with preference for more appropriate formats first
- Atom *xfmt = _glfwLibrary.X11.selection.atoms.string;
- Atom *xfmtend = xfmt + _GLFW_STRING_ATOM_COUNT;
-
// Get the currently active window
Window window = _glfwLibrary.activeWindow->X11.handle;
- for ( ; xfmt != xfmtend; xfmt++)
+ for (i = 0; i < _GLFW_STRING_ATOM_COUNT; i++)
{
// Specify the format we would like.
- _glfwLibrary.X11.selection.request = *xfmt;
+ _glfwLibrary.X11.selection.request =
+ _glfwLibrary.X11.selection.atoms.strings[i];
// Convert the selection into a format we would like.
XConvertSelection(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
- *xfmt, None, window, CurrentTime);
+ _glfwLibrary.X11.selection.request,
+ None, window, CurrentTime);
XFlush(_glfwLibrary.X11.display);
// Process pending events until we get a SelectionNotify.
@@ -190,7 +187,7 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
// Check the length of data to receive (rembytes)
XGetWindowProperty(_glfwLibrary.X11.display,
window,
- *xfmt,
+ _glfwLibrary.X11.selection.request,
0, 0,
0,
AnyPropertyType,
@@ -204,7 +201,7 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
{
int result = XGetWindowProperty(_glfwLibrary.X11.display,
window,
- *xfmt,
+ _glfwLibrary.X11.selection.request,
0, rembytes,
0,
AnyPropertyType,
From b8676f01db7fd42b3127b21593bec6c7198fe378 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:21:54 +0200
Subject: [PATCH 18/37] Clarified clipboard format atom use.
---
src/x11_clipboard.c | 10 +++++-----
src/x11_init.c | 7 ++++---
src/x11_platform.h | 14 ++++++--------
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index c5d00deb..56d71904 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -47,7 +47,7 @@
Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
{
- Atom* formats = _glfwLibrary.X11.selection.atoms.string;
+ Atom* formats = _glfwLibrary.X11.selection.formats;
char* target = _glfwLibrary.X11.selection.clipboard.string;
if (request->target == XA_STRING)
@@ -63,8 +63,8 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
(unsigned char*) target,
8);
}
- else if (request->target == formats[_GLFW_STRING_ATOM_COMPOUND] ||
- request->target == formats[_GLFW_STRING_ATOM_UTF8])
+ else if (request->target == formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] ||
+ request->target == formats[_GLFW_CLIPBOARD_FORMAT_UTF8])
{
XChangeProperty(_glfwLibrary.X11.display,
request->requestor,
@@ -147,11 +147,11 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
// Get the currently active window
Window window = _glfwLibrary.activeWindow->X11.handle;
- for (i = 0; i < _GLFW_STRING_ATOM_COUNT; i++)
+ for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
{
// Specify the format we would like.
_glfwLibrary.X11.selection.request =
- _glfwLibrary.X11.selection.atoms.strings[i];
+ _glfwLibrary.X11.selection.formats[i];
// Convert the selection into a format we would like.
XConvertSelection(_glfwLibrary.X11.display,
diff --git a/src/x11_init.c b/src/x11_init.c
index f9adc7f5..dbadc916 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -461,11 +461,12 @@ static GLboolean initDisplay(void)
XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);
// Find or create selection atoms
- _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_UTF8] =
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] =
XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
- _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_COMPOUND] =
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] =
XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
- _glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_STRING] = XA_STRING;
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
+ XA_STRING;
return GL_TRUE;
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 163fcd19..0bb4c6c4 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -85,11 +85,11 @@
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
-// String atoms
-#define _GLFW_STRING_ATOM_UTF8 0
-#define _GLFW_STRING_ATOM_COMPOUND 1
-#define _GLFW_STRING_ATOM_STRING 2
-#define _GLFW_STRING_ATOM_COUNT 3
+// Clipboard format atom indices
+#define _GLFW_CLIPBOARD_FORMAT_UTF8 0
+#define _GLFW_CLIPBOARD_FORMAT_COMPOUND 1
+#define _GLFW_CLIPBOARD_FORMAT_STRING 2
+#define _GLFW_CLIPBOARD_FORMAT_COUNT 3
//========================================================================
// GLFW platform specific types
@@ -231,9 +231,7 @@ typedef struct _GLFWlibraryX11
// Selection data
struct {
Atom atom;
- struct {
- Atom string[_GLFW_STRING_ATOM_COUNT];
- } atoms;
+ Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT];
struct {
size_t stringlen;
char *string;
From fcd67c69ec956987e6f8e6f88368872a3e037fcc Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:27:32 +0200
Subject: [PATCH 19/37] Simplified clipboard cache layout.
---
src/x11_clipboard.c | 12 ++++++------
src/x11_init.c | 4 ++--
src/x11_platform.h | 6 ++----
3 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 56d71904..e260e7cb 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -48,7 +48,7 @@
Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
{
Atom* formats = _glfwLibrary.X11.selection.formats;
- char* target = _glfwLibrary.X11.selection.clipboard.string;
+ char* target = _glfwLibrary.X11.selection.string;
if (request->target == XA_STRING)
{
@@ -73,7 +73,7 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
8,
PropModeReplace,
(unsigned char*) target,
- _glfwLibrary.X11.selection.clipboard.stringlen);
+ _glfwLibrary.X11.selection.stringLength);
}
else
{
@@ -106,14 +106,14 @@ void _glfwPlatformSetClipboardData(void* data, size_t size, int format)
memcpy(cb, data, size);
// Set the string length
- _glfwLibrary.X11.selection.clipboard.stringlen = size;
+ _glfwLibrary.X11.selection.stringLength = size;
// Check if existing clipboard memory needs to be freed
- if (_glfwLibrary.X11.selection.clipboard.string)
- free(_glfwLibrary.X11.selection.clipboard.string);
+ if (_glfwLibrary.X11.selection.string)
+ free(_glfwLibrary.X11.selection.string);
// Now set the clipboard (awaiting the event SelectionRequest)
- _glfwLibrary.X11.selection.clipboard.string = cb;
+ _glfwLibrary.X11.selection.string = cb;
break;
}
diff --git a/src/x11_init.c b/src/x11_init.c
index dbadc916..a702ad19 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -632,8 +632,8 @@ int _glfwPlatformTerminate(void)
#endif
// Free clipboard memory
- if (_glfwLibrary.X11.selection.clipboard.string)
- free(_glfwLibrary.X11.selection.clipboard.string);
+ if (_glfwLibrary.X11.selection.string)
+ free(_glfwLibrary.X11.selection.string);
return GL_TRUE;
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 0bb4c6c4..19447d47 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -232,10 +232,8 @@ typedef struct _GLFWlibraryX11
struct {
Atom atom;
Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT];
- struct {
- size_t stringlen;
- char *string;
- } clipboard;
+ size_t stringLength;
+ char* string;
Atom request;
int converted;
} selection;
From 2bc8d442f4807bd985b7d6038487a8991b350391 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:36:39 +0200
Subject: [PATCH 20/37] Formatting.
---
include/GL/glfw3.h | 4 ++--
src/clipboard.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index f87be382..a7449099 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -581,8 +581,8 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
/* Clipboard */
-GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format);
-GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format);
+GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format);
+GLFWAPI size_t glfwGetClipboardData(void* data, size_t size, int format);
/* Time */
GLFWAPI double glfwGetTime(void);
diff --git a/src/clipboard.c b/src/clipboard.c
index 480bad8e..0f1889c3 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -41,7 +41,7 @@
// Set the clipboard contents
//========================================================================
-GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format)
+GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format)
{
if (!_glfwInitialized)
{
@@ -60,7 +60,7 @@ GLFWAPI void glfwSetClipboardData(void *data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-GLFWAPI size_t glfwGetClipboardData(void *data, size_t size, int format)
+GLFWAPI size_t glfwGetClipboardData(void* data, size_t size, int format)
{
if (!_glfwInitialized)
{
From 490c472328ad625e3476f3bb127defdf8cadeb7d Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:38:26 +0200
Subject: [PATCH 21/37] Removed unused error.
---
include/GL/glfw3.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index a7449099..e2f25901 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -462,7 +462,6 @@ extern "C" {
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
-#define GLFW_CLIPBOARD_CANNOT_OWN 0x00070011
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
From 7044ed6f06a042eba8e694ba9f14812a35040fce Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 15:54:36 +0200
Subject: [PATCH 22/37] Simplified and made clipboard API more type safe.
---
include/GL/glfw3.h | 10 +++-------
src/clipboard.c | 16 +++++-----------
src/internal.h | 4 ++--
src/x11_clipboard.c | 45 +++++++++++++++++----------------------------
tests/clipboard.c | 8 ++++----
5 files changed, 31 insertions(+), 52 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index e2f25901..d7be4fd2 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -461,15 +461,11 @@ extern "C" {
#define GLFW_VERSION_UNAVAILABLE 0x00070007
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
-#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
+#define GLFW_FORMAT_UNAVAILABLE 0x0007000A
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
-/* Clipboard formats */
-#define GLFW_CLIPBOARD_FORMAT_NONE 0
-#define GLFW_CLIPBOARD_FORMAT_STRING 1
-
/*************************************************************************
* Typedefs
*************************************************************************/
@@ -580,8 +576,8 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
/* Clipboard */
-GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format);
-GLFWAPI size_t glfwGetClipboardData(void* data, size_t size, int format);
+GLFWAPI void glfwSetClipboardString(const char* data);
+GLFWAPI size_t glfwGetClipboardString(char* data, size_t size);
/* Time */
GLFWAPI double glfwGetTime(void);
diff --git a/src/clipboard.c b/src/clipboard.c
index 0f1889c3..a816ebb0 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -41,7 +41,7 @@
// Set the clipboard contents
//========================================================================
-GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format)
+GLFWAPI void glfwSetClipboardString(const char* string)
{
if (!_glfwInitialized)
{
@@ -49,10 +49,7 @@ GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format)
return;
}
- if (format == GLFW_CLIPBOARD_FORMAT_NONE)
- return;
-
- _glfwPlatformSetClipboardData(data, size, format);
+ _glfwPlatformSetClipboardString(string);
}
@@ -60,7 +57,7 @@ GLFWAPI void glfwSetClipboardData(void* data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-GLFWAPI size_t glfwGetClipboardData(void* data, size_t size, int format)
+GLFWAPI size_t glfwGetClipboardString(char* string, size_t size)
{
if (!_glfwInitialized)
{
@@ -68,12 +65,9 @@ GLFWAPI size_t glfwGetClipboardData(void* data, size_t size, int format)
return 0;
}
- if (format == GLFW_CLIPBOARD_FORMAT_NONE)
+ if (!string || !size)
return 0;
- if (!data || !size)
- return 0;
-
- return _glfwPlatformGetClipboardData(data, size, format);
+ return _glfwPlatformGetClipboardString(string, size);
}
diff --git a/src/internal.h b/src/internal.h
index c16fc03f..2e0b9c38 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -289,8 +289,8 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
// Clipboard
-void _glfwPlatformSetClipboardData(void *data, size_t size, int format);
-size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format);
+void _glfwPlatformSetClipboardString(const char* string);
+size_t _glfwPlatformGetClipboardString(char *data, size_t size);
// Joystick
int _glfwPlatformGetJoystickParam(int joy, int param);
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index e260e7cb..b733b486 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -93,35 +93,25 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
// Set the clipboard contents
//========================================================================
-void _glfwPlatformSetClipboardData(void* data, size_t size, int format)
+void _glfwPlatformSetClipboardString(const char* string)
{
- switch (format)
- {
- case GLFW_CLIPBOARD_FORMAT_STRING:
- {
- // Allocate memory to keep track of the clipboard
- char* cb = malloc(size + 1);
+ size_t size = strlen(string) + 1;
- // Copy the clipboard data
- memcpy(cb, data, size);
+ // Allocate memory to keep track of the clipboard
+ char* cb = malloc(size);
- // Set the string length
- _glfwLibrary.X11.selection.stringLength = size;
+ // Copy the clipboard data
+ memcpy(cb, string, size);
- // Check if existing clipboard memory needs to be freed
- if (_glfwLibrary.X11.selection.string)
- free(_glfwLibrary.X11.selection.string);
+ // Set the string length
+ _glfwLibrary.X11.selection.stringLength = size;
- // Now set the clipboard (awaiting the event SelectionRequest)
- _glfwLibrary.X11.selection.string = cb;
- break;
- }
+ // Check if existing clipboard memory needs to be freed
+ if (_glfwLibrary.X11.selection.string)
+ free(_glfwLibrary.X11.selection.string);
- default:
- _glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
- "X11/GLX: Unavailable clipboard format");
- return;
- }
+ // Now set the clipboard (awaiting the event SelectionRequest)
+ _glfwLibrary.X11.selection.string = cb;
// Set the selection owner to our active window
XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
@@ -137,7 +127,7 @@ void _glfwPlatformSetClipboardData(void* data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
+size_t _glfwPlatformGetClipboardString(char* data, size_t size)
{
size_t len, rembytes, dummy;
unsigned char* d;
@@ -176,8 +166,8 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
// Unsuccessful conversion, bail with no clipboard data
if (_glfwLibrary.X11.selection.converted)
{
- _glfwSetError(GLFW_CLIPBOARD_FORMAT_UNAVAILABLE,
- "X11/GLX: Unavailable clipboard format");
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE,
+ "X11/GLX: Failed to convert selection to string");
return 0;
}
@@ -222,8 +212,7 @@ size_t _glfwPlatformGetClipboardData(void* data, size_t size, int format)
memcpy(data, d, s);
// Null-terminate strings.
- if (format == GLFW_CLIPBOARD_FORMAT_STRING)
- ((char*) data)[s] = '\0';
+ ((char*) data)[s] = '\0';
// Free the data allocated using X11.
XFree(d);
diff --git a/tests/clipboard.c b/tests/clipboard.c
index 1960d6ec..ac83448b 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -64,7 +64,7 @@ static void key_callback(GLFWwindow window, int key, int action)
printf("Paste test.\n");
- size = glfwGetClipboardData(buffer, sizeof(buffer), GLFW_CLIPBOARD_FORMAT_STRING);
+ size = glfwGetClipboardString(buffer, sizeof(buffer));
if (size >= sizeof(buffer))
printf("Buffer wasn't big enough to hold clipboard data.\n");
@@ -75,9 +75,9 @@ static void key_callback(GLFWwindow window, int key, int action)
case GLFW_KEY_C:
if (control_is_down(window))
{
- glfwSetClipboardData("Hello GLFW World!", sizeof("Hello GLFW World!"),
- GLFW_CLIPBOARD_FORMAT_STRING);
- printf("Setting clipboard to: %s\n", "Hello GLFW World!");
+ const char* string = "Hello GLFW World!";
+ glfwSetClipboardString(string);
+ printf("Setting clipboard to: %s\n", string);
}
break;
}
From bf1ada029b9032249dcc4d5af605fbefbfeb68d3 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 16:00:54 +0200
Subject: [PATCH 23/37] Added window parameter to clipboard API.
---
include/GL/glfw3.h | 4 ++--
src/clipboard.c | 12 ++++++++----
src/internal.h | 4 ++--
src/x11_clipboard.c | 17 +++++++----------
tests/clipboard.c | 4 ++--
5 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index d7be4fd2..6b1cc470 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -576,8 +576,8 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
/* Clipboard */
-GLFWAPI void glfwSetClipboardString(const char* data);
-GLFWAPI size_t glfwGetClipboardString(char* data, size_t size);
+GLFWAPI void glfwSetClipboardString(GLFWwindow window, const char* data);
+GLFWAPI size_t glfwGetClipboardString(GLFWwindow window, char* data, size_t size);
/* Time */
GLFWAPI double glfwGetTime(void);
diff --git a/src/clipboard.c b/src/clipboard.c
index a816ebb0..b66d5656 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -41,15 +41,17 @@
// Set the clipboard contents
//========================================================================
-GLFWAPI void glfwSetClipboardString(const char* string)
+GLFWAPI void glfwSetClipboardString(GLFWwindow handle, const char* string)
{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
- _glfwPlatformSetClipboardString(string);
+ _glfwPlatformSetClipboardString(window, string);
}
@@ -57,8 +59,10 @@ GLFWAPI void glfwSetClipboardString(const char* string)
// Return the current clipboard contents
//========================================================================
-GLFWAPI size_t glfwGetClipboardString(char* string, size_t size)
+GLFWAPI size_t glfwGetClipboardString(GLFWwindow handle, char* string, size_t size)
{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
@@ -68,6 +72,6 @@ GLFWAPI size_t glfwGetClipboardString(char* string, size_t size)
if (!string || !size)
return 0;
- return _glfwPlatformGetClipboardString(string, size);
+ return _glfwPlatformGetClipboardString(window, string, size);
}
diff --git a/src/internal.h b/src/internal.h
index 2e0b9c38..407270ea 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -289,8 +289,8 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
// Clipboard
-void _glfwPlatformSetClipboardString(const char* string);
-size_t _glfwPlatformGetClipboardString(char *data, size_t size);
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
+size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char *data, size_t size);
// Joystick
int _glfwPlatformGetJoystickParam(int joy, int param);
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index b733b486..4bbfb83c 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -93,7 +93,7 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
// Set the clipboard contents
//========================================================================
-void _glfwPlatformSetClipboardString(const char* string)
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
size_t size = strlen(string) + 1;
@@ -115,10 +115,10 @@ void _glfwPlatformSetClipboardString(const char* string)
// Set the selection owner to our active window
XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
- _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ window->X11.handle, CurrentTime);
XSetSelectionOwner(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
- _glfwLibrary.activeWindow->X11.handle, CurrentTime);
+ window->X11.handle, CurrentTime);
XFlush(_glfwLibrary.X11.display);
}
@@ -127,16 +127,13 @@ void _glfwPlatformSetClipboardString(const char* string)
// Return the current clipboard contents
//========================================================================
-size_t _glfwPlatformGetClipboardString(char* data, size_t size)
+size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* data, size_t size)
{
size_t len, rembytes, dummy;
unsigned char* d;
int i, fmt;
Atom type;
- // Get the currently active window
- Window window = _glfwLibrary.activeWindow->X11.handle;
-
for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
{
// Specify the format we would like.
@@ -147,7 +144,7 @@ size_t _glfwPlatformGetClipboardString(char* data, size_t size)
XConvertSelection(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
_glfwLibrary.X11.selection.request,
- None, window, CurrentTime);
+ None, window->X11.handle, CurrentTime);
XFlush(_glfwLibrary.X11.display);
// Process pending events until we get a SelectionNotify.
@@ -176,7 +173,7 @@ size_t _glfwPlatformGetClipboardString(char* data, size_t size)
// Check the length of data to receive (rembytes)
XGetWindowProperty(_glfwLibrary.X11.display,
- window,
+ window->X11.handle,
_glfwLibrary.X11.selection.request,
0, 0,
0,
@@ -190,7 +187,7 @@ size_t _glfwPlatformGetClipboardString(char* data, size_t size)
if (rembytes > 0)
{
int result = XGetWindowProperty(_glfwLibrary.X11.display,
- window,
+ window->X11.handle,
_glfwLibrary.X11.selection.request,
0, rembytes,
0,
diff --git a/tests/clipboard.c b/tests/clipboard.c
index ac83448b..376ebbcd 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -64,7 +64,7 @@ static void key_callback(GLFWwindow window, int key, int action)
printf("Paste test.\n");
- size = glfwGetClipboardString(buffer, sizeof(buffer));
+ size = glfwGetClipboardString(window, buffer, sizeof(buffer));
if (size >= sizeof(buffer))
printf("Buffer wasn't big enough to hold clipboard data.\n");
@@ -76,7 +76,7 @@ static void key_callback(GLFWwindow window, int key, int action)
if (control_is_down(window))
{
const char* string = "Hello GLFW World!";
- glfwSetClipboardString(string);
+ glfwSetClipboardString(window, string);
printf("Setting clipboard to: %s\n", string);
}
break;
From 1214fa1157e59b870d9f03845624f489dc00139d Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 16:03:14 +0200
Subject: [PATCH 24/37] Formatting.
---
include/GL/glfw3.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 6b1cc470..955086af 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -576,8 +576,8 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
/* Clipboard */
-GLFWAPI void glfwSetClipboardString(GLFWwindow window, const char* data);
-GLFWAPI size_t glfwGetClipboardString(GLFWwindow window, char* data, size_t size);
+GLFWAPI void glfwSetClipboardString(GLFWwindow window, const char* string);
+GLFWAPI size_t glfwGetClipboardString(GLFWwindow window, char* string, size_t size);
/* Time */
GLFWAPI double glfwGetTime(void);
From 877c6337c3d2034b510ccbd7de64368976d99bff Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 16:10:14 +0200
Subject: [PATCH 25/37] Updated remaining ports.
---
src/cocoa_clipboard.m | 4 ++--
src/win32_clipboard.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
index 0f78cf21..4ed01758 100644
--- a/src/cocoa_clipboard.m
+++ b/src/cocoa_clipboard.m
@@ -41,7 +41,7 @@
// Set the clipboard contents
//========================================================================
-void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
}
@@ -49,7 +49,7 @@ void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
+size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
return 0;
}
diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c
index b16c51c4..9a05b08e 100644
--- a/src/win32_clipboard.c
+++ b/src/win32_clipboard.c
@@ -41,7 +41,7 @@
// Set the clipboard contents
//========================================================================
-void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
}
@@ -49,7 +49,7 @@ void _glfwPlatformSetClipboardData(void *data, size_t size, int format)
// Return the current clipboard contents
//========================================================================
-size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
+size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
return 0;
}
From 67a3f5dc8f62b65648aa4dab16baab548727daa5 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 17:41:17 +0200
Subject: [PATCH 26/37] Added error callback.
---
tests/clipboard.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/clipboard.c b/tests/clipboard.c
index 376ebbcd..da776e61 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -88,6 +88,11 @@ static void size_callback(GLFWwindow window, int width, int height)
glViewport(0, 0, width, height);
}
+static void error_callback(int error, const char* description)
+{
+ fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description);
+}
+
int main(int argc, char** argv)
{
int ch;
@@ -107,6 +112,8 @@ int main(int argc, char** argv)
}
}
+ glfwSetErrorCallback(error_callback);
+
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
From ad18589c6c6ffe1898c6aab5471906912c067909 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 17:45:26 +0200
Subject: [PATCH 27/37] Added initial implementation for Win32.
---
src/win32_clipboard.c | 94 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c
index 9a05b08e..c2888236 100644
--- a/src/win32_clipboard.c
+++ b/src/win32_clipboard.c
@@ -31,6 +31,7 @@
#include
#include
+#include
//////////////////////////////////////////////////////////////////////////
@@ -43,6 +44,49 @@
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
+ WCHAR* wideString;
+ HANDLE stringHandle;
+ size_t wideSize;
+
+ wideString = _glfwCreateWideStringFromUTF8(string);
+ if (!wideString)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to convert clipboard string to "
+ "wide string");
+ return;
+ }
+
+ wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR);
+
+ stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);
+ if (!stringHandle)
+ {
+ free(wideString);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to allocate global handle for clipboard");
+ return;
+ }
+
+ memcpy(GlobalLock(stringHandle), wideString, wideSize);
+ GlobalUnlock(stringHandle);
+
+ if (!OpenClipboard(window->Win32.handle))
+ {
+ GlobalFree(stringHandle);
+ free(wideString);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to open clipboard");
+ return;
+ }
+
+ EmptyClipboard();
+ SetClipboardData(CF_UNICODETEXT, stringHandle);
+ CloseClipboard();
+
+ free(wideString);
}
//========================================================================
@@ -51,6 +95,54 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
- return 0;
+ HANDLE stringHandle;
+ char* utf8String;
+ size_t utf8Size;
+
+ if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
+ {
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE, NULL);
+ return 0;
+ }
+
+ if (!OpenClipboard(window->Win32.handle))
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to open clipboard");
+ return 0;
+ }
+
+ stringHandle = GetClipboardData(CF_UNICODETEXT);
+ if (!stringHandle)
+ {
+ CloseClipboard();
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to retrieve clipboard data");
+ return 0;
+ }
+
+ utf8String = _glfwCreateUTF8FromWideString(GlobalLock(stringHandle));
+ GlobalUnlock(stringHandle);
+ CloseClipboard();
+
+ if (!utf8String)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to convert wide string to UTF-8");
+ return 0;
+ }
+
+ utf8Size = strlen(utf8String) + 1;
+ if (utf8Size > size)
+ {
+ memcpy(string, utf8String, size);
+ string[size - 1] = '\0';
+ }
+ else
+ memcpy(string, utf8String, utf8Size);
+
+ free(utf8String);
+ return utf8Size;
}
From ab40dab23590093f7be8a24966e9580d988f203c Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 18:00:07 +0200
Subject: [PATCH 28/37] Formatting.
---
src/cocoa_clipboard.m | 1 +
src/win32_clipboard.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
index 4ed01758..8ac64bcc 100644
--- a/src/cocoa_clipboard.m
+++ b/src/cocoa_clipboard.m
@@ -45,6 +45,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
}
+
//========================================================================
// Return the current clipboard contents
//========================================================================
diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c
index c2888236..9b14f158 100644
--- a/src/win32_clipboard.c
+++ b/src/win32_clipboard.c
@@ -89,6 +89,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
free(wideString);
}
+
//========================================================================
// Return the current clipboard contents
//========================================================================
From 8fe46ac1fecaddc1554a33e3d1bff95aa23b2ef3 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 23:27:06 +0200
Subject: [PATCH 29/37] Formatting.
---
src/cocoa_clipboard.m | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
index 8ac64bcc..e43e9906 100644
--- a/src/cocoa_clipboard.m
+++ b/src/cocoa_clipboard.m
@@ -52,6 +52,6 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
- return 0;
+ return 0;
}
From 3bd54e0b60dcfeb10826f155d0cea1b19912d14c Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 23:55:44 +0200
Subject: [PATCH 30/37] Added inclusion of declaration of size_t.
---
include/GL/glfw3.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 955086af..32c3899a 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -173,6 +173,10 @@ extern "C" {
#endif
#endif
+/* This is needed for the declaration of size_t.
+ */
+#include
+
/*************************************************************************
* GLFW version
From 83901218698a708ef6284d967a757bf9c5f6c068 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 9 Apr 2012 23:56:14 +0200
Subject: [PATCH 31/37] Fixed legacy C warnings.
---
src/cocoa_joystick.m | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m
index b3bd6e41..97510fdf 100644
--- a/src/cocoa_joystick.m
+++ b/src/cocoa_joystick.m
@@ -572,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
int numbuttons)
{
- int button;
+ int i, j, button;
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
return 0;
@@ -599,13 +599,13 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; // Bit fields of button presses for each direction, including nil
- for (int i = 0; i < joystick.numHats; i++)
+ for (i = 0; i < joystick.numHats; i++)
{
_glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.hats, i);
int value = hat->value;
if (value < 0 || value > 8) value = 8;
- for (int j = 0; j < 4 && button < numbuttons; j++)
+ for (j = 0; j < 4 && button < numbuttons; j++)
{
buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
}
From 15e8af1f79337ed3802aefd72ef57f8b0e92244e Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 10 Apr 2012 00:34:08 +0200
Subject: [PATCH 32/37] Added initial implementation for Cocoa.
---
src/cocoa_clipboard.m | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
index e43e9906..e52b839e 100644
--- a/src/cocoa_clipboard.m
+++ b/src/cocoa_clipboard.m
@@ -43,6 +43,12 @@
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
+ NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
+
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+ [pasteboard declareTypes:types owner:nil];
+ [pasteboard setString:[NSString stringWithUTF8String:string]
+ forType:NSStringPboardType];
}
@@ -52,6 +58,30 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
+ const char* source;
+ size_t targetSize;
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+
+ if (![[pasteboard types] containsObject:NSStringPboardType])
+ {
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE, NULL);
+ return 0;
+ }
+
+ NSString* object = [pasteboard stringForType:NSStringPboardType];
+ if (!object)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Cocoa/NSGL: Failed to retrieve object from pasteboard");
+ return 0;
+ }
+
+ source = [object UTF8String];
+ targetSize = strlen(source) + 1;
+ if (targetSize > size)
+ targetSize = size;
+
+ strlcpy(string, source, targetSize);
return 0;
}
From 0ee55ab8e5c947f92284ed26e012baa0b33cf583 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 10 Apr 2012 00:37:53 +0200
Subject: [PATCH 33/37] Updated change log, added credit.
---
readme.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/readme.html b/readme.html
index 3e0966c0..e890f955 100644
--- a/readme.html
+++ b/readme.html
@@ -271,6 +271,7 @@ version of GLFW.
Added glfwGetWindowPos
function for querying the position of the specified window
Added glfwSetWindowFocusCallback
function and GLFWwindowfocusfun
type for receiving window focus events
Added glfwSetWindowIconifyCallback
function and GLFWwindowiconifyfun
type for receiving window iconification events
+ Added glfwGetClipboardString
and glfwSetClipboardString
functions for interacting with the system clipboard
Added glfwGetCurrentContext
function for retrieving the window whose OpenGL context is current
Added glfwCopyContext
function for copying OpenGL state categories between contexts
Added GLFW_OPENGL_ES2_PROFILE
profile for creating OpenGL ES 2.0 contexts using the GLX_EXT_create_context_es2_profile
and WGL_EXT_create_context_es2_profile
extensions
@@ -844,7 +845,7 @@ their skills. Special thanks go out to:
adding logic for the GLFW_ICON
resource
Ralph Eastwood, for the initial design and implementation of the gamma
- correction API
+ correction and clipboard APIs
GeO4d, for the implementation of cursor enter/leave notifications on
Win32.
From 0e9e37bfc451e35ba39b6de231aed84a44dd6823 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 10 Apr 2012 00:52:21 +0200
Subject: [PATCH 34/37] Simplified string storage.
---
src/x11_clipboard.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 4bbfb83c..37d002b5 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -97,21 +97,11 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
size_t size = strlen(string) + 1;
- // Allocate memory to keep track of the clipboard
- char* cb = malloc(size);
-
- // Copy the clipboard data
- memcpy(cb, string, size);
-
- // Set the string length
+ // Store the new string in preparation for a request event
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = malloc(size);
_glfwLibrary.X11.selection.stringLength = size;
-
- // Check if existing clipboard memory needs to be freed
- if (_glfwLibrary.X11.selection.string)
- free(_glfwLibrary.X11.selection.string);
-
- // Now set the clipboard (awaiting the event SelectionRequest)
- _glfwLibrary.X11.selection.string = cb;
+ memcpy(_glfwLibrary.X11.selection.string, string, size);
// Set the selection owner to our active window
XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
From e0c4d81e46e9a604b7d3064dd8c7dfb2c1c34ddd Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 10 Apr 2012 01:15:50 +0200
Subject: [PATCH 35/37] Added function for processing only pending events.
---
src/x11_clipboard.c | 7 +++----
src/x11_platform.h | 3 +++
src/x11_window.c | 19 ++++++++++++++++++-
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index 37d002b5..cd0b5976 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -135,11 +135,10 @@ size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* data, size_t s
_glfwLibrary.X11.selection.atom,
_glfwLibrary.X11.selection.request,
None, window->X11.handle, CurrentTime);
- XFlush(_glfwLibrary.X11.display);
- // Process pending events until we get a SelectionNotify.
- while (!_glfwLibrary.X11.selection.converted)
- _glfwPlatformWaitEvents();
+ // Process the resulting SelectionNotify event
+ XSync(_glfwLibrary.X11.display, False);
+ _glfwProcessPendingEvents();
// Successful?
if (_glfwLibrary.X11.selection.converted == 1)
diff --git a/src/x11_platform.h b/src/x11_platform.h
index f3c4dd35..8de54ead 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -283,4 +283,7 @@ long _glfwKeySym2Unicode(KeySym keysym);
// Clipboard handling
Atom _glfwSelectionRequest(XSelectionRequestEvent *request);
+// Event processing
+void _glfwProcessPendingEvents(void);
+
#endif // _platform_h_
diff --git a/src/x11_window.c b/src/x11_window.c
index 57871d65..854480c5 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -1299,6 +1299,23 @@ static void processSingleEvent(void)
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Processes all pending events
+//========================================================================
+
+void _glfwProcessPendingEvents(void)
+{
+ int i, count = XPending(_glfwLibrary.X11.display);
+
+ for (i = 0; i < count; i++)
+ processSingleEvent();
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -1369,7 +1386,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
}
// Process the window map event and any other that may have arrived
- _glfwPlatformPollEvents();
+ _glfwProcessPendingEvents();
// Retrieve and set initial cursor position
{
From ad48c0e5ef7d61fc76754d62bad32d3ba0970368 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 10 Apr 2012 18:22:15 +0200
Subject: [PATCH 36/37] Added string for new error.
---
src/error.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/error.c b/src/error.c
index 2b46a72c..062fb76a 100644
--- a/src/error.c
+++ b/src/error.c
@@ -109,6 +109,8 @@ GLFWAPI const char* glfwErrorString(int error)
return "A platform-specific error occurred";
case GLFW_WINDOW_NOT_ACTIVE:
return "The specified window is not active";
+ case GLFW_FORMAT_UNAVAILABLE:
+ return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
From f231ed37f007e482e8f5f5d77e1ff161fe338ad6 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Wed, 11 Apr 2012 23:32:50 +0200
Subject: [PATCH 37/37] Re-worked and fixed X11 clipboard support.
---
src/x11_clipboard.c | 214 ++++++++++++++++++++------------------------
src/x11_init.c | 10 ++-
src/x11_platform.h | 16 +++-
src/x11_window.c | 39 +++++---
4 files changed, 144 insertions(+), 135 deletions(-)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
index cd0b5976..1b9e1fa3 100644
--- a/src/x11_clipboard.c
+++ b/src/x11_clipboard.c
@@ -27,8 +27,6 @@
//
//========================================================================
-// TODO: Incremental support? Overkill perhaps.
-
#include "internal.h"
#include
@@ -42,46 +40,90 @@
//////////////////////////////////////////////////////////////////////////
//========================================================================
-// X11 selection request event
+// Save the contents of the specified property
//========================================================================
-Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
+GLboolean _glfwReadSelection(XSelectionEvent* request)
{
- Atom* formats = _glfwLibrary.X11.selection.formats;
- char* target = _glfwLibrary.X11.selection.string;
+ Atom actualType;
+ int actualFormat;
+ unsigned long itemCount, bytesAfter;
+ char* data;
- if (request->target == XA_STRING)
+ if (request->property == None)
+ return GL_FALSE;
+
+ XGetWindowProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ request->property,
+ 0, LONG_MAX,
+ False,
+ request->target,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ (unsigned char**) &data);
+
+ if (actualType == None)
+ return GL_FALSE;
+
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = strdup(data);
+
+ XFree(data);
+ return GL_TRUE;
+}
+
+
+//========================================================================
+// Set the specified property to the contents of the requested selection
+//========================================================================
+
+Atom _glfwWriteSelection(XSelectionRequestEvent* request)
+{
+ int i;
+ Atom property = request->property;
+
+ if (property == None)
+ property = _glfwLibrary.X11.selection.property;
+
+ if (request->target == _glfwLibrary.X11.selection.targets)
{
- // TODO: ISO Latin-1 specific characters don't get converted
- // (yet). For cleanliness, would we need something like iconv?
+ // The list of supported targets was requested
+
XChangeProperty(_glfwLibrary.X11.display,
request->requestor,
- request->target,
- request->target,
- 8,
+ property,
+ XA_ATOM,
+ 32,
PropModeReplace,
- (unsigned char*) target,
- 8);
- }
- else if (request->target == formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] ||
- request->target == formats[_GLFW_CLIPBOARD_FORMAT_UTF8])
- {
- XChangeProperty(_glfwLibrary.X11.display,
- request->requestor,
- request->target,
- request->target,
- 8,
- PropModeReplace,
- (unsigned char*) target,
- _glfwLibrary.X11.selection.stringLength);
- }
- else
- {
- // TODO: Should we set an error? Probably not.
- return None;
+ (unsigned char*) _glfwLibrary.X11.selection.formats,
+ _GLFW_CLIPBOARD_FORMAT_COUNT);
+
+ return property;
}
- return request->target;
+ for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
+ {
+ if (request->target == _glfwLibrary.X11.selection.formats[i])
+ {
+ // The requested format is one we support
+
+ XChangeProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ property,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char*) _glfwLibrary.X11.selection.string,
+ strlen(_glfwLibrary.X11.selection.string));
+
+ return property;
+ }
+ }
+
+ return None;
}
@@ -95,21 +137,14 @@ Atom _glfwSelectionRequest(XSelectionRequestEvent* request)
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
- size_t size = strlen(string) + 1;
-
- // Store the new string in preparation for a request event
+ // Store the new string in preparation for a selection request event
free(_glfwLibrary.X11.selection.string);
- _glfwLibrary.X11.selection.string = malloc(size);
- _glfwLibrary.X11.selection.stringLength = size;
- memcpy(_glfwLibrary.X11.selection.string, string, size);
+ _glfwLibrary.X11.selection.string = strdup(string);
- // Set the selection owner to our active window
- XSetSelectionOwner(_glfwLibrary.X11.display, XA_PRIMARY,
- window->X11.handle, CurrentTime);
+ // Set the specified window as owner of the selection
XSetSelectionOwner(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
window->X11.handle, CurrentTime);
- XFlush(_glfwLibrary.X11.display);
}
@@ -117,103 +152,50 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
// Return the current clipboard contents
//========================================================================
-size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* data, size_t size)
+size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
{
- size_t len, rembytes, dummy;
- unsigned char* d;
- int i, fmt;
- Atom type;
+ int i;
+ size_t sourceSize, targetSize;
+
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_INACTIVE;
for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
{
- // Specify the format we would like.
- _glfwLibrary.X11.selection.request =
+ // Request conversion to the selected format
+ _glfwLibrary.X11.selection.target =
_glfwLibrary.X11.selection.formats[i];
- // Convert the selection into a format we would like.
XConvertSelection(_glfwLibrary.X11.display,
_glfwLibrary.X11.selection.atom,
- _glfwLibrary.X11.selection.request,
- None, window->X11.handle, CurrentTime);
+ _glfwLibrary.X11.selection.target,
+ _glfwLibrary.X11.selection.property,
+ window->X11.handle, CurrentTime);
// Process the resulting SelectionNotify event
XSync(_glfwLibrary.X11.display, False);
- _glfwProcessPendingEvents();
+ while (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_INACTIVE)
+ _glfwPlatformWaitEvents();
- // Successful?
- if (_glfwLibrary.X11.selection.converted == 1)
+ if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_SUCCEEDED)
break;
}
- // Successful?
- if (_glfwLibrary.X11.selection.converted == 1)
- _glfwLibrary.X11.selection.converted = 0;
-
- // Unsuccessful conversion, bail with no clipboard data
- if (_glfwLibrary.X11.selection.converted)
+ if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_FAILED)
{
_glfwSetError(GLFW_FORMAT_UNAVAILABLE,
"X11/GLX: Failed to convert selection to string");
return 0;
}
- // Reset for the next selection
- _glfwLibrary.X11.selection.converted = 0;
+ sourceSize = strlen(_glfwLibrary.X11.selection.string) + 1;
- // Check the length of data to receive (rembytes)
- XGetWindowProperty(_glfwLibrary.X11.display,
- window->X11.handle,
- _glfwLibrary.X11.selection.request,
- 0, 0,
- 0,
- AnyPropertyType,
- &type,
- &fmt,
- &len, &rembytes,
- &d);
+ targetSize = sourceSize;
+ if (targetSize > size)
+ targetSize = size;
- // The number of bytes remaining (which is all of them)
- if (rembytes > 0)
- {
- int result = XGetWindowProperty(_glfwLibrary.X11.display,
- window->X11.handle,
- _glfwLibrary.X11.selection.request,
- 0, rembytes,
- 0,
- AnyPropertyType,
- &type,
- &fmt,
- &len, &dummy,
- &d);
- if (result == Success)
- {
- size_t s;
+ memcpy(string, _glfwLibrary.X11.selection.string, targetSize);
+ string[targetSize - 1] = '\0';
- if (rembytes < size - 1)
- s = rembytes;
- else
- s = size - 1;
-
- // Copy the data out.
- memcpy(data, d, s);
-
- // Null-terminate strings.
- ((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 sourceSize;
}
diff --git a/src/x11_init.c b/src/x11_init.c
index 535ede30..3af08cf4 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -597,11 +597,15 @@ static GLboolean initDisplay(void)
// the keyboard mapping.
updateKeyCodeLUT();
+ // Find or create selection property atom
+ _glfwLibrary.X11.selection.property =
+ XInternAtom(_glfwLibrary.X11.display, "GLFW_SELECTION", False);
+
// Find or create clipboard atom
_glfwLibrary.X11.selection.atom =
XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);
- // Find or create selection atoms
+ // Find or create selection target atoms
_glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] =
XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
_glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] =
@@ -609,6 +613,10 @@ static GLboolean initDisplay(void)
_glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
XA_STRING;
+ _glfwLibrary.X11.selection.targets = XInternAtom(_glfwLibrary.X11.display,
+ "TARGETS",
+ False);
+
return GL_TRUE;
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 8de54ead..2de3367e 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -91,6 +91,12 @@
#define _GLFW_CLIPBOARD_FORMAT_STRING 2
#define _GLFW_CLIPBOARD_FORMAT_COUNT 3
+// Clipboard conversion status tokens
+#define _GLFW_CONVERSION_INACTIVE 0
+#define _GLFW_CONVERSION_SUCCEEDED 1
+#define _GLFW_CONVERSION_FAILED 2
+
+
//========================================================================
// GLFW platform specific types
//========================================================================
@@ -235,10 +241,11 @@ typedef struct _GLFWlibraryX11
struct {
Atom atom;
Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT];
- size_t stringLength;
char* string;
- Atom request;
- int converted;
+ Atom target;
+ Atom targets;
+ Atom property;
+ int status;
} selection;
#if defined(_GLFW_DLOPEN_LIBGL)
@@ -281,7 +288,8 @@ void _glfwTerminateJoysticks(void);
long _glfwKeySym2Unicode(KeySym keysym);
// Clipboard handling
-Atom _glfwSelectionRequest(XSelectionRequestEvent *request);
+GLboolean _glfwReadSelection(XSelectionEvent* request);
+Atom _glfwWriteSelection(XSelectionRequestEvent* request);
// Event processing
void _glfwProcessPendingEvents(void);
diff --git a/src/x11_window.c b/src/x11_window.c
index 854480c5..a84e209a 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -1241,28 +1241,39 @@ static void processSingleEvent(void)
break;
}
+ case SelectionClear:
+ {
+ // The ownership of the selection was lost
+
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = NULL;
+ break;
+ }
+
case SelectionNotify:
{
- // Selection notification triggered by the XConvertSelection
+ // The selection conversion status is available
- // 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;
+ XSelectionEvent* request = &event.xselection;
+
+ if (_glfwReadSelection(request))
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_SUCCEEDED;
+ else
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_FAILED;
break;
}
case SelectionRequest:
{
- // Selection request triggered by someone wanting data from the
- // X11 clipboard
- XSelectionRequestEvent *request = &event.xselectionrequest;
+ // The contents of the selection was requested
+
+ XSelectionRequestEvent* request = &event.xselectionrequest;
- // Construct the response
XEvent response;
- response.xselection.property = _glfwSelectionRequest(request);
+ memset(&response, 0, sizeof(response));
+
+ response.xselection.property = _glfwWriteSelection(request);
response.xselection.type = SelectionNotify;
response.xselection.display = request->display;
response.xselection.requestor = request->requestor;
@@ -1270,9 +1281,9 @@ static void processSingleEvent(void)
response.xselection.target = request->target;
response.xselection.time = request->time;
- // Send off the event
- XSendEvent(_glfwLibrary.X11.display, request->requestor, 0, 0, &response);
-
+ XSendEvent(_glfwLibrary.X11.display,
+ request->requestor,
+ False, 0, &response);
break;
}