1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddecli.cxx,v $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #include <string.h> // memset
37 #include <svtools/svdde.hxx>
39 #include <osl/thread.h>
40 #include <tools/debug.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vos/mutex.hxx>
44 // static DWORD hDdeInst = NULL;
45 // static short nInstance = 0;
47 // DdeConnections* DdeConnection::pConnections = NULL;
49 DdeInstData
* ImpInitInstData()
51 DdeInstData
* pData
= new DdeInstData
;
52 memset( pData
,0,sizeof(DdeInstData
) );
53 DdeInstData
** ppInst
= (DdeInstData
**)GetAppData( SHL_SVDDE
);
58 void ImpDeinitInstData()
60 DdeInstData
** ppInst
= (DdeInstData
**)GetAppData( SHL_SVDDE
);
72 // --- DdeInternat::CliCallback() ----------------------------------
74 HDDEDATA CALLBACK
DdeInternal::CliCallback(
75 WORD nCode
, WORD nCbType
, HCONV hConv
, HSZ
, HSZ hText2
,
76 HDDEDATA hData
, DWORD nInfo1
, DWORD
)
78 HDDEDATA nRet
= DDE_FNOTPROCESSED
;
79 DdeConnections
& rAll
= (DdeConnections
&)DdeConnection::GetConnections();
80 DdeConnection
* self
= 0;
82 DdeInstData
* pInst
= ImpGetInstData();
83 DBG_ASSERT(pInst
,"SVDDE:No instance data");
85 for ( self
= rAll
.First(); self
; self
= rAll
.Next() )
86 if ( self
->pImp
->hConv
== hConv
)
93 for( t
= self
->aTransactions
.First(); t
; t
= self
->aTransactions
.Next() )
97 case XTYP_XACT_COMPLETE
:
98 if( (DWORD
)t
->nId
== nInfo1
)
100 nCode
= t
->nType
& (XCLASS_MASK
| XTYP_MASK
);
102 t
->Done( 0 != hData
);
107 case XTYP_DISCONNECT
:
108 self
->pImp
->hConv
= DdeReconnect( hConv
);
109 self
->pImp
->nStatus
= self
->pImp
->hConv
111 : DdeGetLastError( pInst
->hDdeInstCli
);
118 bFound
= BOOL( *t
->pName
== hText2
);
132 ((DdeLink
*) t
)->Notify();
133 nRet
= (HDDEDATA
)DDE_FACK
;
139 if( !hData
&& XTYP_REQUEST
== nCode
)
145 d
.pImp
->hData
= hData
;
146 d
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
149 nRet
= (HDDEDATA
)DDE_FACK
;
157 // --- DdeConnection::DdeConnection() ------------------------------
159 DdeConnection::DdeConnection( const String
& rService
, const String
& rTopic
)
162 pImp
->nStatus
= DMLERR_NO_ERROR
;
165 DdeInstData
* pInst
= ImpGetInstData();
167 pInst
= ImpInitInstData();
169 pInst
->nInstanceCli
++;
170 if ( !pInst
->hDdeInstCli
)
172 pImp
->nStatus
= DdeInitialize( &pInst
->hDdeInstCli
,
173 (PFNCALLBACK
)DdeInternal::CliCallback
,
174 APPCLASS_STANDARD
| APPCMD_CLIENTONLY
|
175 CBF_FAIL_ALLSVRXACTIONS
|
176 CBF_SKIP_REGISTRATIONS
|
177 CBF_SKIP_UNREGISTRATIONS
, 0L );
178 pInst
->pConnections
= new DdeConnections
;
181 pService
= new DdeString( pInst
->hDdeInstCli
, rService
);
182 pTopic
= new DdeString( pInst
->hDdeInstCli
, rTopic
);
184 if ( pImp
->nStatus
== DMLERR_NO_ERROR
)
186 pImp
->hConv
= DdeConnect( pInst
->hDdeInstCli
,*pService
,*pTopic
, NULL
);
188 pImp
->nStatus
= DdeGetLastError( pInst
->hDdeInstCli
);
191 if ( pInst
->pConnections
)
192 pInst
->pConnections
->Insert( this );
195 // --- DdeConnection::~DdeConnection() -----------------------------
197 DdeConnection::~DdeConnection()
200 DdeDisconnect( pImp
->hConv
);
205 DdeInstData
* pInst
= ImpGetInstData();
206 DBG_ASSERT(pInst
,"SVDDE:No instance data");
207 if ( pInst
->pConnections
)
208 pInst
->pConnections
->Remove( this );
210 pInst
->nInstanceCli
--;
212 if ( !pInst
->nInstanceCli
&& pInst
->hDdeInstCli
)
214 if( DdeUninitialize( pInst
->hDdeInstCli
) )
216 pInst
->hDdeInstCli
= NULL
;
217 delete pInst
->pConnections
;
218 pInst
->pConnections
= NULL
;
219 if( pInst
->nRefCount
== 0 )
226 // --- DdeConnection::IsConnected() --------------------------------
228 BOOL
DdeConnection::IsConnected()
232 c
.nSize
= sizeof( c
);
236 if ( DdeQueryConvInfo( pImp
->hConv
, QID_SYNC
, &c
) )
240 DdeInstData
* pInst
= ImpGetInstData();
241 pImp
->hConv
= DdeReconnect( pImp
->hConv
);
242 pImp
->nStatus
= pImp
->hConv
? DMLERR_NO_ERROR
: DdeGetLastError( pInst
->hDdeInstCli
);
243 return BOOL( pImp
->nStatus
== DMLERR_NO_ERROR
);
247 // --- DdeConnection::GetServiceName() -----------------------------
249 const String
& DdeConnection::GetServiceName()
251 return (const String
&)*pService
;
254 // --- DdeConnection::GetTopicName() -------------------------------
256 const String
& DdeConnection::GetTopicName()
258 return (const String
&)*pTopic
;
261 // --- DdeConnection::GetConvId() ----------------------------------
263 long DdeConnection::GetConvId()
265 return (long)pImp
->hConv
;
268 const DdeConnections
& DdeConnection::GetConnections()
270 DdeInstData
* pInst
= ImpGetInstData();
271 DBG_ASSERT(pInst
,"SVDDE:No instance data");
272 return *(pInst
->pConnections
);
275 // --- DdeTransaction::DdeTransaction() ----------------------------
277 DdeTransaction::DdeTransaction( DdeConnection
& d
, const String
& rItemName
,
281 DdeInstData
* pInst
= ImpGetInstData();
282 pName
= new DdeString( pInst
->hDdeInstCli
, rItemName
);
288 rDde
.aTransactions
.Insert( this );
291 // --- DdeTransaction::~DdeTransaction() ---------------------------
293 DdeTransaction::~DdeTransaction()
295 if ( nId
&& rDde
.pImp
->hConv
)
297 DdeInstData
* pInst
= ImpGetInstData();
298 DdeAbandonTransaction( pInst
->hDdeInstCli
, rDde
.pImp
->hConv
, nId
);
302 rDde
.aTransactions
.Remove( this );
305 // --- DdeTransaction::Execute() -----------------------------------
307 void DdeTransaction::Execute()
310 void* pData
= (void*)(const void *)aDdeData
;
311 DWORD nData
= (DWORD
)(long)aDdeData
;
312 ULONG nIntFmt
= aDdeData
.pImp
->nFmt
;
313 UINT nExtFmt
= DdeData::GetExternalFormat( nIntFmt
);
314 DdeInstData
* pInst
= ImpGetInstData();
316 if ( nType
== XTYP_EXECUTE
)
318 if ( nType
!= XTYP_EXECUTE
&& nType
!= XTYP_POKE
)
325 HDDEDATA hData
= DdeClientTransaction( (unsigned char*)pData
,
326 nData
, rDde
.pImp
->hConv
,
327 hItem
, nExtFmt
, (UINT
)nType
,
328 (DWORD
)nTime
, (DWORD FAR
*)NULL
);
330 rDde
.pImp
->nStatus
= DdeGetLastError( pInst
->hDdeInstCli
);
331 if( hData
&& nType
== XTYP_REQUEST
)
335 d
.pImp
->hData
= hData
;
336 d
.pImp
->nFmt
= nIntFmt
;
340 DdeFreeDataHandle( hData
);
345 if ( nId
&& rDde
.pImp
->hConv
)
346 DdeAbandonTransaction( pInst
->hDdeInstCli
, rDde
.pImp
->hConv
, nId
);
349 HDDEDATA hRet
= DdeClientTransaction( (unsigned char*)pData
, nData
,
350 rDde
.pImp
->hConv
, hItem
, nExtFmt
,
351 (UINT
)nType
, TIMEOUT_ASYNC
,
352 (DWORD FAR
*) ((long*) &nId
) );
353 rDde
.pImp
->nStatus
= hRet
? DMLERR_NO_ERROR
354 : DdeGetLastError( pInst
->hDdeInstCli
);
358 // --- DdeTransaction::GetName() -----------------------------------
360 const String
& DdeTransaction::GetName() const
365 // --- DdeTransaction::Data() --------------------------------------
368 void __EXPORT
DdeTransaction::Data( const DdeData
* p
)
370 Application::GetSolarMutex().acquire();
371 aData
.Call( (void*)p
);
372 Application::GetSolarMutex().release();
375 // --- DdeTransaction::Done() --------------------------------------
377 void __EXPORT
DdeTransaction::Done( BOOL bDataValid
)
379 aDone
.Call( (void*)bDataValid
);
382 // --- DdeLink::DdeLink() ------------------------------------------
384 DdeLink::DdeLink( DdeConnection
& d
, const String
& aItemName
, long n
) :
385 DdeTransaction (d
, aItemName
, n
)
389 // --- DdeLink::~DdeLink() -----------------------------------------
393 nType
= (USHORT
)XTYP_ADVSTOP
;
397 // --- DdeLink::Notify() -----------------------------------------
399 void __EXPORT
DdeLink::Notify()
401 aNotify
.Call( NULL
);
404 // --- DdeRequest::DdeRequest() ------------------------------------
406 DdeRequest::DdeRequest( DdeConnection
& d
, const String
& i
, long n
) :
407 DdeTransaction( d
, i
, n
)
409 nType
= XTYP_REQUEST
;
412 // --- DdeWarmLink::DdeWarmLink() ----------------------------------
414 DdeWarmLink::DdeWarmLink( DdeConnection
& d
, const String
& i
, long n
) :
417 nType
= XTYP_ADVSTART
| XTYPF_NODATA
;
420 // --- DdeHotLink::DdeHotLink() ------------------------------------
422 DdeHotLink::DdeHotLink( DdeConnection
& d
, const String
& i
, long n
) :
425 nType
= XTYP_ADVSTART
;
428 // --- DdePoke::DdePoke() ------------------------------------------
430 DdePoke::DdePoke( DdeConnection
& d
, const String
& i
, const char* p
,
431 long l
, ULONG f
, long n
) :
432 DdeTransaction( d
, i
, n
)
434 aDdeData
= DdeData( p
, l
, f
);
438 // --- DdePoke::DdePoke() ------------------------------------------
440 DdePoke::DdePoke( DdeConnection
& d
, const String
& i
, const String
& rData
,
442 DdeTransaction( d
, i
, n
)
444 // ByteString aByteStr( rData, osl_getThreadTextEncoding() );
445 aDdeData
= DdeData( (void*) rData
.GetBuffer(), sizeof(sal_Unicode
) * (rData
.Len()), CF_TEXT
);
449 // --- DdePoke::DdePoke() ------------------------------------------
451 DdePoke::DdePoke( DdeConnection
& d
, const String
& i
, const DdeData
& rData
,
453 DdeTransaction( d
, i
, n
)
459 // --- DdeExecute::DdeExecute() ------------------------------------
461 DdeExecute::DdeExecute( DdeConnection
& d
, const String
& rData
, long n
) :
462 DdeTransaction( d
, String(), n
)
464 // ByteString aByteStr( rData, osl_getThreadTextEncoding() );
465 aDdeData
= DdeData( (void*)rData
.GetBuffer(), sizeof(sal_Unicode
) * (rData
.Len() + 1), CF_TEXT
);
466 nType
= XTYP_EXECUTE
;
469 // --- DdeConnection::GetError() -----------------------------------
471 long DdeConnection::GetError()
473 return pImp
->nStatus
;