/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "unx/saldisp.hxx"
#include "unx/saldata.hxx"

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#include "tools/prex.h"
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include "tools/postx.h"
#if defined(LINUX) || defined(NETBSD) || defined (FREEBSD)
#include <sys/poll.h>
#else
#include <poll.h>
#endif
#include <sal/alloca.h>

#include <X11_selection.hxx>
#include <X11_clipboard.hxx>
#include <X11_transferable.hxx>
#include <X11_dndcontext.hxx>
#include <bmp.hxx>

#include "vcl/svapp.hxx"

// pointer bitmaps
#include <copydata_curs.h>
#include <copydata_mask.h>
#include <movedata_curs.h>
#include <movedata_mask.h>
#include <linkdata_curs.h>
#include <linkdata_mask.h>
#include <nodrop_curs.h>
#include <nodrop_mask.h>
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include <com/sun/star/awt/MouseEvent.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <rtl/tencinfo.h>
#include <osl/process.h>

#include <comphelper/processfactory.hxx>
#include <vos/mutex.hxx>

#define DRAG_EVENT_MASK	ButtonPressMask			|\
						  	ButtonReleaseMask		|\
						  	PointerMotionMask		|\
						  	EnterWindowMask			|\
						  	LeaveWindowMask

namespace {

namespace css = com::sun::star;

}

using namespace com::sun::star::datatransfer;
using namespace com::sun::star::datatransfer::dnd;
using namespace com::sun::star::lang;
using namespace com::sun::star::awt;
using namespace com::sun::star::uno;
using namespace com::sun::star::frame;
using namespace cppu;
using namespace osl;
using namespace rtl;

using namespace x11;

// stubs to satisfy solaris compiler's rather rigid linking warning
extern "C"
{
    static void call_SelectionManager_run( void * pMgr )
    {
        SelectionManager::run( pMgr );
    }
    
    static void call_SelectionManager_runDragExecute( void * pMgr )
    {
        SelectionManager::runDragExecute( pMgr );
    }
}


static const long nXdndProtocolRevision = 5;

// mapping between mime types (or what the office thinks of mime types)
// and X convention types
struct NativeTypeEntry
{
	Atom			nAtom;
	const char*		pType;				// Mime encoding on our side
	const char*		pNativeType;		// string corresponding to nAtom for the case of nAtom being uninitialized
	int				nFormat;			// the corresponding format
};

// the convention for Xdnd is mime types as specified by the corresponding
// RFC's with the addition that text/plain without charset tag contains iso8859-1
// sadly some applications (e.g. gtk) do not honor the mimetype only rule,
// so for compatibility add UTF8_STRING
static NativeTypeEntry aXdndConversionTab[] =
{
	{ 0, "text/plain;charset=iso8859-1", "text/plain", 8 },
    { 0, "text/plain;charset=utf-8", "UTF8_STRING", 8 }
};

// for clipboard and primary selections there is only a convention for text
// that the encoding name of the text is taken as type in all capitalized letters
static NativeTypeEntry aNativeConversionTab[] =
{
	{ 0, "text/plain;charset=utf-16", "ISO10646-1", 16 },
	{ 0, "text/plain;charset=utf-8", "UTF8_STRING", 8 },
	{ 0, "text/plain;charset=utf-8", "UTF-8", 8 },
	{ 0, "text/plain;charset=utf-8", "text/plain;charset=UTF-8", 8 },
	// ISO encodings
	{ 0, "text/plain;charset=iso8859-2", "ISO8859-2", 8 },
	{ 0, "text/plain;charset=iso8859-3", "ISO8859-3", 8 },
	{ 0, "text/plain;charset=iso8859-4", "ISO8859-4", 8 },
	{ 0, "text/plain;charset=iso8859-5", "ISO8859-5", 8 },
	{ 0, "text/plain;charset=iso8859-6", "ISO8859-6", 8 },
	{ 0, "text/plain;charset=iso8859-7", "ISO8859-7", 8 },
	{ 0, "text/plain;charset=iso8859-8", "ISO8859-8", 8 },
	{ 0, "text/plain;charset=iso8859-9", "ISO8859-9", 8 },
	{ 0, "text/plain;charset=iso8859-10", "ISO8859-10", 8 },
	{ 0, "text/plain;charset=iso8859-13", "ISO8859-13", 8 },
	{ 0, "text/plain;charset=iso8859-14", "ISO8859-14", 8 },
	{ 0, "text/plain;charset=iso8859-15", "ISO8859-15", 8 },
	// asian encodings
	{ 0, "text/plain;charset=jisx0201.1976-0", "JISX0201.1976-0", 8 },
	{ 0, "text/plain;charset=jisx0208.1983-0", "JISX0208.1983-0", 8 },
	{ 0, "text/plain;charset=jisx0208.1990-0", "JISX0208.1990-0", 8 },
	{ 0, "text/plain;charset=jisx0212.1990-0", "JISX0212.1990-0", 8 },
	{ 0, "text/plain;charset=gb2312.1980-0", "GB2312.1980-0", 8 },
	{ 0, "text/plain;charset=ksc5601.1992-0", "KSC5601.1992-0", 8 },
	// eastern european encodings
	{ 0, "text/plain;charset=koi8-r", "KOI8-R", 8 },
	{ 0, "text/plain;charset=koi8-u", "KOI8-U", 8 },
	// String (== iso8859-1)
	{ XA_STRING, "text/plain;charset=iso8859-1", "STRING", 8 },
    // special for compound text
    { 0, "text/plain;charset=compound_text", "COMPOUND_TEXT", 8 },

    // PIXMAP
    { XA_PIXMAP, "image/bmp", "PIXMAP", 32 }
};

rtl_TextEncoding x11::getTextPlainEncoding( const OUString& rMimeType )
{
	rtl_TextEncoding aEncoding = RTL_TEXTENCODING_DONTKNOW;
	OUString aMimeType( rMimeType.toAsciiLowerCase() );
    sal_Int32 nIndex = 0;
	if( aMimeType.getToken( 0, ';', nIndex ).equalsAsciiL( "text/plain" , 10 ) )
	{
		if( aMimeType.getLength() == 10 ) // only "text/plain"
			aEncoding = RTL_TEXTENCODING_ISO_8859_1;
		else
		{
            while( nIndex != -1 )
			{
				OUString aToken = aMimeType.getToken( 0, ';', nIndex );
                sal_Int32 nPos = 0;
				if( aToken.getToken( 0, '=', nPos ).equalsAsciiL( "charset", 7 ) )
				{
					OString aEncToken = OUStringToOString( aToken.getToken( 0, '=', nPos ), RTL_TEXTENCODING_ISO_8859_1 );
					aEncoding = rtl_getTextEncodingFromUnixCharset( aEncToken.getStr() );
					if( aEncoding == RTL_TEXTENCODING_DONTKNOW )
					{
						if( aEncToken.equalsIgnoreAsciiCase( "utf-8" ) )
							aEncoding = RTL_TEXTENCODING_UTF8;
					}
					if( aEncoding != RTL_TEXTENCODING_DONTKNOW )
						break;
				}
			}
		}
	}
#if OSL_DEBUG_LEVEL > 1
    if( aEncoding == RTL_TEXTENCODING_DONTKNOW )
        fprintf( stderr, "getTextPlainEncoding( %s ) failed\n", OUStringToOString( rMimeType, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
	return aEncoding;
}

// ------------------------------------------------------------------------

::std::hash_map< OUString, SelectionManager*, OUStringHash >& SelectionManager::getInstances()
{
    static ::std::hash_map< OUString, SelectionManager*, OUStringHash > aInstances;
    return aInstances;
}

// ------------------------------------------------------------------------

SelectionManager::SelectionManager() :
        m_nIncrementalThreshold( 15*1024 ),
        m_pDisplay( NULL ),
        m_aThread( NULL ),
        m_aDragExecuteThread( NULL ),
        m_aWindow( None ),
        m_nSelectionTimeout( 0 ),
        m_nSelectionTimestamp( CurrentTime ),
        m_bDropEnterSent( true ),
        m_aCurrentDropWindow( None ),
        m_nDropTime( None ),
        m_nLastDropAction( 0 ),
        m_nLastX( 0 ),
        m_nLastY( 0 ),
        m_nDropTimestamp( 0 ),
        m_bDropWaitingForCompletion( false ),
        m_aDropWindow( None ),
        m_aDropProxy( None ),
        m_aDragSourceWindow( None ),
        m_nLastDragX( 0 ),
        m_nLastDragY( 0 ),
        m_nNoPosX( 0 ),
        m_nNoPosY( 0 ),
        m_nNoPosWidth( 0 ),
        m_nNoPosHeight( 0 ),
        m_nDragButton( 0 ),
        m_nUserDragAction( 0 ),
        m_nTargetAcceptAction( 0 ),
        m_nSourceActions( 0 ),
        m_bLastDropAccepted( false ),
        m_bDropSuccess( false ),
        m_bDropSent( false ),
        m_bWaitingForPrimaryConversion( false ),
        m_nDragTimestamp( None ),
        m_aMoveCursor( None ),
        m_aCopyCursor( None ),
        m_aLinkCursor( None ),
        m_aNoneCursor( None ),
        m_aCurrentCursor( None ),
        m_nCurrentProtocolVersion( nXdndProtocolRevision ),
        m_nCLIPBOARDAtom( None ),
        m_nTARGETSAtom( None ),
        m_nTIMESTAMPAtom( None ),
        m_nTEXTAtom( None ),
        m_nINCRAtom( None ),
        m_nCOMPOUNDAtom( None ),
        m_nMULTIPLEAtom( None ),
        m_nUTF16Atom( None ),
        m_nImageBmpAtom( None ),
        m_nXdndAware( None ),
        m_nXdndEnter( None ),
        m_nXdndLeave( None ),
        m_nXdndPosition( None ),
        m_nXdndStatus( None ),
        m_nXdndDrop( None ),
        m_nXdndFinished( None ),
        m_nXdndSelection( None ),
        m_nXdndTypeList( None ),
        m_nXdndProxy( None ),
        m_nXdndActionCopy( None ),
        m_nXdndActionMove( None ),
        m_nXdndActionLink( None ),
        m_nXdndActionAsk( None ),
        m_nXdndActionPrivate( None ),
        m_bShutDown( false )
{
	m_aDropEnterEvent.data.l[0]	= None;
    m_aDragRunning.reset();
}

XLIB_Cursor SelectionManager::createCursor( const char* pPointerData, const char* pMaskData, int width, int height, int hotX, int hotY )
{
	Pixmap aPointer;
	Pixmap aMask;
	XColor aBlack, aWhite;

	aBlack.pixel = BlackPixel( m_pDisplay, 0 );
	aBlack.red = aBlack.green = aBlack.blue = 0;
	aBlack.flags = DoRed | DoGreen | DoBlue;

	aWhite.pixel = WhitePixel( m_pDisplay, 0 );
	aWhite.red = aWhite.green = aWhite.blue = 0xffff;
	aWhite.flags = DoRed | DoGreen | DoBlue;

	aPointer =
		XCreateBitmapFromData( m_pDisplay,
							   m_aWindow,
							   pPointerData,
							   width,
							   height );
	aMask
		= XCreateBitmapFromData( m_pDisplay,
								 m_aWindow,
								 pMaskData,
								 width,
								 height );
	XLIB_Cursor aCursor =
		XCreatePixmapCursor( m_pDisplay, aPointer, aMask,
							 &aBlack, &aWhite,
							 hotX,
							 hotY );
	XFreePixmap( m_pDisplay, aPointer );
	XFreePixmap( m_pDisplay, aMask );

	return aCursor;
}

void SelectionManager::initialize( const Sequence< Any >& arguments ) throw (::com::sun::star::uno::Exception)
{
	MutexGuard aGuard(m_aMutex);

	if( ! m_xDisplayConnection.is() )
	{
		/*
		 *	first argument must be a ::com::sun::star::awt::XDisplayConnection
		 *	from this we will get the XEvents of the vcl event loop by
		 *	registering us as XEventHandler on it.
		 *
		 *	implementor's note:
         *  FIXME:
         *  finally the clipboard and XDND service is back in the module it belongs
         *  now cleanup and sharing of resources with the normal vcl event loop
         *  needs to be added. The display used whould be that of the normal event loop
         *  and synchronization should be done via the SolarMutex.
		 */
		if( arguments.getLength() > 0 )
			arguments.getConstArray()[0] >>= m_xDisplayConnection;
		if( ! m_xDisplayConnection.is() )
		{
#if 0
			// for the time being try to live without XDisplayConnection
			// for the sake of clipboard service
			// clipboard service should be initialized with a XDisplayConnection
			// in the future
			Exception aExc;
			aExc.Message = OUString::createFromAscii( "initialize me with a valid XDisplayConnection" );
			aExc.Context = static_cast< OWeakObject* >(this);
			throw aExc;
#endif
		}
		else
			m_xDisplayConnection->addEventHandler( Any(), this, ~0 );
	}

    if( !m_xBitmapConverter.is() )
    {
        if( arguments.getLength() > 2 )
            arguments.getConstArray()[2] >>= m_xBitmapConverter;
    }

    OUString aParam;
	if( ! m_pDisplay )
	{
		OUString aUDisplay;
		if( m_xDisplayConnection.is() )
		{
			Any aIdentifier;
			aIdentifier = m_xDisplayConnection->getIdentifier();
			aIdentifier >>= aUDisplay;
		}

		OString aDisplayName( OUStringToOString( aUDisplay, RTL_TEXTENCODING_ISO_8859_1 ) );

		m_pDisplay = XOpenDisplay( aDisplayName.getLength() ? aDisplayName.getStr() : NULL );

		if( m_pDisplay )
		{
#ifdef SYNCHRONIZE
			XSynchronize( m_pDisplay, True );
#endif
			// clipboard selection
			m_nCLIPBOARDAtom	= getAtom( OUString::createFromAscii( "CLIPBOARD" ) );

			// special targets
			m_nTARGETSAtom		= getAtom( OUString::createFromAscii( "TARGETS" ) );
            m_nTIMESTAMPAtom    = getAtom( OUString::createFromAscii( "TIMESTAMP" ) );
			m_nTEXTAtom			= getAtom( OUString::createFromAscii( "TEXT" ) );
			m_nINCRAtom			= getAtom( OUString::createFromAscii( "INCR" ) );
            m_nCOMPOUNDAtom		= getAtom( OUString::createFromAscii( "COMPOUND_TEXT" ) );
            m_nMULTIPLEAtom		= getAtom( OUString::createFromAscii( "MULTIPLE" ) );
            m_nUTF16Atom		= getAtom( OUString::createFromAscii( "ISO10646-1" ) );
//            m_nUTF16Atom		= getAtom( OUString::createFromAscii( "text/plain;charset=ISO-10646-UCS-2" ) );
            m_nImageBmpAtom     = getAtom( OUString::createFromAscii( "image/bmp" ) );

			// Atoms for Xdnd protocol
			m_nXdndAware		= getAtom( OUString::createFromAscii( "XdndAware" ) );
			m_nXdndEnter		= getAtom( OUString::createFromAscii( "XdndEnter" ) );
			m_nXdndLeave		= getAtom( OUString::createFromAscii( "XdndLeave" ) );
			m_nXdndPosition		= getAtom( OUString::createFromAscii( "XdndPosition" ) );
			m_nXdndStatus		= getAtom( OUString::createFromAscii( "XdndStatus" ) );
			m_nXdndDrop			= getAtom( OUString::createFromAscii( "XdndDrop" ) );
			m_nXdndFinished		= getAtom( OUString::createFromAscii( "XdndFinished" ) );
			m_nXdndSelection	= getAtom( OUString::createFromAscii( "XdndSelection" ) );
			m_nXdndTypeList		= getAtom( OUString::createFromAscii( "XdndTypeList" ) );
			m_nXdndProxy		= getAtom( OUString::createFromAscii( "XdndProxy" ) );
			m_nXdndActionCopy	= getAtom( OUString::createFromAscii( "XdndActionCopy" ) );
			m_nXdndActionMove	= getAtom( OUString::createFromAscii( "XdndActionMove" ) );
			m_nXdndActionLink	= getAtom( OUString::createFromAscii( "XdndActionLink" ) );
			m_nXdndActionAsk	= getAtom( OUString::createFromAscii( "XdndActionAsk" ) );
			m_nXdndActionPrivate= getAtom( OUString::createFromAscii( "XdndActionPrivate" ) );

			// initialize map with member none
			m_aAtomToString[ 0 ]= OUString::createFromAscii( "None" );
            m_aAtomToString[ XA_PRIMARY ] = OUString::createFromAscii( "PRIMARY" );

			// create a (invisible) message window
			m_aWindow = XCreateSimpleWindow( m_pDisplay, DefaultRootWindow( m_pDisplay ),
											 10, 10, 10, 10, 0, 0, 1 );

            // initialize threshold for incremetal transfers
            // ICCCM says it should be smaller that the max request size
            // which in turn is guaranteed to be at least 16k bytes
            m_nIncrementalThreshold = XMaxRequestSize( m_pDisplay ) - 1024;

			if( m_aWindow )
			{
#define	createCursorFromXPM(name) createCursor((const char*)name##curs##_bits, (const char*)name##mask##_bits, name##curs_width, name##curs_height, name##curs_x_hot, name##curs_y_hot ); 
				// initialize default cursors
				m_aMoveCursor = createCursorFromXPM( movedata_);
				m_aCopyCursor = createCursorFromXPM( copydata_);
				m_aLinkCursor = createCursorFromXPM( linkdata_);
				m_aNoneCursor = createCursorFromXPM( nodrop_);

				// just interested in SelectionClear/Notify/Request and PropertyChange
				XSelectInput( m_pDisplay, m_aWindow, PropertyChangeMask );
				// create the transferable for Drag operations
				m_xDropTransferable = new X11Transferable( *this, static_cast< OWeakObject* >(this), m_nXdndSelection );
				registerHandler( m_nXdndSelection, *this );

				m_aThread = osl_createSuspendedThread( call_SelectionManager_run, this );
    			if( m_aThread )
        			osl_resumeThread( m_aThread );
#if OSL_DEBUG_LEVEL > 1
				else
					fprintf( stderr, "SelectionManager::initialize: creation of dispatch thread failed !\n" );
#endif
			}
		}
	}
}

// ------------------------------------------------------------------------

SelectionManager::~SelectionManager()
{
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "SelectionManager::~SelectionManager (%s)\n", m_pDisplay ? DisplayString(m_pDisplay) : "no display" );
#endif
	{
		MutexGuard aGuard( *Mutex::getGlobalMutex() );

		::std::hash_map< OUString, SelectionManager*, OUStringHash >::iterator it;
		for( it = getInstances().begin(); it != getInstances().end(); ++it )
			if( it->second == this )
			{
				getInstances().erase( it );
				break;
			}
	}
    
	if( m_aThread )
	{
		osl_terminateThread( m_aThread );
		osl_joinWithThread( m_aThread );
		osl_destroyThread( m_aThread );
	}

	if( m_aDragExecuteThread )
	{
		osl_terminateThread( m_aDragExecuteThread );
		osl_joinWithThread( m_aDragExecuteThread );
        m_aDragExecuteThread = NULL;
		// thread handle is freed in dragDoDispatch()
	}

	MutexGuard aGuard(m_aMutex);

#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "shutting down SelectionManager\n" );
#endif

    if( m_xDisplayConnection.is() )
    {
        m_xDisplayConnection->removeEventHandler( Any(), this );
        m_xDisplayConnection.clear();
    }

	if( m_pDisplay )
	{
		deregisterHandler( m_nXdndSelection );
		// destroy message window
		if( m_aWindow )
			XDestroyWindow( m_pDisplay, m_aWindow );
		// release cursors
		if (m_aMoveCursor != None)
			XFreeCursor(m_pDisplay, m_aMoveCursor);
		if (m_aCopyCursor != None)
			XFreeCursor(m_pDisplay, m_aCopyCursor);
		if (m_aLinkCursor != None)
			XFreeCursor(m_pDisplay, m_aLinkCursor);
		if (m_aNoneCursor != None)
			XFreeCursor(m_pDisplay, m_aNoneCursor);

        // paranoia setting, the drag thread should have
        // done that already
		XUngrabPointer( m_pDisplay, CurrentTime );
		XUngrabKeyboard( m_pDisplay, CurrentTime );

		XCloseDisplay( m_pDisplay );
	}
}

// ------------------------------------------------------------------------

SelectionAdaptor* SelectionManager::getAdaptor( Atom selection )
{
	::std::hash_map< Atom, Selection* >::iterator it =
		  m_aSelections.find( selection );
	return it != m_aSelections.end() ? it->second->m_pAdaptor : NULL;
}

// ------------------------------------------------------------------------

OUString SelectionManager::convertFromCompound( const char* pText, int nLen )
{
    MutexGuard aGuard( m_aMutex );
    OUString aRet;
    if( nLen < 0 )
        nLen = strlen( pText );

    char** pTextList = NULL;
    int nTexts = 0;

    XTextProperty aProp;
    aProp.value		= (unsigned char*)pText;
    aProp.encoding	= m_nCOMPOUNDAtom;
    aProp.format	= 8;
    aProp.nitems	= nLen;
    XmbTextPropertyToTextList( m_pDisplay,
                               &aProp,
                               &pTextList,
                               &nTexts );
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
    for( int i = 0; i < nTexts; i++ )
        aRet += OStringToOUString( pTextList[i], aEncoding );

    if( pTextList )
        XFreeStringList( pTextList );

    return aRet;
}

// ------------------------------------------------------------------------

OString SelectionManager::convertToCompound( const OUString& rText )
{
    MutexGuard aGuard( m_aMutex );
    XTextProperty aProp;
    aProp.value = NULL;
    aProp.encoding = XA_STRING;
    aProp.format = 8;
    aProp.nitems = 0;

    OString aRet( rText.getStr(), rText.getLength(), osl_getThreadTextEncoding() );
    char* pT = const_cast<char*>(aRet.getStr());

    XmbTextListToTextProperty( m_pDisplay,
                               &pT,
                               1,
                               XCompoundTextStyle,
                               &aProp );
    if( aProp.value )
    {
        aRet = (char*)aProp.value;
        XFree( aProp.value );
#ifdef SOLARIS
        /*  #97070#
         *  for currently unknown reasons XmbTextListToTextProperty on Solaris returns
         *  no data in ISO8859-n encodings (at least for n = 1, 15)
         *  in these encodings the directly converted text does the
         *  trick, also.
         */
        if( ! aRet.getLength() && rText.getLength() )
            aRet = OUStringToOString( rText, osl_getThreadTextEncoding() );
#endif
    }
    else
        aRet = OString();

    return aRet;
}

// ------------------------------------------------------------------------

bool SelectionManager::convertData(
                                   const css::uno::Reference< XTransferable >& xTransferable,
                                   Atom nType,
                                   Atom nSelection,
                                   int& rFormat,
                                   Sequence< sal_Int8 >& rData )
{
	bool bSuccess = false;

	if( ! xTransferable.is() )
		return bSuccess;

    try
    {

        DataFlavor aFlavor;
        aFlavor.MimeType = convertTypeFromNative( nType, nSelection, rFormat );

        sal_Int32 nIndex = 0;
        if( aFlavor.MimeType.getToken( 0, ';', nIndex ).compareToAscii( "text/plain" ) == 0 )
        {
            if( aFlavor.MimeType.getToken( 0, ';', nIndex ).compareToAscii( "charset=utf-16" ) == 0 )
                aFlavor.DataType = getCppuType( (OUString *) 0 );
            else
                aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 );
        }
        else
            aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 );

        if( xTransferable->isDataFlavorSupported( aFlavor ) )
        {
            Any aValue( xTransferable->getTransferData( aFlavor ) );
            if( aValue.getValueTypeClass() == TypeClass_STRING )
            {
                OUString aString;
                aValue >>= aString;
                rData = Sequence< sal_Int8 >( (sal_Int8*)aString.getStr(), aString.getLength() * sizeof( sal_Unicode ) );
                bSuccess = true;
            }
            else if( aValue.getValueType() == getCppuType( (Sequence< sal_Int8 >*)0 ) )
            {
                aValue >>= rData;
                bSuccess = true;
            }
        }
        else if( aFlavor.MimeType.compareToAscii( "text/plain", 10 ) == 0 )
        {
            rtl_TextEncoding aEncoding = RTL_TEXTENCODING_DONTKNOW;
            bool bCompoundText = false;
            if( nType == m_nCOMPOUNDAtom )
                bCompoundText = true;
            else
                aEncoding = getTextPlainEncoding( aFlavor.MimeType );
            if( aEncoding != RTL_TEXTENCODING_DONTKNOW || bCompoundText )
            {
                aFlavor.MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
                aFlavor.DataType = getCppuType( (OUString *) 0 );
                if( xTransferable->isDataFlavorSupported( aFlavor ) )
                {
                    Any aValue( xTransferable->getTransferData( aFlavor ) );
                    OUString aString;
                    aValue >>= aString;
                    OString aByteString( bCompoundText ? convertToCompound( aString ) : OUStringToOString( aString, aEncoding ) );
                    rData = Sequence< sal_Int8 >( (sal_Int8*)aByteString.getStr(), aByteString.getLength() * sizeof( sal_Char ) );
                    bSuccess = true;
                }
            }
        }
    }
    // various exceptions possible ... which all lead to a failed conversion
    // so simplify here to a catch all
    catch(...)
    {
    }

	return bSuccess;
}

