xref: /aoo42x/main/basic/source/runtime/ddectrl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 #include <tools/errcode.hxx>
31 #include <svl/svdde.hxx>
32 #include "ddectrl.hxx"
33 #ifndef _SBERRORS_HXX
34 #include <basic/sberrors.hxx>
35 #endif
36 
37 #define DDE_FREECHANNEL	((DdeConnection*)0xffffffff)
38 
39 #define DDE_FIRSTERR	0x4000
40 #define DDE_LASTERR		0x4011
41 
42 static const SbError nDdeErrMap[] =
43 {
44 	/* DMLERR_ADVACKTIMEOUT 	  */  0x4000, SbERR_DDE_TIMEOUT,
45 	/* DMLERR_BUSY 				  */  0x4001, SbERR_DDE_BUSY,
46 	/* DMLERR_DATAACKTIMEOUT 	  */  0x4002, SbERR_DDE_TIMEOUT,
47 	/* DMLERR_DLL_NOT_INITIALIZED */  0x4003, SbERR_DDE_ERROR,
48 	/* DMLERR_DLL_USAGE           */  0x4004, SbERR_DDE_ERROR,
49 	/* DMLERR_EXECACKTIMEOUT      */  0x4005, SbERR_DDE_TIMEOUT,
50 	/* DMLERR_INVALIDPARAMETER    */  0x4006, SbERR_DDE_ERROR,
51 	/* DMLERR_LOW_MEMORY          */  0x4007, SbERR_DDE_ERROR,
52 	/* DMLERR_MEMORY_ERROR        */  0x4008, SbERR_DDE_ERROR,
53 	/* DMLERR_NOTPROCESSED        */  0x4009, SbERR_DDE_NOTPROCESSED,
54 	/* DMLERR_NO_CONV_ESTABLISHED */  0x400a, SbERR_DDE_NO_CHANNEL,
55 	/* DMLERR_POKEACKTIMEOUT      */  0x400b, SbERR_DDE_TIMEOUT,
56 	/* DMLERR_POSTMSG_FAILED      */  0x400c, SbERR_DDE_QUEUE_OVERFLOW,
57 	/* DMLERR_REENTRANCY          */  0x400d, SbERR_DDE_ERROR,
58 	/* DMLERR_SERVER_DIED         */  0x400e, SbERR_DDE_PARTNER_QUIT,
59 	/* DMLERR_SYS_ERROR           */  0x400f, SbERR_DDE_ERROR,
60 	/* DMLERR_UNADVACKTIMEOUT     */  0x4010, SbERR_DDE_TIMEOUT,
61 	/* DMLERR_UNFOUND_QUEUE_ID    */  0x4011, SbERR_DDE_NO_CHANNEL
62 };
63 
64 SbError SbiDdeControl::GetLastErr( DdeConnection* pConv )
65 {
66 	if( !pConv )
67 		return 0;
68 	long nErr = pConv->GetError();
69 	if( !nErr )
70 		return 0;
71 	if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR )
72 		return SbERR_DDE_ERROR;
73 	return nDdeErrMap[ 2*(nErr - DDE_FIRSTERR) + 1 ];
74 }
75 
76 IMPL_LINK_INLINE( SbiDdeControl,Data , DdeData*, pData,
77 {
78     aData = String::CreateFromAscii( (char*)(const void*)*pData );
79 	return 1;
80 }
81 )
82 
83 SbiDdeControl::SbiDdeControl()
84 {
85 	pConvList = new DdeConnections;
86 	DdeConnection* pPtr = DDE_FREECHANNEL;
87 	pConvList->Insert( pPtr );
88 }
89 
90 SbiDdeControl::~SbiDdeControl()
91 {
92 	TerminateAll();
93 	delete pConvList;
94 }
95 
96 sal_Int16 SbiDdeControl::GetFreeChannel()
97 {
98 	sal_Int16 nListSize = (sal_Int16)pConvList->Count();
99 	DdeConnection* pPtr = pConvList->First();
100 	pPtr = pConvList->Next(); // nullten eintrag ueberspringen
101 	sal_Int16 nChannel;
102 	for( nChannel = 1; nChannel < nListSize; nChannel++ )
103 	{
104 		if( pPtr == DDE_FREECHANNEL )
105 			return nChannel;
106 		pPtr = pConvList->Next();
107 	}
108 	pPtr = DDE_FREECHANNEL;
109 	pConvList->Insert( pPtr, LIST_APPEND );
110 	return nChannel;
111 }
112 
113 SbError SbiDdeControl::Initiate( const String& rService, const String& rTopic,
114 			sal_Int16& rnHandle )
115 {
116 	SbError nErr;
117 	DdeConnection* pConv = new DdeConnection( rService, rTopic );
118 	nErr = GetLastErr( pConv );
119 	if( nErr )
120 	{
121 		delete pConv;
122 		rnHandle = 0;
123 	}
124 	else
125 	{
126 		sal_Int16 nChannel = GetFreeChannel();
127 		pConvList->Replace( pConv, (sal_uIntPtr)nChannel );
128 		rnHandle = nChannel;
129 	}
130 	return 0;
131 }
132 
133 SbError SbiDdeControl::Terminate( sal_Int16 nChannel )
134 {
135 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
136 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
137 		return SbERR_DDE_NO_CHANNEL;
138 	pConvList->Replace( DDE_FREECHANNEL, (sal_uIntPtr)nChannel );
139 	delete pConv;
140 	return 0L;
141 }
142 
143 SbError SbiDdeControl::TerminateAll()
144 {
145 	sal_Int16 nChannel = (sal_Int16)pConvList->Count();
146 	while( nChannel )
147 	{
148 		nChannel--;
149 		Terminate( nChannel );
150 	}
151 
152 	pConvList->Clear();
153 	DdeConnection* pPtr = DDE_FREECHANNEL;
154 	pConvList->Insert( pPtr );
155 
156 	return 0;
157 }
158 
159 SbError SbiDdeControl::Request( sal_Int16 nChannel, const String& rItem, String& rResult )
160 {
161 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
162 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
163 		return SbERR_DDE_NO_CHANNEL;
164 
165 	DdeRequest aRequest( *pConv, rItem, 30000 );
166 	aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) );
167 	aRequest.Execute();
168 	rResult = aData;
169 	return GetLastErr( pConv );
170 }
171 
172 SbError SbiDdeControl::Execute( sal_Int16 nChannel, const String& rCommand )
173 {
174 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
175 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
176 		return SbERR_DDE_NO_CHANNEL;
177 	DdeExecute aRequest( *pConv, rCommand, 30000 );
178 	aRequest.Execute();
179 	return GetLastErr( pConv );
180 }
181 
182 SbError SbiDdeControl::Poke( sal_Int16 nChannel, const String& rItem, const String& rData )
183 {
184 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
185 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
186 		return SbERR_DDE_NO_CHANNEL;
187 	DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 );
188 	aRequest.Execute();
189 	return GetLastErr( pConv );
190 }
191 
192 
193