LibreOffice Module dtrans (master)  1
WinClipbImpl.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <osl/diagnose.h>
21 #include "WinClipbImpl.hxx"
22 
23 #include <systools/win32/comtools.hxx>
24 #include "../../inc/DtObjFactory.hxx"
25 #include "../dtobj/APNDataObject.hxx"
26 #include "../dtobj/DOTransferable.hxx"
27 #include "WinClipboard.hxx"
28 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp>
29 #include "../dtobj/XNotifyingDataObject.hxx"
30 
31 #if !defined WIN32_LEAN_AND_MEAN
32 # define WIN32_LEAN_AND_MEAN
33 #endif
34 #include <windows.h>
35 #include <ole2.h>
36 #include <objidl.h>
37 
38 using namespace osl;
39 using namespace std;
40 using namespace cppu;
41 
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::datatransfer;
46 
47 // definition of static members
49 osl::Mutex CWinClipbImpl::s_aMutex;
50 
51 CWinClipbImpl::CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ) :
52  m_itsName( aClipboardName ),
53  m_pWinClipboard( theWinClipboard ),
54  m_pCurrentClipContent( nullptr )
55 {
56  OSL_ASSERT( nullptr != m_pWinClipboard );
57 
58  // necessary to reassociate from
59  // the static callback function
60  s_pCWinClipbImpl = this;
62 }
63 
65 {
66  {
67  MutexGuard aGuard(s_aMutex);
68  s_pCWinClipbImpl = nullptr;
69  }
70 
72 }
73 
75 {
76  // use the shortcut or create a transferable from
77  // system clipboard
78  {
79  MutexGuard aGuard(m_ClipContentMutex);
80 
81  if (nullptr != m_pCurrentClipContent)
82  {
84  }
85 
86  // Content cached?
87  if (m_foreignContent.is())
88  return m_foreignContent;
89 
90  // release the mutex, so that the variable may be
91  // changed by other threads
92  }
93 
94  Reference< XTransferable > rClipContent;
95 
96  // get the current dataobject from clipboard
97  IDataObjectPtr pIDataObject;
98  HRESULT hr = m_MtaOleClipboard.getClipboard( &pIDataObject );
99 
100  if ( SUCCEEDED( hr ) )
101  {
102  // create an apartment neutral dataobject and initialize it with a
103  // com smart pointer to the IDataObject from clipboard
104  IDataObjectPtr pIDo( new CAPNDataObject( pIDataObject ) );
105 
106  // remember pIDo destroys itself due to the smart pointer
107  rClipContent = CDOTransferable::create( m_pWinClipboard->m_xContext, pIDo );
108 
109  MutexGuard aGuard(m_ClipContentMutex);
110  m_foreignContent = rClipContent;
111  }
112 
113  return rClipContent;
114 }
115 
117  const Reference< XTransferable >& xTransferable,
118  const Reference< XClipboardOwner >& xClipboardOwner )
119 {
120  IDataObjectPtr pIDataObj;
121 
122  if ( xTransferable.is( ) )
123  {
124  {
125  MutexGuard aGuard(m_ClipContentMutex);
126 
127  m_foreignContent.clear();
128 
131  m_pWinClipboard->m_xContext, xTransferable),
132  xTransferable, xClipboardOwner, this);
133  }
134 
135  pIDataObj = IDataObjectPtr( m_pCurrentClipContent );
136  }
137 
138  m_MtaOleClipboard.setClipboard(pIDataObj.get());
139 }
140 
142 {
143  return m_itsName;
144 }
145 
147 {
148  return ( Delayed | Persistant );
149 }
150 
152 {
153  // actually it should be ClearableMutexGuard aGuard( m_ClipContentMutex );
154  // but it does not work since FlushClipboard does a callback and frees DataObject
155  // which results in a deadlock in onReleaseDataObject.
156  // FlushClipboard had to be synchron in order to prevent shutdown until all
157  // clipboard-formats are rendered.
158  // The request is needed to prevent flushing if we are not clipboard owner (it is
159  // not known what happens if we flush but aren't clipboard owner).
160  // It may be possible to move the request to the clipboard STA thread by saving the
161  // DataObject and call OleIsCurrentClipboard before flushing.
162 
163  if ( nullptr != m_pCurrentClipContent )
165 }
166 
168 {
170 }
171 
173 {
175 }
176 
178 {
179  OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" );
180 }
181 
183 {
184  MutexGuard aGuard( s_aMutex );
185 
186  // reassociation to instance through static member
187  if ( nullptr != s_pCWinClipbImpl )
188  {
191  }
192 }
193 
195 {
196  OSL_ASSERT( nullptr != theCaller );
197 
198  if ( theCaller )
199  theCaller->lostOwnership( );
200 
201  // if the current caller is the one we currently
202  // hold, then set it to NULL because an external
203  // source must be the clipboardowner now
204  MutexGuard aGuard( m_ClipContentMutex );
205 
206  if ( m_pCurrentClipContent == theCaller )
207  m_pCurrentClipContent = nullptr;
208 }
209 
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const css::uno::Reference< css::datatransfer::XTransferable > m_XTransferable
static sal_Int8 getRenderingCapabilities()
signed char sal_Int8
EXTERN_C BOOL BOOL const wchar_t *pProgramPath HRESULT hr
osl::Mutex m_ClipContentMutex
void flushClipboard()
void notifyAllClipboardListener()
OUString m_itsName
css::uno::Reference< css::uno::XComponentContext > m_xContext
static CWinClipbImpl * s_pCWinClipbImpl
bool registerClipViewer(LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback)
static css::uno::Reference< css::datatransfer::XTransferable > create(const css::uno::Reference< css::uno::XComponentContext > &rxContext, IDataObjectPtr pIDataObject)
OUString getName()
void setContents(const css::uno::Reference< css::datatransfer::XTransferable > &xTransferable, const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner > &xClipboardOwner)
static void WINAPI onClipboardContentChanged()
CWinClipboard * m_pWinClipboard
CMtaOleClipboard m_MtaOleClipboard
com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > m_foreignContent
HRESULT flushClipboard()
IDataObjectPtr createDataObjFromTransferable(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::datatransfer::XTransferable > &refXTransferable)
static osl::Mutex s_aMutex
CWinClipbImpl(const OUString &aClipboardName, CWinClipboard *theWinClipboard)
friend class CXNotifyingDataObject
void unregisterClipboardViewer()
void onReleaseDataObject(CXNotifyingDataObject *theCaller)
CXNotifyingDataObject * m_pCurrentClipContent
HRESULT setClipboard(IDataObject *pIDataObject)
HRESULT getClipboard(IDataObject **ppIDataObject)
void registerClipboardViewer()
css::uno::Reference< css::datatransfer::XTransferable > getContents()