summaryrefslogtreecommitdiff
path: root/dtrans/source/X11
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2004-07-05 08:15:59 +0000
committerOliver Bolte <obo@openoffice.org>2004-07-05 08:15:59 +0000
commit51cd62a64ce252b5efa3cc231555dfaa72099fa6 (patch)
treefc991fd126623871c8a7df6dacf24fc96afd7fba /dtrans/source/X11
parentba83e7087facfa9323a2ac3cbc001c0ea2e1f224 (diff)
INTEGRATION: CWS vcl22 (1.68.8); FILE MERGED
2004/04/28 09:51:41 pl 1.68.8.1: #i28193# larger threshold for incremental transfers, better handling for failed incrmental transfers
Diffstat (limited to 'dtrans/source/X11')
-rw-r--r--dtrans/source/X11/X11_selection.cxx164
1 files changed, 103 insertions, 61 deletions
diff --git a/dtrans/source/X11/X11_selection.cxx b/dtrans/source/X11/X11_selection.cxx
index b3e62140a80a..682d336db2fd 100644
--- a/dtrans/source/X11/X11_selection.cxx
+++ b/dtrans/source/X11/X11_selection.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: X11_selection.cxx,v $
*
- * $Revision: 1.69 $
+ * $Revision: 1.70 $
*
- * last change: $Author: rt $ $Date: 2004-06-17 11:59:37 $
+ * last change: $Author: obo $ $Date: 2004-07-05 09:15:59 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -109,7 +109,6 @@
#include <rtl/tencinfo.h>
#endif
-#define INCR_MIN_SIZE 1024
#define INCR_TIMEOUT 5
#define DRAG_EVENT_MASK ButtonPressMask |\
@@ -238,26 +237,8 @@ rtl_TextEncoding x11::getTextPlainEncoding( const OUString& rMimeType )
// ------------------------------------------------------------------------
-SelectionManager::IncrementalTransfer::IncrementalTransfer(
- const Sequence< sal_Int8 >& rData,
- Window aRequestor,
- Atom aProperty,
- Atom aTarget,
- int nFormat
- ) :
- m_aData( rData ),
- m_aRequestor( aRequestor ),
- m_aProperty( aProperty ),
- m_aTarget( aTarget ),
- m_nFormat( nFormat ),
- m_nBufferPos( 0 ),
- m_nTransferStartTime( time( NULL ) )
-{
-}
-
-// ------------------------------------------------------------------------
-
SelectionManager::SelectionManager() :
+ m_nIncrementalThreshold( 15*1024 ),
m_pDisplay( NULL ),
m_aWindow( None ),
m_aDropWindow( None ),
@@ -437,6 +418,11 @@ void SelectionManager::initialize( const Sequence< Any >& arguments ) throw (::c
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 )
{
// initialize default cursors
@@ -1550,24 +1536,43 @@ bool SelectionManager::sendData( SelectionAdaptor* pAdaptor,
if( bConverted )
{
// conversion succeeded
- if( aData.getLength() > INCR_MIN_SIZE )
+ if( aData.getLength() > m_nIncrementalThreshold )
{
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "using INCR protocol\n" );
+ std::hash_map< 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%x, 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
- // use incr protocol
+
+ // 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
int nBufferPos = 0;
- int nMinSize = INCR_MIN_SIZE;
+ int nMinSize = m_nIncrementalThreshold;
+ XSelectInput( m_pDisplay, requestor, PropertyChangeMask );
XChangeProperty( m_pDisplay, requestor, property,
m_nINCRAtom, 32, PropModeReplace, (unsigned char*)&nMinSize, 1 );
- XSelectInput( m_pDisplay, requestor, PropertyChangeMask );
- IncrementalTransfer aTransfer( aData,
- requestor,
- property,
- target,
- nFormat
- );
- m_aIncrementals[ requestor ].push_back( aTransfer );
+ XFlush( m_pDisplay );
}
else
XChangeProperty( m_pDisplay,
@@ -1911,43 +1916,80 @@ void SelectionManager::handleSendPropertyNotify( XPropertyEvent& rNotify )
// feed incrementals
if( rNotify.state == PropertyDelete )
{
- ::std::hash_map< Window, ::std::list< IncrementalTransfer > >::iterator it;
+ std::hash_map< Window, std::hash_map< Atom, IncrementalTransfer > >::iterator it;
it = m_aIncrementals.find( rNotify.window );
- int nCurrentTime = time( NULL );
if( it != m_aIncrementals.end() )
{
- ::std::list< IncrementalTransfer >::iterator inc_it = it->second.begin();
- while( inc_it != it->second.end() )
+ 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 )
{
- bool bDone = false;
- if( inc_it->m_aProperty == rNotify.atom )
+ if( (nCurrentTime - inc_it->second.m_nTransferStartTime) > INCR_TIMEOUT )
{
- int nBytes = inc_it->m_aData.getLength() - inc_it->m_nBufferPos;
- nBytes = nBytes > INCR_MIN_SIZE ? INCR_MIN_SIZE : nBytes;
- XChangeProperty(
- m_pDisplay,
- inc_it->m_aRequestor,
- inc_it->m_aProperty,
- inc_it->m_aTarget,
- inc_it->m_nFormat,
- PropModeReplace,
- (const unsigned char*)inc_it->m_aData.getConstArray()+inc_it->m_nBufferPos,
- nBytes/(inc_it->m_nFormat/8) );
- inc_it->m_nBufferPos += nBytes;
- if( nBytes == 0 )
- bDone = true;
+ 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%x, 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
}
- else if( nCurrentTime - inc_it->m_nTransferStartTime > INCR_TIMEOUT )
- bDone = true;
- if( bDone )
+ }
+
+ 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
+
+ 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/(rInc.m_nFormat/8) );
+ rInc.m_nBufferPos += nBytes;
+ rInc.m_nTransferStartTime = nCurrentTime;
+
+ if( nBytes == 0 ) // transfer finished
{
- ::std::list< IncrementalTransfer >::iterator temp_it = inc_it;
- ++inc_it;
- it->second.erase( temp_it );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "finished INCR transfer for window 0x%x, 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 );
}
- else
- ++inc_it;
+
}
+ // eventually clean up the hash map
+ if( it->second.begin() == it->second.end() )
+ m_aIncrementals.erase( it );
}
}
}