// ------------------------------------------------------------------------

SelectionManager& SelectionManager::get( const OUString& rDisplayName )
{
	MutexGuard aGuard( *Mutex::getGlobalMutex() );

    OUString aDisplayName( rDisplayName );
    if( ! aDisplayName.getLength() )
        aDisplayName = OStringToOUString( getenv( "DISPLAY" ), RTL_TEXTENCODING_ISO_8859_1 );
	SelectionManager* pInstance = NULL;

	::std::hash_map< OUString, SelectionManager*, OUStringHash >::iterator it = getInstances().find( aDisplayName );
	if( it != getInstances().end() )
		pInstance = it->second;
	else pInstance = getInstances()[ aDisplayName ] = new SelectionManager();

	return *pInstance;
}

// ------------------------------------------------------------------------

const OUString& SelectionManager::getString( Atom aAtom )
{
	MutexGuard aGuard(m_aMutex);

	::std::hash_map< Atom, OUString >::const_iterator it;
	if( ( it = m_aAtomToString.find( aAtom ) ) == m_aAtomToString.end() )
	{
		static OUString aEmpty;
		char* pAtom = m_pDisplay ? XGetAtomName( m_pDisplay, aAtom ) : NULL;
		if( ! pAtom )
			return aEmpty;
		OUString aString( OStringToOUString( pAtom, RTL_TEXTENCODING_ISO_8859_1 ) );
		XFree( pAtom );
		m_aStringToAtom[ aString ] = aAtom;
		m_aAtomToString[ aAtom ] = aString;
	}
	return m_aAtomToString[ aAtom ];
}

// ------------------------------------------------------------------------

Atom SelectionManager::getAtom( const OUString& rString )
{
	MutexGuard aGuard(m_aMutex);

	::std::hash_map< OUString, Atom, OUStringHash >::const_iterator it;
	if( ( it = m_aStringToAtom.find( rString ) ) == m_aStringToAtom.end() )
	{
		static Atom nNoDisplayAtoms = 1;
		Atom aAtom = m_pDisplay ? XInternAtom( m_pDisplay, OUStringToOString( rString, RTL_TEXTENCODING_ISO_8859_1).getStr(), False ) : nNoDisplayAtoms++;
		m_aStringToAtom[ rString ] = aAtom;
		m_aAtomToString[ aAtom ] = rString;
	}
	return m_aStringToAtom[ rString ];
}

// ------------------------------------------------------------------------

