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