mirror of
https://github.com/gwm17/glfw.git
synced 2024-11-23 18:58:52 -05:00
Merge remote-tracking branch 'raedwulf/clipboard' into clipboard
Conflicts: src/CMakeLists.txt
This commit is contained in:
commit
ea36557b93
|
@ -455,10 +455,16 @@ extern "C" {
|
||||||
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
||||||
#define GLFW_PLATFORM_ERROR 0x00070008
|
#define GLFW_PLATFORM_ERROR 0x00070008
|
||||||
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
||||||
|
#define GLFW_CLIPBOARD_FORMAT_UNAVAILABLE 0x00070010
|
||||||
|
#define GLFW_CLIPBOARD_CANNOT_OWN 0x00070011
|
||||||
|
|
||||||
/* Gamma ramps */
|
/* Gamma ramps */
|
||||||
#define GLFW_GAMMA_RAMP_SIZE 256
|
#define GLFW_GAMMA_RAMP_SIZE 256
|
||||||
|
|
||||||
|
/* Clipboard formats */
|
||||||
|
#define GLFW_CLIPBOARD_FORMAT_NONE 0
|
||||||
|
#define GLFW_CLIPBOARD_FORMAT_STRING 1
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
@ -566,6 +572,10 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param);
|
||||||
GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
|
GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
|
||||||
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
|
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 */
|
/* Time */
|
||||||
GLFWAPI double glfwGetTime(void);
|
GLFWAPI double glfwGetTime(void);
|
||||||
GLFWAPI void glfwSetTime(double time);
|
GLFWAPI void glfwSetTime(double time);
|
||||||
|
|
|
@ -15,24 +15,25 @@ include_directories(${GLFW_SOURCE_DIR}/src
|
||||||
${GLFW_BINARY_DIR}/src
|
${GLFW_BINARY_DIR}/src
|
||||||
${GLFW_INCLUDE_DIR})
|
${GLFW_INCLUDE_DIR})
|
||||||
|
|
||||||
set(common_SOURCES error.c fullscreen.c gamma.c init.c input.c
|
set(common_SOURCES clipboard.c error.c fullscreen.c gamma.c init.c input.c
|
||||||
joystick.c opengl.c time.c window.c)
|
joystick.c opengl.c time.c window.c)
|
||||||
|
|
||||||
if(_GLFW_COCOA_NSGL)
|
if(_GLFW_COCOA_NSGL)
|
||||||
set(libglfw_SOURCES ${common_SOURCES} cocoa_fullscreen.m cocoa_gamma.c
|
set(libglfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
|
||||||
cocoa_init.m cocoa_input.m cocoa_joystick.m
|
cocoa_gamma.c cocoa_init.m cocoa_input.m
|
||||||
cocoa_opengl.m cocoa_time.c cocoa_window.m)
|
cocoa_joystick.m cocoa_opengl.m cocoa_time.c
|
||||||
|
cocoa_window.m)
|
||||||
|
|
||||||
# For some reason, CMake doesn't know about .m
|
# For some reason, CMake doesn't know about .m
|
||||||
set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C)
|
set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C)
|
||||||
elseif(_GLFW_WIN32_WGL)
|
elseif(_GLFW_WIN32_WGL)
|
||||||
set(libglfw_SOURCES ${common_SOURCES} win32_fullscreen.c win32_gamma.c
|
set(libglfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c
|
||||||
win32_init.c win32_input.c win32_joystick.c
|
win32_gamma.c win32_init.c win32_input.c win32_joystick.c
|
||||||
win32_opengl.c win32_time.c win32_window.c
|
win32_opengl.c win32_time.c win32_window.c
|
||||||
win32_dllmain.c)
|
win32_dllmain.c)
|
||||||
elseif(_GLFW_X11_GLX)
|
elseif(_GLFW_X11_GLX)
|
||||||
set(libglfw_SOURCES ${common_SOURCES} x11_fullscreen.c x11_gamma.c
|
set(libglfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
|
||||||
x11_init.c x11_input.c x11_joystick.c
|
x11_gamma.c x11_init.c x11_input.c x11_joystick.c
|
||||||
x11_keysym2unicode.c x11_opengl.c x11_time.c
|
x11_keysym2unicode.c x11_opengl.c x11_time.c
|
||||||
x11_window.c)
|
x11_window.c)
|
||||||
else()
|
else()
|
||||||
|
|
78
src/clipboard.c
Normal file
78
src/clipboard.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
//========================================================================
|
||||||
|
// GLFW - An OpenGL library
|
||||||
|
// Platform: Any
|
||||||
|
// API version: 3.0
|
||||||
|
// WWW: http://www.glfw.org/
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// 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 <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == GLFW_CLIPBOARD_FORMAT_NONE)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == GLFW_CLIPBOARD_FORMAT_NONE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!data || !size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _glfwPlatformGetClipboardData(data, size, format);
|
||||||
|
}
|
56
src/cocoa_clipboard.m
Normal file
56
src/cocoa_clipboard.m
Normal file
|
@ -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 <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// 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 <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// 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;
|
||||||
|
}
|
||||||
|
|
|
@ -285,6 +285,10 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
|
||||||
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
|
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
|
||||||
void _glfwPlatformSetGammaRamp(const 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
|
// Joystick
|
||||||
int _glfwPlatformGetJoystickParam(int joy, int param);
|
int _glfwPlatformGetJoystickParam(int joy, int param);
|
||||||
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes);
|
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes);
|
||||||
|
|
|
@ -9,4 +9,5 @@ Version: 3.0.0
|
||||||
URL: http://www.glfw.org/
|
URL: http://www.glfw.org/
|
||||||
Requires.private: gl x11 @GLFW_PKGLIBS@
|
Requires.private: gl x11 @GLFW_PKGLIBS@
|
||||||
Libs: -L${libdir} -lglfw
|
Libs: -L${libdir} -lglfw
|
||||||
|
Libs.private: @GLFW_LIBRARIES@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
56
src/win32_clipboard.c
Normal file
56
src/win32_clipboard.c
Normal file
|
@ -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 <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// 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 <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// 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;
|
||||||
|
}
|
||||||
|
|
248
src/x11_clipboard.c
Normal file
248
src/x11_clipboard.c
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
//========================================================================
|
||||||
|
// GLFW - An OpenGL library
|
||||||
|
// Platform: X11/GLX
|
||||||
|
// API version: 3.0
|
||||||
|
// WWW: http://www.glfw.org/
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
// TODO: Incremental support? Overkill perhaps.
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Get the corresponding X11 format for a given GLFW format.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
static Atom *getInternalFormat(int fmt)
|
||||||
|
{
|
||||||
|
// Get the necessary atoms
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case GLFW_CLIPBOARD_FORMAT_STRING:
|
||||||
|
return _glfwLibrary.X11.selection.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
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
size_t _glfwPlatformGetClipboardData(void *data, size_t size, int format)
|
||||||
|
{
|
||||||
|
size_t len, rembytes, dummy;
|
||||||
|
unsigned char *d;
|
||||||
|
int fmt;
|
||||||
|
Atom type;
|
||||||
|
|
||||||
|
// 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++)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (rembytes)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -447,6 +447,21 @@ static GLboolean initDisplay(void)
|
||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
updateKeyCodeLUT();
|
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.atoms.string[_GLFW_STRING_ATOM_UTF8] =
|
||||||
|
XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
|
||||||
|
_glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_COMPOUND] =
|
||||||
|
XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
|
||||||
|
_glfwLibrary.X11.selection.atoms.string[_GLFW_STRING_ATOM_STRING] = XA_STRING;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +625,10 @@ int _glfwPlatformTerminate(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Free clipboard memory
|
||||||
|
if (_glfwLibrary.X11.selection.clipboard.string)
|
||||||
|
free(_glfwLibrary.X11.selection.clipboard.string);
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,17 @@
|
||||||
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
||||||
|
|
||||||
|
// 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
|
// GLFW platform specific types
|
||||||
|
@ -223,6 +234,20 @@ typedef struct _GLFWlibraryX11
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
} timer;
|
} timer;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int converted;
|
||||||
|
} selection;
|
||||||
|
|
||||||
#if defined(_GLFW_DLOPEN_LIBGL)
|
#if defined(_GLFW_DLOPEN_LIBGL)
|
||||||
void* libGL; // dlopen handle for libGL.so
|
void* libGL; // dlopen handle for libGL.so
|
||||||
#endif
|
#endif
|
||||||
|
@ -262,5 +287,7 @@ void _glfwTerminateJoysticks(void);
|
||||||
// Unicode support
|
// Unicode support
|
||||||
long _glfwKeySym2Unicode(KeySym keysym);
|
long _glfwKeySym2Unicode(KeySym keysym);
|
||||||
|
|
||||||
|
// Clipboard handling
|
||||||
|
Atom _glfwSelectionRequest(XSelectionRequestEvent *request);
|
||||||
|
|
||||||
#endif // _platform_h_
|
#endif // _platform_h_
|
||||||
|
|
|
@ -1359,6 +1359,41 @@ static void processSingleEvent(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
// Selection notification triggered by the XConvertSelection
|
||||||
|
|
||||||
|
// Check if the notification property matches the request
|
||||||
|
if (event.xselection.property != _glfwLibrary.X11.selection.request)
|
||||||
|
_glfwLibrary.X11.selection.converted = 2;
|
||||||
|
else // It was successful
|
||||||
|
_glfwLibrary.X11.selection.converted = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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?
|
// Was the window destroyed?
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -5,6 +5,8 @@ set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||||
include_directories(${GLFW_SOURCE_DIR}/include
|
include_directories(${GLFW_SOURCE_DIR}/include
|
||||||
${GLFW_SOURCE_DIR}/support
|
${GLFW_SOURCE_DIR}/support
|
||||||
${OPENGL_INCLUDE_DIR})
|
${OPENGL_INCLUDE_DIR})
|
||||||
|
add_executable(clipboard clipboard.c)
|
||||||
|
target_link_libraries(clipboard ${STATIC_DEPS})
|
||||||
|
|
||||||
add_executable(defaults defaults.c)
|
add_executable(defaults defaults.c)
|
||||||
target_link_libraries(defaults ${STATIC_DEPS})
|
target_link_libraries(defaults ${STATIC_DEPS})
|
||||||
|
|
147
tests/clipboard.c
Normal file
147
tests/clipboard.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
//========================================================================
|
||||||
|
// Gamma correction test program
|
||||||
|
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// 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 <GL/glfw3.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user