@ -675,6 +675,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
_glfw . x11 . COMPOUND_STRING ,
XA_STRING } ;
const int formatCount = sizeof ( formats ) / sizeof ( formats [ 0 ] ) ;
char * selectionString = request - > selection = = _glfw . x11 . PRIMARY ?
_glfw . x11 . primarySelectionString : _glfw . x11 . clipboardString ;
if ( request - > property = = None )
{
@ -735,8 +737,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
targets [ i ] ,
8 ,
PropModeReplace ,
( unsigned char * ) _glfw . x11 . clipboard String,
strlen ( _glfw . x11 . clipboard String) ) ;
( unsigned char * ) selection String,
strlen ( selection String) ) ;
}
else
targets [ i + 1 ] = None ;
@ -787,8 +789,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
request - > target ,
8 ,
PropModeReplace ,
( unsigned char * ) _glfw . x11 . clipboard String,
strlen ( _glfw . x11 . clipboard String) ) ;
( unsigned char * ) selection String,
strlen ( selection String) ) ;
return request - > property ;
}
@ -801,8 +803,17 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
static void handleSelectionClear ( XEvent * event )
{
free ( _glfw . x11 . clipboardString ) ;
_glfw . x11 . clipboardString = NULL ;
const XSelectionClearEvent * request = & event - > xselectionclear ;
if ( request - > selection = = _glfw . x11 . PRIMARY )
{
free ( _glfw . x11 . primarySelectionString ) ;
_glfw . x11 . primarySelectionString = NULL ;
}
else if ( request - > selection = = _glfw . x11 . CLIPBOARD )
{
free ( _glfw . x11 . clipboardString ) ;
_glfw . x11 . clipboardString = NULL ;
}
}
static void handleSelectionRequest ( XEvent * event )
@ -823,6 +834,76 @@ static void handleSelectionRequest(XEvent* event)
XSendEvent ( _glfw . x11 . display , request - > requestor , False , 0 , & reply ) ;
}
static const char * getSelection ( Atom selection , char * * ptr )
{
size_t i ;
const Atom formats [ ] = { _glfw . x11 . UTF8_STRING ,
_glfw . x11 . COMPOUND_STRING ,
XA_STRING } ;
const size_t formatCount = sizeof ( formats ) / sizeof ( formats [ 0 ] ) ;
if ( XGetSelectionOwner ( _glfw . x11 . display , selection ) = =
_glfw . x11 . helperWindowHandle )
{
// Instead of doing a large number of X round-trips just to put this
// string into a window property and then read it back, just return it
return * ptr ;
}
free ( * ptr ) ;
* ptr = NULL ;
for ( i = 0 ; i < formatCount ; i + + )
{
char * data ;
XEvent event ;
XConvertSelection ( _glfw . x11 . display ,
selection ,
formats [ i ] ,
_glfw . x11 . GLFW_SELECTION ,
_glfw . x11 . helperWindowHandle ,
CurrentTime ) ;
while ( ! XCheckTypedWindowEvent ( _glfw . x11 . display ,
_glfw . x11 . helperWindowHandle ,
SelectionNotify ,
& event ) )
{
waitForEvent ( NULL ) ;
}
if ( event . xselection . property = = None )
continue ;
if ( _glfwGetWindowPropertyX11 ( event . xselection . requestor ,
event . xselection . property ,
event . xselection . target ,
( unsigned char * * ) & data ) )
{
* ptr = strdup ( data ) ;
}
if ( data )
XFree ( data ) ;
XDeleteProperty ( _glfw . x11 . display ,
event . xselection . requestor ,
event . xselection . property ) ;
if ( * ptr )
break ;
}
if ( * ptr = = NULL )
{
_glfwInputError ( GLFW_FORMAT_UNAVAILABLE ,
" X11: Failed to convert clipboard to string " ) ;
}
return * ptr ;
}
// Make the specified window and its video mode active on its monitor
//
static GLFWbool acquireMonitor ( _GLFWwindow * window )
@ -2572,72 +2653,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
const char * _glfwPlatformGetClipboardString ( _GLFWwindow * window )
{
size_t i ;
const Atom formats [ ] = { _glfw . x11 . UTF8_STRING ,
_glfw . x11 . COMPOUND_STRING ,
XA_STRING } ;
const size_t formatCount = sizeof ( formats ) / sizeof ( formats [ 0 ] ) ;
if ( XGetSelectionOwner ( _glfw . x11 . display , _glfw . x11 . CLIPBOARD ) = =
_glfw . x11 . helperWindowHandle )
{
// Instead of doing a large number of X round-trips just to put this
// string into a window property and then read it back, just return it
return _glfw . x11 . clipboardString ;
}
free ( _glfw . x11 . clipboardString ) ;
_glfw . x11 . clipboardString = NULL ;
for ( i = 0 ; i < formatCount ; i + + )
{
char * data ;
XEvent event ;
XConvertSelection ( _glfw . x11 . display ,
_glfw . x11 . CLIPBOARD ,
formats [ i ] ,
_glfw . x11 . GLFW_SELECTION ,
_glfw . x11 . helperWindowHandle ,
CurrentTime ) ;
while ( ! XCheckTypedWindowEvent ( _glfw . x11 . display ,
_glfw . x11 . helperWindowHandle ,
SelectionNotify ,
& event ) )
{
waitForEvent ( NULL ) ;
}
if ( event . xselection . property = = None )
continue ;
if ( _glfwGetWindowPropertyX11 ( event . xselection . requestor ,
event . xselection . property ,
event . xselection . target ,
( unsigned char * * ) & data ) )
{
_glfw . x11 . clipboardString = strdup ( data ) ;
}
if ( data )
XFree ( data ) ;
XDeleteProperty ( _glfw . x11 . display ,
event . xselection . requestor ,
event . xselection . property ) ;
if ( _glfw . x11 . clipboardString )
break ;
}
if ( _glfw . x11 . clipboardString = = NULL )
{
_glfwInputError ( GLFW_FORMAT_UNAVAILABLE ,
" X11: Failed to convert clipboard to string " ) ;
}
return _glfw . x11 . clipboardString ;
return getSelection ( _glfw . x11 . CLIPBOARD , & _glfw . x11 . clipboardString ) ;
}
void _glfwPlatformGetRequiredInstanceExtensions ( char * * extensions )
@ -2807,3 +2823,28 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return window - > x11 . handle ;
}
GLFWAPI void glfwSetX11SelectionString ( const char * string )
{
_GLFW_REQUIRE_INIT ( ) ;
free ( _glfw . x11 . primarySelectionString ) ;
_glfw . x11 . primarySelectionString = strdup ( string ) ;
XSetSelectionOwner ( _glfw . x11 . display ,
_glfw . x11 . PRIMARY ,
_glfw . x11 . helperWindowHandle ,
CurrentTime ) ;
if ( XGetSelectionOwner ( _glfw . x11 . display , _glfw . x11 . PRIMARY ) ! =
_glfw . x11 . helperWindowHandle )
{
_glfwInputError ( GLFW_PLATFORM_ERROR ,
" X11: Failed to become owner of primary selection " ) ;
}
}
GLFWAPI const char * glfwGetX11SelectionString ( void )
{
_GLFW_REQUIRE_INIT_OR_RETURN ( NULL ) ;
return getSelection ( _glfw . x11 . PRIMARY , & _glfw . x11 . primarySelectionString ) ;
}