bool SelectionManager::requestOwnership( Atom selection )
{
	bool bSuccess = false;
	if( m_pDisplay && m_aWindow )
	{
		MutexGuard aGuard(m_aMutex);

		SelectionAdaptor* pAdaptor = getAdaptor( selection );
		if( pAdaptor )
		{
			XSetSelectionOwner( m_pDisplay, selection, m_aWindow, CurrentTime );
			if( XGetSelectionOwner( m_pDisplay, selection ) == m_aWindow )
				bSuccess = true;
#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "%s ownership for selection %s\n",
					 bSuccess ? "acquired" : "failed to acquire",
					 OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
            Selection* pSel = m_aSelections[ selection ];
            pSel->m_bOwner = bSuccess;
            delete pSel->m_pPixmap;
            pSel->m_pPixmap = NULL;
            pSel->m_nOrigTimestamp = m_nSelectionTimestamp;
		}
#if OSL_DEBUG_LEVEL > 1
		else
			fprintf( stderr, "no adaptor for selection %s\n",
					 OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );

        if( pAdaptor->getTransferable().is() )
        {
            Sequence< DataFlavor > aTypes = pAdaptor->getTransferable()->getTransferDataFlavors();
            for( int i = 0; i < aTypes.getLength(); i++ )
            {
                fprintf( stderr, "   %s\n", OUStringToOString( aTypes.getConstArray()[i].MimeType, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
            }
        }
#endif
	}
	return bSuccess;
}

// ------------------------------------------------------------------------

void SelectionManager::convertTypeToNative( const OUString& rType, Atom selection, int& rFormat, ::std::list< Atom >& rConversions, bool bPushFront )
{
	NativeTypeEntry* pTab = selection == m_nXdndSelection ? aXdndConversionTab : aNativeConversionTab;
	int nTabEntries = selection == m_nXdndSelection
		? sizeof(aXdndConversionTab)/sizeof(aXdndConversionTab[0]) :
		sizeof(aNativeConversionTab)/sizeof(aNativeConversionTab[0]);

	OString aType( OUStringToOString( rType, RTL_TEXTENCODING_ISO_8859_1 ) );
    rFormat = 0;
	for( int i = 0; i < nTabEntries; i++ )
	{
		if( aType.equalsIgnoreAsciiCase( pTab[i].pType ) )
		{
			if( ! pTab[i].nAtom )
				pTab[i].nAtom = getAtom( OStringToOUString( pTab[i].pNativeType, RTL_TEXTENCODING_ISO_8859_1 ) );
			rFormat = pTab[i].nFormat;
            if( bPushFront )
                rConversions.push_front( pTab[i].nAtom );
            else
                rConversions.push_back( pTab[i].nAtom );
            if( pTab[i].nFormat == XA_PIXMAP )
            {
                if( bPushFront )
                {
                    rConversions.push_front( XA_VISUALID );
                    rConversions.push_front( XA_COLORMAP );
                }
                else
                {
                    rConversions.push_back( XA_VISUALID );
                    rConversions.push_back( XA_COLORMAP );
                }
            }
		}
	}
    if( ! rFormat )
        rFormat = 8; // byte buffer
    if( bPushFront )
        rConversions.push_front( getAtom( rType ) );
    else
        rConversions.push_back( getAtom( rType ) );
};

// ------------------------------------------------------------------------

void SelectionManager::getNativeTypeList( const Sequence< DataFlavor >& rTypes, std::list< Atom >& rOutTypeList, Atom targetselection )
{
    rOutTypeList.clear();

    int nFormat;
    int nFlavors = rTypes.getLength();
    const DataFlavor* pFlavors = rTypes.getConstArray();
    bool bHaveText = false;
    for( int i = 0; i < nFlavors; i++ )
    {
        if( pFlavors[i].MimeType.compareToAscii( "text/plain", 10 ) == 0)
            bHaveText = true;
        else
            convertTypeToNative( pFlavors[i].MimeType, targetselection, nFormat, rOutTypeList );
    }
    if( bHaveText )
    {
        if( targetselection != m_nXdndSelection )
        {
            // only mimetypes should go into Xdnd type list
            rOutTypeList.push_front( XA_STRING );
            rOutTypeList.push_front( m_nCOMPOUNDAtom );
        }
        convertTypeToNative( OUString::createFromAscii( "text/plain;charset=utf-8" ), targetselection, nFormat, rOutTypeList, true );
    }
    if( targetselection != m_nXdndSelection )
        rOutTypeList.push_back( m_nMULTIPLEAtom );
}

// ------------------------------------------------------------------------

OUString SelectionManager::convertTypeFromNative( Atom nType, Atom selection, int& rFormat )
{
	NativeTypeEntry* pTab = selection == m_nXdndSelection ? aXdndConversionTab : aNativeConversionTab;
	int nTabEntries = selection == m_nXdndSelection
		? sizeof(aXdndConversionTab)/sizeof(aXdndConversionTab[0]) :
		sizeof(aNativeConversionTab)/sizeof(aNativeConversionTab[0]);

	for( int i = 0; i < nTabEntries; i++ )
	{
		if( ! pTab[i].nAtom )
			pTab[i].nAtom = getAtom( OStringToOUString( pTab[i].pNativeType, RTL_TEXTENCODING_ISO_8859_1 ) );
		if( nType == pTab[i].nAtom )
        {
            rFormat = pTab[i].nFormat;
			return OStringToOUString( pTab[i].pType, RTL_TEXTENCODING_ISO_8859_1 );
        }
	}
    rFormat = 8;
	return getString( nType );
}

// ------------------------------------------------------------------------

bool SelectionManager::getPasteData( Atom selection, Atom type, Sequence< sal_Int8 >& rData )
{
    ResettableMutexGuard aGuard(m_aMutex);
	::std::hash_map< Atom, Selection* >::iterator it;
	bool bSuccess = false;

#if OSL_DEBUG_LEVEL > 1
    OUString aSelection( getString( selection ) );
    OUString aType( getString( type ) );
    fprintf( stderr, "getPasteData( %s, native: %s )\n",
             OUStringToOString( aSelection, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
             OUStringToOString( aType, RTL_TEXTENCODING_ISO_8859_1 ).getStr()
             );
#endif

    if( ! m_pDisplay )
        return false;

    it = m_aSelections.find( selection );
    if( it == m_aSelections.end() )
        return false;

    XLIB_Window aSelectionOwner = XGetSelectionOwner( m_pDisplay, selection );
    if( aSelectionOwner == None )
        return false;
    if( aSelectionOwner == m_aWindow )
    {
        // probably bad timing led us here
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "Innere Nabelschau\n" );
#endif
        return false;
    }

    // ICCCM recommends to destroy property before convert request unless
    // parameters are transported; we do only in case of MULTIPLE,
    // so destroy property unless target is MULTIPLE
    if( type != m_nMULTIPLEAtom )
        XDeleteProperty( m_pDisplay, m_aWindow, selection );

    XConvertSelection( m_pDisplay, selection, type, selection, m_aWindow, selection == m_nXdndSelection ? m_nDropTime : CurrentTime );
    it->second->m_eState			= Selection::WaitingForResponse;
    it->second->m_aRequestedType	= type;
    it->second->m_aData				= Sequence< sal_Int8 >();
    it->second->m_aDataArrived.reset();
    // really start the request; if we don't flush the
    // queue the request won't leave it because there are no more
    // X calls after this until the data arrived or timeout
    XFlush( m_pDisplay );
    
	// do a reschedule
    struct timeval tv_last, tv_current;
    gettimeofday( &tv_last, NULL );
    tv_current = tv_last;
    
    XEvent aEvent;
	do
	{
        bool bAdjustTime = false;
        {
            bool bHandle = false;

            if( XCheckTypedEvent( m_pDisplay,
                                  PropertyNotify,
                                  &aEvent
                                  ) )
            {
                bHandle = true;
                if( aEvent.xproperty.window == m_aWindow
                    && aEvent.xproperty.atom == selection )
                    bAdjustTime = true;
            }
            else
            if( XCheckTypedEvent( m_pDisplay,
                                  SelectionClear,
                                  &aEvent
                                  ) )
            {
                bHandle = true;
            }
            else
            if( XCheckTypedEvent( m_pDisplay,
                                  SelectionRequest,
                                  &aEvent
                                  ) )
                bHandle = true;
            else
            if( XCheckTypedEvent( m_pDisplay,
                                  SelectionNotify,
                                  &aEvent
                                  ) )
            {
                bHandle = true;
                if( aEvent.xselection.selection == selection
                    && ( aEvent.xselection.requestor == m_aWindow ||
                         aEvent.xselection.requestor == m_aCurrentDropWindow )
                    )
                    bAdjustTime = true;
            }
            else
            {
                TimeValue aTVal;
                aTVal.Seconds = 0;
                aTVal.Nanosec = 100000000;
                aGuard.clear();
                osl_waitThread( &aTVal );
                aGuard.reset();
            }
            if( bHandle )
            {
                aGuard.clear();
                handleXEvent( aEvent );
                aGuard.reset();
            }
        }
        gettimeofday( &tv_current, NULL );
        if( bAdjustTime )
            tv_last = tv_current;
	} while( ! it->second->m_aDataArrived.check() && (tv_current.tv_sec - tv_last.tv_sec) < getSelectionTimeout() );

#if OSL_DEBUG_LEVEL > 1
    if( (tv_current.tv_sec - tv_last.tv_sec) > getSelectionTimeout() )
        fprintf( stderr, "timed out\n" );
#endif
	if( it->second->m_aDataArrived.check() &&
		it->second->m_aData.getLength() )
	{
		rData = it->second->m_aData;
		bSuccess = true;
	}
#if OSL_DEBUG_LEVEL > 1
    else
        fprintf( stderr, "conversion unsuccessful\n" );
#endif
	return bSuccess;
}

// ------------------------------------------------------------------------

bool SelectionManager::getPasteData( Atom selection, const ::rtl::OUString& rType, Sequence< sal_Int8 >& rData )
{
	int nFormat;
	bool bSuccess = false;

    ::std::hash_map< Atom, Selection* >::iterator it;
    {
        MutexGuard aGuard(m_aMutex);

        it = m_aSelections.find( selection );
        if( it == m_aSelections.end() )
            return false;
    }

    if( it->second->m_aTypes.getLength() == 0 )
    {
        Sequence< DataFlavor > aFlavors;
        getPasteDataTypes( selection, aFlavors );
        if( it->second->m_aTypes.getLength() == 0 )
            return false;
    }

    const Sequence< DataFlavor >& rTypes( it->second->m_aTypes );
    const std::vector< Atom >& rNativeTypes( it->second->m_aNativeTypes );
#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "getPasteData( \"%s\", \"%s\" )\n",
             OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
             OUStringToOString( rType, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif

	if( rType.equalsAsciiL( "text/plain;charset=utf-16", 25 ) )
	{
		// lets see if we have UTF16 else try to find something convertible
		if( it->second->m_aTypes.getLength() && ! it->second->m_bHaveUTF16 )
		{
			Sequence< sal_Int8 > aData;
			if( it->second->m_aUTF8Type != None &&
				getPasteData( selection,
							  it->second->m_aUTF8Type,
							  aData )
				)
			{
			  OUString aRet( (const sal_Char*)aData.getConstArray(), aData.getLength(), RTL_TEXTENCODING_UTF8 );
			  rData = Sequence< sal_Int8 >( (sal_Int8*)aRet.getStr(), (aRet.getLength()+1)*sizeof( sal_Unicode ) );
			  bSuccess = true;
			}
            else if( it->second->m_bHaveCompound &&
                getPasteData( selection,
                              m_nCOMPOUNDAtom,
                              aData )
                )
            {
                OUString aRet( convertFromCompound( (const char*)aData.getConstArray(), aData.getLength() ) );
                rData = Sequence< sal_Int8 >( (sal_Int8*)aRet.getStr(), (aRet.getLength()+1)*sizeof( sal_Unicode ) );
                bSuccess = true;
            }
            else
            {
                for( int i = 0; i < rTypes.getLength(); i++ )
                {
                    rtl_TextEncoding aEncoding = getTextPlainEncoding( rTypes.getConstArray()[i].MimeType );
                    if( aEncoding != RTL_TEXTENCODING_DONTKNOW	&&
                        aEncoding != RTL_TEXTENCODING_UNICODE	&&
                        getPasteData( selection,
                                      rNativeTypes[i],
                                      aData )
                        )
                    {
#if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "using \"%s\" instead of \"%s\"\n",
                                 OUStringToOString( rTypes.getConstArray()[i].MimeType, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                                 OUStringToOString( rType, RTL_TEXTENCODING_ISO_8859_1 ).getStr()
                                 );
#endif
                        OString aConvert( (sal_Char*)aData.getConstArray(), aData.getLength() );
                        OUString aUTF( OStringToOUString( aConvert, aEncoding ) );
                        rData = Sequence< sal_Int8 >( (sal_Int8*)aUTF.getStr(), (aUTF.getLength()+1)*sizeof( sal_Unicode ) );
                        bSuccess = true;
                        break;
                    }
                }
            }
        }
    }
    else if( rType.equalsAsciiL( "image/bmp", 9 ) )
    {
        // #i83376# try if someone has the data in image/bmp already before
        // doing the PIXMAP stuff (e.g. the gimp has this)
        bSuccess = getPasteData( selection, m_nImageBmpAtom, rData );
        #if OSL_DEBUG_LEVEL > 1
        if( bSuccess )
            fprintf( stderr, "got %d bytes of image/bmp\n", (int)rData.getLength() );
        #endif
        if( ! bSuccess )
        {
            Pixmap aPixmap = None;
            Colormap aColormap = None;
            
            // prepare property for MULTIPLE request
            Sequence< sal_Int8 > aData;
            Atom pTypes[4] = { XA_PIXMAP, XA_PIXMAP,
            XA_COLORMAP, XA_COLORMAP };
            {
                MutexGuard aGuard(m_aMutex);
                
                XChangeProperty( m_pDisplay,
                    m_aWindow,
                    selection,
                    XA_ATOM,
                    32,
                    PropModeReplace,
                    (unsigned char*)pTypes,
                    4 );
            }
            
            // try MULTIPLE request
            if( getPasteData( selection, m_nMULTIPLEAtom, aData ) )
            {
                Atom* pReturnedTypes = (Atom*)aData.getArray();
                if( pReturnedTypes[0] == XA_PIXMAP && pReturnedTypes[1] == XA_PIXMAP )
                {
                    MutexGuard aGuard(m_aMutex);
                    
                    Atom type = None;
                    int format = 0;
                    unsigned long nItems = 0;
                    unsigned long nBytes = 0;
                    unsigned char* pReturn = NULL;
                    XGetWindowProperty( m_pDisplay, m_aWindow, XA_PIXMAP, 0, 1, True, XA_PIXMAP, &type, &format, &nItems, &nBytes, &pReturn );
                    if( pReturn )
                    {
                        if( type == XA_PIXMAP )
                            aPixmap = *(Pixmap*)pReturn;
                        XFree( pReturn );
                        pReturn = NULL;
                        if( pReturnedTypes[2] == XA_COLORMAP && pReturnedTypes[3] == XA_COLORMAP )
                        {
                            XGetWindowProperty( m_pDisplay, m_aWindow, XA_COLORMAP, 0, 1, True, XA_COLORMAP, &type, &format, &nItems, &nBytes, &pReturn );
                            if( pReturn )
                            {
                                if( type == XA_COLORMAP )
                                    aColormap = *(Colormap*)pReturn;
                                XFree( pReturn );
                            }
                        }
                    }
                    #if OSL_DEBUG_LEVEL > 1
                    else
                    {
                        fprintf( stderr, "could not get PIXMAP property: type=%s, format=%d, items=%ld, bytes=%ld, ret=0x%p\n", OUStringToOString( getString( type ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(), format, nItems, nBytes, pReturn );
                    }
                    #endif
                }
            }
            
            if( aPixmap == None )
            {
                // perhaps two normal requests will work
                if( getPasteData( selection, XA_PIXMAP, aData ) )
                {
                    aPixmap = *(Pixmap*)aData.getArray();
                    if( aColormap == None && getPasteData( selection, XA_COLORMAP, aData ) )
                        aColormap = *(Colormap*)aData.getArray();
                }
            }
            
            // convert data if possible
            if( aPixmap != None )
            {
                MutexGuard aGuard(m_aMutex);
                
                sal_Int32 nOutSize = 0;
                sal_uInt8* pBytes = X11_getBmpFromPixmap( m_pDisplay, aPixmap, aColormap, nOutSize );
                if( pBytes && nOutSize )
                {
                    rData = Sequence< sal_Int8 >( nOutSize );
                    memcpy( rData.getArray(), pBytes, nOutSize );
                    X11_freeBmp( pBytes );
                    bSuccess = true;
                }
            }
        }
    }

	if( ! bSuccess )
    {
        ::std::list< Atom > aTypes;
        convertTypeToNative( rType, selection, nFormat, aTypes );
        ::std::list< Atom >::const_iterator type_it;
        Atom nSelectedType = None;
        for( type_it = aTypes.begin(); type_it != aTypes.end() && nSelectedType == None; ++type_it )
        {
            for( unsigned int i = 0; i < rNativeTypes.size() && nSelectedType == None; i++ )
                if( rNativeTypes[i] == *type_it )
                    nSelectedType = *type_it;
        }
        if( nSelectedType != None )
            bSuccess = getPasteData( selection, nSelectedType, rData );
    }
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "getPasteData for selection %s and data type %s returns %s, returned sequence has length %ld\n",
			 OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
			 OUStringToOString( rType, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
			 bSuccess ? "true" : "false",
			 rData.getLength()
			 );
#endif
	return bSuccess;
}

// ------------------------------------------------------------------------

bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >& rTypes )
{
	::std::hash_map< Atom, Selection* >::iterator it;
	{
		MutexGuard aGuard(m_aMutex);

		it = m_aSelections.find( selection );
		if( it != m_aSelections.end()							&&
			it->second->m_aTypes.getLength()					&&
			abs( it->second->m_nLastTimestamp - time( NULL ) ) < 2
			)
		{
			rTypes = it->second->m_aTypes;
			return true;
		}
	}

	bool bSuccess = false;
	bool bHaveUTF16 = false;
	Atom aUTF8Type = None;
    bool bHaveCompound = false;
	bool bHaveText = false;
	Sequence< sal_Int8 > aAtoms;

	if( selection == m_nXdndSelection )
	{
		// xdnd sends first three types with XdndEnter
		// if more than three types are supported then the XDndTypeList
		// property on the source window is used
		if( m_aDropEnterEvent.data.l[0] && m_aCurrentDropWindow )
		{
			if( m_aDropEnterEvent.data.l[1] & 1 )
			{
				const unsigned int atomcount = 256;
				// more than three types; look in property
				MutexGuard aGuard(m_aMutex);

				Atom nType;
				int nFormat;
				unsigned long nItems, nBytes;
				unsigned char* pBytes = NULL;

				XGetWindowProperty( m_pDisplay, m_aDropEnterEvent.data.l[0],
									m_nXdndTypeList, 0, atomcount, False,
									XA_ATOM,
									&nType, &nFormat, &nItems, &nBytes, &pBytes );
#if OSL_DEBUG_LEVEL > 1
				fprintf( stderr, "have %ld data types in XdndTypeList\n", nItems );
#endif
				if( nItems == atomcount && nBytes > 0 )
				{
					// wow ... more than 256 types !
					aAtoms.realloc( sizeof( Atom )*atomcount+nBytes );
					memcpy( aAtoms.getArray(), pBytes, sizeof( Atom )*atomcount );
					XFree( pBytes );
					pBytes = NULL;
					XGetWindowProperty( m_pDisplay, m_aDropEnterEvent.data.l[0],
										m_nXdndTypeList, atomcount, nBytes/sizeof(Atom),
										False, XA_ATOM,
										&nType, &nFormat, &nItems, &nBytes, &pBytes );
					{
						memcpy( aAtoms.getArray()+atomcount*sizeof(Atom), pBytes, nItems*sizeof(Atom) );
						XFree( pBytes );
					}
				}
				else
				{
					aAtoms.realloc( sizeof(Atom)*nItems );
					memcpy( aAtoms.getArray(), pBytes, nItems*sizeof(Atom) );
					XFree( pBytes );
				}
			}
			else
			{
				// one to three types
				int n = 0, i;
				for( i = 0; i < 3; i++ )
					if( m_aDropEnterEvent.data.l[2+i] )
						n++;
#if OSL_DEBUG_LEVEL > 1
				fprintf( stderr, "have %d data types in XdndEnter\n", n );
#endif
				aAtoms.realloc( sizeof(Atom)*n );
				for( i = 0, n = 0; i < 3; i++ )
					if( m_aDropEnterEvent.data.l[2+i] )
						((Atom*)aAtoms.getArray())[n++] = m_aDropEnterEvent.data.l[2+i];
			}
		}
	}
	// get data of type TARGETS
	else if( ! getPasteData( selection, m_nTARGETSAtom, aAtoms ) )
		aAtoms = Sequence< sal_Int8 >();

	std::vector< Atom > aNativeTypes;
	if( aAtoms.getLength() )
	{
		sal_Int32 nAtoms = aAtoms.getLength() / sizeof(Atom);
		Atom* pAtoms = (Atom*)aAtoms.getArray();
		rTypes.realloc( nAtoms );
		aNativeTypes.resize( nAtoms );
		DataFlavor* pFlavors = rTypes.getArray();
		sal_Int32 nNativeTypesIndex = 0;
		while( nAtoms-- )
		{
#if OSL_DEBUG_LEVEL > 1
            if( *pAtoms && *pAtoms < 0x01000000 )
                fprintf( stderr, "native type: %s\n", OUStringToOString( getString( *pAtoms ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
            if( *pAtoms == m_nCOMPOUNDAtom )
                bHaveText = bHaveCompound = true;
			else if( *pAtoms && *pAtoms < 0x01000000 )
			{
                int nFormat;
				pFlavors->MimeType = convertTypeFromNative( *pAtoms, selection, nFormat );
				pFlavors->DataType = getCppuType( (Sequence< sal_Int8 >*)0 );
                sal_Int32 nIndex = 0;
				if( pFlavors->MimeType.getToken( 0, ';', nIndex ).equalsAsciiL( "text/plain", 10 ) )
				{
                    OUString aToken(pFlavors->MimeType.getToken( 0, ';', nIndex ));
                    // omit text/plain;charset=unicode since it is not well defined
					if( aToken.compareToAscii( "charset=unicode" ) == 0 )
                    {
                        pAtoms++;
                        continue;
                    }
					bHaveText = true;
					if( aToken.compareToAscii( "charset=utf-16" ) == 0 )
					{
						bHaveUTF16 = true;
						pFlavors->DataType = getCppuType( (OUString*)0 );
					}
					else if( aToken.compareToAscii( "charset=utf-8" ) == 0 )
					{
					    aUTF8Type = *pAtoms;
					}
				}
                pFlavors++;
                aNativeTypes[ nNativeTypesIndex ] = *pAtoms;
                nNativeTypesIndex++;
			}
			pAtoms++;
		}
        if( (pFlavors - rTypes.getArray()) < rTypes.getLength() )
            rTypes.realloc(pFlavors - rTypes.getArray());
		bSuccess = rTypes.getLength() ? true : false;
		if( bHaveText && ! bHaveUTF16 )
		{
               int i = 0;

			int nNewFlavors = rTypes.getLength()+1;
			Sequence< DataFlavor > aTemp( nNewFlavors );
			for( i = 0; i < nNewFlavors-1; i++ )
				aTemp.getArray()[i+1] = rTypes.getConstArray()[i];
			aTemp.getArray()[0].MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
			aTemp.getArray()[0].DataType = getCppuType( (OUString*)0 );
			rTypes = aTemp;

			std::vector< Atom > aNativeTemp( nNewFlavors );
			for( i = 0; i < nNewFlavors-1; i++ )
				aNativeTemp[ i + 1 ] = aNativeTypes[ i ];
			aNativeTemp[0] = None;
			aNativeTypes = aNativeTemp;
		}
	}

	{
		MutexGuard aGuard(m_aMutex);

		it = m_aSelections.find( selection );
		if( it != m_aSelections.end() )
		{
			if( bSuccess )
			{
				it->second->m_aTypes			= rTypes;
                it->second->m_aNativeTypes		= aNativeTypes;
				it->second->m_nLastTimestamp	= time( NULL );
				it->second->m_bHaveUTF16		= bHaveUTF16;
				it->second->m_aUTF8Type         = aUTF8Type;
                it->second->m_bHaveCompound		= bHaveCompound;
			}
			else
			{
				it->second->m_aTypes			= Sequence< DataFlavor >();
				it->second->m_aNativeTypes		= std::vector< Atom >();
				it->second->m_nLastTimestamp	= 0;
				it->second->m_bHaveUTF16		= false;
				it->second->m_aUTF8Type         = None;
                it->second->m_bHaveCompound		= false;
			}
		}
	}

#if OSL_DEBUG_LEVEL > 1
//    if( selection != m_nCLIPBOARDAtom )
    {
        fprintf( stderr, "SelectionManager::getPasteDataTypes( %s ) = %s\n", OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(), bSuccess ? "true" : "false" );
        for( int i = 0; i < rTypes.getLength(); i++ )
            fprintf( stderr, "type: %s\n", OUStringToOString( rTypes.getConstArray()[i].MimeType, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
    }
#endif

	return bSuccess;
}

// ------------------------------------------------------------------------

PixmapHolder* SelectionManager::getPixmapHolder( Atom selection )
{
    std::hash_map< Atom, Selection* >::const_iterator it = m_aSelections.find( selection );
    if( it == m_aSelections.end() )
        return NULL;
    if( ! it->second->m_pPixmap )
        it->second->m_pPixmap = new PixmapHolder( m_pDisplay );
    return it->second->m_pPixmap;
}

static sal_Size GetTrueFormatSize(int nFormat)
{
	// http://mail.gnome.org/archives/wm-spec-list/2003-March/msg00067.html
	return nFormat == 32 ? sizeof(long) : nFormat/8;	
}

bool SelectionManager::sendData( SelectionAdaptor* pAdaptor,
                                 XLIB_Window requestor,
                                 Atom target,
                                 Atom property,
                                 Atom selection )
{
    ResettableMutexGuard aGuard( m_aMutex );

    // handle targets related to image/bmp
    if( target == XA_COLORMAP || target == XA_PIXMAP || target == XA_BITMAP || target == XA_VISUALID )
    {
        PixmapHolder* pPixmap = getPixmapHolder( selection );
        if( ! pPixmap ) return false;
        XID nValue = None;

        // handle colormap request
        if( target == XA_COLORMAP )
            nValue = (XID)pPixmap->getColormap();
        else if( target == XA_VISUALID )
            nValue = (XID)pPixmap->getVisualID();
        else if( target == XA_PIXMAP || target == XA_BITMAP )
        {
            nValue = (XID)pPixmap->getPixmap();
            if( nValue == None )
            {
                // first conversion
                Sequence< sal_Int8 > aData;
                int nFormat;
                aGuard.clear();
                bool bConverted = convertData( pAdaptor->getTransferable(), target, selection, nFormat, aData );
                aGuard.reset();
                if( bConverted )
                {
				    // get pixmap again since clearing the guard could have invalidated
					// the pixmap in another thread
        			pPixmap = getPixmapHolder( selection );
                    // conversion succeeded, so aData contains image/bmp now
                    if( pPixmap->needsConversion( (const sal_uInt8*)aData.getConstArray() )
                        && m_xBitmapConverter.is() )
                    {
#if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "trying bitmap conversion\n" );
#endif
                        css::uno::Reference<XBitmap> xBM( new BmpTransporter( aData ) );
                        Sequence<Any> aArgs(2), aOutArgs;
                        Sequence<sal_Int16> aOutIndex;
                        aArgs.getArray()[0] = makeAny( xBM );
                        aArgs.getArray()[1] = makeAny( (sal_uInt16)pPixmap->getDepth() );
                        aGuard.clear();
                        try
                        {
                            Any aResult =
                                m_xBitmapConverter->invoke( OUString::createFromAscii( "convert-bitmap-depth" ),
                                                            aArgs, aOutIndex, aOutArgs );
                            if( aResult >>= xBM )
                                aData = xBM->getDIB();
                        }
                        catch(...)
                        {
#if OSL_DEBUG_LEVEL > 1
                            fprintf( stderr, "exception in bitmap converter\n" );
#endif
                        }
                        aGuard.reset();
                    }
				    // get pixmap again since clearing the guard could have invalidated
					// the pixmap in another thread
        			pPixmap = getPixmapHolder( selection );
                    nValue = (XID)pPixmap->setBitmapData( (const sal_uInt8*)aData.getConstArray() );
                }
                if( nValue == None )
                    return false;
            }
            if( target == XA_BITMAP )
                nValue = (XID)pPixmap->getBitmap();
        }

        XChangeProperty( m_pDisplay,
                         requestor,
                         property,
                         target,
                         32,
                         PropModeReplace,
                         (const unsigned char*)&nValue,
                         1);
        return true;
    }

    /*
     *  special target TEXT allows us to transfer
     *  the data in an encoding of our choice
     *  COMPOUND_TEXT will work with most applications
     */
    if( target == m_nTEXTAtom )
        target = m_nCOMPOUNDAtom;

    Sequence< sal_Int8 > aData;
    int nFormat;
    aGuard.clear();
    bool bConverted = convertData( pAdaptor->getTransferable(), target, selection, nFormat, aData );
    aGuard.reset();
    if( bConverted )
    {
        // conversion succeeded
        if( aData.getLength() > m_nIncrementalThreshold )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "using INCR protocol\n" );
            std::hash_map< XLIB_Window, std::hash_map< Atom, IncrementalTransfer > >::const_iterator win_it = m_aIncrementals.find( requestor );
            if( win_it != m_aIncrementals.end() )
            {
                std::hash_map< Atom, IncrementalTransfer >::const_iterator inc_it = win_it->second.find( property );
                if( inc_it != win_it->second.end() )
                {
                    const IncrementalTransfer& rInc = inc_it->second;
                    fprintf( stderr, "premature end and new start for INCR transfer for window 0x%lx, property %s, type %s\n",
                             rInc.m_aRequestor,
                             OUStringToOString( getString( rInc.m_aProperty ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                             OUStringToOString( getString( rInc.m_aTarget ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
                             );
                }
            }
#endif

            // insert IncrementalTransfer
            IncrementalTransfer& rInc	= m_aIncrementals[ requestor ][ property ];
            rInc.m_aData				= aData;
            rInc.m_nBufferPos			= 0;
            rInc.m_aRequestor			= requestor;
            rInc.m_aProperty			= property;
            rInc.m_aTarget				= target;
            rInc.m_nFormat				= nFormat;
            rInc.m_nTransferStartTime	= time( NULL );

            // use incr protocol, signal start to requestor
            long nMinSize = m_nIncrementalThreshold;
            XSelectInput( m_pDisplay, requestor, PropertyChangeMask );
            XChangeProperty( m_pDisplay, requestor, property,
                             m_nINCRAtom, 32,  PropModeReplace, (unsigned char*)&nMinSize, 1 );
            XFlush( m_pDisplay );
        }
        else
        {
            sal_Size nUnitSize = GetTrueFormatSize(nFormat);
            XChangeProperty( m_pDisplay,
                             requestor,
                             property,
                             target,
                             nFormat,
                             PropModeReplace,
                             (const unsigned char*)aData.getConstArray(),
                             aData.getLength()/nUnitSize );
            }
    }
#if OSL_DEBUG_LEVEL > 1
    else
        fprintf( stderr, "convertData failed for type: %s \n",
                 OUStringToOString( convertTypeFromNative( target, selection, nFormat ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
    return bConverted;
}

// ------------------------------------------------------------------------

bool SelectionManager::handleSelectionRequest( XSelectionRequestEvent& rRequest )
{
    ResettableMutexGuard aGuard( m_aMutex );
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "handleSelectionRequest for selection %s and target %s\n",
			 OUStringToOString( getString( rRequest.selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
			 OUStringToOString( getString( rRequest.target ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
			 );
#endif

	XEvent aNotify;

	aNotify.type                  = SelectionNotify;
	aNotify.xselection.display    = rRequest.display;
	aNotify.xselection.send_event = True;
	aNotify.xselection.requestor  = rRequest.requestor;
	aNotify.xselection.selection  = rRequest.selection;
	aNotify.xselection.time       = rRequest.time;
	aNotify.xselection.target     = rRequest.target;
	aNotify.xselection.property   = None;

	SelectionAdaptor* pAdaptor = getAdaptor( rRequest.selection );
	// ensure that we still own that selection
	if( pAdaptor &&
		XGetSelectionOwner( m_pDisplay, rRequest.selection ) == m_aWindow )
	{
        css::uno::Reference< XTransferable > xTrans( pAdaptor->getTransferable() );
		if( rRequest.target == m_nTARGETSAtom )
		{
			// someone requests our types
			if( xTrans.is() )
			{
                aGuard.clear();
				Sequence< DataFlavor > aFlavors = xTrans->getTransferDataFlavors();
                aGuard.reset();

                ::std::list< Atom > aConversions;
                getNativeTypeList( aFlavors, aConversions, rRequest.selection );

                int i, nTypes = aConversions.size();
				Atom* pTypes = (Atom*)alloca( nTypes * sizeof( Atom ) );
                std::list< Atom >::const_iterator it;
				for( i = 0, it = aConversions.begin(); i < nTypes; i++, ++it )
					pTypes[i] = *it;
				XChangeProperty( m_pDisplay, rRequest.requestor, rRequest.property,
								 XA_ATOM, 32, PropModeReplace, (const unsigned char*)pTypes, nTypes );
				aNotify.xselection.property = rRequest.property;
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "sending type list:\n" );
                for( int k = 0; k < nTypes; k++ )
                    fprintf( stderr, "   %s\n", pTypes[k] ? XGetAtomName( m_pDisplay, pTypes[k] ) : "<None>" );
#endif
			}
		}
        else if( rRequest.target == m_nTIMESTAMPAtom )
        {
            long nTimeStamp = (long)m_aSelections[rRequest.selection]->m_nOrigTimestamp;
            XChangeProperty( m_pDisplay, rRequest.requestor, rRequest.property,
                             XA_INTEGER, 32, PropModeReplace, (const unsigned char*)&nTimeStamp, 1 );
            aNotify.xselection.property = rRequest.property;
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "sending timestamp: %d\n", (int)nTimeStamp );
#endif
        }
		else
		{
            bool bEventSuccess = false;
            if( rRequest.target == m_nMULTIPLEAtom )
            {
                // get all targets
                Atom nType = None;
                int nFormat = 0;
                unsigned long nItems = 0, nBytes = 0;
                unsigned char* pData = NULL;

                // get number of atoms
                XGetWindowProperty( m_pDisplay,
                                    rRequest.requestor,
                                    rRequest.property,
                                    0, 0,
                                    False,
                                    AnyPropertyType,
                                    &nType, &nFormat,
                                    &nItems, &nBytes,
                                    &pData );
                if( nFormat == 32 && nBytes/4 )
                {
                    if( pData ) // ?? should not happen
                    {
                        XFree( pData );
                        pData = NULL;
                    }
                    XGetWindowProperty( m_pDisplay,
                                        rRequest.requestor,
                                        rRequest.property,
                                        0, nBytes/4,
                                        False,
                                        nType,
                                        &nType, &nFormat,
                                        &nItems, &nBytes,
                                        &pData );
                    if( pData && nItems )
                    {
#if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "found %ld atoms in MULTIPLE request\n", nItems );
#endif
                        bEventSuccess = true;
                        bool bResetAtoms = false;
                        Atom* pAtoms = (Atom*)pData;
                        aGuard.clear();
                        for( unsigned int i = 0; i < nItems; i += 2 )
                        {
#if OSL_DEBUG_LEVEL > 1
                            fprintf( stderr, "   %s => %s: ",
                                     OUStringToOString( getString( pAtoms[i] ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                                     OUStringToOString( getString( pAtoms[i+1] ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
                            bool bSuccess = sendData( pAdaptor, rRequest.requestor, pAtoms[i], pAtoms[i+1], rRequest.selection );
#if OSL_DEBUG_LEVEL > 1
                            fprintf( stderr, "%s\n", bSuccess ? "succeeded" : "failed" );
#endif
                            if( ! bSuccess )
                            {
                                pAtoms[i] = None;
                                bResetAtoms = true;
                            }
                        }
                        aGuard.reset();
                        if( bResetAtoms )
                            XChangeProperty( m_pDisplay,
                                             rRequest.requestor,
                                             rRequest.property,
                                             XA_ATOM,
                                             32,
                                             PropModeReplace,
                                             pData,
                                             nBytes/4 );
                    }
                    if( pData )
                        XFree( pData );
                }
#if OSL_DEBUG_LEVEL > 1
                else
                {
                    fprintf( stderr, "could not get type list from \"%s\" of type \"%s\" on requestor 0x%lx, requestor has properties:",
                             OUStringToOString( getString( rRequest.property ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                             OUStringToOString( getString( nType ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                             rRequest.requestor );
                    int nProps = 0;
                    Atom* pProps = XListProperties( m_pDisplay, rRequest.requestor, &nProps );
                    if( pProps )
                    {
                        for( int i = 0; i < nProps; i++ )
                            fprintf( stderr, " \"%s\"", OUStringToOString( getString( pProps[i]), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
                        XFree( pProps );
                    }
                }
#endif
            }
            else
            {
                aGuard.clear();
                bEventSuccess = sendData( pAdaptor, rRequest.requestor, rRequest.target, rRequest.property, rRequest.selection );
                aGuard.reset();
            }
            if( bEventSuccess )
            {
                aNotify.xselection.target = rRequest.target;
                aNotify.xselection.property = rRequest.property;
            }
		}
        aGuard.clear();
        xTrans.clear();
        aGuard.reset();
	}
	XSendEvent( m_pDisplay, rRequest.requestor, False, 0, &aNotify );

	if( rRequest.selection == XA_PRIMARY	&&
		m_bWaitingForPrimaryConversion		&&
		m_xDragSourceListener.is() )
	{
		DragSourceDropEvent dsde;
		dsde.Source					= static_cast< OWeakObject* >(this);
		dsde.DragSourceContext		= new DragSourceContext( m_aDropWindow, rRequest.time, *this );
		dsde.DragSource				= static_cast< XDragSource* >(this);
		if( aNotify.xselection.property != None )
		{
			dsde.DropAction			= DNDConstants::ACTION_COPY;
			dsde.DropSuccess		= sal_True;
		}
		else
		{
			dsde.DropAction			= DNDConstants::ACTION_NONE;
			dsde.DropSuccess		= sal_False;
		}
        css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
		m_xDragSourceListener.clear();
        aGuard.clear();
        if( xListener.is() )
            xListener->dragDropEnd( dsde );
	}

    // we handled the event in any case by answering
    return true;
}

// ------------------------------------------------------------------------

bool SelectionManager::handleReceivePropertyNotify( XPropertyEvent& rNotify )
{
    MutexGuard aGuard( m_aMutex );
	// data we requested arrived
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "handleReceivePropertyNotify for property %s\n",
			 OUStringToOString( getString( rNotify.atom ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
    bool bHandled = false;

	::std::hash_map< Atom, Selection* >::iterator it =
		  m_aSelections.find( rNotify.atom );
	if( it != m_aSelections.end() &&
		rNotify.state == PropertyNewValue &&
		( it->second->m_eState == Selection::WaitingForResponse		||
		  it->second->m_eState == Selection::WaitingForData 		||
		  it->second->m_eState == Selection::IncrementalTransfer
		  )
		)
	{
        // MULTIPLE requests are only complete after selection notify
        if( it->second->m_aRequestedType == m_nMULTIPLEAtom &&
            ( it->second->m_eState == Selection::WaitingForResponse ||
              it->second->m_eState == Selection::WaitingForData ) )
            return false;

        bHandled = true;

		Atom nType = None;
		int nFormat = 0;
		unsigned long nItems = 0, nBytes = 0;
		unsigned char* pData = NULL;

		// get type and length
		XGetWindowProperty( m_pDisplay,
							rNotify.window,
							rNotify.atom,
							0, 0,
							False,
							AnyPropertyType,
							&nType, &nFormat,
							&nItems, &nBytes,
							&pData );
#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "found %ld bytes data of type %s and format %d, items = %ld\n",
				 nBytes,
				 OUStringToOString( getString( nType ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
				 nFormat, nItems );
#endif
		if( pData )
		{
			XFree( pData );
			pData = NULL;
		}

		if( nType == m_nINCRAtom )
		{
			// start data transfer
			XDeleteProperty( m_pDisplay, rNotify.window, rNotify.atom );
			it->second->m_eState = Selection::IncrementalTransfer;
		}
		else if( nType != None )
		{
			XGetWindowProperty( m_pDisplay,
								rNotify.window,
								rNotify.atom,
								0, nBytes/4 +1,
								True,
								nType,
								&nType, &nFormat,
								&nItems, &nBytes,
								&pData );
#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "read %ld items data of type %s and format %d, %ld bytes left in property\n",
					 nItems,
					 OUStringToOString( getString( nType ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
					 nFormat, nBytes );
#endif
	
			sal_Size nUnitSize = GetTrueFormatSize(nFormat);

			if( it->second->m_eState == Selection::WaitingForData ||
				it->second->m_eState == Selection::WaitingForResponse )
			{
				// copy data
				it->second->m_aData = Sequence< sal_Int8 >( (sal_Int8*)pData, nItems*nUnitSize );
				it->second->m_eState = Selection::Inactive;
				it->second->m_aDataArrived.set();
			}
			else if( it->second->m_eState == Selection::IncrementalTransfer )
			{
                if( nItems )
                {
                    // append data
                    Sequence< sal_Int8 > aData( it->second->m_aData.getLength() + nItems*nUnitSize );
                    memcpy( aData.getArray(), it->second->m_aData.getArray(), it->second->m_aData.getLength() );
                    memcpy( aData.getArray() + it->second->m_aData.getLength(), pData, nItems*nUnitSize );
                    it->second->m_aData = aData;
                }
                else
                {
                    it->second->m_eState = Selection::Inactive;
                    it->second->m_aDataArrived.set();
                }
			}
			if( pData )
				XFree( pData );
		}
		else if( it->second->m_eState == Selection::IncrementalTransfer )
		{
			it->second->m_eState = Selection::Inactive;
			it->second->m_aDataArrived.set();
		}
	}
    return bHandled;
}

// ------------------------------------------------------------------------

bool SelectionManager::handleSendPropertyNotify( XPropertyEvent& rNotify )
{
    MutexGuard aGuard( m_aMutex );

	// ready for next part of a IncrementalTransfer
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "handleSendPropertyNotify for property %s (%s)\n",
			 OUStringToOString( getString( rNotify.atom ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
             rNotify.state == PropertyNewValue ? "new value" : ( rNotify.state == PropertyDelete ? "deleted" : "unknown")
             );
#endif

    bool bHandled = false;
    // feed incrementals
    if( rNotify.state == PropertyDelete )
    {
        std::hash_map< XLIB_Window, std::hash_map< Atom, IncrementalTransfer > >::iterator it;
        it = m_aIncrementals.find( rNotify.window );
        if( it != m_aIncrementals.end() )
        {
            bHandled = true;
            int nCurrentTime = time( NULL );
            std::hash_map< Atom, IncrementalTransfer >::iterator inc_it;
            // throw out aborted transfers
            std::list< Atom > aTimeouts;
            for( inc_it = it->second.begin(); inc_it != it->second.end(); ++inc_it )
            {
                if( (nCurrentTime - inc_it->second.m_nTransferStartTime) > (getSelectionTimeout()+2) )
                {
                    aTimeouts.push_back( inc_it->first );
#if OSL_DEBUG_LEVEL > 1
                    const IncrementalTransfer& rInc = inc_it->second;
                    fprintf( stderr, "timeout on INCR transfer for window 0x%lx, property %s, type %s\n",
                             rInc.m_aRequestor,
                             OUStringToOString( getString( rInc.m_aProperty ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                             OUStringToOString( getString( rInc.m_aTarget ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
                             );
#endif
                }
            }

            while( aTimeouts.begin() != aTimeouts.end() )
            {
                // transfer broken, might even be a new client with the
                // same window id
                it->second.erase( aTimeouts.front() );
                aTimeouts.pop_front();
            }

            inc_it = it->second.find( rNotify.atom );
            if( inc_it != it->second.end() )
            {
                IncrementalTransfer& rInc = inc_it->second;

                int nBytes = rInc.m_aData.getLength() - rInc.m_nBufferPos;
                nBytes = (nBytes > m_nIncrementalThreshold) ? m_nIncrementalThreshold : nBytes;
                if( nBytes < 0 )  // sanity check
                    nBytes = 0;
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "pushing %d bytes: \"%.*s\"...\n",
                         nBytes, nBytes > 32 ? 32 : nBytes,
                         (const unsigned char*)rInc.m_aData.getConstArray()+rInc.m_nBufferPos );
#endif

				sal_Size nUnitSize = GetTrueFormatSize(rInc.m_nFormat);
                
                XChangeProperty( m_pDisplay,
                                 rInc.m_aRequestor,
                                 rInc.m_aProperty,
                                 rInc.m_aTarget,
                                 rInc.m_nFormat,
                                 PropModeReplace,
                                 (const unsigned char*)rInc.m_aData.getConstArray()+rInc.m_nBufferPos,
                                 nBytes/nUnitSize );
                rInc.m_nBufferPos += nBytes;
                rInc.m_nTransferStartTime = nCurrentTime;

                if( nBytes == 0 ) // transfer finished
                {
#if OSL_DEBUG_LEVEL > 1
                    fprintf( stderr, "finished INCR transfer for window 0x%lx, property %s, type %s\n",
                             rInc.m_aRequestor,
                             OUStringToOString( getString( rInc.m_aProperty ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
                             OUStringToOString( getString( rInc.m_aTarget ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
                             );
#endif
                    it->second.erase( inc_it );
                }

            }
            // eventually clean up the hash map
            if( it->second.begin() == it->second.end() )
                m_aIncrementals.erase( it );
        }
    }
    return bHandled;
}

// ------------------------------------------------------------------------

bool SelectionManager::handleSelectionNotify( XSelectionEvent& rNotify )
{
    MutexGuard aGuard( m_aMutex );

    bool bHandled = false;

	// notification about success/failure of one of our conversion requests
#if OSL_DEBUG_LEVEL > 1
    OUString aSelection( getString( rNotify.selection ) );
    OUString aProperty( OUString::createFromAscii( "None" ) );
    if( rNotify.property )
        aProperty = getString( rNotify.property );
	fprintf( stderr, "handleSelectionNotify for selection %s and property %s (0x%lx)\n",
			 OUStringToOString( aSelection, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
			 OUStringToOString( aProperty, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
             rNotify.property
			 );
    if( rNotify.requestor != m_aWindow && rNotify.requestor != m_aCurrentDropWindow )
        fprintf( stderr, "Warning: selection notify for unknown window 0x%lx\n", rNotify.requestor );
#endif
	::std::hash_map< Atom, Selection* >::iterator it =
		  m_aSelections.find( rNotify.selection );
    if (
        (rNotify.requestor == m_aWindow || rNotify.requestor == m_aCurrentDropWindow) &&
        it != m_aSelections.end() &&
        (
         (it->second->m_eState == Selection::WaitingForResponse) ||
         (it->second->m_eState == Selection::WaitingForData)
        )
       )
	{
        bHandled = true;
        if( it->second->m_aRequestedType == m_nMULTIPLEAtom )
        {
            Atom nType = None;
            int nFormat = 0;
            unsigned long nItems = 0, nBytes = 0;
            unsigned char* pData = NULL;

            // get type and length
            XGetWindowProperty( m_pDisplay,
                                rNotify.requestor,
                                rNotify.property,
                                0, 256,
                                False,
                                AnyPropertyType,
                                &nType, &nFormat,
                                &nItems, &nBytes,
                                &pData );
            if( nBytes ) // HUGE request !!!
            {
                if( pData )
                    XFree( pData );
                XGetWindowProperty( m_pDisplay,
                                    rNotify.requestor,
                                    rNotify.property,
                                    0, 256+(nBytes+3)/4,
                                    False,
                                    AnyPropertyType,
                                    &nType, &nFormat,
                                    &nItems, &nBytes,
                                    &pData );
            }
            it->second->m_eState		= Selection::Inactive;
            sal_Size nUnitSize = GetTrueFormatSize(nFormat);
            it->second->m_aData			= Sequence< sal_Int8 >((sal_Int8*)pData, nItems * nUnitSize);
            it->second->m_aDataArrived.set();
            if( pData )
                XFree( pData );
        }
        // WaitingForData can actually happen; some
        // applications (e.g. cmdtool on Solaris) first send
        // a success and then cancel it. Weird !
		else if( rNotify.property == None )
		{
            // conversion failed, stop transfer
			it->second->m_eState		= Selection::Inactive;
			it->second->m_aData			= Sequence< sal_Int8 >();
			it->second->m_aDataArrived.set();
		}
		// get the bytes, by INCR if necessary
		else
			it->second->m_eState = Selection::WaitingForData;
	}
#if OSL_DEBUG_LEVEL > 1
    else if( it != m_aSelections.end() )
        fprintf( stderr, "Warning: selection in state %d\n", it->second->m_eState );
#endif
    return bHandled;
}

// ------------------------------------------------------------------------

bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
{
    ResettableMutexGuard aGuard(m_aMutex);

	// handle drop related events
	XLIB_Window aSource = rMessage.data.l[0];
	XLIB_Window aTarget = rMessage.window;

    bool bHandled = false;

	::std::hash_map< XLIB_Window, DropTargetEntry >::iterator it =
		  m_aDropTargets.find( aTarget );

#if OSL_DEBUG_LEVEL > 1
	if( rMessage.message_type == m_nXdndEnter     ||
		rMessage.message_type == m_nXdndLeave     ||
		rMessage.message_type == m_nXdndDrop      ||
		rMessage.message_type == m_nXdndPosition  )
	{
		fprintf( stderr, "got drop event %s, ", OUStringToOString( getString( rMessage.message_type ), RTL_TEXTENCODING_ASCII_US).getStr() );
		if( it == m_aDropTargets.end() )
			fprintf( stderr, "but no target found\n" );
		else if( ! it->second.m_pTarget->m_bActive )
			fprintf( stderr, "but target is inactive\n" );
		else if( m_aDropEnterEvent.data.l[0] != None && (XLIB_Window)m_aDropEnterEvent.data.l[0] != aSource )
			fprintf( stderr, "but source 0x%lx is unknown (expected 0x%lx or 0)\n", aSource, m_aDropEnterEvent.data.l[0] );
		else
			fprintf( stderr, "processing.\n" );
	}
#endif

    if( it != m_aDropTargets.end() && it->second.m_pTarget->m_bActive &&
        m_bDropWaitingForCompletion && m_aDropEnterEvent.data.l[0] )
    {
        bHandled = true;
        OSL_ENSURE( 0, "someone forgot to call dropComplete ?" );
        // some listener forgot to call dropComplete in the last operation
        // let us end it now and accept the new enter event
        aGuard.clear();
        dropComplete( sal_False, m_aCurrentDropWindow, m_nDropTime );
        aGuard.reset();
    }

	if( it != m_aDropTargets.end() &&
		it->second.m_pTarget->m_bActive &&
       ( m_aDropEnterEvent.data.l[0] == None || XLIB_Window(m_aDropEnterEvent.data.l[0]) == aSource )
		)
	{
		if( rMessage.message_type == m_nXdndEnter )
		{
            bHandled = true;
			m_aDropEnterEvent			= rMessage;
			m_bDropEnterSent			= false;
			m_aCurrentDropWindow		= aTarget;
			m_nCurrentProtocolVersion	= m_aDropEnterEvent.data.l[1] >> 24;
#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "received XdndEnter on 0x%lx\n", aTarget );
#endif
		}
		else if(
                rMessage.message_type == m_nXdndPosition &&
                aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
                )
		{
            bHandled = true;
			m_nDropTime = m_nCurrentProtocolVersion > 0 ? rMessage.data.l[3] : CurrentTime;
			if( ! m_bDropEnterSent )
				m_nDropTimestamp = m_nDropTime;

			XLIB_Window aChild;
			XTranslateCoordinates( m_pDisplay,
								   it->second.m_aRootWindow,
								   it->first,
								   rMessage.data.l[2] >> 16,
								   rMessage.data.l[2] & 0xffff,
								   &m_nLastX, &m_nLastY,
								   &aChild );

#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "received XdndPosition on 0x%lx (%d, %d)\n", aTarget, m_nLastX, m_nLastY );
#endif
			DropTargetDragEnterEvent aEvent;
			aEvent.Source		= static_cast< XDropTarget* >(it->second.m_pTarget);
			aEvent.Context		= new DropTargetDragContext( m_aCurrentDropWindow, m_nDropTimestamp, *this );
			aEvent.LocationX	= m_nLastX;
			aEvent.LocationY	= m_nLastY;
            aEvent.SourceActions = m_nSourceActions;
			if( m_nCurrentProtocolVersion < 2 )
				aEvent.DropAction = DNDConstants::ACTION_COPY;
			else if( Atom(rMessage.data.l[4]) == m_nXdndActionCopy )
				aEvent.DropAction = DNDConstants::ACTION_COPY;
			else if( Atom(rMessage.data.l[4]) == m_nXdndActionMove )
				aEvent.DropAction = DNDConstants::ACTION_MOVE;
			else if( Atom(rMessage.data.l[4]) == m_nXdndActionLink )
				aEvent.DropAction = DNDConstants::ACTION_LINK;
			else if( Atom(rMessage.data.l[4]) == m_nXdndActionAsk )
				// currently no interface to implement ask
				aEvent.DropAction = ~0;
			else
				aEvent.DropAction = DNDConstants::ACTION_NONE;

			m_nLastDropAction	= aEvent.DropAction;
			if( ! m_bDropEnterSent )
			{
				m_bDropEnterSent = true;
				aEvent.SupportedDataFlavors = m_xDropTransferable->getTransferDataFlavors();
                aGuard.clear();
				it->second->dragEnter( aEvent );
			}
			else
            {
                aGuard.clear();
				it->second->dragOver( aEvent );
            }
		}
		else if(
                rMessage.message_type == m_nXdndLeave  &&
                aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
                )
		{
            bHandled = true;
#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "received XdndLeave on 0x%lx\n", aTarget );
#endif
			DropTargetEvent aEvent;
			aEvent.Source = static_cast< XDropTarget* >(it->second.m_pTarget);
			m_aDropEnterEvent.data.l[0] = None;
			if( m_aCurrentDropWindow == aTarget )
				m_aCurrentDropWindow = None;
			m_nCurrentProtocolVersion = nXdndProtocolRevision;
            aGuard.clear();
			it->second->dragExit( aEvent );
		}
		else if(
                rMessage.message_type == m_nXdndDrop &&
                aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
                )
		{
            bHandled = true;
			m_nDropTime = m_nCurrentProtocolVersion > 0 ? rMessage.data.l[2] : CurrentTime;

#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "received XdndDrop on 0x%lx (%d, %d)\n", aTarget, m_nLastX, m_nLastY );
#endif
            if( m_bLastDropAccepted )
            {
                DropTargetDropEvent aEvent;
                aEvent.Source		= static_cast< XDropTarget* >(it->second.m_pTarget);
                aEvent.Context		= new DropTargetDropContext( m_aCurrentDropWindow, m_nDropTimestamp, *this );
                aEvent.LocationX	= m_nLastX;
                aEvent.LocationY	= m_nLastY;
                aEvent.DropAction	= m_nLastDropAction;
                // there is nothing corresponding to source supported actions
                // every source can do link, copy and move
                aEvent.SourceActions= m_nLastDropAction;
                aEvent.Transferable	= m_xDropTransferable;

                m_bDropWaitingForCompletion = true;
                aGuard.clear();
                it->second->drop( aEvent );
            }
            else
            {
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "XdndDrop canceled due to m_bLastDropAccepted = fale\n" );
#endif
                DropTargetEvent aEvent;
                aEvent.Source = static_cast< XDropTarget* >(it->second.m_pTarget);
                aGuard.clear();
                it->second->dragExit( aEvent );
                // reset the drop status, notify source
                dropComplete( sal_False, m_aCurrentDropWindow, m_nDropTime );
            }
        }
	}
    return bHandled;
}

/*
 *	methods for XDropTargetDropContext
 */

void SelectionManager::dropComplete( sal_Bool bSuccess, XLIB_Window aDropWindow, XLIB_Time )
{
	ClearableMutexGuard aGuard(m_aMutex);

	if( aDropWindow == m_aCurrentDropWindow )
	{
		if( m_xDragSourceListener.is() )
		{
			DragSourceDropEvent dsde;
			dsde.Source				= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource			= static_cast< XDragSource* >(this);
			dsde.DropAction			= getUserDragAction();
			dsde.DropSuccess		= bSuccess;
            css::uno::Reference< XDragSourceListener > xListener = m_xDragSourceListener;
			m_xDragSourceListener.clear();

            aGuard.clear();
			xListener->dragDropEnd( dsde );
		}
		else if( m_aDropEnterEvent.data.l[0] && m_aCurrentDropWindow )
		{
			XEvent aEvent;
			aEvent.xclient.type			= ClientMessage;
			aEvent.xclient.display		= m_pDisplay;
			aEvent.xclient.window		= m_aDropEnterEvent.data.l[0];
			aEvent.xclient.message_type	= m_nXdndFinished;
			aEvent.xclient.format		= 32;
			aEvent.xclient.data.l[0]	= m_aCurrentDropWindow;
			aEvent.xclient.data.l[1]	= bSuccess ? 1 : 0;
			aEvent.xclient.data.l[2]	= 0;
			aEvent.xclient.data.l[3]	= 0;
			aEvent.xclient.data.l[4]	= 0;
            if( bSuccess )
            {
                if( m_nLastDropAction & DNDConstants::ACTION_MOVE )
                    aEvent.xclient.data.l[2] = m_nXdndActionMove;
                else if( m_nLastDropAction & DNDConstants::ACTION_COPY )
                    aEvent.xclient.data.l[2] = m_nXdndActionCopy;
                else if( m_nLastDropAction & DNDConstants::ACTION_LINK )
                    aEvent.xclient.data.l[2] = m_nXdndActionLink;
            }

#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "Sending XdndFinished to 0x%lx\n",
					 m_aDropEnterEvent.data.l[0]
					 );
#endif

			XSendEvent( m_pDisplay, m_aDropEnterEvent.data.l[0],
						False, NoEventMask, & aEvent );

			m_aDropEnterEvent.data.l[0]	= None;
			m_aCurrentDropWindow		= None;
			m_nCurrentProtocolVersion	= nXdndProtocolRevision;
		}
        m_bDropWaitingForCompletion = false;
	}
	else
		OSL_ASSERT( "dropComplete from invalid DropTargetDropContext" );
}

/*
 *	methods for XDropTargetDragContext
 */

// ------------------------------------------------------------------------

void SelectionManager::sendDragStatus( Atom nDropAction )
{
	ClearableMutexGuard aGuard(m_aMutex);

	if( m_xDragSourceListener.is() )
	{
		sal_Int8 nNewDragAction;
		if( nDropAction == m_nXdndActionMove )
			nNewDragAction = DNDConstants::ACTION_MOVE;
		else if( nDropAction == m_nXdndActionCopy )
			nNewDragAction = DNDConstants::ACTION_COPY;
		else if( nDropAction == m_nXdndActionLink )
			nNewDragAction = DNDConstants::ACTION_LINK;
		else
			nNewDragAction = DNDConstants::ACTION_NONE;
        nNewDragAction &= m_nSourceActions;

        if( nNewDragAction != m_nTargetAcceptAction )
        {
            setCursor( getDefaultCursor( nNewDragAction ), m_aDropWindow, m_nDragTimestamp );
            m_nTargetAcceptAction = nNewDragAction;
        }

		DragSourceDragEvent dsde;
		dsde.Source				= static_cast< OWeakObject* >(this);
		dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
		dsde.DragSource			= static_cast< XDragSource* >(this);
		dsde.DropAction			= m_nSourceActions;
		dsde.UserAction			= getUserDragAction();

        css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
        // caution: do not change anything after this
        aGuard.clear();
        if( xListener.is() )
            xListener->dragOver( dsde );
	}
	else if( m_aDropEnterEvent.data.l[0] && m_aCurrentDropWindow )
	{
		XEvent aEvent;
		aEvent.xclient.type			= ClientMessage;
		aEvent.xclient.display		= m_pDisplay;
		aEvent.xclient.window		= m_aDropEnterEvent.data.l[0];
		aEvent.xclient.message_type	= m_nXdndStatus;
		aEvent.xclient.format		= 32;
		aEvent.xclient.data.l[0]	= m_aCurrentDropWindow;
		aEvent.xclient.data.l[1]	= 2;
		if( nDropAction == m_nXdndActionMove	||
			nDropAction == m_nXdndActionLink	||
			nDropAction == m_nXdndActionCopy )
			aEvent.xclient.data.l[1] |= 1;
		aEvent.xclient.data.l[2] = 0;
		aEvent.xclient.data.l[3] = 0;
		aEvent.xclient.data.l[4] = m_nCurrentProtocolVersion > 1 ? nDropAction : 0;

#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "Sending XdndStatus to 0x%lx with action %s\n",
				 m_aDropEnterEvent.data.l[0],
				 OUStringToOString( getString( nDropAction ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
				 );
#endif

		XSendEvent( m_pDisplay, m_aDropEnterEvent.data.l[0],
					False, NoEventMask, & aEvent );
		XFlush( m_pDisplay );
	}
}

// ------------------------------------------------------------------------

sal_Int8 SelectionManager::getUserDragAction() const
{
    return (m_nTargetAcceptAction != DNDConstants::ACTION_DEFAULT) ? m_nTargetAcceptAction : m_nUserDragAction;
}

// ------------------------------------------------------------------------

bool SelectionManager::updateDragAction( int modifierState )
{
	bool bRet = false;

	sal_Int8 nNewDropAction = DNDConstants::ACTION_MOVE;
	if( ( modifierState & ShiftMask ) && ! ( modifierState & ControlMask ) )
		nNewDropAction = DNDConstants::ACTION_MOVE;
	else if( ( modifierState & ControlMask ) && ! ( modifierState & ShiftMask ) )
		nNewDropAction = DNDConstants::ACTION_COPY;
	else if( ( modifierState & ShiftMask ) && ( modifierState & ControlMask ) )
		nNewDropAction = DNDConstants::ACTION_LINK;
	if( m_nCurrentProtocolVersion < 0 && m_aDropWindow != None )
		nNewDropAction = DNDConstants::ACTION_COPY;
    nNewDropAction &= m_nSourceActions;

    if( ! ( modifierState & ( ControlMask | ShiftMask ) ) )
    {
        if( ! nNewDropAction )
        {
            // default to an action so the user does not have to press
            // keys explicitly
            if( m_nSourceActions & DNDConstants::ACTION_MOVE )
                nNewDropAction = DNDConstants::ACTION_MOVE;
            else if( m_nSourceActions & DNDConstants::ACTION_COPY )
                nNewDropAction = DNDConstants::ACTION_COPY;
            else if( m_nSourceActions & DNDConstants::ACTION_LINK )
                nNewDropAction = DNDConstants::ACTION_LINK;
        }
        nNewDropAction |= DNDConstants::ACTION_DEFAULT;
    }

	if( nNewDropAction != m_nUserDragAction || m_nTargetAcceptAction != DNDConstants::ACTION_DEFAULT )
	{
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "updateDragAction: %x -> %x\n", (int)m_nUserDragAction, (int)nNewDropAction );
#endif
		bRet = true;
		m_nUserDragAction = nNewDropAction;

		DragSourceDragEvent dsde;
		dsde.Source				= static_cast< OWeakObject* >(this);
		dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
		dsde.DragSource			= static_cast< XDragSource* >(this);
		dsde.DropAction			= m_nUserDragAction;
		dsde.UserAction			= m_nUserDragAction;
        m_nTargetAcceptAction	= DNDConstants::ACTION_DEFAULT; // invalidate last accept
		m_xDragSourceListener->dropActionChanged( dsde );
	}
	return bRet;
}

// ------------------------------------------------------------------------

void SelectionManager::sendDropPosition( bool bForce, XLIB_Time eventTime )
{
    ClearableMutexGuard aGuard(m_aMutex);

    if( m_bDropSent )
        return;

	::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
		  m_aDropTargets.find( m_aDropWindow );
	if( it != m_aDropTargets.end() )
	{
		if( it->second.m_pTarget->m_bActive )
		{
			int x, y;
			XLIB_Window aChild;
			XTranslateCoordinates( m_pDisplay, it->second.m_aRootWindow, m_aDropWindow, m_nLastDragX, m_nLastDragY, &x, &y, &aChild );
			DropTargetDragEvent dtde;
			dtde.Source			= static_cast< OWeakObject* >(it->second.m_pTarget );
			dtde.Context		= new DropTargetDragContext( m_aCurrentDropWindow, m_nDropTimestamp, *this );
			dtde.LocationX		= x;
			dtde.LocationY		= y;
			dtde.DropAction		= getUserDragAction();
			dtde.SourceActions	= m_nSourceActions;
            aGuard.clear();
			it->second->dragOver( dtde );
		}
	}
	else if( bForce ||

			 m_nLastDragX < m_nNoPosX || m_nLastDragX >= m_nNoPosX+m_nNoPosWidth ||
			 m_nLastDragY < m_nNoPosY || m_nLastDragY >= m_nNoPosY+m_nNoPosHeight
			 )
	{
		// send XdndPosition
		XEvent aEvent;
		aEvent.type = ClientMessage;
		aEvent.xclient.display		= m_pDisplay;
		aEvent.xclient.format		= 32;
		aEvent.xclient.message_type	= m_nXdndPosition;
		aEvent.xclient.window		= m_aDropWindow;
		aEvent.xclient.data.l[0]	= m_aWindow;
		aEvent.xclient.data.l[1]	= 0;
		aEvent.xclient.data.l[2]	= m_nLastDragX << 16 | (m_nLastDragY&0xffff);
		aEvent.xclient.data.l[3]	= eventTime;

		if( m_nUserDragAction & DNDConstants::ACTION_COPY )
			aEvent.xclient.data.l[4]=m_nXdndActionCopy;
		else if( m_nUserDragAction & DNDConstants::ACTION_MOVE )
			aEvent.xclient.data.l[4]=m_nXdndActionMove;
		else if( m_nUserDragAction & DNDConstants::ACTION_LINK )
			aEvent.xclient.data.l[4]=m_nXdndActionLink;
		else
			aEvent.xclient.data.l[4]=m_nXdndActionCopy;
		XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
		m_nNoPosX = m_nNoPosY = m_nNoPosWidth = m_nNoPosHeight = 0;
	}
}

// ------------------------------------------------------------------------

bool SelectionManager::handleDragEvent( XEvent& rMessage )
{
	if( ! m_xDragSourceListener.is() )
		return false;

    ResettableMutexGuard aGuard(m_aMutex);

    bool bHandled = false;

	// for shortcut
	::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
		  m_aDropTargets.find( m_aDropWindow );
#if OSL_DEBUG_LEVEL > 1
	switch( rMessage.type )
	{
		case ClientMessage:
			fprintf( stderr, "handleDragEvent: %s\n", OUStringToOString( getString( rMessage.xclient.message_type ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
			break;
		case MotionNotify:
//			fprintf( stderr, "handleDragEvent: MotionNotify\n" );
			break;
		case EnterNotify:
			fprintf( stderr, "handleDragEvent: EnterNotify\n" );
			break;
		case LeaveNotify:
			fprintf( stderr, "handleDragEvent: LeaveNotify\n" );
			break;
		case ButtonPress:
			fprintf( stderr, "handleDragEvent: ButtonPress %d (m_nDragButton = %d)\n", rMessage.xbutton.button, m_nDragButton );
			break;
		case ButtonRelease:
			fprintf( stderr, "handleDragEvent: ButtonRelease %d (m_nDragButton = %d)\n", rMessage.xbutton.button, m_nDragButton );
			break;
		case XLIB_KeyPress:
			fprintf( stderr, "handleDragEvent: KeyPress\n" );
			break;
		case KeyRelease:
			fprintf( stderr, "handleDragEvent: KeyRelease\n" );
			break;
		default:
			fprintf( stderr, "handleDragEvent: <unknown type %d>\n", rMessage.type );
			break;
	}
#endif

	// handle drag related events
	if( rMessage.type == ClientMessage )
	{
		if( Atom(rMessage.xclient.message_type) == m_nXdndStatus && Atom(rMessage.xclient.data.l[0]) == m_aDropWindow )
		{
            bHandled = true;
			DragSourceDragEvent dsde;
			dsde.Source					= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext		= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource				= static_cast< XDragSource* >( this );
            dsde.UserAction = getUserDragAction();
			dsde.DropAction = DNDConstants::ACTION_NONE;
			m_bDropSuccess = rMessage.xclient.data.l[1] & 1 ? true : false;
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "status drop action: accept = %s, %s\n",
                     m_bDropSuccess ? "true" : "false",
                     OUStringToOString( getString( rMessage.xclient.data.l[4] ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
#endif
			if( rMessage.xclient.data.l[1] & 1 )
			{
				if( m_nCurrentProtocolVersion > 1 )
				{
					if( Atom(rMessage.xclient.data.l[4]) == m_nXdndActionCopy )
						dsde.DropAction = DNDConstants::ACTION_COPY;
					else if( Atom(rMessage.xclient.data.l[4]) == m_nXdndActionMove )
						dsde.DropAction = DNDConstants::ACTION_MOVE;
					else if( Atom(rMessage.xclient.data.l[4]) == m_nXdndActionLink )
						dsde.DropAction = DNDConstants::ACTION_LINK;
				}
				else
					dsde.DropAction = DNDConstants::ACTION_COPY;
			}
			m_nTargetAcceptAction = dsde.DropAction;

			if( ! ( rMessage.xclient.data.l[1] & 2 ) )
			{
				m_nNoPosX		= rMessage.xclient.data.l[2] >> 16;
				m_nNoPosY		= rMessage.xclient.data.l[2] & 0xffff;
				m_nNoPosWidth	= rMessage.xclient.data.l[3] >> 16;
				m_nNoPosHeight	= rMessage.xclient.data.l[3] & 0xffff;
			}
			else
				m_nNoPosX = m_nNoPosY = m_nNoPosWidth = m_nNoPosHeight = 0;

            setCursor( getDefaultCursor( dsde.DropAction ), m_aDropWindow, m_nDragTimestamp );
            aGuard.clear();
            m_xDragSourceListener->dragOver( dsde );
		}
		else if( Atom(rMessage.xclient.message_type) == m_nXdndFinished && m_aDropWindow == Atom(rMessage.xclient.data.l[0]) )
		{
            bHandled = true;
			// notify the listener
			DragSourceDropEvent dsde;
			dsde.Source				= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource			= static_cast< XDragSource* >(this);
			dsde.DropAction			= m_nTargetAcceptAction;
			dsde.DropSuccess		= m_bDropSuccess;
            css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
			m_xDragSourceListener.clear();
            aGuard.clear();
			xListener->dragDropEnd( dsde );
		}
	}
	else if( rMessage.type == MotionNotify ||
			 rMessage.type == EnterNotify || rMessage.type == LeaveNotify
			 )
	{
        bHandled = true;
		bool bForce = false;
		int root_x	= rMessage.type == MotionNotify ? rMessage.xmotion.x_root : rMessage.xcrossing.x_root;
		int root_y	= rMessage.type == MotionNotify ? rMessage.xmotion.y_root : rMessage.xcrossing.y_root;
		XLIB_Window root = rMessage.type == MotionNotify ? rMessage.xmotion.root : rMessage.xcrossing.root;
		m_nDragTimestamp = rMessage.type == MotionNotify ? rMessage.xmotion.time : rMessage.xcrossing.time;

        aGuard.clear();
		if( rMessage.type == MotionNotify )
        {
			bForce = updateDragAction( rMessage.xmotion.state );
        }
		updateDragWindow( root_x, root_y, root );
        aGuard.reset();

		if( m_nCurrentProtocolVersion >= 0 && m_aDropProxy != None )
        {
            aGuard.clear();
			sendDropPosition( bForce, rMessage.type == MotionNotify ? rMessage.xmotion.time : rMessage.xcrossing.time );
        }
	}
	else if( rMessage.type == XLIB_KeyPress || rMessage.type == KeyRelease )
	{
		bHandled = true;
		const KeySym aKey = XkbKeycodeToKeysym( m_pDisplay, rMessage.xkey.keycode, 0, 0 );
		if( aKey == XK_Escape )
		{
			// abort drag
			if( it != m_aDropTargets.end() )
			{
				DropTargetEvent dte;
				dte.Source = static_cast< OWeakObject* >( it->second.m_pTarget );
                aGuard.clear();
				it->second.m_pTarget->dragExit( dte );
			}
			else if( m_aDropProxy != None && m_nCurrentProtocolVersion >= 0 )
			{
				// send XdndLeave
				XEvent aEvent;
				aEvent.type = ClientMessage;
				aEvent.xclient.display		= m_pDisplay;
				aEvent.xclient.format		= 32;
				aEvent.xclient.message_type	= m_nXdndLeave;
				aEvent.xclient.window		= m_aDropWindow;
				aEvent.xclient.data.l[0]	= m_aWindow;
				memset( aEvent.xclient.data.l+1, 0, sizeof(long)*4);
				m_aDropWindow = m_aDropProxy = None;
				XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
			}
			// notify the listener
			DragSourceDropEvent dsde;
			dsde.Source				= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource			= static_cast< XDragSource* >(this);
			dsde.DropAction			= DNDConstants::ACTION_NONE;
			dsde.DropSuccess		= sal_False;
            css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
			m_xDragSourceListener.clear();
            aGuard.clear();
			xListener->dragDropEnd( dsde );
		}
		else
		{
			/*
			 *	man page says: state is state immediate PRIOR to the
			 *	event. It would seem that this is a somewhat arguable
			 *	design decision.
			 */
			int nState = rMessage.xkey.state;
			int nNewState = 0;
			switch( aKey )
			{
				case XK_Shift_R:
				case XK_Shift_L: nNewState = ShiftMask;break;
				case XK_Control_R:
				case XK_Control_L: nNewState = ControlMask;break;
					// just interested in shift and ctrl for dnd
			}
			if( rMessage.type == XLIB_KeyPress )
				nState |= nNewState;
			else
				nState &= ~nNewState;
            aGuard.clear();
			if( updateDragAction( nState ) )
				sendDropPosition( true, rMessage.xkey.time );
		}
	}
	else if(
            ( rMessage.type == ButtonPress || rMessage.type == ButtonRelease ) &&
            rMessage.xbutton.button == m_nDragButton )
	{
		bool bCancel = true;
		if( m_aDropWindow != None )
		{
			if( it != m_aDropTargets.end() )
			{
				if( it->second.m_pTarget->m_bActive && m_nUserDragAction != DNDConstants::ACTION_NONE && m_bLastDropAccepted )
				{
                    bHandled = true;
					int x, y;
					XLIB_Window aChild;
					XTranslateCoordinates( m_pDisplay, rMessage.xbutton.root, m_aDropWindow, rMessage.xbutton.x_root, rMessage.xbutton.y_root, &x, &y, &aChild );
					DropTargetDropEvent dtde;
					dtde.Source			= static_cast< OWeakObject* >(it->second.m_pTarget );
					dtde.Context		= new DropTargetDropContext( m_aCurrentDropWindow, m_nDropTimestamp, *this );
					dtde.LocationX		= x;
					dtde.LocationY		= y;
					dtde.DropAction		= m_nUserDragAction;
					dtde.SourceActions	= m_nSourceActions;
					dtde.Transferable	= m_xDragSourceTransferable;
					m_bDropSent					= true;
					m_nDropTimeout				= time( NULL );
                    m_bDropWaitingForCompletion = true;
                    aGuard.clear();
					it->second->drop( dtde );
					bCancel = false;
				}
				else bCancel = true;
			}
			else if( m_nCurrentProtocolVersion >= 0 )
			{
                bHandled = true;

				XEvent aEvent;
				aEvent.type = ClientMessage;
				aEvent.xclient.display		= m_pDisplay;
				aEvent.xclient.format		= 32;
				aEvent.xclient.message_type	= m_nXdndDrop;
				aEvent.xclient.window		= m_aDropWindow;
				aEvent.xclient.data.l[0]	= m_aWindow;
				aEvent.xclient.data.l[1]	= 0;
				aEvent.xclient.data.l[2]	= rMessage.xbutton.time;
				aEvent.xclient.data.l[3]	= 0;
				aEvent.xclient.data.l[4]	= 0;

				m_bDropSent					= true;
				m_nDropTimeout				= time( NULL );
				XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
				bCancel = false;
			}
			else
			{
				// dropping on non XdndWindows: acquire ownership of
				// PRIMARY and send a middle mouse button click down/up to
				// target window
				SelectionAdaptor* pAdaptor = getAdaptor( XA_PRIMARY );
				if( pAdaptor )
				{
                    bHandled = true;

					XLIB_Window aDummy;
					XEvent aEvent;
					aEvent.type = ButtonPress;
					aEvent.xbutton.display		= m_pDisplay;
					aEvent.xbutton.window		= m_aDropWindow;
					aEvent.xbutton.root			= rMessage.xbutton.root;
					aEvent.xbutton.subwindow	= m_aDropWindow;
					aEvent.xbutton.time			= rMessage.xbutton.time+1;
					aEvent.xbutton.x_root		= rMessage.xbutton.x_root;
					aEvent.xbutton.y_root		= rMessage.xbutton.y_root;
					aEvent.xbutton.state		= rMessage.xbutton.state;
					aEvent.xbutton.button		= Button2;
					aEvent.xbutton.same_screen	= True;
					XTranslateCoordinates( m_pDisplay,
										   rMessage.xbutton.root, m_aDropWindow,
										   rMessage.xbutton.x_root, rMessage.xbutton.y_root,
										   &aEvent.xbutton.x, &aEvent.xbutton.y,
										   &aDummy );
					XSendEvent( m_pDisplay, m_aDropWindow, False, ButtonPressMask, &aEvent );
					aEvent.xbutton.type   = ButtonRelease;
					aEvent.xbutton.time++;
					aEvent.xbutton.state |= Button2Mask;
					XSendEvent( m_pDisplay, m_aDropWindow, False, ButtonReleaseMask, &aEvent );

					m_bDropSent					= true;
					m_nDropTimeout				= time( NULL );
					XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
					m_bWaitingForPrimaryConversion	= true;
					m_bDropSent						= true;
					m_nDropTimeout					= time( NULL );
					// HACK :-)
                    aGuard.clear();
					static_cast< X11Clipboard* >( pAdaptor )->setContents( m_xDragSourceTransferable, css::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >() );
                    aGuard.reset();
					bCancel = false;
				}
			}
		}
		if( bCancel )
		{
			// cancel drag
			DragSourceDropEvent dsde;
			dsde.Source				= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource			= static_cast< XDragSource* >(this);
			dsde.DropAction			= DNDConstants::ACTION_NONE;
			dsde.DropSuccess		= sal_False;
            css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
			m_xDragSourceListener.clear();
            aGuard.clear();
			xListener->dragDropEnd( dsde );
            bHandled = true;
		}
	}
    return bHandled;
}

// ------------------------------------------------------------------------

void SelectionManager::accept( sal_Int8 dragOperation, XLIB_Window aDropWindow, XLIB_Time )
{
	if( aDropWindow == m_aCurrentDropWindow )
	{
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "accept: %x\n", dragOperation );
#endif
		Atom nAction = None;
        dragOperation &= (DNDConstants::ACTION_MOVE | DNDConstants::ACTION_COPY | DNDConstants::ACTION_LINK);
        if( dragOperation & DNDConstants::ACTION_MOVE )
            nAction = m_nXdndActionMove;
        else if( dragOperation & DNDConstants::ACTION_COPY )
            nAction = m_nXdndActionCopy;
        else if( dragOperation & DNDConstants::ACTION_LINK )
            nAction = m_nXdndActionLink;
        m_bLastDropAccepted = true;
		sendDragStatus( nAction );
	}
}

// ------------------------------------------------------------------------

void SelectionManager::reject( XLIB_Window aDropWindow, XLIB_Time )
{
	if( aDropWindow == m_aCurrentDropWindow )
	{
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "reject\n" );
#endif
        m_bLastDropAccepted = false;
		sendDragStatus( None );
		if( m_bDropSent && m_xDragSourceListener.is() )
		{
			DragSourceDropEvent dsde;
			dsde.Source				= static_cast< OWeakObject* >(this);
			dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
			dsde.DragSource			= static_cast< XDragSource* >(this);
			dsde.DropAction			= DNDConstants::ACTION_NONE;
			dsde.DropSuccess		= sal_False;
			m_xDragSourceListener->dragDropEnd( dsde );
			m_xDragSourceListener.clear();
		}
	}
}

/*
 *	XDragSource
 */

sal_Bool SelectionManager::isDragImageSupported() throw()
{
	return sal_False;
}

// ------------------------------------------------------------------------

sal_Int32 SelectionManager::getDefaultCursor( sal_Int8 dragAction ) throw()
{
	XLIB_Cursor aCursor = m_aNoneCursor;
	if( dragAction & DNDConstants::ACTION_MOVE )
		aCursor = m_aMoveCursor;
	else if( dragAction & DNDConstants::ACTION_COPY )
		aCursor = m_aCopyCursor;
	else if( dragAction & DNDConstants::ACTION_LINK )
		aCursor = m_aLinkCursor;
	return aCursor;
}

// ------------------------------------------------------------------------

int SelectionManager::getXdndVersion( XLIB_Window aWindow, XLIB_Window& rProxy )
{
	Atom* pProperties = NULL;
	int nProperties = 0;
	Atom nType;
	int nFormat;
	unsigned long nItems, nBytes;
	unsigned char* pBytes = NULL;

	int nVersion = -1;
	rProxy = None;

	/*
	 *	XListProperties is used here to avoid unnecessary XGetWindowProperty calls
	 *	and therefore reducing latency penalty
	 */
	pProperties = XListProperties( m_pDisplay, aWindow, &nProperties );
	// first look for proxy
	int i;
	for( i = 0; i < nProperties; i++ )
	{
		if( pProperties[i] == m_nXdndProxy )
		{
			XGetWindowProperty( m_pDisplay, aWindow, m_nXdndProxy, 0, 1, False, XA_WINDOW,
								&nType, &nFormat, &nItems, &nBytes, &pBytes );
			if( pBytes )
			{
				if( nType == XA_WINDOW )
					rProxy = *(XLIB_Window*)pBytes;
				XFree( pBytes );
				pBytes = NULL;
				if( rProxy != None )
				{
					// now check proxy wether it points to itself
					XGetWindowProperty( m_pDisplay, rProxy, m_nXdndProxy, 0, 1, False, XA_WINDOW,
										&nType, &nFormat, &nItems, &nBytes, &pBytes );
					if( pBytes )
					{
						if( nType == XA_WINDOW && *(XLIB_Window*)pBytes != rProxy )
							rProxy = None;
						XFree( pBytes );
						pBytes = NULL;
					}
					else
						rProxy = None;
				}
			}
			break;
		}
	}
	XLIB_Window aAwareWindow = rProxy != None ? rProxy : aWindow;

	XGetWindowProperty( m_pDisplay, aAwareWindow, m_nXdndAware, 0, 1, False, XA_ATOM,
						&nType, &nFormat, &nItems, &nBytes, &pBytes );
	if( pBytes )
	{
		if( nType == XA_ATOM )
			nVersion = *(Atom*)pBytes;
		XFree( pBytes );
	}

	nVersion = nVersion > nXdndProtocolRevision ? nXdndProtocolRevision : nVersion;

	return nVersion;
}

// ------------------------------------------------------------------------

void SelectionManager::updateDragWindow( int nX, int nY, XLIB_Window aRoot )
{
    ResettableMutexGuard aGuard( m_aMutex );

    css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );

	m_nLastDragX = nX;
	m_nLastDragY = nY;

	XLIB_Window aParent = aRoot;
	XLIB_Window aChild;
	XLIB_Window aNewProxy = None, aNewCurrentWindow = None;
	int nNewProtocolVersion = -1;
	int nWinX, nWinY;

	// find the first XdndAware window or check if root window is
	// XdndAware or has XdndProxy
	do
	{
		XTranslateCoordinates( m_pDisplay, aRoot, aParent, nX, nY, &nWinX, &nWinY, &aChild );
		if( aChild != None )
		{
			if( aChild == m_aCurrentDropWindow && aChild != aRoot && m_nCurrentProtocolVersion >= 0 )
			{
				aParent = aChild;
				break;
			}
			nNewProtocolVersion = getXdndVersion( aChild, aNewProxy );
			aParent = aChild;
		}
	} while( aChild != None && nNewProtocolVersion < 0 );

	aNewCurrentWindow = aParent;
	if( aNewCurrentWindow == aRoot )
	{
		// no children, try root drop
		nNewProtocolVersion = getXdndVersion( aNewCurrentWindow, aNewProxy );
		if( nNewProtocolVersion < 3 )
		{
			aNewCurrentWindow = aNewProxy = None;
			nNewProtocolVersion = nXdndProtocolRevision;
		}
	}


	DragSourceDragEvent dsde;
	dsde.Source				= static_cast< OWeakObject* >(this);
	dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
	dsde.DragSource			= static_cast< XDragSource* >(this);
	dsde.DropAction			= nNewProtocolVersion >= 0 ? m_nUserDragAction : DNDConstants::ACTION_COPY;
	dsde.UserAction			= nNewProtocolVersion >= 0 ? m_nUserDragAction : DNDConstants::ACTION_COPY;

	::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it;
	if( aNewCurrentWindow != m_aDropWindow )
	{
#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "drag left window 0x%lx (rev. %d), entered window 0x%lx (rev %d)\n", m_aDropWindow, m_nCurrentProtocolVersion, aNewCurrentWindow, nNewProtocolVersion );
#endif

		if( m_aDropWindow != None )
		{
			it = m_aDropTargets.find( m_aDropWindow );
			if( it != m_aDropTargets.end() )
				// shortcut for own drop targets
			{
				DropTargetEvent dte;
				dte.Source	= static_cast< OWeakObject* >( it->second.m_pTarget );
                aGuard.clear();
				it->second.m_pTarget->dragExit( dte );
                aGuard.reset();
			}
			else
			{
				// send old drop target a XdndLeave
				XEvent aEvent;
				aEvent.type = ClientMessage;
				aEvent.xclient.display			= m_pDisplay;
				aEvent.xclient.format			= 32;
				aEvent.xclient.message_type		= m_nXdndLeave;
				aEvent.xclient.window			= m_aDropWindow;
				aEvent.xclient.data.l[0]		= m_aWindow;
				aEvent.xclient.data.l[1]		= 0;
				XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
			}
            if( xListener.is() )
            {
                aGuard.clear();
                xListener->dragExit( dsde );
                aGuard.reset();
            }
		}

		m_nCurrentProtocolVersion	= nNewProtocolVersion;
		m_aDropWindow				= aNewCurrentWindow;
		m_aDropProxy				= aNewProxy != None ? aNewProxy : m_aDropWindow;

		it = m_aDropTargets.find( m_aDropWindow );
		if( it != m_aDropTargets.end() && ! it->second.m_pTarget->m_bActive )
			m_aDropProxy = None;

		if( m_aDropProxy != None && xListener.is() )
        {
            aGuard.clear();
            xListener->dragEnter( dsde );
            aGuard.reset();
        }
		// send XdndEnter
		if( m_aDropProxy != None && m_nCurrentProtocolVersion >= 0 )
		{
			it = m_aDropTargets.find( m_aDropWindow );
			if( it != m_aDropTargets.end() )
			{
				XTranslateCoordinates( m_pDisplay, aRoot, m_aDropWindow, nX, nY, &nWinX, &nWinY, &aChild );
				DropTargetDragEnterEvent dtde;
				dtde.Source					= static_cast< OWeakObject* >( it->second.m_pTarget );
				dtde.Context				= new DropTargetDragContext( m_aCurrentDropWindow, m_nDropTimestamp, *this );
				dtde.LocationX				= nWinX;
				dtde.LocationY				= nWinY;
				dtde.DropAction				= m_nUserDragAction;
                dtde.SourceActions			= m_nSourceActions;
				dtde.SupportedDataFlavors	= m_xDragSourceTransferable->getTransferDataFlavors();
                aGuard.clear();
				it->second.m_pTarget->dragEnter( dtde );
                aGuard.reset();
			}
			else
			{
				XEvent aEvent;
				aEvent.type = ClientMessage;
				aEvent.xclient.display			= m_pDisplay;
				aEvent.xclient.format			= 32;
				aEvent.xclient.message_type	= m_nXdndEnter;
				aEvent.xclient.window		= m_aDropWindow;
				aEvent.xclient.data.l[0]	= m_aWindow;
				aEvent.xclient.data.l[1]	= m_nCurrentProtocolVersion << 24;
				memset( aEvent.xclient.data.l + 2, 0, sizeof( long )*3 );
				// fill in data types
                ::std::list< Atom > aConversions;
                getNativeTypeList( m_aDragFlavors, aConversions, m_nXdndSelection );
				if( aConversions.size() > 3 )
					aEvent.xclient.data.l[1] |= 1;
                ::std::list< Atom >::const_iterator type_it = aConversions.begin();
				for( int i = 0; type_it != aConversions.end() && i < 3; i++, ++type_it )
					aEvent.xclient.data.l[i+2] = *type_it;
				XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
			}
		}
		m_nNoPosX = m_nNoPosY = m_nNoPosWidth = m_nNoPosHeight = 0;
	}
	else if( m_aDropProxy != None && xListener.is() )
    {
        aGuard.clear();
		// drag over for XdndAware windows comes when receiving XdndStatus
        xListener->dragOver( dsde );
    }
}

// ------------------------------------------------------------------------

void SelectionManager::startDrag(
                                 const DragGestureEvent& trigger,
                                 sal_Int8 sourceActions,
                                 sal_Int32,
                                 sal_Int32,
                                 const css::uno::Reference< XTransferable >& transferable,
                                 const css::uno::Reference< XDragSourceListener >& listener
                                 ) throw()
{
#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "startDrag( sourceActions = %x )\n", (int)sourceActions );
#endif

	DragSourceDropEvent aDragFailedEvent;
	aDragFailedEvent.Source				= static_cast< OWeakObject* >(this);
	aDragFailedEvent.DragSource			= static_cast< XDragSource* >(this);
	aDragFailedEvent.DragSourceContext	= new DragSourceContext( None, CurrentTime, *this );
	aDragFailedEvent.DropAction			= DNDConstants::ACTION_NONE;
	aDragFailedEvent.DropSuccess		= sal_False;

	if( m_aDragRunning.check() )
	{
		if( listener.is() )
			listener->dragDropEnd( aDragFailedEvent );

#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "*** ERROR *** second drag and drop started.\n" );
        if( m_xDragSourceListener.is() )
            fprintf( stderr, "*** ERROR *** drag source listener already set.\n" );
        else
            fprintf( stderr, "*** ERROR *** drag thread already running.\n" );
#endif
		return;
	}

    SalFrame* pCaptureFrame = NULL;

	{
		ClearableMutexGuard aGuard(m_aMutex);

        // first get the current pointer position and the window that
        // the pointer is located in. since said window should be one
        // of our DropTargets at the time of executeDrag we can use
        // them for a start
        XLIB_Window aRoot, aParent, aChild;
        int root_x, root_y, win_x, win_y;
        unsigned int mask;

		::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it;
		it = m_aDropTargets.begin();
		while( it != m_aDropTargets.end() )
		{
			if( XQueryPointer( m_pDisplay, it->second.m_aRootWindow,
							   &aRoot, &aParent,
							   &root_x, &root_y,
							   &win_x, &win_y,
							   &mask ) )
			{
				aParent = it->second.m_aRootWindow;
				break;
			}
			++it;
		}

        // don't start DnD if there is none of our windows on the same screen as
        // the pointer or if no mouse button is pressed
		if( it == m_aDropTargets.end() || (mask & (Button1Mask|Button2Mask|Button3Mask)) == 0 )
		{
            aGuard.clear();
			if( listener.is() )
				listener->dragDropEnd( aDragFailedEvent );
			return;
		}

        // try to find which of our drop targets is the drag source
        // if that drop target is deregistered we should stop executing
        // the drag (actually this is a poor substitute for an "endDrag"
        // method ).
        m_aDragSourceWindow = None;
        aParent = aRoot = it->second.m_aRootWindow;
        do
        {
            XTranslateCoordinates( m_pDisplay, aRoot, aParent, root_x, root_y, &win_x, &win_y, &aChild );
            if( aChild != None && m_aDropTargets.find( aChild ) != m_aDropTargets.end() )
            {
                m_aDragSourceWindow = aChild;
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "found drag source window 0x%lx\n", m_aDragSourceWindow );
#endif
                break;
            }
            aParent = aChild;
        } while( aChild != None );


#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "try to grab pointer ... " );
#endif
		int nPointerGrabSuccess =
			XGrabPointer( m_pDisplay, it->second.m_aRootWindow, True,
						  DRAG_EVENT_MASK,
						  GrabModeAsync, GrabModeAsync,
						  None,
						  None,
						  CurrentTime );
        /* if we could not grab the pointer here, there is a chance
           that the pointer is grabbed by the other vcl display (the main loop)
           so let's break that grab an reset it later
           
           remark: this whole code should really be molten into normal vcl so only
           one display is used ....
        */
        if( nPointerGrabSuccess != GrabSuccess )
        {
            vos::IMutex& rSolarMutex( Application::GetSolarMutex() );
            if( rSolarMutex.tryToAcquire() )
            {
                pCaptureFrame = GetX11SalData()->GetDisplay()->GetCaptureFrame();
                if( pCaptureFrame )
                {
                    GetX11SalData()->GetDisplay()->CaptureMouse( NULL );
                    nPointerGrabSuccess =
                                XGrabPointer( m_pDisplay, it->second.m_aRootWindow, True,
                                              DRAG_EVENT_MASK,
                                              GrabModeAsync, GrabModeAsync,
                                              None,
                                              None,
                                              CurrentTime );
                }
            }
        }
#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "%d\n", nPointerGrabSuccess );
#endif
#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "try to grab keyboard ... " );
#endif
		int nKeyboardGrabSuccess =
			XGrabKeyboard( m_pDisplay, it->second.m_aRootWindow, True,
                           GrabModeAsync, GrabModeAsync, CurrentTime );
#if OSL_DEBUG_LEVEL > 1
		fprintf( stderr, "%d\n", nKeyboardGrabSuccess );
#endif
		if( nPointerGrabSuccess != GrabSuccess || nKeyboardGrabSuccess != GrabSuccess )
		{
			if( nPointerGrabSuccess == GrabSuccess )
				XUngrabPointer( m_pDisplay, CurrentTime );
			if( nKeyboardGrabSuccess == GrabSuccess )
				XUngrabKeyboard( m_pDisplay, CurrentTime );
            XFlush( m_pDisplay );
            aGuard.clear();
			if( listener.is() )
				listener->dragDropEnd( aDragFailedEvent );
            if( pCaptureFrame )
            {
                vos::IMutex& rSolarMutex( Application::GetSolarMutex() );
                if( rSolarMutex.tryToAcquire() )
                    GetX11SalData()->GetDisplay()->CaptureMouse( pCaptureFrame );
#if OSL_DEBUG_LEVEL > 0
                else
                    OSL_ENSURE( 0, "failed to acquire SolarMutex to reset capture frame" );
#endif
            }
			return;
		}

		m_xDragSourceTransferable	= transferable;
		m_xDragSourceListener		= listener;
		m_aDragFlavors				= transferable->getTransferDataFlavors();
		m_aCurrentCursor			= None;

		requestOwnership( m_nXdndSelection );

        ::std::list< Atom > aConversions;
        ::std::list< Atom >::const_iterator type_it;
        getNativeTypeList( m_aDragFlavors, aConversions, m_nXdndSelection );

        int nTypes = aConversions.size();
		Atom* pTypes = (Atom*)alloca( sizeof(Atom)*nTypes );
        type_it = aConversions.begin();
        for( int n = 0; n < nTypes; n++, ++type_it )
            pTypes[n] = *type_it;

		XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, nTypes );

		m_nSourceActions				= sourceActions | DNDConstants::ACTION_DEFAULT;
		m_nUserDragAction				= DNDConstants::ACTION_MOVE & m_nSourceActions;
        if( ! m_nUserDragAction )
            m_nUserDragAction			= DNDConstants::ACTION_COPY & m_nSourceActions;
        if( ! m_nUserDragAction )
            m_nUserDragAction			= DNDConstants::ACTION_LINK & m_nSourceActions;
        m_nTargetAcceptAction			= DNDConstants::ACTION_DEFAULT;
		m_bDropSent						= false;
		m_bDropSuccess					= false;
		m_bWaitingForPrimaryConversion	= false;
		m_nDragButton					= Button1; // default to left button
        com::sun::star::awt::MouseEvent aEvent;
		if( trigger.Event >>= aEvent )
		{
			if( aEvent.Buttons & MouseButton::LEFT )
				m_nDragButton = Button1;
			else if( aEvent.Buttons & MouseButton::RIGHT )
				m_nDragButton = Button3;
			else if( aEvent.Buttons & MouseButton::MIDDLE )
				m_nDragButton = Button2;
		}
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "m_nUserDragAction = %x\n", (int)m_nUserDragAction );
#endif
		updateDragWindow( root_x, root_y, aRoot );
        m_nUserDragAction = ~0;
		updateDragAction( mask );
	}

    m_aDragRunning.set();
	m_aDragExecuteThread = osl_createSuspendedThread( call_SelectionManager_runDragExecute, this );
    if( m_aDragExecuteThread )
        osl_resumeThread( m_aDragExecuteThread );
    else
    {
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "osl_createSuspendedThread failed for drag execute\n" );
#endif
        m_xDragSourceListener.clear();
        m_xDragSourceTransferable.clear();

		m_bDropSent							= false;
		m_bDropSuccess						= false;
		m_bWaitingForPrimaryConversion		= false;
		m_aDropWindow						= None;
		m_aDropProxy						= None;
		m_nCurrentProtocolVersion			= nXdndProtocolRevision;
		m_nNoPosX							= 0;
		m_nNoPosY							= 0;
		m_nNoPosWidth						= 0;
		m_nNoPosHeight						= 0;
		m_aCurrentCursor					= None;

		XUngrabPointer( m_pDisplay, CurrentTime );
		XUngrabKeyboard( m_pDisplay, CurrentTime );
        XFlush( m_pDisplay );

        if( pCaptureFrame )
        {
            vos::IMutex& rSolarMutex( Application::GetSolarMutex() );
            if( rSolarMutex.tryToAcquire() )
                GetX11SalData()->GetDisplay()->CaptureMouse( pCaptureFrame );
#if OSL_DEBUG_LEVEL > 0
            else
                OSL_ENSURE( 0, "failed to acquire SolarMutex to reset capture frame" );
#endif
        }

        m_aDragRunning.reset();

		if( listener.is() )
			listener->dragDropEnd( aDragFailedEvent );
    }
}

void SelectionManager::runDragExecute( void* pThis )
{
	SelectionManager* This = (SelectionManager*)pThis;
	This->dragDoDispatch();
}

void SelectionManager::dragDoDispatch()
{

	// do drag
	// m_xDragSourceListener will be cleared on finished drop
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "begin executeDrag dispatching\n" );
#endif
	TimeValue aTVal;
	aTVal.Seconds = 0;
	aTVal.Nanosec = 200000000;
	oslThread aThread = m_aDragExecuteThread;
	while( m_xDragSourceListener.is() && ( ! m_bDropSent || time(NULL)-m_nDropTimeout < 5 ) && osl_scheduleThread( aThread ) )
	{
        // let the thread in the run method do the dispatching
        // just look occasionally here whether drop timed out or is completed
		osl_waitThread( &aTVal );
	}
#if OSL_DEBUG_LEVEL > 1
	fprintf( stderr, "end executeDrag dispatching\n" );
#endif
	{
		ClearableMutexGuard aGuard(m_aMutex);

        css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
        css::uno::Reference< XTransferable > xTransferable( m_xDragSourceTransferable );
        m_xDragSourceListener.clear();
        m_xDragSourceTransferable.clear();

        DragSourceDropEvent dsde;
        dsde.Source				= static_cast< OWeakObject* >(this);
        dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
        dsde.DragSource			= static_cast< XDragSource* >(this);
        dsde.DropAction			= DNDConstants::ACTION_NONE;
        dsde.DropSuccess		= sal_False;

		// cleanup after drag
		if( m_bWaitingForPrimaryConversion )
			getAdaptor( XA_PRIMARY )->clearTransferable();

		m_bDropSent							= false;
		m_bDropSuccess						= false;
		m_bWaitingForPrimaryConversion		= false;
		m_aDropWindow						= None;
		m_aDropProxy						= None;
		m_nCurrentProtocolVersion			= nXdndProtocolRevision;
		m_nNoPosX							= 0;
		m_nNoPosY							= 0;
		m_nNoPosWidth						= 0;
		m_nNoPosHeight						= 0;
		m_aCurrentCursor					= None;

		XUngrabPointer( m_pDisplay, CurrentTime );
		XUngrabKeyboard( m_pDisplay, CurrentTime );
        XFlush( m_pDisplay );

		m_aDragExecuteThread = NULL;
        m_aDragRunning.reset();

        aGuard.clear();
        if( xListener.is() )
		{
            xTransferable.clear();
			xListener->dragDropEnd( dsde );
		}
	}
	osl_destroyThread( aThread );
}

/*
 *	XDragSourceContext
 */

sal_Int32 SelectionManager::getCurrentCursor()
{
	return m_aCurrentCursor;
}

// ------------------------------------------------------------------------

void SelectionManager::setCursor( sal_Int32 cursor, XLIB_Window aDropWindow, XLIB_Time )
{
    MutexGuard aGuard( m_aMutex );
	if( aDropWindow == m_aDropWindow && XLIB_Cursor(cursor) != m_aCurrentCursor )
	{
		if( m_xDragSourceListener.is() && ! m_bDropSent )
		{
			m_aCurrentCursor = cursor;
			XChangeActivePointerGrab( m_pDisplay, DRAG_EVENT_MASK, cursor, CurrentTime );
			XFlush( m_pDisplay );
		}
	}
}

// ------------------------------------------------------------------------

void SelectionManager::setImage( sal_Int32, XLIB_Window, XLIB_Time )
{
}

// ------------------------------------------------------------------------

void SelectionManager::transferablesFlavorsChanged()
{
	MutexGuard aGuard(m_aMutex);

	m_aDragFlavors = m_xDragSourceTransferable->getTransferDataFlavors();
	int i;

    std::list< Atom > aConversions;
    std::list< Atom >::const_iterator type_it;

    getNativeTypeList( m_aDragFlavors, aConversions, m_nXdndSelection );

    int nTypes = aConversions.size();
	Atom* pTypes = (Atom*)alloca( sizeof(Atom)*aConversions.size() );
    for( i = 0, type_it = aConversions.begin(); type_it != aConversions.end(); ++type_it, i++ )
        pTypes[i] = *type_it;
	XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, nTypes );

	if( m_aCurrentDropWindow != None && m_nCurrentProtocolVersion >= 0 )
	{
		// send synthetic leave and enter events

		XEvent aEvent;

		aEvent.type = ClientMessage;
		aEvent.xclient.display			= m_pDisplay;
		aEvent.xclient.format			= 32;
		aEvent.xclient.window			= m_aDropWindow;
		aEvent.xclient.data.l[0]		= m_aWindow;

		aEvent.xclient.message_type		= m_nXdndLeave;
		aEvent.xclient.data.l[1]		= 0;
		XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );

		aEvent.xclient.message_type	= m_nXdndEnter;
		aEvent.xclient.data.l[1]	= m_nCurrentProtocolVersion << 24;
		memset( aEvent.xclient.data.l + 2, 0, sizeof( long )*3 );
		// fill in data types
		if( nTypes > 3 )
			aEvent.xclient.data.l[1] |= 1;
		for( int j = 0; j < nTypes && j < 3; j++ )
			aEvent.xclient.data.l[j+2] = pTypes[j];

		XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
	}
}

/*
 *	dispatch loop
 */

// ------------------------------------------------------------------------

bool SelectionManager::handleXEvent( XEvent& rEvent )
{
	/*
	 *	since we are XConnectionListener to a second X display
	 *	to get client messages it is essential not to dispatch
	 *	events twice that we get on both connections
     *
     *  #95201# between dispatching ButtonPress and startDrag
     *  the user can already have released the mouse. The ButtonRelease
     *  will then be dispatched in VCLs queue and never turn up here.
     *  Which is not so good, since startDrag will XGrabPointer and
     *  XGrabKeyboard -> solid lock.
	 */
	if( rEvent.xany.display != m_pDisplay
        && rEvent.type != ClientMessage
        && rEvent.type != ButtonPress
        && rEvent.type != ButtonRelease
        )
		return false;

    bool bHandled = false;
	switch (rEvent.type)
	{
		case SelectionClear:
		{
            ClearableMutexGuard aGuard(m_aMutex);
#if OSL_DEBUG_LEVEL > 1
			fprintf( stderr, "SelectionClear for selection %s\n",
					 OUStringToOString( getString( rEvent.xselectionclear.selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr()
					 );
#endif
			SelectionAdaptor* pAdaptor = getAdaptor( rEvent.xselectionclear.selection );
            std::hash_map< Atom, Selection* >::iterator it( m_aSelections.find( rEvent.xselectionclear.selection ) );
            if( it != m_aSelections.end() )
                it->second->m_bOwner = false;
            aGuard.clear();
			if ( pAdaptor )
				pAdaptor->clearTransferable();
		}
		break;

		case SelectionRequest:
			bHandled = handleSelectionRequest( rEvent.xselectionrequest );
			break;
		case PropertyNotify:
			if( rEvent.xproperty.window == m_aWindow ||
				rEvent.xproperty.window == m_aCurrentDropWindow
				)
				bHandled = handleReceivePropertyNotify( rEvent.xproperty );
			else
				bHandled = handleSendPropertyNotify( rEvent.xproperty );
			break;
		case SelectionNotify:
			bHandled = handleSelectionNotify( rEvent.xselection );
			break;
		case ClientMessage:
			// messages from drag target
			if( rEvent.xclient.message_type == m_nXdndStatus ||
				rEvent.xclient.message_type == m_nXdndFinished )
				bHandled = handleDragEvent( rEvent );
			// messages from drag source
			else if(
                    rEvent.xclient.message_type == m_nXdndEnter		||
                    rEvent.xclient.message_type == m_nXdndLeave		||
                    rEvent.xclient.message_type == m_nXdndPosition	||
                    rEvent.xclient.message_type == m_nXdndDrop
                    )
				bHandled = handleDropEvent( rEvent.xclient );
			break;
		case EnterNotify:
		case LeaveNotify:
		case MotionNotify:
		case ButtonPress:
		case ButtonRelease:
		case XLIB_KeyPress:
		case KeyRelease:
			bHandled = handleDragEvent( rEvent );
			break;
		default:
			;
	}
    return bHandled;
}

// ------------------------------------------------------------------------

void SelectionManager::dispatchEvent( int millisec )
{
	pollfd aPollFD;
	XEvent event;

	// query socket handle to poll on
	aPollFD.fd      = ConnectionNumber( m_pDisplay );
	aPollFD.events  = POLLIN;
	aPollFD.revents = 0;

	// wait for activity (outside the xlib)
	if( poll( &aPollFD, 1, millisec ) > 0 )
	{
		// now acquire the mutex to prevent other threads
		// from using the same X connection
		ResettableMutexGuard aGuard(m_aMutex);

		// prevent that another thread already ate the input
		// this can happen if e.g. another thread does
		// an X request getting a response. the response
		// would be removed from the queue and we would end up
		// with an empty socket here
		if( poll( &aPollFD, 1, 0 ) > 0 )
		{
            int nPending = 1;
			while( nPending )
			{
                nPending = XPending( m_pDisplay );
                if( nPending )
                {
                    XNextEvent( m_pDisplay, &event );
                    aGuard.clear();
                    handleXEvent( event );
                    aGuard.reset();
                }
			}
		}
	}
}

// ------------------------------------------------------------------------

void SelectionManager::run( void* pThis )
{
#if OSL_DEBUG_LEVEL > 1
	fprintf(stderr, "SelectionManager::run\n" );
#endif
	// dispatch until the cows come home

	SelectionManager* This = (SelectionManager*)pThis;

	timeval aLast;
	gettimeofday( &aLast, 0 );

	css::uno::Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
	if( xFact.is() )
	{
		css::uno::Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
		if( xDesktop.is() )
			xDesktop->addTerminateListener(This);
	}

	while( osl_scheduleThread(This->m_aThread) )
	{
		This->dispatchEvent( 1000 );

		timeval aNow;
		gettimeofday( &aNow, 0 );

        if( (aNow.tv_sec - aLast.tv_sec) > 0 )
        {
            ClearableMutexGuard aGuard(This->m_aMutex);
            std::list< std::pair< SelectionAdaptor*, css::uno::Reference< XInterface > > > aChangeList;

            for( std::hash_map< Atom, Selection* >::iterator it = This->m_aSelections.begin(); it != This->m_aSelections.end(); ++it )
            {
                if( it->first != This->m_nXdndSelection && ! it->second->m_bOwner )
                {
                    XLIB_Window aOwner = XGetSelectionOwner( This->m_pDisplay, it->first );
                    if( aOwner != it->second->m_aLastOwner )
                    {
                        it->second->m_aLastOwner = aOwner;
                        std::pair< SelectionAdaptor*, css::uno::Reference< XInterface > >
                            aKeep( it->second->m_pAdaptor, it->second->m_pAdaptor->getReference() );
                        aChangeList.push_back( aKeep );
                    }
                }
            }
            aGuard.clear();
            while( aChangeList.begin() != aChangeList.end() )
            {
                aChangeList.front().first->fireContentsChanged();
                aChangeList.pop_front();
            }
            aLast = aNow;
        }
	}
#if OSL_DEBUG_LEVEL > 1
	fprintf(stderr, "SelectionManager::run end\n" );
#endif
}

void SelectionManager::shutdown() throw()
{
    ResettableMutexGuard aGuard(m_aMutex);
    if( m_bShutDown )
    {
        return;
    }
    m_bShutDown = true;
    // stop dispatching
    if( m_aThread )
    {
        osl_terminateThread( m_aThread );
        /*
         * Allow thread to finish before app exits to avoid pulling the carpet
         * out from under it if pasting is occurring during shutdown
         *
         * a) allow it to have the Mutex and 
         * b) reschedule to allow it to complete callbacks to any
         * Application::GetSolarMutex protected regions, etc. e.g.
         * TransferableHelper::getTransferDataFlavors (via
         * SelectionManager::handleSelectionRequest) which it might
         * currently be trying to enter. 
         *
         * Otherwise the thread may be left still waiting on a GlobalMutex
         * when that gets destroyed, letting the thread blow up and die
         * when enters the section in a now dead OOo instance.
         */
        aGuard.clear();
        while (osl_isThreadRunning(m_aThread))
        {
            vos::OGuard guard2(Application::GetSolarMutex());
            Application::Reschedule();
        }
        osl_joinWithThread( m_aThread );
        osl_destroyThread( m_aThread );
        m_aThread = NULL;
        aGuard.reset();
    }
    m_xDisplayConnection->removeEventHandler( Any(), this );
    m_xDisplayConnection.clear();
}

// ------------------------------------------------------------------------

sal_Bool SelectionManager::handleEvent( const Any& event ) throw()
{
    Sequence< sal_Int8 > aSeq;
    if( (event >>= aSeq) )
    {
        XEvent* pEvent = (XEvent*)aSeq.getArray();
        XLIB_Time nTimestamp = CurrentTime;
        if( pEvent->type == ButtonPress || pEvent->type == ButtonRelease )
            nTimestamp = pEvent->xbutton.time;
        else if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
            nTimestamp = pEvent->xkey.time;
        else if( pEvent->type == MotionNotify )
            nTimestamp = pEvent->xmotion.time;
        else if( pEvent->type == PropertyNotify )
            nTimestamp = pEvent->xproperty.time;
        
        if( nTimestamp != CurrentTime )
        {
            MutexGuard aGuard(m_aMutex);
            
            m_nSelectionTimestamp = nTimestamp;
        }
        
        return sal_Bool( handleXEvent( *pEvent ) );
    }
    else
    {
        #if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "SelectionManager got downing event\n" );
        #endif
        shutdown();
    }
    return sal_True;
}

void SAL_CALL SelectionManager::disposing( const ::com::sun::star::lang::EventObject& )
    throw( ::com::sun::star::uno::RuntimeException )
{
}

void SAL_CALL SelectionManager::queryTermination( const ::com::sun::star::lang::EventObject& )
    throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException )
{
}

/*
 * To be safe, shutdown needs to be called before the ~SfxApplication is called, waiting until
 * the downing event can be too late if paste are requested during shutdown and ~SfxApplication
 * has been called before vcl is shutdown
 */
void SAL_CALL SelectionManager::notifyTermination( const ::com::sun::star::lang::EventObject& rEvent )
    throw( ::com::sun::star::uno::RuntimeException )
{
    css::uno::Reference< XDesktop > xDesktop( rEvent.Source, UNO_QUERY );
    if( xDesktop.is() == sal_True )
        xDesktop->removeTerminateListener( this );
    #if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "SelectionManager got app termination event\n" );
    #endif
    shutdown();
}

// ------------------------------------------------------------------------

void SelectionManager::registerHandler( Atom selection, SelectionAdaptor& rAdaptor )
{
	MutexGuard aGuard(m_aMutex);

	Selection* pNewSelection	= new Selection();
	pNewSelection->m_pAdaptor	= &rAdaptor;
	pNewSelection->m_aAtom		= selection;
	m_aSelections[ selection ]	= pNewSelection;
}

// ------------------------------------------------------------------------

void SelectionManager::deregisterHandler( Atom selection )
{
	MutexGuard aGuard(m_aMutex);

	::std::hash_map< Atom, Selection* >::iterator it =
		  m_aSelections.find( selection );
	if( it != m_aSelections.end() )
	{
        delete it->second->m_pPixmap;
		delete it->second;
		m_aSelections.erase( it );
	}
}

// ------------------------------------------------------------------------

static bool bWasError = false;

extern "C"
{
    int local_xerror_handler(Display* , XErrorEvent*)
    {
        bWasError = true;
        return 0;
    }
    typedef int(*xerror_hdl_t)(Display*,XErrorEvent*);
}

void SelectionManager::registerDropTarget( XLIB_Window aWindow, DropTarget* pTarget )
{
	MutexGuard aGuard(m_aMutex);

	// sanity check
	::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
		  m_aDropTargets.find( aWindow );
	if( it != m_aDropTargets.end() )
		OSL_ASSERT( "attempt to register window as drop target twice" );
	else if( aWindow && m_pDisplay )
	{
		DropTargetEntry aEntry( pTarget );
        bWasError=false;
        /* #i100000# ugly workaround: gtk sets its own XErrorHandler which is not suitable for us
           unfortunately XErrorHandler is not per display, so this is just and ugly hack
           Need to remove separate display and integrate clipboard/dnd into vcl's unx code ASAP
        */
		xerror_hdl_t pOldHandler = XSetErrorHandler( local_xerror_handler );
		XSelectInput( m_pDisplay, aWindow, PropertyChangeMask );
        if( ! bWasError )
        {
		    // set XdndAware
		    XChangeProperty( m_pDisplay, aWindow, m_nXdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&nXdndProtocolRevision, 1 );
            if( ! bWasError )
            {
		        // get root window of window (in 99.999% of all cases this will be
		        // DefaultRootWindow( m_pDisplay )
		        int x, y;
		        unsigned int w, h, bw, d;
		        XGetGeometry( m_pDisplay, aWindow, &aEntry.m_aRootWindow,
			                  &x, &y, &w, &h, &bw, &d );
            }
        }
        XSetErrorHandler( pOldHandler );
        if(bWasError)
            return;
		m_aDropTargets[ aWindow ] = aEntry;
	}
	else
		OSL_ASSERT( "attempt to register None as drop target" );
}

// ------------------------------------------------------------------------

void SelectionManager::deregisterDropTarget( XLIB_Window aWindow )
{
	ClearableMutexGuard aGuard(m_aMutex);

	m_aDropTargets.erase( aWindow );
    if( aWindow == m_aDragSourceWindow && m_aDragRunning.check() )
    {
        // abort drag
        std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
            m_aDropTargets.find( m_aDropWindow );
        if( it != m_aDropTargets.end() )
        {
            DropTargetEvent dte;
            dte.Source = static_cast< OWeakObject* >( it->second.m_pTarget );
            aGuard.clear();
            it->second.m_pTarget->dragExit( dte );
        }
        else if( m_aDropProxy != None && m_nCurrentProtocolVersion >= 0 )
        {
            // send XdndLeave
            XEvent aEvent;
            aEvent.type = ClientMessage;
            aEvent.xclient.display		= m_pDisplay;
            aEvent.xclient.format		= 32;
            aEvent.xclient.message_type	= m_nXdndLeave;
            aEvent.xclient.window		= m_aDropWindow;
            aEvent.xclient.data.l[0]	= m_aWindow;
            memset( aEvent.xclient.data.l+1, 0, sizeof(long)*4);
            m_aDropWindow = m_aDropProxy = None;
            XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
        }
        // notify the listener
        DragSourceDropEvent dsde;
        dsde.Source				= static_cast< OWeakObject* >(this);
        dsde.DragSourceContext	= new DragSourceContext( m_aDropWindow, m_nDragTimestamp, *this );
        dsde.DragSource			= static_cast< XDragSource* >(this);
        dsde.DropAction			= DNDConstants::ACTION_NONE;
        dsde.DropSuccess		= sal_False;
        css::uno::Reference< XDragSourceListener > xListener( m_xDragSourceListener );
        m_xDragSourceListener.clear();
        aGuard.clear();
        xListener->dragDropEnd( dsde );
    }
}

/*
 *	SelectionAdaptor
 */

css::uno::Reference< XTransferable > SelectionManager::getTransferable() throw()
{
	return m_xDragSourceTransferable;
}

// ------------------------------------------------------------------------

void SelectionManager::clearTransferable() throw()
{
	m_xDragSourceTransferable.clear();
}

// ------------------------------------------------------------------------

void SelectionManager::fireContentsChanged() throw()
{
}

// ------------------------------------------------------------------------

css::uno::Reference< XInterface > SelectionManager::getReference() throw()
{
    return css::uno::Reference< XInterface >( static_cast<OWeakObject*>(this) );
}

// ------------------------------------------------------------------------

/*
 *	SelectionManagerHolder
 */

SelectionManagerHolder::SelectionManagerHolder() :
		::cppu::WeakComponentImplHelper3<
    XDragSource,
    XInitialization,
    XServiceInfo > (m_aMutex)
{
}

// ------------------------------------------------------------------------

SelectionManagerHolder::~SelectionManagerHolder()
{
}

// ------------------------------------------------------------------------

void SelectionManagerHolder::initialize( const Sequence< Any >& arguments ) throw( ::com::sun::star::uno::Exception )
{
	OUString aDisplayName;

	if( arguments.getLength() > 0 )
	{
		css::uno::Reference< XDisplayConnection > xConn;
		arguments.getConstArray()[0] >>= xConn;
		if( xConn.is() )
		{
			Any aIdentifier;
			aIdentifier >>= aDisplayName;
		}
	}

	SelectionManager& rManager = SelectionManager::get( aDisplayName );
	rManager.initialize( arguments );
	m_xRealDragSource = static_cast< XDragSource* >(&rManager);
}

/*
 * 	XDragSource
 */

sal_Bool SelectionManagerHolder::isDragImageSupported() throw()
{
	return m_xRealDragSource.is() ? m_xRealDragSource->isDragImageSupported() : sal_False;
}

// ------------------------------------------------------------------------

sal_Int32 SelectionManagerHolder::getDefaultCursor( sal_Int8 dragAction ) throw()
{
	return m_xRealDragSource.is() ? m_xRealDragSource->getDefaultCursor( dragAction ) : 0;
}

// ------------------------------------------------------------------------

void SelectionManagerHolder::startDrag(
                                       const ::com::sun::star::datatransfer::dnd::DragGestureEvent& trigger,
                                       sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
                                       const css::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& transferable,
                                       const css::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSourceListener >& listener
                                       ) throw()
{
	if( m_xRealDragSource.is() )
		m_xRealDragSource->startDrag( trigger, sourceActions, cursor, image, transferable, listener );
}

// ------------------------------------------------------------------------

/*
 *	XServiceInfo
 */

// ------------------------------------------------------------------------

OUString SelectionManagerHolder::getImplementationName() throw()
{
	return OUString::createFromAscii(XDND_IMPLEMENTATION_NAME);
}

// ------------------------------------------------------------------------

sal_Bool SelectionManagerHolder::supportsService( const OUString& ServiceName ) throw()
{
	Sequence < OUString > SupportedServicesNames = Xdnd_getSupportedServiceNames();

	for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
		if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
			return sal_True;

	return sal_False;
}

// ------------------------------------------------------------------------

Sequence< OUString > SelectionManagerHolder::getSupportedServiceNames() throw()
{
	return Xdnd_getSupportedServiceNames();
}


// ------------------------------------------------------------------------

