Update ooo320-m1
[ooovba.git] / dtrans / source / os2 / clipb / Os2Clipboard.cxx
blob195ad48b6ead6474fbef9d48c1f3ca0e90fbe09b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Os2Clipboard.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
35 #include "Os2Clipboard.hxx"
37 //------------------------------------------------------------------------
38 // namespace directives
39 //------------------------------------------------------------------------
41 using namespace com::sun::star::datatransfer;
42 using namespace com::sun::star::datatransfer::clipboard;
43 using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::uno;
46 using namespace cppu;
47 using namespace osl;
48 using namespace rtl;
49 using namespace os2;
51 const Type CPPUTYPE_SEQINT8 = getCppuType( ( Sequence< sal_Int8 >* )0 );
52 const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
54 #define DTRANS_OBJ_CLASSNAME "DTRANSOBJWND"
56 // -----------------------------------------------------------------------
58 inline void SetWindowPtr( HWND hWnd, Os2Clipboard* pThis )
60 WinSetWindowULong( hWnd, QWL_USER, (ULONG)pThis );
63 inline Os2Clipboard* GetWindowPtr( HWND hWnd )
65 return (Os2Clipboard*)WinQueryWindowULong( hWnd, QWL_USER );
68 // -----------------------------------------------------------------------
70 MRESULT EXPENTRY DtransObjWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 )
73 switch ( nMsg )
75 case WM_DRAWCLIPBOARD: // clipboard content has changed
77 Os2Clipboard* os2Clipboard = GetWindowPtr( hWnd);
78 if (os2Clipboard)
80 //MutexGuard aGuard(os2Clipboard->m_aMutex);
81 debug_printf("WM_DRAWCLIPBOARD os2Clipboard %08x\n", os2Clipboard);
82 if (os2Clipboard->m_bInSetClipboardData)
84 debug_printf("WM_DRAWCLIPBOARD our change\n");
86 else
88 // notify listener for clipboard change
89 debug_printf("WM_DRAWCLIPBOARD notify change\n");
90 os2Clipboard->notifyAllClipboardListener();
94 break;
97 return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
100 // -----------------------------------------------------------------------
102 Os2Clipboard::Os2Clipboard() :
103 m_aMutex(),
104 WeakComponentImplHelper4< XClipboardEx, XClipboardNotifier, XServiceInfo, XInitialization > (m_aMutex),
105 m_bInitialized(sal_False),
106 m_bInSetClipboardData(sal_False)
108 MutexGuard aGuard(m_aMutex);
110 debug_printf("Os2Clipboard::Os2Clipboard\n");
111 hAB = WinQueryAnchorBlock( HWND_DESKTOP );
112 hText = 0;
113 hBitmap = 0;
115 #if 0
116 // register object class
117 if ( WinRegisterClass( hAB, (PSZ)DTRANS_OBJ_CLASSNAME,
118 (PFNWP)DtransObjWndProc, 0, sizeof(ULONG) ))
120 APIRET rc;
121 // create object window to get clip viewer messages
122 hObjWnd = WinCreateWindow( HWND_OBJECT, (PCSZ)DTRANS_OBJ_CLASSNAME,
123 (PCSZ)"", 0, 0, 0, 0, 0,
124 HWND_OBJECT, HWND_TOP,
125 222, NULL, NULL);
126 // store pointer
127 SetWindowPtr( hObjWnd, this);
128 // register the viewer window
129 rc = WinOpenClipbrd(hAB);
130 rc = WinSetClipbrdViewer(hAB, hObjWnd);
131 rc = WinCloseClipbrd(hAB);
133 #endif
137 Os2Clipboard::~Os2Clipboard()
139 debug_printf("Os2Clipboard::~Os2Clipboard\n");
142 void SAL_CALL Os2Clipboard::initialize( const Sequence< Any >& aArguments )
143 throw(Exception, RuntimeException)
145 if (!m_bInitialized)
147 for (sal_Int32 n = 0, nmax = aArguments.getLength(); n < nmax; n++)
148 if (aArguments[n].getValueType() == getCppuType((OUString *) 0))
150 aArguments[0] >>= m_aName;
151 break;
156 OUString SAL_CALL Os2Clipboard::getImplementationName() throw( RuntimeException )
158 debug_printf("Os2Clipboard::getImplementationName\n");
159 return OUString::createFromAscii( OS2_CLIPBOARD_IMPL_NAME );
162 sal_Bool SAL_CALL Os2Clipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException )
164 debug_printf("Os2Clipboard::supportsService\n");
165 Sequence < OUString > SupportedServicesNames = Os2Clipboard_getSupportedServiceNames();
167 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
168 if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
169 return sal_True;
171 return sal_False;
174 Sequence< OUString > SAL_CALL Os2Clipboard::getSupportedServiceNames() throw( RuntimeException )
176 debug_printf("Os2Clipboard::getSupportedServiceNames\n");
177 return Os2Clipboard_getSupportedServiceNames();
180 Reference< XTransferable > SAL_CALL Os2Clipboard::getContents() throw( RuntimeException )
182 debug_printf("Os2Clipboard::getContents\n");
183 MutexGuard aGuard(m_aMutex);
185 // os2 can have only one viewer at time, and we don't get a notification
186 // when the viewer changes. So we need to check handles of clipboard
187 // data and compare with previous handles
188 if (UWinOpenClipbrd(hAB)) {
189 sal_Bool fireChanged = sal_False;
190 ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT);
191 if (handle) {
192 if (handle != hText) {
193 hText = handle;
194 fireChanged = sal_True;
197 handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP);
198 if (handle) {
199 if (handle != hBitmap) {
200 hBitmap = handle;
201 fireChanged = sal_True;
204 UWinCloseClipbrd( hAB);
205 if (fireChanged)
207 // notify listener for clipboard change
208 debug_printf("Os2Clipboard::getContents notify change\n");
209 notifyAllClipboardListener();
213 if( ! m_aContents.is() )
214 m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );
216 return m_aContents;
219 void SAL_CALL Os2Clipboard::setContents( const Reference< XTransferable >& xTrans, const Reference< XClipboardOwner >& xClipboardOwner ) throw( RuntimeException )
221 debug_printf("Os2Clipboard::setContents\n");
222 // remember old values for callbacks before setting the new ones.
223 ClearableMutexGuard aGuard(m_aMutex);
225 Reference< XClipboardOwner > oldOwner(m_aOwner);
226 m_aOwner = xClipboardOwner;
228 Reference< XTransferable > oldContents(m_aContents);
229 m_aContents = xTrans;
231 aGuard.clear();
233 // notify old owner on loss of ownership
234 if( oldOwner.is() )
235 oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents);
237 // notify all listeners on content changes
238 OInterfaceContainerHelper *pContainer =
239 rBHelper.aLC.getContainer(getCppuType( (Reference < XClipboardListener > *) 0));
240 if (pContainer)
242 ClipboardEvent aEvent(static_cast < XClipboard * > (this), m_aContents);
243 OInterfaceIteratorHelper aIterator(*pContainer);
245 while (aIterator.hasMoreElements())
247 Reference < XClipboardListener > xListener(aIterator.next(), UNO_QUERY);
248 if (xListener.is())
249 xListener->changedContents(aEvent);
253 #if OSL_DEBUG_LEVEL>0
254 // dump list of available mimetypes
255 Sequence< DataFlavor > aFlavors( m_aContents->getTransferDataFlavors() );
256 for( int i = 0; i < aFlavors.getLength(); i++ )
257 debug_printf("Os2Clipboard::setContents available mimetype: %d %s\n",
258 i, CHAR_POINTER(aFlavors.getConstArray()[i].MimeType));
259 #endif
261 // we can only export text or bitmap
262 DataFlavor nFlavorText( OUString::createFromAscii( "text/plain;charset=utf-16" ),
263 OUString::createFromAscii( "Unicode-Text" ), CPPUTYPE_OUSTRING);
264 DataFlavor nFlavorBitmap( OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ),
265 OUString::createFromAscii( "Bitmap" ), CPPUTYPE_DEFAULT);
267 // try text transfer data (if any)
268 PSZ pSharedText = NULL;
269 HBITMAP hbm = NULL;
272 Any aAny = m_aContents->getTransferData( nFlavorText );
273 if (aAny.hasValue())
275 APIRET rc;
276 // copy unicode text to clipboard
277 OUString aString;
278 aAny >>= aString;
279 // share text
280 rc = DosAllocSharedMem( (PPVOID) &pSharedText, NULL,
281 aString.getLength() * 2 + 2,
282 PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_ANY);
283 if (!rc)
284 memcpy( pSharedText, aString.getStr(), aString.getLength() * 2 + 2 );
285 else
286 pSharedText = NULL;
287 debug_printf("Os2Clipboard::setContents SetClipbrdData text done\n");
289 } catch ( UnsupportedFlavorException&) {
290 debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no text)\n");
293 // try bitmap transfer data (if any)
296 Any aAnyB = m_aContents->getTransferData( nFlavorBitmap );
297 if (aAnyB.hasValue())
299 hbm = OOoBmpToOS2Handle( aAnyB);
300 debug_printf("Os2Clipboard::setContents SetClipbrdData bitmap done\n");
302 } catch ( UnsupportedFlavorException&) {
303 debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no bitmap)\n");
306 // copy to clipboard
307 if ( UWinOpenClipbrd( hAB) && (pSharedText || hbm))
309 // set the flag, so we will ignore the next WM_DRAWCLIPBOARD
310 // since we generate it with following code.
311 m_bInSetClipboardData = sal_True;
312 UWinEmptyClipbrd( hAB);
313 // give pointer to clipboard (it will become owner of pSharedText!)
314 if (pSharedText) {
315 UWinSetClipbrdData( hAB, (ULONG) pSharedText, UCLIP_CF_UNICODETEXT, CFI_POINTER);
316 // update internal handle to avoid detection of this text as new data
317 hText = (ULONG)pSharedText;
319 // give bitmap to clipboard
320 if (hbm) {
321 UWinSetClipbrdData( hAB, (ULONG) hbm, UCLIP_CF_BITMAP, CFI_HANDLE);
322 // update internal handle to avoid detection of this bitmap as new data
323 hBitmap = hbm;
325 // reset the flag, so we will not ignore next WM_DRAWCLIPBOARD
326 m_bInSetClipboardData = sal_False;
327 UWinCloseClipbrd( hAB);
332 OUString SAL_CALL Os2Clipboard::getName() throw( RuntimeException )
334 debug_printf("Os2Clipboard::getName\n");
335 return m_aName;
338 sal_Int8 SAL_CALL Os2Clipboard::getRenderingCapabilities() throw( RuntimeException )
340 debug_printf("Os2Clipboard::getRenderingCapabilities\n");
341 return Delayed;
344 //========================================================================
345 // XClipboardNotifier
346 //========================================================================
348 void SAL_CALL Os2Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
350 debug_printf("Os2Clipboard::addClipboardListener\n");
351 MutexGuard aGuard( rBHelper.rMutex );
352 OSL_ENSURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" );
353 OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
354 if (!rBHelper.bInDispose && !rBHelper.bDisposed)
355 rBHelper.aLC.addInterface( getCppuType( (const ::com::sun::star::uno::Reference< XClipboardListener > *) 0), listener );
358 void SAL_CALL Os2Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
360 debug_printf("Os2Clipboard::removeClipboardListener\n");
361 MutexGuard aGuard( rBHelper.rMutex );
362 OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
363 if (!rBHelper.bInDispose && !rBHelper.bDisposed)
364 rBHelper.aLC.removeInterface( getCppuType( (const Reference< XClipboardListener > *) 0 ), listener ); \
367 // ------------------------------------------------------------------------
369 void SAL_CALL Os2Clipboard::notifyAllClipboardListener( )
371 if ( !rBHelper.bDisposed )
373 ClearableMutexGuard aGuard( rBHelper.rMutex );
374 if ( !rBHelper.bDisposed )
376 aGuard.clear( );
378 ClearableMutexGuard aGuard(m_aMutex);
379 // copy member references on stack so they can be called
380 // without having the mutex
381 Reference< XClipboardOwner > xOwner( m_aOwner );
382 Reference< XTransferable > xTrans( m_aContents );
383 // clear members
384 m_aOwner.clear();
385 m_aContents.clear();
386 // release the mutex
387 aGuard.clear();
389 // inform previous owner of lost ownership
390 if ( xOwner.is() )
391 xOwner->lostOwnership(static_cast < XClipboard * > (this), m_aContents);
393 OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
394 getCppuType( ( Reference< XClipboardListener > * ) 0 ) );
396 if ( pICHelper )
400 OInterfaceIteratorHelper iter(*pICHelper);
401 m_aContents = 0;
402 m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );
403 ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), m_aContents);
405 while(iter.hasMoreElements())
409 Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
410 if (xCBListener.is())
411 xCBListener->changedContents(aClipbEvent);
413 catch(RuntimeException&)
415 OSL_ENSURE( false, "RuntimeException caught" );
416 debug_printf( "RuntimeException caught" );
420 catch(const ::com::sun::star::lang::DisposedException&)
422 OSL_ENSURE(false, "Service Manager disposed");
423 debug_printf( "Service Manager disposed");
425 // no further clipboard changed notifications
426 //m_pImpl->unregisterClipboardViewer();
429 } // end if
430 } // end if
431 } // end if
434 // ------------------------------------------------------------------------
436 Sequence< OUString > SAL_CALL Os2Clipboard_getSupportedServiceNames()
438 Sequence< OUString > aRet(1);
439 aRet[0] = OUString::createFromAscii( OS2_CLIPBOARD_SERVICE_NAME );
440 return aRet;
443 // ------------------------------------------------------------------------
445 Reference< XInterface > SAL_CALL Os2Clipboard_createInstance(
446 const Reference< XMultiServiceFactory > & xMultiServiceFactory)
448 return Reference < XInterface >( ( OWeakObject * ) new Os2Clipboard());