Line data Source code
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 <tools/errcode.hxx>
21 : #include <svl/svdde.hxx>
22 : #include "ddectrl.hxx"
23 : #include <basic/sberrors.hxx>
24 :
25 : #define DDE_FREECHANNEL (reinterpret_cast<DdeConnection*>(sal_IntPtr(-1)))
26 :
27 : #define DDE_FIRSTERR 0x4000
28 : #define DDE_LASTERR 0x4011
29 :
30 : static const SbError nDdeErrMap[] =
31 : {
32 : /* DMLERR_ADVACKTIMEOUT */ 0x4000, SbERR_DDE_TIMEOUT,
33 : /* DMLERR_BUSY */ 0x4001, SbERR_DDE_BUSY,
34 : /* DMLERR_DATAACKTIMEOUT */ 0x4002, SbERR_DDE_TIMEOUT,
35 : /* DMLERR_DLL_NOT_INITIALIZED */ 0x4003, SbERR_DDE_ERROR,
36 : /* DMLERR_DLL_USAGE */ 0x4004, SbERR_DDE_ERROR,
37 : /* DMLERR_EXECACKTIMEOUT */ 0x4005, SbERR_DDE_TIMEOUT,
38 : /* DMLERR_INVALIDPARAMETER */ 0x4006, SbERR_DDE_ERROR,
39 : /* DMLERR_LOW_MEMORY */ 0x4007, SbERR_DDE_ERROR,
40 : /* DMLERR_MEMORY_ERROR */ 0x4008, SbERR_DDE_ERROR,
41 : /* DMLERR_NOTPROCESSED */ 0x4009, SbERR_DDE_NOTPROCESSED,
42 : /* DMLERR_NO_CONV_ESTABLISHED */ 0x400a, SbERR_DDE_NO_CHANNEL,
43 : /* DMLERR_POKEACKTIMEOUT */ 0x400b, SbERR_DDE_TIMEOUT,
44 : /* DMLERR_POSTMSG_FAILED */ 0x400c, SbERR_DDE_QUEUE_OVERFLOW,
45 : /* DMLERR_REENTRANCY */ 0x400d, SbERR_DDE_ERROR,
46 : /* DMLERR_SERVER_DIED */ 0x400e, SbERR_DDE_PARTNER_QUIT,
47 : /* DMLERR_SYS_ERROR */ 0x400f, SbERR_DDE_ERROR,
48 : /* DMLERR_UNADVACKTIMEOUT */ 0x4010, SbERR_DDE_TIMEOUT,
49 : /* DMLERR_UNFOUND_QUEUE_ID */ 0x4011, SbERR_DDE_NO_CHANNEL
50 : };
51 :
52 0 : SbError SbiDdeControl::GetLastErr( DdeConnection* pConv )
53 : {
54 0 : if( !pConv )
55 : {
56 0 : return 0;
57 : }
58 0 : long nErr = pConv->GetError();
59 0 : if( !nErr )
60 : {
61 0 : return 0;
62 : }
63 0 : if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR )
64 : {
65 0 : return SbERR_DDE_ERROR;
66 : }
67 0 : return nDdeErrMap[ 2 * (nErr - DDE_FIRSTERR) + 1 ];
68 : }
69 :
70 0 : IMPL_LINK( SbiDdeControl,Data , DdeData*, pData )
71 : {
72 0 : aData = OUString::createFromAscii( static_cast<const char*>(static_cast<const void*>(*pData)) );
73 0 : return 1;
74 : }
75 :
76 70 : SbiDdeControl::SbiDdeControl()
77 : {
78 70 : }
79 :
80 140 : SbiDdeControl::~SbiDdeControl()
81 : {
82 70 : TerminateAll();
83 70 : }
84 :
85 0 : size_t SbiDdeControl::GetFreeChannel()
86 : {
87 0 : size_t nChannel = 0;
88 0 : size_t nListSize = aConvList.size();
89 :
90 0 : for (; nChannel < nListSize; ++nChannel)
91 : {
92 0 : if (aConvList[nChannel] == DDE_FREECHANNEL)
93 : {
94 0 : return nChannel+1;
95 : }
96 : }
97 :
98 0 : aConvList.push_back(DDE_FREECHANNEL);
99 0 : return nChannel+1;
100 : }
101 :
102 0 : SbError SbiDdeControl::Initiate( const OUString& rService, const OUString& rTopic,
103 : size_t& rnHandle )
104 : {
105 : SbError nErr;
106 0 : DdeConnection* pConv = new DdeConnection( rService, rTopic );
107 0 : nErr = GetLastErr( pConv );
108 0 : if( nErr )
109 : {
110 0 : delete pConv;
111 0 : rnHandle = 0;
112 : }
113 : else
114 : {
115 0 : size_t nChannel = GetFreeChannel();
116 0 : aConvList[nChannel-1] = pConv;
117 0 : rnHandle = nChannel;
118 : }
119 0 : return 0;
120 : }
121 :
122 0 : SbError SbiDdeControl::Terminate( size_t nChannel )
123 : {
124 0 : if (!nChannel || nChannel > aConvList.size())
125 : {
126 0 : return SbERR_DDE_NO_CHANNEL;
127 : }
128 0 : DdeConnection* pConv = aConvList[nChannel-1];
129 :
130 0 : if( pConv == DDE_FREECHANNEL )
131 : {
132 0 : return SbERR_DDE_NO_CHANNEL;
133 : }
134 0 : delete pConv;
135 0 : aConvList[nChannel-1] = DDE_FREECHANNEL;
136 :
137 0 : return 0L;
138 : }
139 :
140 70 : SbError SbiDdeControl::TerminateAll()
141 : {
142 70 : for (size_t nChannel = 0; nChannel < aConvList.size(); ++nChannel)
143 : {
144 0 : DdeConnection *conv = aConvList[nChannel];
145 :
146 0 : if (conv != DDE_FREECHANNEL)
147 : {
148 0 : delete conv;
149 : }
150 : }
151 :
152 70 : aConvList.clear();
153 :
154 70 : return 0;
155 : }
156 :
157 0 : SbError SbiDdeControl::Request( size_t nChannel, const OUString& rItem, OUString& rResult )
158 : {
159 0 : if (!nChannel || nChannel > aConvList.size())
160 : {
161 0 : return SbERR_DDE_NO_CHANNEL;
162 : }
163 :
164 0 : DdeConnection* pConv = aConvList[nChannel-1];
165 :
166 0 : if( pConv == DDE_FREECHANNEL )
167 : {
168 0 : return SbERR_DDE_NO_CHANNEL;
169 : }
170 :
171 0 : DdeRequest aRequest( *pConv, rItem, 30000 );
172 0 : aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) );
173 0 : aRequest.Execute();
174 0 : rResult = aData;
175 0 : return GetLastErr( pConv );
176 : }
177 :
178 0 : SbError SbiDdeControl::Execute( size_t nChannel, const OUString& rCommand )
179 : {
180 0 : if (!nChannel || nChannel > aConvList.size())
181 : {
182 0 : return SbERR_DDE_NO_CHANNEL;
183 : }
184 :
185 0 : DdeConnection* pConv = aConvList[nChannel-1];
186 :
187 0 : if( pConv == DDE_FREECHANNEL )
188 : {
189 0 : return SbERR_DDE_NO_CHANNEL;
190 : }
191 0 : DdeExecute aRequest( *pConv, rCommand, 30000 );
192 0 : aRequest.Execute();
193 0 : return GetLastErr( pConv );
194 : }
195 :
196 0 : SbError SbiDdeControl::Poke( size_t nChannel, const OUString& rItem, const OUString& rData )
197 : {
198 0 : if (!nChannel || nChannel > aConvList.size())
199 : {
200 0 : return SbERR_DDE_NO_CHANNEL;
201 : }
202 0 : DdeConnection* pConv = aConvList[nChannel-1];
203 :
204 0 : if( pConv == DDE_FREECHANNEL )
205 : {
206 0 : return SbERR_DDE_NO_CHANNEL;
207 : }
208 0 : DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 );
209 0 : aRequest.Execute();
210 0 : return GetLastErr( pConv );
211 : }
212 :
213 :
214 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|