xref: /AOO41X/main/automation/source/server/server.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_automation.hxx"
30 
31 // do not use Application Idle but AutoTimer instead
32 #define TIMERIDLE
33 
34 #define NO_JPEG
35 
36 #ifndef NO_JPEG
37 #include <svtools/jpeg.hxx>
38 #endif
39 #include <vcl/timer.hxx>
40 #include <vcl/wrkwin.hxx>
41 #include <osl/diagnose.h>
42 #include <osl/mutex.hxx>
43 
44 #ifndef _DIALOG_HXX //autogen
45 #include <vcl/dialog.hxx>
46 #endif
47 #include <tools/stream.hxx>
48 #include <tools/config.hxx>
49 
50 #include <vos/socket.hxx>
51 
52 #if 1
53 #include <svtools/ttprops.hxx>
54 #include <basic/ttstrhlp.hxx>
55 #include <svl/stritem.hxx>
56 #include <svtools/stringtransfer.hxx>
57 #include <vcl/sound.hxx>
58 #include "testtool.hrc"
59 #include <vcl/bitmap.hxx>
60 // Hat keinen Includeschutz
61 #include <svtools/svtdata.hxx>
62 //#ifndef _DTRANS_HXX //autogen
63 //#include <so2/dtrans.hxx>
64 //#endif
65 #endif // 1
66 #include <rtl/textenc.h>
67 #include <rtl/uri.h>
68 #include <rtl/uri.hxx>
69 #include "statemnt.hxx"
70 #include "scmdstrm.hxx"
71 #include "rcontrol.hxx"
72 #include "server.hxx"
73 #include "testtool.hxx"
74 #include "automation/automation.hxx"
75 #include "recorder.hxx"
76 
77 #include "basic/svtmsg.hrc"
78 
79 #ifdef DBG_UTIL
80 void TestToolDebugPrint( const sal_Char *pString )
81 {
82     if ( !DbgFilterMessage( pString ) )
83     	StatementList::DirectLog( S_AssertError, UniString( pString, RTL_TEXTENCODING_UTF8 ) );
84 }
85 void SAL_CALL osl_TestToolDebugPrint( const sal_Char *pString )
86 {
87     TestToolDebugPrint( pString );
88 }
89 #endif
90 
91 
92 sal_uLong RemoteControlCommunicationManager::nPortIs = TT_PORT_NOT_INITIALIZED;
93 sal_uInt16 RemoteControlCommunicationManager::nComm = 0;
94 sal_Bool RemoteControlCommunicationManager::bQuiet = sal_False;
95 
96 #if OSL_DEBUG_LEVEL > 1
97 RemoteControlCommunicationManager::RemoteControlCommunicationManager( EditWindow * pDbgWin )
98 #else
99 RemoteControlCommunicationManager::RemoteControlCommunicationManager()
100 #endif
101 : CommunicationManagerServerViaSocket( GetPort(), 1, sal_True )
102 #if OSL_DEBUG_LEVEL > 1
103 , m_pDbgWin( pDbgWin )
104 #endif
105 , pTimer( NULL )
106 {
107 	bIsPortValid = ( GetPort() != 0 );
108 	if ( bQuiet )
109 	{
110 		SetInfoType( CM_NO_TEXT );
111 	}
112 	else
113 	{
114 		SetInfoType( CM_SHORT_TEXT | CM_ALL );
115         ByteString aByteString;
116 		InfoMsg( InfoString( aByteString, CM_ALL ) );	// Anzeigen, da� wir da sind
117 	}
118 }
119 
120 RemoteControlCommunicationManager::~RemoteControlCommunicationManager()
121 {
122 	if ( pTimer )
123 		delete pTimer;
124     DoQuickShutdown();
125 }
126 
127 void RemoteControlCommunicationManager::ConnectionOpened( CommunicationLink* pCL )
128 {
129 	StatementFlow::pCommLink = pCL;
130 	CommunicationManagerServerViaSocket::ConnectionOpened( pCL );
131 }
132 
133 
134 void RemoteControlCommunicationManager::ConnectionClosed( CommunicationLink* pCL )
135 {
136 	StatementFlow::pCommLink = NULL;
137 	CommunicationManagerServerViaSocket::ConnectionClosed( pCL );
138 }
139 
140 
141 IMPL_LINK( RemoteControlCommunicationManager, SetWinCaption, Timer*, EMPTYARG )
142 {
143 	if ( pTimer )
144 	{
145 		delete pTimer;
146 		pTimer = NULL;
147 	}
148 
149 	if ( StatementList::GetFirstDocFrame() )
150 	{
151 		if ( !aOriginalWinCaption.Len() )
152 			aOriginalWinCaption = StatementList::GetFirstDocFrame()->GetText();
153 		StatementList::GetFirstDocFrame()->SetText(String(aOriginalWinCaption).AppendAscii(" TT").Append(aAdditionalWinCaption).AppendAscii("[").Append(UniString::CreateFromInt32(nPortToListen)).AppendAscii("]"));
154 	}
155 	else
156 	{	// Dann Probieren wir es eben in 1 Sekunde nochmal
157 		pTimer = new Timer();	// Wird im Link gel�scht
158 		pTimer->SetTimeout( 1000 );
159 		pTimer->SetTimeoutHdl( LINK( this, RemoteControlCommunicationManager, SetWinCaption ) );
160 		pTimer->Start();
161 	}
162 	return 0;
163 }
164 
165 void RemoteControlCommunicationManager::InfoMsg( InfoString aMsg )
166 {
167 	if ( !bIsPortValid )
168 		return;
169 	aAdditionalWinCaption = UniString( aMsg, RTL_TEXTENCODING_ASCII_US );
170 	SetWinCaption();
171 #if OSL_DEBUG_LEVEL > 1
172 	m_pDbgWin->AddText( UniString( (ByteString)aMsg, RTL_TEXTENCODING_ASCII_US ) );
173 	m_pDbgWin->AddText( "\n" );
174 #endif
175 }
176 
177 sal_uLong RemoteControlCommunicationManager::GetPort()
178 {
179 	if ( TT_PORT_NOT_INITIALIZED == nPortIs )
180 	{	// Read Config
181 
182         sal_uInt16 i;
183         // are we to be automated at all?
184         sal_Bool bAutomate = sal_False;
185 		for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
186 		{
187 			if ( Application::GetCommandLineParam( i ).EqualsIgnoreCaseAscii("/enableautomation")
188 				|| Application::GetCommandLineParam( i ).EqualsIgnoreCaseAscii("-enableautomation"))
189             {
190                 bAutomate = sal_True;
191                 break;
192             }
193         }
194 
195 // if started within Portal determin location of testtool.ini/rc by analysing the commandline
196 // /userid:demo1[/export/home/user/demo1]
197 // -userid:demo1[/export/home/user/demo1]
198 		String aIniFileDir;
199 		for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
200 		{
201 			if ( Application::GetCommandLineParam( i ).Copy(0,8).EqualsIgnoreCaseAscii("/userid:")
202 				|| Application::GetCommandLineParam( i ).Copy(0,8).EqualsIgnoreCaseAscii("-userid:") )
203 			{
204 				rtl::OUString aEncHome
205 					= Application::GetCommandLineParam(i).GetBuffer();
206 
207 				rtl::OUString aDecHome = rtl::Uri::decode(aEncHome,
208 						rtl_UriDecodeWithCharset,
209 						RTL_TEXTENCODING_UTF8);
210 
211 				aIniFileDir = aDecHome;
212 				aIniFileDir.Erase( 0, aIniFileDir.Search('[')+1 );
213 				aIniFileDir.Erase( aIniFileDir.Search(']') );
214 			}
215 		}
216 
217 		if ( ! aIniFileDir.Len() )
218 			aIniFileDir = Config::GetDefDirectory();
219 
220 		Config aConf(Config::GetConfigName( aIniFileDir, CUniString("testtool") ));
221 		aConf.SetGroup("Communication");
222 
223 		ByteString aNoTesttoolKey( ByteString("Exclude_").Append( ByteString( Application::GetAppFileName(), RTL_TEXTENCODING_UTF8 ) ) );
224 // -notesttool
225 		for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
226 		{
227 			if ( Application::GetCommandLineParam( i ).CompareIgnoreCaseToAscii("-notesttool") == COMPARE_EQUAL )
228 				aConf.WriteKey( aNoTesttoolKey, "something" );
229 		}
230 
231 		nPortIs = aConf.ReadKey("TTPort","0").ToInt32();
232 
233         // noch pr�fen ob dieses Office getestet werden soll.
234 		if ( !bAutomate || aConf.ReadKey( aNoTesttoolKey, "" ) != "" )
235 			nPortIs = 0;
236 
237 		nComm = (sal_uInt16)aConf.ReadKey("Comm","0").ToInt32();
238 		if ( nComm )
239 			aConf.DeleteKey("Comm");
240 
241 		bQuiet = ( aConf.ReadKey("Quiet","no").CompareIgnoreCaseToAscii("yes") == COMPARE_EQUAL );
242 	}
243 	return nPortIs;
244 }
245 
246 #if OSL_DEBUG_LEVEL > 1
247 #define MIN_IDLE 10000		// Ruhe vor dem Sturm min 10 Sekunden
248 #else
249 #define MIN_IDLE 60000		// Ruhe vor dem Sturm min 1 Minuten
250 #endif
251 
252 class ExtraIdle : public AutoTimer
253 {
254 	virtual void    Timeout();
255 
256 	sal_uInt16 nStep;
257 	ImplRemoteControl *pRemoteControl;
258 public:
259 	ExtraIdle( ImplRemoteControl *pRC );
260 };
261 
262 
263 ExtraIdle::ExtraIdle( ImplRemoteControl *pRC )
264 : nStep( 0 )
265 , pRemoteControl (pRC )
266 {
267 	SetTimeout( 120000 );	// 2 Minuten
268 #if OSL_DEBUG_LEVEL > 1
269 	SetTimeout( 40000 );	// 40 Sekunden
270 #endif
271 	Start();
272 }
273 
274 void ExtraIdle::Timeout()
275 {
276 	if ( !StatementList::pTTProperties )
277 		StatementList::pTTProperties = new TTProperties();
278 
279 	if ( !StatementList::pTTProperties->GetSlots() )
280 	{
281 		delete this;
282 		return;
283 	}
284 
285 	// M�ssen wir selbst idlen?
286 #if OSL_DEBUG_LEVEL > 1
287 	sal_uLong nLastInputInterval = Application::GetLastInputInterval();
288 	sal_Bool bIsInModalMode = Application::IsInModalMode();
289 	if ( bIsInModalMode || nLastInputInterval < MIN_IDLE )
290 #else
291 	if ( Application::IsInModalMode() || Application::GetLastInputInterval() < MIN_IDLE )
292 #endif
293 	{
294 		if ( nStep )	// Schon angefangen? dann abbrechen, sonst sp�ter nochmal
295 		{
296             if ( nStep < 15 )
297             {
298 			    Sound::Beep();
299 			    Sound::Beep();
300             }
301 #if OSL_DEBUG_LEVEL < 2
302 			delete this;
303 #endif
304 		}
305 #if OSL_DEBUG_LEVEL > 1
306         if ( nStep < 15 )
307         {
308 			Sound::Beep();
309 			Sound::Beep();
310         }
311 #endif
312 		return;
313 	}
314 
315 	if ( StatementList::pFirst )	// Verarbeitung neu aufsetzen
316 	{
317 		GetpApp()->PostUserEvent( LINK( pRemoteControl, ImplRemoteControl, CommandHdl ) );
318 		return;
319 	}
320 
321 
322 	switch ( nStep++ )		// Probieren ob wir noch was machen k�nnen
323 	{
324 		case 0:
325 		{
326 			SfxPoolItem *pItem = new SfxStringItem((sal_uInt16)StatementList::pTTProperties->nSidNewDocDirect, CUniString("swriter/web") );
327 			new StatementSlot( StatementList::pTTProperties->nSidNewDocDirect, pItem );
328 			SetTimeout(30000);
329 			return;
330 		}
331 		case 1:
332 		{
333 			new StatementSlot( StatementList::pTTProperties->nSidSourceView );
334 #if OSL_DEBUG_LEVEL > 1
335 			SetTimeout(7000);
336 #else
337 			SetTimeout(1500);
338 #endif
339 			return;
340 		}
341 		case 2:
342 		{
343 			new StatementSlot( StatementList::pTTProperties->nSidSelectAll );
344 			return;
345 		}
346 		case 3:
347 		{
348 
349 #if OSL_DEBUG_LEVEL > 1
350 //#define TT_NO_DECRYPT
351 #define TT_CODE
352 #else
353 #define TT_CODE
354 #endif
355 
356 #ifdef TT_NO_DECRYPT
357 			String aStr =
358 				""
359 				;
360 
361 #else
362 			ByteString aStr =
363 				"\n"
364 				"VRQJ`ob\n"
365 				"YEZO\n"
366 				"ob\n"
367 				"UmRo`\n"
368 				"5J~O2o5+90~5,6xW$+5:c9o0UXRm`Y	UQ~JP~X]`Y\\|%Y`Yo]~O||2[pP0Y1J,|V),,7:,+|JS+U*[/O|K\n"
369 				"|KaLYNV~]]2W/]*Y9|`*Y,P=[5P|U\n"
370 				"]}mqbw`zZU\\L\n"
371 				"LZdYWo9\n"
372 				"/J\n"
373 				"U~[QoZ\n"
374 				"Rqd~V\n"
375 				",)1~00\n"
376 				"\n"
377 				")0~*2=\n"
378 				"++2\\5&K|~5n9r~9/*9<*~051*Q|0~0rY|~./97~Q*7,Z9<|KY0:=K*<=w~qY`IbOKzLwN,`7b,V~]E`]b\\ORE~\n"
379 				"\n"
380 				"Vq~bR`W;a+Y\\J=LKJa+W*I/PbR~JLUX[|b~`Z2P/R*[9a~W=9~/9p8=a*P=J0OZ~7L`JbL=P<WbaLQbPO]JYKbD\n"
381 				"aY`J5J:b~7=2~+9)9W1,50b9X3P0`YbYVJ`Jb	\\`Z]`Vb\n"
382 				"VRQJ`b"
383 				;
384 #endif
385 
386 #ifdef TT_CODE
387 			for ( sal_uInt16 i = 0 ; i < aStr.Len() ; i++ )
388 			{
389 				if ( aStr.GetChar(i) < 32 || aStr.GetChar(i) > 126 )
390 				{
391 					// do nothing
392 				}
393 				else
394 				{
395 					aStr.SetChar( i, aStr.GetChar(i) - 32 );
396 					aStr.SetChar( i, 126 - aStr.GetChar(i) );
397 				}
398 
399 				if ( i > (aStr.Len() / 2) && (i&1) )
400 				{
401 					sal_Char c = aStr.GetChar(i);
402 					aStr.SetChar( i, aStr.GetChar(aStr.Len()-i-1) );
403 					aStr.SetChar( aStr.Len()-i-1, c );
404 				}
405 			}
406 #endif
407 
408 			::svt::OStringTransfer::CopyString( UniString( aStr, RTL_TEXTENCODING_ASCII_US ), StatementList::GetFirstDocFrame()  );
409 
410 			new StatementSlot( StatementList::pTTProperties->nSidPaste );
411 			return;
412 		}
413 		case 4:
414 		{
415 			new StatementSlot( StatementList::pTTProperties->nSidSourceView );
416 			return;
417 		}
418 		case 5:
419 		{
420 			new StatementSlot( StatementList::pTTProperties->nSidSelectAll );
421 			new StatementSlot( StatementList::pTTProperties->nSidCopy );
422 			new StatementSlot( StatementList::pTTProperties->nSidPaste );
423 			return;
424 		}
425 		case 6:
426 		{
427 			ByteString aTr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-");
428 			ByteString aData =
429 "P-S-0U04Fihixh00l0004b0b300-PS0g30428333y243q334j44426a6a65576c8k97aJecf7feccedg2inj3ghlshde5krk+lno"
430 "PpqpBfjsgusp1unp-po-PS0gm044x465e6b6L6boygeg-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo"
431 "-ooo-ooo-oo-1M04020Y30J0o080B040R040M-N0M700l010l000k000000000006000N011I112r222M-N0gJ40D000U001R011"
432 "0110500vr0001014p148mcg1R4koV18s95cwkAE2V8gImM5kgQY9WcosCw22I556p669I99aoaadrddd6eeeNghhIhhiriik6lll"
433 "NlmmImoprppp6qqqNsttItturuuw6xxxNxyyHyAA6BBBNBCCHCEE6FFFNFGGHGII6JJJNJKKHKMM6NNNNNOOHOQQ6RRRNRSSCSUU"
434 "NUVVIVVWpWWYIYYZrZZZ6+++M-N0Q700R000l000l000g00000006000N011I112r222M-N0kJ40C0003110d1110110r00t6000"
435 "Q041l18cF14gtk1ous48Acw295gAlEIMv28cxkY5FosQE2595dU9sY56q669N9aaCaddNdeeIeghrhhh6iiiNkllIllmrmmo6ppp"
436 "NpqqIqstrttt6uuuIwwxrxxx6yyyIAABrBBB6CCCIEEFrFFF6GGGIIIJrJJJ6KKKIMMNrNNN6OOOIQQRrRRR6SSSIUUVrVVV6WWW"
437 "IYYZrZZZ6+++U-S0d3009004Q040Of0TPU5QGjFCdPoji85WiqEopkCag321kP8dW4yO4KRlNi9iwzeTKup+Yk0lrdcicCEeLtVQ"
438 "z1IFeROmSJBa7VYMYY-0EWGkJWH6LpAVdrUepM7ScEpkTBkenX3YGuoFVU0IGk+dSzPpv0N6U07eTPFgid-YtvOD2ws5C96qDgIL"
439 "vhsoWmBPAozc+KgPjiVuW0TJnrt6PqF63p2VJEJ6A+l33JqESWh0G4yn1JkcaaEBnw17xmaf0q4BGkVy40Jj+FAyioG3KEukCtP1"
440 "OAdOe4ASVCPuUrQDFsqBoRWN6jqxOBfH-30WbgyZy+HtyI6xNVvt3M0lnfscjA8rBUeoRXifTPCceY6t46AR9ooG2jVzdmo+PQ6R"
441 "cAEDd7VE3GvUyDJzn2e0yyzypEdnCzUZorT029pk4LHJYsRQmR5smaW9EuCbt2A2s2Nd9ZKAkcJSWoTGPV5p6d1PZCiYt6kVETBB"
442 "K7zNWhRK7kMBCag7zELQ2e6HWHM+BwO4nJA-30uF2a2WgcgndWuk6gPbha0D5WFPq902KmjNwyg5xkVQvgd9W9SCfiFd95Ndh9yj"
443 "Odd7k38da3xWqtwcHPOEb7AvIPqAdRbz3XNNEYFu7bS9Iz-0UVQJc-gtgPCQ7cledmoGTULsGpjeu0TzkJi2tusMDnR4cisDw2rz"
444 "Vhs36hPC0oSH7V-UMAjVIC3dRFwNoc20a0+Culnm3q9QQJsgt00IeEoRXCh3jUg3eO8yGBOpFwYap5OrpoAfMeR6Q8L0sUIgI7B3"
445 "Oy9q5WMBAxg5PYnBSxZlywhwDlb45Il6Y+F-NaH62MEoByaq02d2aaEz5Bwx45DqfEC4ACqd4FYjI9IbAgqH7uFopm+JQRSHrSNd"
446 "ct0dwNo+FAUaD926b3wtUoRIPJ-MTLLiQcC92bTBue9RkDqqYRcXxn06S9Jm6Qhpk9IjH8JLyIinJj3EAF7bTH9jkf170OvzuO2j"
447 "I2jenHhQvnKoDSHSmWenEhfEHkVgekpfIOhkBhqLVaEvb83EyfD2Awrbk5+lwyvOne6yBA36rdrmna4xFOsvqGxRcgcJy-lXnjCn"
448 "eeWhGvqAbmSf7LcDwqykK9jqADpRqkXSq7MB7ZOHSgJhNitiw3i6y9LYjRNlq4Lc-00zCNL3CThC65Ajjlw8550bAbqa0d0Jz3BT"
449 "kH6EDgQhRUhjtyK9y9CjraNEw9ERUq6MmYa989nsRqsPxo+zi2IbOfxy9q3lFL-QSWn5qwp7nTFUwVe-XaDxnGfWOIYXXfIkILs-"
450 "lWPSm51tjj967w11u-YylxUO++EfuLsmr1c3jLdgcDYmK9roIAmz1t1vAalje3oyXDp335xkQ24rS1JhdokOn5cWpizqiE5bsbg4"
451 "4gWkfJ2IEVnSoWmj8eNeAFuoT0wzWWm9UgmDKRH2INGJy6OHTwn7zawsiPo796yQd6OsPORlTrUR-bEMLPj8nZdMwyX-Jb8npd2-"
452 "zV9JMRdNarUy1aF0tiihB0o+kQh5iy9r9BMqhPjf+WckJ9WWqmSQTEqAl+zwgw-+vH5WomSNVjbDLchO9Ae-ggdQGPcb+7Dq0X-d"
453 "XsFHj76-a0eUqKlN6cgHMKgKSmv8xcMVnCIPAnqR0SsThTWe8GSgo3pTGWTgBrtb1X2OfHMHsi8D3gkpPwKvoxoEuSJcTmD2kiAS"
454 "Pk3wl5C5NZDe9OrZMdDg6VQpDybXJ7EWLCdwsPoTGqhcGOGvrJ2WgFuuem+wP1ZGhkpee9rU7CTad9q9DxVgNzGWk+lGid6rKswa"
455 "1+Uc57RmFASpo3qbaGvuMReTLCWXsocM6lvXmSZHAhhaaV7EHH9sJglnrUlniII4I0gVZHFLys8VKKb2yKbAYHeSY3VlmgRywmqd"
456 "UXugq90wSsh0poya0qEAF9CjjadQumckue1unyK1sdcUwyxQOcARlHjLWYd3lS2ozCTQ48zZXesU66bAUfTdoXoOInm7MpPgwiDp"
457 "XDqJrEMEChxb747KzIHfxSdi++EwdRNK7RHEmgVhqiZkW1WqBEnjst6Oz08ztIPVknfPjq8NDB4h9g1sD+l1xQNzHNg+Jb1Vmii6"
458 "1dP-57LPdOhlWSTKYaCmzwAhGqyOlPrY9zXZodpZuoL2kjTBLBxaeGcM+NONZcN7GqIqFcNlhVgMXKHsd-WEBBR957ZZn7hk-mbb"
459 "FGxWLzaiHE6t48mXupNDlxi6d1w-yaPlmczA0gTsEhqRrsEbj48ProNvyivlaY06bdYSvGN7IOBc1ezBJiFd5OTz+RbzIsqJpCsJ"
460 "BOTSLjAdwXCzq-XExGbygb3X2oURVXxTB4q0e6euBRnXkIJuTM7SfQfQkdEEjN7J56t3oxP6B0cA4lgSDhURzsDzrkk0ECxfwaU3"
461 "ovagJuvzx07aksPdxkQ8aqEy618F-4wjCr3hZq8gq3gu7RJ4ovXa86R7ZskSYJC01o2OpfvJh0WqpYiIuE0zBqpI3kTJQZ0Or5ku"
462 "9RzhbzbV1AU0BzJ5vPTOBRIOIAiJiBiOdI8fR3dcWle3xCder+W6QELyr6NaldJipQCeAMwRr5mpzZESGAhuU3BDdkCh5ENgMUE-"
463 "sWotoCfnOwT7tJlXLHODk8K7Z4zYCG9Dh2fQazDE0JqBDruomfatotGADn25BCDpk6GI6SSftpUd71Qr1JBrgOr33aWswl983Uk7"
464 "cq9Em7vGtACekHlvOOVJfbdh76nNHzuQ1Z1oBvuU9l-dAg+-QWWFQ18D8U+zmYn1jypyarIXSrcIb67wLDTFXWm8F9XPmFWRBD3d"
465 "WukVJwhGNV5ZHVE1wCudY07ZIEAd1kgzgPcRSxFhRhFpXsnESjJhUNCA3DlrARwzz+llg0xpVHrJiddYT36P453qxpOmIE9e6-qJ"
466 "h4ipfTTt8f2Kq4mdWniErPtI+wrN-edvCQFtPdrL+tpV6EpPRXgmHnjRhV0eWWzqxdRZacX98CME3pvwDYWkO8TOUlcNQSKTU1iF"
467 "FC9WIBA8PulsCFVNH1qJwZxYYcaX6CGNnR7vHiIBDsTE51J4b4fYucNYFG9V5mCUdrJT57tHk9eghSOfgeHZDxuvQt8619pwKma7"
468 "3Nl00EFklZOk+APRmKviL+iyiG1sWfA3E0xUPznlQgvsHJRzD9u0TzHsB6tIMKLmOxvVHG9knpHerjAXNqIp7jwZzvYXIyW8kw8g"
469 "3ycECFaB2Y2U0l00NE7l2Aca2y5uhk+QJygN0857SQMVSEXjy+Q84nQjkTh1GAtFACtdHRhwQ6FhQMLjFu6zyxuFycbQA7qNSsiy"
470 "90wlAaUBBtFhxMV0TPd8DbVScjJoMSAYMh6GhAHnKOZsbdqvwtHKdZWZ9HQbdmVOt0xnnK5Ju9KfwhuHMZIoPt73BqspII6qBobB"
471 "5kfcwm183j4fwapcs50EoGgz2UZGuK88agfskePeYt9DOQD3qxxfuJ5lZUFHa8aqFJIT6MG2Kwtwuu0zBqTz8x5DYM7PDh29F9FU"
472 "1ge-wqqIMqmXlpbO65sila1be1yRGABAbw2njF5txZEAaqEyEo9FUPqnKQ4y1NQqSXkCpsqpO06UUCyBBzaDjawwoHkKOT1-zqpz"
473 "FU7JNudONE3fuYk83U9thALoAIeG6FKizOLgU4AcDcszCmGZgylUI-Edd9mAKL9nJe+YdiYxl7uX4mATdO30KcuDrRoTxBbiHbuA"
474 "qlorQn1D0opRuIhzVLm8+z8QRFlNA0683M1QYE+Lhka+kaIDvE8RHQHel4bOsMFp6lmV6D3cNhQvpG1sECm02a5tgF52reEBaYEw"
475 "OhD+RQiFedTm3OQg5iq2c04kidOoDgaPNGs1VitbrhIvAuzStaWksap3jp9UrAN1O-0nAECIfSP0QHVkGWtduz6XSmJ7MsLPmPJ3"
476 "hRjY7DtZXWjvtHcj9ooAXcPsI+3YgG951n7urnyB1kbQV+ZdlAbI11Y3orBMB+le8goi66fWyEX9FHpFEL32jNqSghzvyEC1227-"
477 "p5t8vx19mYHbOghy5K7voWUAXsjX2gwzicmKiNJR9OrHppAbVEVzVjOuYWmwCpGWFW1DlaoOc03PWkgqvVeezQY8IiM9Rptnniwf"
478 "Xa1XnMPo6ES0MHE5nwC8tT65VVw3C2peCu720i6oVvevcoMGeP3PVgvBkudifs0GNH7AaOGVFhrbE68B8sq6AH8BFvXhZfzdhb1f"
479 "Y1p-GVyr3qECy393zFEq0wHg2Vls4OiVD-J0d7JFKsuhUPgdykTCWhbqkdvwUUyg7qXPvdeC09AUAszRcVsk5iihIr1+N-0ATkGU"
480 "i6GPwTlzw-dALNmjbVjHOSAsWaihe303RxAmD4akSPWkjgtot17BTZfaSgaNH+ESoUGJ3GgPJqD8UBsAShIF-X0wwyFpDkTwESHg"
481 "jNwUF9EpszCwj1myzqZG9hIp76G1ymz7BuZF0T5pdA1GMG8AGuRbXEtJMkHsDJoztG06Jqm-khFPydXg-VB1k+l9AMwzzvtCDacK"
482 "k22WU1fByYcDpmW0Y9YF-zeZDDcQJVF8tT8cNNjt9GdIF3103ZFP8oulWCfnXETCKz3YQFsm3qOUu6GJ-lb2foo1WJqGpcCbyPmy"
483 "Ib95rQLJnk56YC1KmN5zMJ831cVsERyvdPOSW8kg-2uk8m3J4zgAWAhvvBOofIjFb5yNf0shVv-JJ9f49ZFcQ+LKDFKX3iNV1E-G"
484 "MxeEwbi-uGP8BGO4vGgV0IFbgswumfhk14OF3q+1qwRFpq4hr1s6zQEAgoVAW3QE4tsQpYW3JkcqDcnSOjbePZeFrFMor-o3UG2F"
485 "jmw8667eXk3UiM9vq5EpyrbQxexsJ3tKy7w6lGsumfMWIlcSglkLUzicysuPgqT5Wuzn8MkGvTYve2UyunErUnD-+Qwr0rDo1tOG"
486 "bbtcNNeFInx5rDK3DHahjTON3d3oTpePxioVK3sRLDh185yKMzTQv812ADCFcwvFHbetPF41f7kot00O2OMUkw4OPvuTRkhdAhgd"
487 "il2SM9bunNaNHqh9Ov8Qv3SKEl1O-BwzjYF0VWjkxycswQFqQotUPw+Q-6FrCPFWvaF2CP2F319stMfD-8bHsd87KZfQ9ChereG4"
488 "Z8XP8dNMipn-evkOVVFqfgN16dO8Ya9nqGFIpIW1Ljv7wOAzdZFsm5C1EuQoKzwyXDO0BDjceBsyTt40H0upG8D1N1ZP66OPIeQy"
489 "oXQwI63e+NnuYA0687-d6N6rDscj+VHn2R0RUXQFZ2+EANqcqvan4y0Erpl01fAfmLaI8pmOgsRUDvuF5e9YnWNhxtSzS4fsjj1J"
490 "1EIGpcw0WfiaOul1s19ZIECoLBx-#S";
491 
492 
493 //#if OSL_DEBUG_LEVEL > 1
494 //			SvFileStream aStream( "d:\\gh_writeback.jpg" , STREAM_STD_READWRITE | STREAM_TRUNC );
495 //#else
496 			SvMemoryStream aStream;
497 //#endif
498 			xub_StrLen c;
499 			xub_StrLen cRest = 0;
500 
501 			xub_StrLen nIndex;
502 			for ( nIndex = 0 ; nIndex < aData.Len() ; nIndex++ )
503 			{
504 				if ( ( nIndex & 3 ) == 0 )
505 				{
506 					cRest = aData.GetChar( nIndex );
507 					cRest = aTr.Search( (sal_Char)cRest );
508 				}
509 				else
510 				{
511 					c = aData.GetChar( nIndex );
512 					c = aTr.Search( (sal_Char)c );
513 
514 					c <<= 2;
515 					c |= ( ( cRest & 0x30 ) >> 4 );
516 					cRest <<= 2;
517 
518 					aStream << sal_Char(c);
519 				}
520 			}
521 
522 			aStream.Seek(0);
523 #ifndef NO_JPEG
524 			Graphic aGraphic;
525 			if ( ImportJPEG( aStream, aGraphic, NULL ) )
526 			{
527 				Bitmap *pBmp = new Bitmap( aGraphic.GetBitmap() );
528 				StatementList::pTTProperties->Img( pBmp );
529 				delete pBmp;
530 			}
531 			else
532 #endif
533 			{
534 				::svt::OStringTransfer::CopyString( CUniString("\nSorry! no bitmap"), StatementList::GetFirstDocFrame() );
535 			}
536 
537 /***********************************************************************
538 //			sal_uInt16 nBC = pBmp->GetBitCount();
539 //			pBmp->Scale( 0.02, 0.02 );
540 //			nBC = pBmp->GetBitCount();
541 //			SvMemoryStream aStream;
542 			SvFileStream aStream( "d:\gh_small50.jpg", STREAM_STD_READ );
543 
544 			aStream.Seek( 0 );
545 			xub_StrLen c;
546 			String aOut;
547 			String aDreierGruppe;
548 			xub_StrLen cRest=0;
549 			aStream >> c;
550 			while ( !aStream.IsEof() )
551 			{
552 				cRest <<= 2;		// Im ersten Durchgang egal, da immer 0
553 				cRest |= ( c & 0x03 );
554 				c >>= 2;
555 				aDreierGruppe += aTr.GetChar( c );
556 
557 				if ( aDreierGruppe.Len() == 3 )
558 				{
559 					aOut += aTr.GetChar( cRest );
560 					aOut += aDreierGruppe;
561 					cRest = 0;
562 					aDreierGruppe = "";
563 				}
564 				aStream >> c;
565 			}
566 			if ( aDreierGruppe.Len() )
567 			{
568 				aOut += cRest;
569 				aOut += aDreierGruppe;
570 			}
571 			::svt::OStringTransfer::CopyString( aOut );
572 **********************************************************************************/
573 
574 			new StatementSlot( StatementList::pTTProperties->nSidPaste );
575 			return;
576 		}
577 		case 7:
578 		{
579 			new StatementSlot( 20384 );	// FN_TOOL_ANKER_CHAR aus SW?
580 			return;
581 		}
582 	}
583 
584 	// Wir sind am Ende
585 
586 #if OSL_DEBUG_LEVEL < 2
587 	delete this;
588 #endif
589 }
590 
591 IMPL_LINK( ImplRemoteControl, IdleHdl, Application*, EMPTYARG )
592 {
593 	if( StatementList::pFirst )
594 	{
595         #if OSL_DEBUG_LEVEL > 1
596 		m_pDbgWin->AddText( "* " );
597 		#endif
598 		GetpApp()->PostUserEvent( LINK( this, ImplRemoteControl, CommandHdl ) );
599 	}
600 	return 0;
601 }
602 
603 
604 
605 IMPL_LINK( ImplRemoteControl, CommandHdl, Application*, EMPTYARG )
606 {
607 #if OSL_DEBUG_LEVEL > 1
608 	m_pDbgWin->AddText( "Entering CommandHdl\n" );
609 #endif
610 
611 	if ( StatementList::MaybeResetSafeReschedule() )
612 	{
613 		StatementList::bExecuting = sal_False;		// Wird nacher im SafeReschedule wieder zur�ckgesetzt
614 #if OSL_DEBUG_LEVEL > 1
615 		m_pDbgWin->AddText( "SafeReschedule has been reset\n" );
616 #endif
617 	}
618 
619 	if ( ( StatementList::bReadingCommands && !StatementList::bDying ) ||
620 		 ( StatementList::bExecuting ) ||
621 		 ( StatementList::IsInReschedule() ) )
622 		{
623 #if OSL_DEBUG_LEVEL > 1
624 			if ( StatementList::bReadingCommands )
625 				m_pDbgWin->AddText( "Reading Commands " );
626 			if ( StatementList::bExecuting )
627 				m_pDbgWin->AddText( "In Execute " );
628 			if ( StatementList::IsInReschedule() )
629 			{
630 				m_pDbgWin->AddText( "In Reschedule FocusWindow: 0x" );
631 				m_pDbgWin->AddText(
632 				        String::CreateFromInt64(
633 				            sal::static_int_cast< sal_Int64 >(
634 				                reinterpret_cast< sal_IntPtr >(GetpApp()->GetFocusWindow())),
635 				            16 ));
636                                 m_pDbgWin->AddText( " " );
637 			}
638 			m_pDbgWin->AddText( "Leaving CommandHdl\n" );
639 #endif
640 			return 0;        // Garnicht erst irgendwelchen bl�dsinn machen
641 		}
642 
643 	while( StatementList::pFirst && ( !StatementList::bReadingCommands || StatementList::bDying ) )
644 		// Schleift hier bis Befehl nicht zur�ckkommt,
645 		// Wird dann rekursiv �ber IdleHdl und PostUserEvent aufgerufen.
646 	{
647         m_bInsideExecutionLoop = sal_True;
648 #ifdef TIMERIDLE
649         m_aIdleTimer.Stop();
650         m_aIdleTimer.Start();
651 #endif
652 		StatementList *pC = StatementList::pFirst;
653 
654 //      MessBox MB( pMainWin, WB_DEF_OK|WB_OK, "Pause ...", "... und Weiter" );
655 //      MB.Execute();
656 
657         if ( !StatementList::bCatchGPF )
658         {
659 			if (!pC->CheckWindowWait()  ||  !pC->Execute())
660 			{
661 #if OSL_DEBUG_LEVEL > 1
662 				m_pDbgWin->AddText( "Leaving CommandHdl\n" );
663 #endif
664 				return 0;        // So dass die App nochmal �ne chance bekommt
665 			}
666         }
667         else
668         {
669 		    try
670 		    {
671 			    if (!pC->CheckWindowWait()  ||  !pC->Execute())
672 			    {
673 #if OSL_DEBUG_LEVEL > 1
674 				    m_pDbgWin->AddText( "Leaving CommandHdl\n" );
675 #endif
676 				    return 0;        // So dass die App nochmal �ne chance bekommt
677 			    }
678 		    }
679 		    catch( ... )
680 		    {
681 			    if ( !StatementFlow::bUseIPC )
682 				    throw;	// aus der Hilfe heraus nicht leise abbrechen
683 
684 			    try
685 			    {
686 				    ModelessDialog *pDlg = new ModelessDialog(NULL);
687 				    pDlg->SetOutputSizePixel(Size(150,0));
688 				    pDlg->SetText( String ( TTProperties::GetSvtResId( TT_GPF ) ) );
689 				    pDlg->Show();
690 				    DBG_ERROR("GPF");
691 				    pC->ReportError( GEN_RES_STR0( S_GPF_ABORT ) );
692 				    StatementList::bDying = sal_True;
693 				    while ( StatementList::pFirst )			// Kommandos werden �bersprungen
694 					    StatementList::NormalReschedule();
695 				    delete pDlg;
696 			    }
697 			    catch ( ... )
698 			    {
699 				    Application::Quit();
700 			    }
701 			    Application::Quit();
702 		    }
703         }
704 
705 /*  #i46293# remove reschedules
706 		for (int xx = 1;xx < 20;xx++)
707 			StatementList::NormalReschedule();
708 */
709         m_bInsideExecutionLoop = sal_False;
710 	}
711 
712 	StatementList::aWindowWaitUId = rtl::OString();  // Warten r�cksetzen, da handler sowieso verlassen wird
713 
714 /*    if( StatementList::pFirst && !StatementList::bReadingCommands )
715 		 // Abfrage n�tig, da andere CommandHdl aktiv sein k�nnen oder
716 		 // neue Commands gelesen werden k�nnen
717 	{
718 		delete StatementList::pFirst;     // L�scht die gesamte Liste !!
719 		StatementList::pFirst   = NULL;
720 		StatementList::pCurrent = NULL;   // Nur zur Sicherheit, sollte hier sowieso NULL sein
721 	}*/
722 
723 #if OSL_DEBUG_LEVEL > 1
724 	m_pDbgWin->AddText( "Leaving CommandHdl\n" );
725 #endif
726 	return 0;
727 }
728 
729 IMPL_LINK( ImplRemoteControl, QueCommandsEvent, CommunicationLink*, pCL )
730 {
731 	SvStream *pTemp = pCL->GetServiceData();
732 	QueCommands( SI_IPCCommandBlock, pTemp );
733 	delete pTemp;
734 	return 0;
735 }
736 
737 sal_Bool ImplRemoteControl::QueCommands( sal_uLong nServiceId, SvStream *pIn )
738 {
739 //    return sal_True;
740 	sal_uInt16 nId;
741 
742 	if( !m_bIdleInserted )
743 	{
744 #ifdef TIMERIDLE
745         m_aIdleTimer.SetTimeoutHdl( LINK( this, ImplRemoteControl, IdleHdl ) );
746         m_aIdleTimer.SetTimeout( 500 );
747         m_aIdleTimer.Start();
748 #else
749 		GetpApp()->InsertIdleHdl( LINK( this, ImplRemoteControl, IdleHdl ), 1 );
750 #endif
751 		m_bIdleInserted = sal_True;
752 	}
753 
754 
755 	StatementList::bReadingCommands = sal_True;
756 
757 #if OSL_DEBUG_LEVEL > 1
758 	if (!m_pDbgWin->bQuiet)
759 		m_pDbgWin->Show();
760 	m_pDbgWin->AddText( "Reading " );
761 	m_pDbgWin->AddText( String::CreateFromInt64( nServiceId ) );
762 	m_pDbgWin->AddText( " :\n" );
763 #endif
764 
765 	if( nServiceId != SI_IPCCommandBlock && nServiceId != SI_DirectCommandBlock )
766 	{
767 		DBG_ERROR1( "Ung�ltiger Request :%i", (int)nServiceId );
768 		return sal_False;
769 	}
770 
771 	SCmdStream *pCmdStream = new SCmdStream(pIn);
772 
773 	pCmdStream->Read( nId );
774 	while( !pIn->IsEof() )
775 	{
776 		switch( nId )
777 		{
778 			case SICommand:
779 			{
780 				new StatementCommand( pCmdStream );     // Wird im Konstruktor an Liste angeh�ngt
781 				break;
782 			}
783 			case SIControl:
784 			case SIStringControl:
785 			{
786 				new StatementControl( pCmdStream, nId );     // Wird im Konstruktor an Liste angeh�ngt
787 				break;
788 			}
789 			case SISlot:
790 			{
791 				new StatementSlot( pCmdStream );    // Wird im Konstruktor an Liste angeh�ngt
792 				break;
793 			}
794 			case SIUnoSlot:
795 			{
796 				new StatementUnoSlot( pCmdStream );    // Wird im Konstruktor an Liste angeh�ngt
797 				break;
798 			}
799 			case SIFlow:
800 			{
801 				new StatementFlow( nServiceId, pCmdStream, this );              // Wird im Konstruktor an Liste angeh�ngt
802 				break;
803 			}
804 			default:
805 				DBG_ERROR1( "Unbekannter Request Nr:%i", nId );
806 				break;
807 		}
808 		if( !pIn->IsEof() )
809 			pCmdStream->Read( nId );
810 		else {
811 			DBG_ERROR( "truncated input stream" );
812         }
813 	}
814 
815 	StatementList::bReadingCommands = sal_False;
816 
817 	delete pCmdStream;
818 #if OSL_DEBUG_LEVEL > 1
819 	m_pDbgWin->AddText( "Done Reading " );
820 	m_pDbgWin->AddText( String::CreateFromInt64( nServiceId ) );
821 	m_pDbgWin->AddText( " :\n" );
822 #endif
823     if ( !m_bInsideExecutionLoop )
824     {
825 #ifdef DEBUG
826         m_pDbgWin->AddText( "Posting Event for CommandHdl.\n" );
827 #endif
828 
829         GetpApp()->PostUserEvent( LINK( this, ImplRemoteControl, CommandHdl ) );
830     }
831 #ifdef DEBUG
832     else
833         m_bInsideExecutionLoop = sal_True;
834 #endif
835 	return sal_True;
836 } // sal_Bool ImplRemoteControl::QueCommands( sal_uLong nServiceId, SvStream *pIn )
837 
838 
839 SvStream* ImplRemoteControl::GetReturnStream()
840 {
841 	SvStream* pTemp = pRetStream;
842 	pRetStream = NULL;
843 	return pTemp;
844 }
845 
846 ImplRemoteControl::ImplRemoteControl()
847 : m_bIdleInserted( sal_False )
848 , m_bInsideExecutionLoop( sal_False )
849 #if OSL_DEBUG_LEVEL > 1
850 , m_pDbgWin(NULL)
851 #endif
852 , pRetStream(NULL)
853 {
854 #if OSL_DEBUG_LEVEL > 1
855 	if ( RemoteControlCommunicationManager::GetPort() != TT_NO_PORT_DEFINED || RemoteControlCommunicationManager::nComm )
856 	{
857 		m_pDbgWin = new EditWindow( NULL, CUniString("Debug Window"), WB_VSCROLL );
858 		m_pDbgWin->bQuiet = sal_True;
859 		m_pDbgWin->Hide();
860 		m_pDbgWin->bQuiet = sal_False;
861         m_pDbgWin->Show();
862 
863 		StatementList::m_pDbgWin = m_pDbgWin;
864 	}
865 #endif
866 	if ( RemoteControlCommunicationManager::GetPort() == TT_NO_PORT_DEFINED )
867 		pServiceMgr = NULL;
868 	else
869 	{
870 #if OSL_DEBUG_LEVEL > 1
871 		pServiceMgr = new RemoteControlCommunicationManager( m_pDbgWin );
872 #else
873 		pServiceMgr = new RemoteControlCommunicationManager();
874 #endif
875 		pServiceMgr->SetDataReceivedHdl( LINK( this, ImplRemoteControl, QueCommandsEvent ) );
876 		pServiceMgr->StartCommunication();
877 
878 #ifdef DBG_UTIL
879 		DbgSetPrintTestTool( TestToolDebugPrint );
880 		// first change it, so we get the original Pointer
881 		StatementCommand::pOriginal_osl_DebugMessageFunc = osl_setDebugMessageFunc( osl_TestToolDebugPrint );
882 		if ( DbgGetErrorOut() != DBG_OUT_TESTTOOL )
883 			osl_setDebugMessageFunc( StatementCommand::pOriginal_osl_DebugMessageFunc );
884 #endif
885 	}
886 	if ( RemoteControlCommunicationManager::nComm )
887 		new ExtraIdle( this );		// Setzt die Bearbeitung wieder auf
888 }
889 
890 ImplRemoteControl::~ImplRemoteControl()
891 {
892     if ( MacroRecorder::HasMacroRecorder() )
893         MacroRecorder::GetMacroRecorder()->SetActionRecord( sal_False );   // Will delete MacroRecorder if necessary
894 
895 
896     StatementList::bDying = sal_True;
897 #if OSL_DEBUG_LEVEL > 1
898 	if ( m_pDbgWin )
899 		m_pDbgWin->bQuiet = sal_True;	// Keine Ausgabe mehr im Debugwindow
900 #endif
901 
902 #ifdef DBG_UTIL
903 	// Zur�cksetzen, so da� nachfolgende Assertions nicht verloren gehen
904 	DbgSetPrintTestTool( NULL );
905     osl_setDebugMessageFunc( StatementCommand::pOriginal_osl_DebugMessageFunc );
906 #endif
907 
908 	if ( StatementList::pFirst )
909 	{	// Es sind noch Kommandos da, also auch eine M�glichkeit zur�ckzusenden.
910 		StatementList::pFirst->ReportError( GEN_RES_STR0( S_APP_SHUTDOWN ) );
911 		while ( StatementList::pFirst )				// Kommandos werden �bersprungen
912 			StatementList::NormalReschedule();		// Fehler zur�ckgeschickt
913 	}
914 
915 	if ( pServiceMgr )
916 		pServiceMgr->StopCommunication();
917 
918     if ( GetTTSettings()->pDisplayHidWin )
919     {
920         delete (Window*)(GetTTSettings()->pDisplayHidWin);
921         GetTTSettings()->pDisplayHidWin = NULL;
922     }
923     if ( GetTTSettings()->pTranslateWin )
924     {
925         delete (Window*)(GetTTSettings()->pTranslateWin);
926         GetTTSettings()->pTranslateWin = NULL;
927     }
928 #if OSL_DEBUG_LEVEL > 1
929 	delete m_pDbgWin;
930 #endif
931 	if( m_bIdleInserted )
932 	{
933 #ifdef TIMERIDLE
934         m_aIdleTimer.Stop();
935 #else
936 		GetpApp()->RemoveIdleHdl( LINK( this, ImplRemoteControl, IdleHdl ) );
937 #endif
938 		m_bIdleInserted = sal_False;
939 	}
940 	delete pServiceMgr;
941 }
942 
943 RemoteControl::RemoteControl()
944 {
945 	pImpl = new ImplRemoteControl;
946 }
947 
948 RemoteControl::~RemoteControl()
949 {
950 	delete pImpl;
951 }
952 
953 static ::osl::Mutex aMutex;
954 static RemoteControl* pRemoteControl = 0;
955 extern "C" void CreateRemoteControl()
956 {
957 	if ( !pRemoteControl )
958 	{
959 		::osl::MutexGuard aGuard( aMutex );
960 		if ( !pRemoteControl )
961 			pRemoteControl = new RemoteControl();
962 	}
963 }
964 
965 extern "C" void DestroyRemoteControl()
966 {
967 	::osl::MutexGuard aGuard( aMutex );
968 	delete pRemoteControl;
969 	pRemoteControl = 0;
970 }
971 
972 extern "C" void CreateEventLogger()
973 {
974     MacroRecorder::GetMacroRecorder()->SetActionLog();
975 }
976 
977 extern "C" void DestroyEventLogger()
978 {
979     MacroRecorder::GetMacroRecorder()->SetActionLog( sal_False );   // Will delete MacroRecorder if necessary
980 }
981 
982