Merge branch 'clipboard'

This commit is contained in:
Camilla Berglund 2012-04-11 23:40:27 +02:00
commit 67b5bb1d45
15 changed files with 819 additions and 18 deletions

View File

@ -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);

View File

@ -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>

View File

@ -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
View 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
View 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;
}

View File

@ -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;
} }

View File

@ -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";

View File

@ -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
View 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
View 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;
}

View File

@ -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;
} }

View File

@ -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_

View File

@ -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
{ {

View File

@ -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
View 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);
}