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