xref: /trunk/main/basic/source/runtime/ddectrl.cxx (revision e1f63238)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <tools/errcode.hxx>
27 #include <svl/svdde.hxx>
28 #include "ddectrl.hxx"
29 #ifndef _SBERRORS_HXX
30 #include <basic/sberrors.hxx>
31 #endif
32 
33 #define DDE_FREECHANNEL	((DdeConnection*)0xffffffff)
34 
35 #define DDE_FIRSTERR	0x4000
36 #define DDE_LASTERR		0x4011
37 
38 static const SbError nDdeErrMap[] =
39 {
40 	/* DMLERR_ADVACKTIMEOUT 	  */  0x4000, SbERR_DDE_TIMEOUT,
41 	/* DMLERR_BUSY 				  */  0x4001, SbERR_DDE_BUSY,
42 	/* DMLERR_DATAACKTIMEOUT 	  */  0x4002, SbERR_DDE_TIMEOUT,
43 	/* DMLERR_DLL_NOT_INITIALIZED */  0x4003, SbERR_DDE_ERROR,
44 	/* DMLERR_DLL_USAGE           */  0x4004, SbERR_DDE_ERROR,
45 	/* DMLERR_EXECACKTIMEOUT      */  0x4005, SbERR_DDE_TIMEOUT,
46 	/* DMLERR_INVALIDPARAMETER    */  0x4006, SbERR_DDE_ERROR,
47 	/* DMLERR_LOW_MEMORY          */  0x4007, SbERR_DDE_ERROR,
48 	/* DMLERR_MEMORY_ERROR        */  0x4008, SbERR_DDE_ERROR,
49 	/* DMLERR_NOTPROCESSED        */  0x4009, SbERR_DDE_NOTPROCESSED,
50 	/* DMLERR_NO_CONV_ESTABLISHED */  0x400a, SbERR_DDE_NO_CHANNEL,
51 	/* DMLERR_POKEACKTIMEOUT      */  0x400b, SbERR_DDE_TIMEOUT,
52 	/* DMLERR_POSTMSG_FAILED      */  0x400c, SbERR_DDE_QUEUE_OVERFLOW,
53 	/* DMLERR_REENTRANCY          */  0x400d, SbERR_DDE_ERROR,
54 	/* DMLERR_SERVER_DIED         */  0x400e, SbERR_DDE_PARTNER_QUIT,
55 	/* DMLERR_SYS_ERROR           */  0x400f, SbERR_DDE_ERROR,
56 	/* DMLERR_UNADVACKTIMEOUT     */  0x4010, SbERR_DDE_TIMEOUT,
57 	/* DMLERR_UNFOUND_QUEUE_ID    */  0x4011, SbERR_DDE_NO_CHANNEL
58 };
59 
GetLastErr(DdeConnection * pConv)60 SbError SbiDdeControl::GetLastErr( DdeConnection* pConv )
61 {
62 	if( !pConv )
63 		return 0;
64 	long nErr = pConv->GetError();
65 	if( !nErr )
66 		return 0;
67 	if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR )
68 		return SbERR_DDE_ERROR;
69 	return nDdeErrMap[ 2*(nErr - DDE_FIRSTERR) + 1 ];
70 }
71 
72 IMPL_LINK_INLINE( SbiDdeControl,Data , DdeData*, pData,
73 {
74     aData = String::CreateFromAscii( (char*)(const void*)*pData );
75 	return 1;
76 }
77 )
78 
SbiDdeControl()79 SbiDdeControl::SbiDdeControl()
80 {
81 	pConvList = new DdeConnections;
82 	DdeConnection* pPtr = DDE_FREECHANNEL;
83 	pConvList->Insert( pPtr );
84 }
85 
~SbiDdeControl()86 SbiDdeControl::~SbiDdeControl()
87 {
88 	TerminateAll();
89 	delete pConvList;
90 }
91 
GetFreeChannel()92 sal_Int16 SbiDdeControl::GetFreeChannel()
93 {
94 	sal_Int16 nListSize = (sal_Int16)pConvList->Count();
95 	DdeConnection* pPtr = pConvList->First();
96 	pPtr = pConvList->Next(); // nullten eintrag ueberspringen
97 	sal_Int16 nChannel;
98 	for( nChannel = 1; nChannel < nListSize; nChannel++ )
99 	{
100 		if( pPtr == DDE_FREECHANNEL )
101 			return nChannel;
102 		pPtr = pConvList->Next();
103 	}
104 	pPtr = DDE_FREECHANNEL;
105 	pConvList->Insert( pPtr, LIST_APPEND );
106 	return nChannel;
107 }
108 
Initiate(const String & rService,const String & rTopic,sal_Int16 & rnHandle)109 SbError SbiDdeControl::Initiate( const String& rService, const String& rTopic,
110 			sal_Int16& rnHandle )
111 {
112 	SbError nErr;
113 	DdeConnection* pConv = new DdeConnection( rService, rTopic );
114 	nErr = GetLastErr( pConv );
115 	if( nErr )
116 	{
117 		delete pConv;
118 		rnHandle = 0;
119 	}
120 	else
121 	{
122 		sal_Int16 nChannel = GetFreeChannel();
123 		pConvList->Replace( pConv, (sal_uIntPtr)nChannel );
124 		rnHandle = nChannel;
125 	}
126 	return 0;
127 }
128 
Terminate(sal_Int16 nChannel)129 SbError SbiDdeControl::Terminate( sal_Int16 nChannel )
130 {
131 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
132 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
133 		return SbERR_DDE_NO_CHANNEL;
134 	pConvList->Replace( DDE_FREECHANNEL, (sal_uIntPtr)nChannel );
135 	delete pConv;
136 	return 0L;
137 }
138 
TerminateAll()139 SbError SbiDdeControl::TerminateAll()
140 {
141 	sal_Int16 nChannel = (sal_Int16)pConvList->Count();
142 	while( nChannel )
143 	{
144 		nChannel--;
145 		Terminate( nChannel );
146 	}
147 
148 	pConvList->Clear();
149 	DdeConnection* pPtr = DDE_FREECHANNEL;
150 	pConvList->Insert( pPtr );
151 
152 	return 0;
153 }
154 
Request(sal_Int16 nChannel,const String & rItem,String & rResult)155 SbError SbiDdeControl::Request( sal_Int16 nChannel, const String& rItem, String& rResult )
156 {
157 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
158 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
159 		return SbERR_DDE_NO_CHANNEL;
160 
161 	DdeRequest aRequest( *pConv, rItem, 30000 );
162 	aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) );
163 	aRequest.Execute();
164 	rResult = aData;
165 	return GetLastErr( pConv );
166 }
167 
Execute(sal_Int16 nChannel,const String & rCommand)168 SbError SbiDdeControl::Execute( sal_Int16 nChannel, const String& rCommand )
169 {
170 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
171 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
172 		return SbERR_DDE_NO_CHANNEL;
173 	DdeExecute aRequest( *pConv, rCommand, 30000 );
174 	aRequest.Execute();
175 	return GetLastErr( pConv );
176 }
177 
Poke(sal_Int16 nChannel,const String & rItem,const String & rData)178 SbError SbiDdeControl::Poke( sal_Int16 nChannel, const String& rItem, const String& rData )
179 {
180 	DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel );
181 	if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
182 		return SbERR_DDE_NO_CHANNEL;
183 	DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 );
184 	aRequest.Execute();
185 	return GetLastErr( pConv );
186 }
187 
188 
189