merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / svdde / ddecli.cxx
blobf76253a78dc5d86374b238572f613d48c612cdff
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: ddecli.cxx,v $
10 * $Revision: 1.9 $
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"
34 #define UNICODE
35 #include <string.h> // memset
36 #include "ddeimp.hxx"
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 );
54 *ppInst = pData;
55 return pData;
58 void ImpDeinitInstData()
60 DdeInstData** ppInst = (DdeInstData**)GetAppData( SHL_SVDDE );
61 delete (*ppInst);
62 *ppInst = 0;
66 struct DdeImp
68 HCONV hConv;
69 long nStatus;
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 )
87 break;
89 if( self )
91 DdeTransaction* t;
92 BOOL bFound = FALSE;
93 for( t = self->aTransactions.First(); t; t = self->aTransactions.Next() )
95 switch( nCode )
97 case XTYP_XACT_COMPLETE:
98 if( (DWORD)t->nId == nInfo1 )
100 nCode = t->nType & (XCLASS_MASK | XTYP_MASK);
101 t->bBusy = FALSE;
102 t->Done( 0 != hData );
103 bFound = TRUE;
105 break;
107 case XTYP_DISCONNECT:
108 self->pImp->hConv = DdeReconnect( hConv );
109 self->pImp->nStatus = self->pImp->hConv
110 ? DMLERR_NO_ERROR
111 : DdeGetLastError( pInst->hDdeInstCli );
112 t = 0;
113 nRet = 0;
114 bFound = TRUE;
115 break;
117 case XTYP_ADVDATA:
118 bFound = BOOL( *t->pName == hText2 );
119 break;
121 if( bFound )
122 break;
125 if( t )
127 switch( nCode )
129 case XTYP_ADVDATA:
130 if( !hData )
132 ((DdeLink*) t)->Notify();
133 nRet = (HDDEDATA)DDE_FACK;
134 break;
136 // kein break;
138 case XTYP_REQUEST:
139 if( !hData && XTYP_REQUEST == nCode )
144 DdeData d;
145 d.pImp->hData = hData;
146 d.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
147 d.Lock();
148 t->Data( &d );
149 nRet = (HDDEDATA)DDE_FACK;
150 break;
154 return nRet;
157 // --- DdeConnection::DdeConnection() ------------------------------
159 DdeConnection::DdeConnection( const String& rService, const String& rTopic )
161 pImp = new DdeImp;
162 pImp->nStatus = DMLERR_NO_ERROR;
163 pImp->hConv = NULL;
165 DdeInstData* pInst = ImpGetInstData();
166 if( !pInst )
167 pInst = ImpInitInstData();
168 pInst->nRefCount++;
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);
187 if( !pImp->hConv )
188 pImp->nStatus = DdeGetLastError( pInst->hDdeInstCli );
191 if ( pInst->pConnections )
192 pInst->pConnections->Insert( this );
195 // --- DdeConnection::~DdeConnection() -----------------------------
197 DdeConnection::~DdeConnection()
199 if ( pImp->hConv )
200 DdeDisconnect( pImp->hConv );
202 delete pService;
203 delete pTopic;
205 DdeInstData* pInst = ImpGetInstData();
206 DBG_ASSERT(pInst,"SVDDE:No instance data");
207 if ( pInst->pConnections )
208 pInst->pConnections->Remove( this );
210 pInst->nInstanceCli--;
211 pInst->nRefCount--;
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 )
220 ImpDeinitInstData();
223 delete pImp;
226 // --- DdeConnection::IsConnected() --------------------------------
228 BOOL DdeConnection::IsConnected()
230 CONVINFO c;
231 #ifdef OS2
232 c.nSize = sizeof( c );
233 #else
234 c.cb = sizeof( c );
235 #endif
236 if ( DdeQueryConvInfo( pImp->hConv, QID_SYNC, &c ) )
237 return TRUE;
238 else
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,
278 long n ) :
279 rDde( d )
281 DdeInstData* pInst = ImpGetInstData();
282 pName = new DdeString( pInst->hDdeInstCli, rItemName );
283 nTime = n;
284 nId = 0;
285 nType = 0;
286 bBusy = FALSE;
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 );
301 delete pName;
302 rDde.aTransactions.Remove( this );
305 // --- DdeTransaction::Execute() -----------------------------------
307 void DdeTransaction::Execute()
309 HSZ hItem = *pName;
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 )
317 hItem = NULL;
318 if ( nType != XTYP_EXECUTE && nType != XTYP_POKE )
320 pData = NULL;
321 nData = 0L;
323 if ( nTime )
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 )
334 DdeData d;
335 d.pImp->hData = hData;
336 d.pImp->nFmt = nIntFmt;
337 d.Lock();
338 Data( &d );
340 DdeFreeDataHandle( hData );
343 else
345 if ( nId && rDde.pImp->hConv )
346 DdeAbandonTransaction( pInst->hDdeInstCli, rDde.pImp->hConv, nId);
347 nId = 0;
348 bBusy = TRUE;
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
362 return *pName;
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() -----------------------------------------
391 DdeLink::~DdeLink()
393 nType = (USHORT)XTYP_ADVSTOP;
394 nTime = 0;
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 ) :
415 DdeLink( d, i, n )
417 nType = XTYP_ADVSTART | XTYPF_NODATA;
420 // --- DdeHotLink::DdeHotLink() ------------------------------------
422 DdeHotLink::DdeHotLink( DdeConnection& d, const String& i, long n ) :
423 DdeLink( d, i, 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 );
435 nType = XTYP_POKE;
438 // --- DdePoke::DdePoke() ------------------------------------------
440 DdePoke::DdePoke( DdeConnection& d, const String& i, const String& rData,
441 long n ) :
442 DdeTransaction( d, i, n )
444 // ByteString aByteStr( rData, osl_getThreadTextEncoding() );
445 aDdeData = DdeData( (void*) rData.GetBuffer(), sizeof(sal_Unicode) * (rData.Len()), CF_TEXT );
446 nType = XTYP_POKE;
449 // --- DdePoke::DdePoke() ------------------------------------------
451 DdePoke::DdePoke( DdeConnection& d, const String& i, const DdeData& rData,
452 long n ) :
453 DdeTransaction( d, i, n )
455 aDdeData = rData;
456 nType = XTYP_POKE;
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;