xref: /AOO41X/main/basic/source/runtime/ddectrl.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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