mirror of
https://github.com/glfw/glfw.git
synced 2024-11-23 02:25:10 +00:00
Merge branch 'clipboard'
This commit is contained in:
commit
67b5bb1d45
@ -173,6 +173,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is needed for the declaration of size_t.
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* GLFW version
|
* GLFW version
|
||||||
@ -461,6 +465,7 @@ extern "C" {
|
|||||||
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
#define GLFW_VERSION_UNAVAILABLE 0x00070007
|
||||||
#define GLFW_PLATFORM_ERROR 0x00070008
|
#define GLFW_PLATFORM_ERROR 0x00070008
|
||||||
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
|
||||||
|
#define GLFW_FORMAT_UNAVAILABLE 0x0007000A
|
||||||
|
|
||||||
/* Gamma ramps */
|
/* Gamma ramps */
|
||||||
#define GLFW_GAMMA_RAMP_SIZE 256
|
#define GLFW_GAMMA_RAMP_SIZE 256
|
||||||
@ -574,6 +579,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 glfwSetClipboardString(GLFWwindow window, const char* string);
|
||||||
|
GLFWAPI size_t glfwGetClipboardString(GLFWwindow window, char* string, size_t size);
|
||||||
|
|
||||||
/* Time */
|
/* Time */
|
||||||
GLFWAPI double glfwGetTime(void);
|
GLFWAPI double glfwGetTime(void);
|
||||||
GLFWAPI void glfwSetTime(double time);
|
GLFWAPI void glfwSetTime(double time);
|
||||||
|
@ -277,6 +277,7 @@ version of GLFW.</p>
|
|||||||
<li>Added <code>glfwGetWindowPos</code> function for querying the position of the specified window</li>
|
<li>Added <code>glfwGetWindowPos</code> function for querying the position of the specified window</li>
|
||||||
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
|
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
|
||||||
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
|
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
|
||||||
|
<li>Added <code>glfwGetClipboardString</code> and <code>glfwSetClipboardString</code> functions for interacting with the system clipboard</li>
|
||||||
<li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li>
|
<li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li>
|
||||||
<li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li>
|
<li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li>
|
||||||
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
|
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
|
||||||
@ -850,7 +851,7 @@ their skills. Special thanks go out to:</p>
|
|||||||
adding logic for the <code>GLFW_ICON</code> resource</li>
|
adding logic for the <code>GLFW_ICON</code> resource</li>
|
||||||
|
|
||||||
<li>Ralph Eastwood, for the initial design and implementation of the gamma
|
<li>Ralph Eastwood, for the initial design and implementation of the gamma
|
||||||
correction API</li>
|
correction and clipboard APIs</li>
|
||||||
|
|
||||||
<li>GeO4d, for the implementation of cursor enter/leave notifications on
|
<li>GeO4d, for the implementation of cursor enter/leave notifications on
|
||||||
Win32.</li>
|
Win32.</li>
|
||||||
|
@ -4,29 +4,27 @@ include_directories(${GLFW_SOURCE_DIR}/src
|
|||||||
${glfw_INCLUDE_DIRS})
|
${glfw_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
|
set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
|
||||||
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(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} cocoa_fullscreen.m cocoa_gamma.c
|
set(glfw_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_joystick.m
|
||||||
cocoa_opengl.m cocoa_time.c cocoa_window.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(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
||||||
elseif (_GLFW_WIN32_WGL)
|
elseif (_GLFW_WIN32_WGL)
|
||||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} win32_fullscreen.c win32_gamma.c
|
set(glfw_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(glfw_HEADERS ${common_HEADERS} x11_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} x11_fullscreen.c x11_gamma.c
|
set(glfw_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)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||||
|
77
src/clipboard.c
Normal file
77
src/clipboard.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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 glfwSetClipboardString(GLFWwindow handle, const char* string)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetClipboardString(window, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Return the current clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLFWAPI size_t glfwGetClipboardString(GLFWwindow handle, char* string, size_t size)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string || !size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _glfwPlatformGetClipboardString(window, string, size);
|
||||||
|
}
|
||||||
|
|
87
src/cocoa_clipboard.m
Normal file
87
src/cocoa_clipboard.m
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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 _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];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Return the current clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -572,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
|
|||||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||||
int numbuttons)
|
int numbuttons)
|
||||||
{
|
{
|
||||||
int button;
|
int i, j, button;
|
||||||
|
|
||||||
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
|
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
|
||||||
return 0;
|
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
|
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);
|
_glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.hats, i);
|
||||||
int value = hat->value;
|
int value = hat->value;
|
||||||
if (value < 0 || value > 8) value = 8;
|
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;
|
buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,8 @@ GLFWAPI const char* glfwErrorString(int error)
|
|||||||
return "A platform-specific error occurred";
|
return "A platform-specific error occurred";
|
||||||
case GLFW_WINDOW_NOT_ACTIVE:
|
case GLFW_WINDOW_NOT_ACTIVE:
|
||||||
return "The specified window is 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";
|
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
|
||||||
|
@ -288,6 +288,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 _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
|
||||||
|
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char *data, size_t size);
|
||||||
|
|
||||||
// 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);
|
||||||
|
149
src/win32_clipboard.c
Normal file
149
src/win32_clipboard.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Set the clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Return the current clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
201
src/x11_clipboard.c
Normal file
201
src/x11_clipboard.c
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Save the contents of the specified property
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLboolean _glfwReadSelection(XSelectionEvent* request)
|
||||||
|
{
|
||||||
|
Atom actualType;
|
||||||
|
int actualFormat;
|
||||||
|
unsigned long itemCount, bytesAfter;
|
||||||
|
char* data;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// The list of supported targets was requested
|
||||||
|
|
||||||
|
XChangeProperty(_glfwLibrary.X11.display,
|
||||||
|
request->requestor,
|
||||||
|
property,
|
||||||
|
XA_ATOM,
|
||||||
|
32,
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char*) _glfwLibrary.X11.selection.formats,
|
||||||
|
_GLFW_CLIPBOARD_FORMAT_COUNT);
|
||||||
|
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Set the clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||||
|
{
|
||||||
|
// Store the new string in preparation for a selection request event
|
||||||
|
free(_glfwLibrary.X11.selection.string);
|
||||||
|
_glfwLibrary.X11.selection.string = strdup(string);
|
||||||
|
|
||||||
|
// Set the specified window as owner of the selection
|
||||||
|
XSetSelectionOwner(_glfwLibrary.X11.display,
|
||||||
|
_glfwLibrary.X11.selection.atom,
|
||||||
|
window->X11.handle, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Return the current clipboard contents
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
size_t _glfwPlatformGetClipboardString(_GLFWwindow* window, char* string, size_t size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t sourceSize, targetSize;
|
||||||
|
|
||||||
|
_glfwLibrary.X11.selection.status = _GLFW_CONVERSION_INACTIVE;
|
||||||
|
|
||||||
|
for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
|
||||||
|
{
|
||||||
|
// Request conversion to the selected format
|
||||||
|
_glfwLibrary.X11.selection.target =
|
||||||
|
_glfwLibrary.X11.selection.formats[i];
|
||||||
|
|
||||||
|
XConvertSelection(_glfwLibrary.X11.display,
|
||||||
|
_glfwLibrary.X11.selection.atom,
|
||||||
|
_glfwLibrary.X11.selection.target,
|
||||||
|
_glfwLibrary.X11.selection.property,
|
||||||
|
window->X11.handle, CurrentTime);
|
||||||
|
|
||||||
|
// Process the resulting SelectionNotify event
|
||||||
|
XSync(_glfwLibrary.X11.display, False);
|
||||||
|
while (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_INACTIVE)
|
||||||
|
_glfwPlatformWaitEvents();
|
||||||
|
|
||||||
|
if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_SUCCEEDED)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_FAILED)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"X11/GLX: Failed to convert selection to string");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSize = strlen(_glfwLibrary.X11.selection.string) + 1;
|
||||||
|
|
||||||
|
targetSize = sourceSize;
|
||||||
|
if (targetSize > size)
|
||||||
|
targetSize = size;
|
||||||
|
|
||||||
|
memcpy(string, _glfwLibrary.X11.selection.string, targetSize);
|
||||||
|
string[targetSize - 1] = '\0';
|
||||||
|
|
||||||
|
return sourceSize;
|
||||||
|
}
|
||||||
|
|
@ -597,6 +597,26 @@ static GLboolean initDisplay(void)
|
|||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
updateKeyCodeLUT();
|
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 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] =
|
||||||
|
XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
|
||||||
|
_glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
|
||||||
|
XA_STRING;
|
||||||
|
|
||||||
|
_glfwLibrary.X11.selection.targets = XInternAtom(_glfwLibrary.X11.display,
|
||||||
|
"TARGETS",
|
||||||
|
False);
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,6 +782,10 @@ int _glfwPlatformTerminate(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Free clipboard memory
|
||||||
|
if (_glfwLibrary.X11.selection.string)
|
||||||
|
free(_glfwLibrary.X11.selection.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 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
|
||||||
|
|
||||||
|
// Clipboard conversion status tokens
|
||||||
|
#define _GLFW_CONVERSION_INACTIVE 0
|
||||||
|
#define _GLFW_CONVERSION_SUCCEEDED 1
|
||||||
|
#define _GLFW_CONVERSION_FAILED 2
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW platform specific types
|
// GLFW platform specific types
|
||||||
@ -226,6 +237,17 @@ typedef struct _GLFWlibraryX11
|
|||||||
uint64_t base;
|
uint64_t base;
|
||||||
} timer;
|
} timer;
|
||||||
|
|
||||||
|
// Selection data
|
||||||
|
struct {
|
||||||
|
Atom atom;
|
||||||
|
Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT];
|
||||||
|
char* string;
|
||||||
|
Atom target;
|
||||||
|
Atom targets;
|
||||||
|
Atom property;
|
||||||
|
int status;
|
||||||
|
} 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
|
||||||
@ -265,5 +287,11 @@ void _glfwTerminateJoysticks(void);
|
|||||||
// Unicode support
|
// Unicode support
|
||||||
long _glfwKeySym2Unicode(KeySym keysym);
|
long _glfwKeySym2Unicode(KeySym keysym);
|
||||||
|
|
||||||
|
// Clipboard handling
|
||||||
|
GLboolean _glfwReadSelection(XSelectionEvent* request);
|
||||||
|
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
|
||||||
|
|
||||||
|
// Event processing
|
||||||
|
void _glfwProcessPendingEvents(void);
|
||||||
|
|
||||||
#endif // _platform_h_
|
#endif // _platform_h_
|
||||||
|
@ -1241,6 +1241,52 @@ static void processSingleEvent(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SelectionClear:
|
||||||
|
{
|
||||||
|
// The ownership of the selection was lost
|
||||||
|
|
||||||
|
free(_glfwLibrary.X11.selection.string);
|
||||||
|
_glfwLibrary.X11.selection.string = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
// The selection conversion status is available
|
||||||
|
|
||||||
|
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:
|
||||||
|
{
|
||||||
|
// The contents of the selection was requested
|
||||||
|
|
||||||
|
XSelectionRequestEvent* request = &event.xselectionrequest;
|
||||||
|
|
||||||
|
XEvent response;
|
||||||
|
memset(&response, 0, sizeof(response));
|
||||||
|
|
||||||
|
response.xselection.property = _glfwWriteSelection(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;
|
||||||
|
|
||||||
|
XSendEvent(_glfwLibrary.X11.display,
|
||||||
|
request->requestor,
|
||||||
|
False, 0, &response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Was the window destroyed?
|
// Was the window destroyed?
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
return;
|
return;
|
||||||
@ -1264,6 +1310,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 //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -1334,7 +1397,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process the window map event and any other that may have arrived
|
// Process the window map event and any other that may have arrived
|
||||||
_glfwPlatformPollEvents();
|
_glfwProcessPendingEvents();
|
||||||
|
|
||||||
// Retrieve and set initial cursor position
|
// Retrieve and set initial cursor position
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,8 @@ endif()
|
|||||||
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)
|
||||||
add_executable(events events.c)
|
add_executable(events events.c)
|
||||||
|
156
tests/clipboard.c
Normal file
156
tests/clipboard.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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 GLboolean control_is_down(GLFWwindow window)
|
||||||
|
{
|
||||||
|
return glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) ||
|
||||||
|
glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void key_callback(GLFWwindow window, int key, int action)
|
||||||
|
{
|
||||||
|
if (action != GLFW_PRESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case GLFW_KEY_ESCAPE:
|
||||||
|
glfwCloseWindow(window);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GLFW_KEY_V:
|
||||||
|
if (control_is_down(window))
|
||||||
|
{
|
||||||
|
char buffer[4096];
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
printf("Paste test.\n");
|
||||||
|
|
||||||
|
size = glfwGetClipboardString(window, buffer, sizeof(buffer));
|
||||||
|
if (size >= sizeof(buffer))
|
||||||
|
printf("Buffer wasn't big enough to hold clipboard data.\n");
|
||||||
|
|
||||||
|
printf("[%lu]: %s\n", (unsigned long) size, buffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GLFW_KEY_C:
|
||||||
|
if (control_is_down(window))
|
||||||
|
{
|
||||||
|
const char* string = "Hello GLFW World!";
|
||||||
|
glfwSetClipboardString(window, string);
|
||||||
|
printf("Setting clipboard to: %s\n", string);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
GLFWwindow window;
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "h")) != -1)
|
||||||
|
{
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
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