19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file
59f62ea84SAndrew Rist * distributed with this work for additional information
69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file
79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist * software distributed under the License is distributed on an
159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the
179f62ea84SAndrew Rist * specific language governing permissions and limitations
189f62ea84SAndrew Rist * under the License.
19cdf0e10cSrcweir *
209f62ea84SAndrew Rist *************************************************************/
219f62ea84SAndrew Rist
229f62ea84SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <stdio.h>
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "tools/fsys.hxx"
30cdf0e10cSrcweir #include "tools/getprocessworkingdir.hxx"
31cdf0e10cSrcweir #include <tools/solarmutex.hxx>
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include "osl/process.h"
34cdf0e10cSrcweir
35cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
36cdf0e10cSrcweir
37cdf0e10cSrcweir #include "vcl/svapp.hxx"
38cdf0e10cSrcweir #include "vcl/window.hxx"
39cdf0e10cSrcweir #include "vcl/timer.hxx"
40cdf0e10cSrcweir
41cdf0e10cSrcweir #include "aqua/saldata.hxx"
42cdf0e10cSrcweir #include "aqua/salinst.h"
43cdf0e10cSrcweir #include "aqua/salframe.h"
44cdf0e10cSrcweir #include "aqua/salobj.h"
45cdf0e10cSrcweir #include "aqua/salsys.h"
46cdf0e10cSrcweir #include "aqua/salvd.h"
47cdf0e10cSrcweir #include "aqua/salbmp.h"
48cdf0e10cSrcweir #include "aqua/salprn.h"
49cdf0e10cSrcweir #include "aqua/saltimer.h"
50cdf0e10cSrcweir #include "aqua/vclnsapp.h"
51cdf0e10cSrcweir
52cdf0e10cSrcweir #include "print.h"
53cdf0e10cSrcweir #include "impbmp.hxx"
54cdf0e10cSrcweir #include "salimestatus.hxx"
55cdf0e10cSrcweir
56cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
57cdf0e10cSrcweir
58cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
59cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60cdf0e10cSrcweir #include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp>
61cdf0e10cSrcweir #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
62cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
63cdf0e10cSrcweir
64cdf0e10cSrcweir #include "premac.h"
65cdf0e10cSrcweir #include <Foundation/Foundation.h>
66cdf0e10cSrcweir #include <ApplicationServices/ApplicationServices.h>
67cdf0e10cSrcweir #import "apple_remote/RemoteMainController.h"
68cdf0e10cSrcweir #include "apple_remote/RemoteControl.h"
69cdf0e10cSrcweir #include "postmac.h"
70cdf0e10cSrcweir
71cdf0e10cSrcweir using namespace std;
72cdf0e10cSrcweir using namespace ::com::sun::star;
73cdf0e10cSrcweir
74cdf0e10cSrcweir extern sal_Bool ImplSVMain();
75cdf0e10cSrcweir
76cdf0e10cSrcweir static sal_Bool* gpbInit = 0;
77cdf0e10cSrcweir static NSMenu* pDockMenu = nil;
78cdf0e10cSrcweir static bool bNoSVMain = true;
79cdf0e10cSrcweir static bool bLeftMain = false;
80cdf0e10cSrcweir // -----------------------------------------------------------------------
81cdf0e10cSrcweir
82cdf0e10cSrcweir class AquaDelayedSettingsChanged : public Timer
83cdf0e10cSrcweir {
84cdf0e10cSrcweir bool mbInvalidate;
85cdf0e10cSrcweir public:
AquaDelayedSettingsChanged(bool bInvalidate)86cdf0e10cSrcweir AquaDelayedSettingsChanged( bool bInvalidate ) :
87cdf0e10cSrcweir mbInvalidate( bInvalidate )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir }
90cdf0e10cSrcweir
Timeout()91cdf0e10cSrcweir virtual void Timeout()
92cdf0e10cSrcweir {
93cdf0e10cSrcweir SalData* pSalData = GetSalData();
94cdf0e10cSrcweir if( ! pSalData->maFrames.empty() )
95cdf0e10cSrcweir pSalData->maFrames.front()->CallCallback( SALEVENT_SETTINGSCHANGED, NULL );
96cdf0e10cSrcweir
97cdf0e10cSrcweir if( mbInvalidate )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir for( std::list< AquaSalFrame* >::iterator it = pSalData->maFrames.begin();
100cdf0e10cSrcweir it != pSalData->maFrames.end(); ++it )
101cdf0e10cSrcweir {
102cdf0e10cSrcweir if( (*it)->mbShown )
103cdf0e10cSrcweir (*it)->SendPaintEvent( NULL );
104cdf0e10cSrcweir }
105cdf0e10cSrcweir }
106cdf0e10cSrcweir Stop();
107cdf0e10cSrcweir delete this;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir };
110cdf0e10cSrcweir
delayedSettingsChanged(bool bInvalidate)111cdf0e10cSrcweir void AquaSalInstance::delayedSettingsChanged( bool bInvalidate )
112cdf0e10cSrcweir {
113cdf0e10cSrcweir vos::OGuard aGuard( *mpSalYieldMutex );
114cdf0e10cSrcweir AquaDelayedSettingsChanged* pTimer = new AquaDelayedSettingsChanged( bInvalidate );
115cdf0e10cSrcweir pTimer->SetTimeout( 50 );
116cdf0e10cSrcweir pTimer->Start();
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
119cdf0e10cSrcweir
120cdf0e10cSrcweir // the AppEventList must be available before any SalData/SalInst/etc. objects are ready
121cdf0e10cSrcweir typedef std::list<const ApplicationEvent*> AppEventList;
122cdf0e10cSrcweir AppEventList AquaSalInstance::aAppEventList;
123cdf0e10cSrcweir
GetDynamicDockMenu()124cdf0e10cSrcweir NSMenu* AquaSalInstance::GetDynamicDockMenu()
125cdf0e10cSrcweir {
126cdf0e10cSrcweir if( ! pDockMenu && ! bLeftMain )
127cdf0e10cSrcweir pDockMenu = [[NSMenu alloc] initWithTitle: @""];
128cdf0e10cSrcweir return pDockMenu;
129cdf0e10cSrcweir }
130cdf0e10cSrcweir
isOnCommandLine(const rtl::OUString & rArg)131cdf0e10cSrcweir bool AquaSalInstance::isOnCommandLine( const rtl::OUString& rArg )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir sal_uInt32 nArgs = osl_getCommandArgCount();
134cdf0e10cSrcweir for( sal_uInt32 i = 0; i < nArgs; i++ )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir rtl::OUString aArg;
137cdf0e10cSrcweir osl_getCommandArg( i, &aArg.pData );
138cdf0e10cSrcweir if( aArg.equals( rArg ) )
139cdf0e10cSrcweir return true;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir return false;
142cdf0e10cSrcweir }
143cdf0e10cSrcweir
144cdf0e10cSrcweir
145cdf0e10cSrcweir // initialize the cocoa VCL_NSApplication object
146cdf0e10cSrcweir // returns an NSAutoreleasePool that must be released when the event loop begins
initNSApp()147cdf0e10cSrcweir static void initNSApp()
148cdf0e10cSrcweir {
149cdf0e10cSrcweir // create our cocoa NSApplication
150cdf0e10cSrcweir [VCL_NSApplication sharedApplication];
151cdf0e10cSrcweir
152cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
153cdf0e10cSrcweir
154cdf0e10cSrcweir // put cocoa into multithreaded mode
155cdf0e10cSrcweir [NSThread detachNewThreadSelector:@selector(enableCocoaThreads:) toTarget:[[CocoaThreadEnabler alloc] init] withObject:nil];
156cdf0e10cSrcweir
157cdf0e10cSrcweir // activate our delegate methods
158cdf0e10cSrcweir [NSApp setDelegate: NSApp];
159cdf0e10cSrcweir
160cdf0e10cSrcweir [[NSNotificationCenter defaultCenter] addObserver: NSApp
161cdf0e10cSrcweir selector: @selector(systemColorsChanged:)
162cdf0e10cSrcweir name: NSSystemColorsDidChangeNotification
163cdf0e10cSrcweir object: nil ];
164cdf0e10cSrcweir [[NSNotificationCenter defaultCenter] addObserver: NSApp
165cdf0e10cSrcweir selector: @selector(screenParametersChanged:)
166cdf0e10cSrcweir name: NSApplicationDidChangeScreenParametersNotification
167cdf0e10cSrcweir object: nil ];
168cdf0e10cSrcweir // add observers for some settings changes that affect vcl's settings
169cdf0e10cSrcweir // scrollbar variant
170cdf0e10cSrcweir [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp
171cdf0e10cSrcweir selector: @selector(scrollbarVariantChanged:)
172cdf0e10cSrcweir name: @"AppleAquaScrollBarVariantChanged"
173cdf0e10cSrcweir object: nil ];
174cdf0e10cSrcweir // scrollbar page behavior ("jump to here" or not)
175cdf0e10cSrcweir [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp
176cdf0e10cSrcweir selector: @selector(scrollbarSettingsChanged:)
177cdf0e10cSrcweir name: @"AppleNoRedisplayAppearancePreferenceChanged"
178cdf0e10cSrcweir object: nil ];
179cdf0e10cSrcweir
180cdf0e10cSrcweir // get System Version and store the value in GetSalData()->mnSystemVersion
181245318c3SHerbert Dürr SInt32 systemVersion = OSX_VER_LION; // initialize with the minimal requirement
182245318c3SHerbert Dürr const OSErr err = Gestalt( gestaltSystemVersion, &systemVersion);
183245318c3SHerbert Dürr if( err == noErr )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir GetSalData()->mnSystemVersion = systemVersion;
186cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
187245318c3SHerbert Dürr fprintf( stderr, "OSX System Version 0x%04x\n", (unsigned int)systemVersion);
188cdf0e10cSrcweir #endif
189cdf0e10cSrcweir }
190cdf0e10cSrcweir else
191cdf0e10cSrcweir NSLog(@"Unable to obtain system version: %ld", (long)err);
192cdf0e10cSrcweir
193dbfe0a54SHerbert Dürr GetSalData()->mpAppleRemoteMainController = [[AppleRemoteMainController alloc] init];
194cdf0e10cSrcweir
195cdf0e10cSrcweir [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp
196cdf0e10cSrcweir selector: @selector(applicationWillBecomeActive:)
197cdf0e10cSrcweir name: @"AppleRemoteWillBecomeActive"
198cdf0e10cSrcweir object: nil ];
199cdf0e10cSrcweir
200cdf0e10cSrcweir [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp
201cdf0e10cSrcweir selector: @selector(applicationWillResignActive:)
202cdf0e10cSrcweir name: @"AppleRemoteWillResignActive"
203cdf0e10cSrcweir object: nil ];
204cdf0e10cSrcweir
205cdf0e10cSrcweir if( ImplGetSVData()->mbIsTestTool )
206cdf0e10cSrcweir [NSApp activateIgnoringOtherApps: YES];
207cdf0e10cSrcweir }
208cdf0e10cSrcweir
ImplSVMainHook(sal_Bool * pbInit)209cdf0e10cSrcweir sal_Bool ImplSVMainHook( sal_Bool * pbInit )
210cdf0e10cSrcweir {
211cdf0e10cSrcweir gpbInit = pbInit;
212cdf0e10cSrcweir
213cdf0e10cSrcweir bNoSVMain = false;
214cdf0e10cSrcweir initNSApp();
215cdf0e10cSrcweir
216cdf0e10cSrcweir rtl::OUString aExeURL, aExe;
217cdf0e10cSrcweir osl_getExecutableFile( &aExeURL.pData );
218cdf0e10cSrcweir osl_getSystemPathFromFileURL( aExeURL.pData, &aExe.pData );
219cdf0e10cSrcweir rtl::OString aByteExe( rtl::OUStringToOString( aExe, osl_getThreadTextEncoding() ) );
220cdf0e10cSrcweir
221cdf0e10cSrcweir #ifdef DEBUG
222cdf0e10cSrcweir aByteExe += OString ( " NSAccessibilityDebugLogLevel 1" );
223cdf0e10cSrcweir const char* pArgv[] = { aByteExe.getStr(), NULL };
224cdf0e10cSrcweir NSApplicationMain( 3, pArgv );
225cdf0e10cSrcweir #else
226cdf0e10cSrcweir const char* pArgv[] = { aByteExe.getStr(), NULL };
227cdf0e10cSrcweir NSApplicationMain( 1, pArgv );
228cdf0e10cSrcweir #endif
229cdf0e10cSrcweir
230cdf0e10cSrcweir return TRUE; // indicate that ImplSVMainHook is implemented
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir // =======================================================================
234cdf0e10cSrcweir
SalAbort(const XubString & rErrorText)235cdf0e10cSrcweir void SalAbort( const XubString& rErrorText )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir if( !rErrorText.Len() )
238cdf0e10cSrcweir fprintf( stderr, "Application Error " );
239cdf0e10cSrcweir else
240cdf0e10cSrcweir fprintf( stderr, "%s ",
241cdf0e10cSrcweir ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
242cdf0e10cSrcweir abort();
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir // -----------------------------------------------------------------------
246cdf0e10cSrcweir
InitSalData()247cdf0e10cSrcweir void InitSalData()
248cdf0e10cSrcweir {
249cdf0e10cSrcweir SalData *pSalData = new SalData;
250cdf0e10cSrcweir SetSalData( pSalData );
251cdf0e10cSrcweir }
252cdf0e10cSrcweir
253cdf0e10cSrcweir // -----------------------------------------------------------------------
254cdf0e10cSrcweir
SalGetDesktopEnvironment()255cdf0e10cSrcweir const ::rtl::OUString& SalGetDesktopEnvironment()
256cdf0e10cSrcweir {
257cdf0e10cSrcweir static OUString aDesktopEnvironment(RTL_CONSTASCII_USTRINGPARAM( "MacOSX" ));
258cdf0e10cSrcweir return aDesktopEnvironment;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir // -----------------------------------------------------------------------
262cdf0e10cSrcweir
DeInitSalData()263cdf0e10cSrcweir void DeInitSalData()
264cdf0e10cSrcweir {
265cdf0e10cSrcweir SalData *pSalData = GetSalData();
266cdf0e10cSrcweir if( pSalData->mpStatusItem )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir [pSalData->mpStatusItem release];
269cdf0e10cSrcweir pSalData->mpStatusItem = nil;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir delete pSalData;
272cdf0e10cSrcweir SetSalData( NULL );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir // -----------------------------------------------------------------------
276cdf0e10cSrcweir
277cdf0e10cSrcweir extern "C" {
278cdf0e10cSrcweir #include <crt_externs.h>
279cdf0e10cSrcweir }
280cdf0e10cSrcweir
281cdf0e10cSrcweir // -----------------------------------------------------------------------
282cdf0e10cSrcweir
InitSalMain()283cdf0e10cSrcweir void InitSalMain()
284cdf0e10cSrcweir {
285cdf0e10cSrcweir rtl::OUString urlWorkDir;
286cdf0e10cSrcweir rtl_uString *sysWorkDir = NULL;
287cdf0e10cSrcweir if (tools::getProcessWorkingDir(&urlWorkDir))
288cdf0e10cSrcweir {
289cdf0e10cSrcweir oslFileError err2 = osl_getSystemPathFromFileURL(urlWorkDir.pData, &sysWorkDir);
290cdf0e10cSrcweir if (err2 == osl_File_E_None)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir ByteString aPath( getenv( "PATH" ) );
293cdf0e10cSrcweir ByteString aResPath( getenv( "STAR_RESOURCEPATH" ) );
294cdf0e10cSrcweir ByteString aLibPath( getenv( "DYLD_LIBRARY_PATH" ) );
295cdf0e10cSrcweir ByteString aCmdPath( OUStringToOString(OUString(sysWorkDir), RTL_TEXTENCODING_UTF8).getStr() );
296cdf0e10cSrcweir ByteString aTmpPath;
297cdf0e10cSrcweir // Get absolute path of command's directory
298cdf0e10cSrcweir if ( aCmdPath.Len() ) {
299cdf0e10cSrcweir DirEntry aCmdDirEntry( aCmdPath );
300cdf0e10cSrcweir aCmdDirEntry.ToAbs();
301cdf0e10cSrcweir aCmdPath = ByteString( aCmdDirEntry.GetPath().GetFull(), RTL_TEXTENCODING_ASCII_US );
302cdf0e10cSrcweir }
303cdf0e10cSrcweir // Assign to PATH environment variable
304cdf0e10cSrcweir if ( aCmdPath.Len() )
305cdf0e10cSrcweir {
306343cc52dSHerbert Dürr aTmpPath = aCmdPath;
307cdf0e10cSrcweir if ( aPath.Len() )
308cdf0e10cSrcweir aTmpPath += ByteString( DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US );
309cdf0e10cSrcweir aTmpPath += aPath;
310343cc52dSHerbert Dürr setenv( "PATH", aTmpPath.GetBuffer(), TRUE );
311cdf0e10cSrcweir }
312cdf0e10cSrcweir // Assign to STAR_RESOURCEPATH environment variable
313cdf0e10cSrcweir if ( aCmdPath.Len() )
314cdf0e10cSrcweir {
315343cc52dSHerbert Dürr aTmpPath = aCmdPath;
316cdf0e10cSrcweir if ( aResPath.Len() )
317cdf0e10cSrcweir aTmpPath += ByteString( DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US );
318cdf0e10cSrcweir aTmpPath += aResPath;
319343cc52dSHerbert Dürr setenv( "STAR_RESOURCEPATH", aTmpPath.GetBuffer(), TRUE );
320cdf0e10cSrcweir }
321cdf0e10cSrcweir // Assign to DYLD_LIBRARY_PATH environment variable
322cdf0e10cSrcweir if ( aCmdPath.Len() )
323cdf0e10cSrcweir {
324343cc52dSHerbert Dürr aTmpPath = aCmdPath;
325cdf0e10cSrcweir if ( aLibPath.Len() )
326cdf0e10cSrcweir aTmpPath += ByteString( DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US );
327cdf0e10cSrcweir aTmpPath += aLibPath;
328343cc52dSHerbert Dürr setenv( "DYLD_LIBRARY_PATH", aTmpPath.GetBuffer(), TRUE );
329cdf0e10cSrcweir }
330cdf0e10cSrcweir }
331cdf0e10cSrcweir }
332cdf0e10cSrcweir }
333cdf0e10cSrcweir
334cdf0e10cSrcweir // -----------------------------------------------------------------------
335cdf0e10cSrcweir
DeInitSalMain()336cdf0e10cSrcweir void DeInitSalMain()
337cdf0e10cSrcweir {
338cdf0e10cSrcweir }
339cdf0e10cSrcweir
340cdf0e10cSrcweir // =======================================================================
341cdf0e10cSrcweir
SalYieldMutex()342cdf0e10cSrcweir SalYieldMutex::SalYieldMutex()
343cdf0e10cSrcweir {
344cdf0e10cSrcweir mnCount = 0;
345cdf0e10cSrcweir mnThreadId = 0;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
acquire()348cdf0e10cSrcweir void SalYieldMutex::acquire()
349cdf0e10cSrcweir {
350cdf0e10cSrcweir OMutex::acquire();
351cdf0e10cSrcweir mnThreadId = vos::OThread::getCurrentIdentifier();
352cdf0e10cSrcweir mnCount++;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
release()355cdf0e10cSrcweir void SalYieldMutex::release()
356cdf0e10cSrcweir {
357cdf0e10cSrcweir if ( mnThreadId == vos::OThread::getCurrentIdentifier() )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir if ( mnCount == 1 )
360cdf0e10cSrcweir mnThreadId = 0;
361cdf0e10cSrcweir mnCount--;
362cdf0e10cSrcweir }
363cdf0e10cSrcweir OMutex::release();
364cdf0e10cSrcweir }
365cdf0e10cSrcweir
tryToAcquire()366cdf0e10cSrcweir sal_Bool SalYieldMutex::tryToAcquire()
367cdf0e10cSrcweir {
368cdf0e10cSrcweir if ( OMutex::tryToAcquire() )
369cdf0e10cSrcweir {
370cdf0e10cSrcweir mnThreadId = vos::OThread::getCurrentIdentifier();
371cdf0e10cSrcweir mnCount++;
372cdf0e10cSrcweir return sal_True;
373cdf0e10cSrcweir }
374cdf0e10cSrcweir else
375cdf0e10cSrcweir return sal_False;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir
378cdf0e10cSrcweir // -----------------------------------------------------------------------
379cdf0e10cSrcweir
380cdf0e10cSrcweir // some convenience functions regarding the yield mutex, aka solar mutex
381cdf0e10cSrcweir
ImplSalYieldMutexTryToAcquire()382cdf0e10cSrcweir sal_Bool ImplSalYieldMutexTryToAcquire()
383cdf0e10cSrcweir {
384cdf0e10cSrcweir AquaSalInstance* pInst = (AquaSalInstance*) GetSalData()->mpFirstInstance;
385cdf0e10cSrcweir if ( pInst )
386cdf0e10cSrcweir return pInst->mpSalYieldMutex->tryToAcquire();
387cdf0e10cSrcweir else
388cdf0e10cSrcweir return FALSE;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir
ImplSalYieldMutexAcquire()391cdf0e10cSrcweir void ImplSalYieldMutexAcquire()
392cdf0e10cSrcweir {
393cdf0e10cSrcweir AquaSalInstance* pInst = (AquaSalInstance*) GetSalData()->mpFirstInstance;
394cdf0e10cSrcweir if ( pInst )
395cdf0e10cSrcweir pInst->mpSalYieldMutex->acquire();
396cdf0e10cSrcweir }
397cdf0e10cSrcweir
ImplSalYieldMutexRelease()398cdf0e10cSrcweir void ImplSalYieldMutexRelease()
399cdf0e10cSrcweir {
400cdf0e10cSrcweir AquaSalInstance* pInst = (AquaSalInstance*) GetSalData()->mpFirstInstance;
401cdf0e10cSrcweir if ( pInst )
402cdf0e10cSrcweir pInst->mpSalYieldMutex->release();
403cdf0e10cSrcweir }
404cdf0e10cSrcweir
405cdf0e10cSrcweir // =======================================================================
406cdf0e10cSrcweir
CreateSalInstance()407cdf0e10cSrcweir SalInstance* CreateSalInstance()
408cdf0e10cSrcweir {
409cdf0e10cSrcweir // this is the case for not using SVMain
410cdf0e10cSrcweir // not so good
411cdf0e10cSrcweir if( bNoSVMain )
412cdf0e10cSrcweir initNSApp();
413cdf0e10cSrcweir
414cdf0e10cSrcweir SalData* pSalData = GetSalData();
415cdf0e10cSrcweir DBG_ASSERT( pSalData->mpFirstInstance == NULL, "more than one instance created" );
416cdf0e10cSrcweir AquaSalInstance* pInst = new AquaSalInstance;
417cdf0e10cSrcweir
418cdf0e10cSrcweir // init instance (only one instance in this version !!!)
419cdf0e10cSrcweir pSalData->mpFirstInstance = pInst;
420cdf0e10cSrcweir // this one is for outside AquaSalInstance::Yield
421cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
422cdf0e10cSrcweir // no focus rects on NWF aqua
423cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbNoFocusRects = true;
424cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbNoBoldTabFocus = true;
425cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbNoActiveTabTextRaise = true;
426cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbCenteredTabs = true;
427cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbProgressNeedsErase = true;
428cdf0e10cSrcweir ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase = true;
429cdf0e10cSrcweir ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset = 10;
430cdf0e10cSrcweir ImplGetSVData()->maGDIData.mbNoXORClipping = true;
431cdf0e10cSrcweir ImplGetSVData()->maWinData.mbNoSaveBackground = true;
432cdf0e10cSrcweir
433cdf0e10cSrcweir return pInst;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir
436cdf0e10cSrcweir // -----------------------------------------------------------------------
437cdf0e10cSrcweir
DestroySalInstance(SalInstance * pInst)438cdf0e10cSrcweir void DestroySalInstance( SalInstance* pInst )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir delete pInst;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir
443cdf0e10cSrcweir // -----------------------------------------------------------------------
444cdf0e10cSrcweir
AquaSalInstance()445cdf0e10cSrcweir AquaSalInstance::AquaSalInstance()
446cdf0e10cSrcweir {
447cdf0e10cSrcweir mpSalYieldMutex = new SalYieldMutex;
448cdf0e10cSrcweir mpSalYieldMutex->acquire();
449cdf0e10cSrcweir ::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex );
450cdf0e10cSrcweir maMainThread = vos::OThread::getCurrentIdentifier();
451cdf0e10cSrcweir mbWaitingYield = false;
452cdf0e10cSrcweir maUserEventListMutex = osl_createMutex();
453cdf0e10cSrcweir mnActivePrintJobs = 0;
454cdf0e10cSrcweir maWaitingYieldCond = osl_createCondition();
455cdf0e10cSrcweir }
456cdf0e10cSrcweir
457cdf0e10cSrcweir // -----------------------------------------------------------------------
458cdf0e10cSrcweir
~AquaSalInstance()459cdf0e10cSrcweir AquaSalInstance::~AquaSalInstance()
460cdf0e10cSrcweir {
461cdf0e10cSrcweir ::tools::SolarMutex::SetSolarMutex( 0 );
462cdf0e10cSrcweir mpSalYieldMutex->release();
463cdf0e10cSrcweir delete mpSalYieldMutex;
464cdf0e10cSrcweir osl_destroyMutex( maUserEventListMutex );
465cdf0e10cSrcweir osl_destroyCondition( maWaitingYieldCond );
466cdf0e10cSrcweir }
467cdf0e10cSrcweir
468cdf0e10cSrcweir // -----------------------------------------------------------------------
469cdf0e10cSrcweir
wakeupYield()470cdf0e10cSrcweir void AquaSalInstance::wakeupYield()
471cdf0e10cSrcweir {
472cdf0e10cSrcweir // wakeup :Yield
473cdf0e10cSrcweir if( mbWaitingYield )
474cdf0e10cSrcweir {
475cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
476cdf0e10cSrcweir NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
47701367266SHerbert Dürr location: NSZeroPoint
478cdf0e10cSrcweir modifierFlags: 0
479cdf0e10cSrcweir timestamp: 0
480cdf0e10cSrcweir windowNumber: 0
481cdf0e10cSrcweir context: nil
482cdf0e10cSrcweir subtype: AquaSalInstance::YieldWakeupEvent
483cdf0e10cSrcweir data1: 0
484cdf0e10cSrcweir data2: 0 ];
485cdf0e10cSrcweir if( pEvent )
486cdf0e10cSrcweir [NSApp postEvent: pEvent atStart: NO];
487cdf0e10cSrcweir }
488cdf0e10cSrcweir }
489cdf0e10cSrcweir
490cdf0e10cSrcweir // -----------------------------------------------------------------------
491cdf0e10cSrcweir
PostUserEvent(AquaSalFrame * pFrame,sal_uInt16 nType,void * pData)492cdf0e10cSrcweir void AquaSalInstance::PostUserEvent( AquaSalFrame* pFrame, sal_uInt16 nType, void* pData )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir osl_acquireMutex( maUserEventListMutex );
495cdf0e10cSrcweir maUserEvents.push_back( SalUserEvent( pFrame, pData, nType ) );
496cdf0e10cSrcweir osl_releaseMutex( maUserEventListMutex );
497cdf0e10cSrcweir
498cdf0e10cSrcweir // notify main loop that an event has arrived
499cdf0e10cSrcweir wakeupYield();
500cdf0e10cSrcweir }
501cdf0e10cSrcweir
502cdf0e10cSrcweir // -----------------------------------------------------------------------
503cdf0e10cSrcweir
GetYieldMutex()504cdf0e10cSrcweir vos::IMutex* AquaSalInstance::GetYieldMutex()
505cdf0e10cSrcweir {
506cdf0e10cSrcweir return mpSalYieldMutex;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir
509cdf0e10cSrcweir // -----------------------------------------------------------------------
510cdf0e10cSrcweir
ReleaseYieldMutex()511cdf0e10cSrcweir sal_uLong AquaSalInstance::ReleaseYieldMutex()
512cdf0e10cSrcweir {
513cdf0e10cSrcweir SalYieldMutex* pYieldMutex = mpSalYieldMutex;
514cdf0e10cSrcweir if ( pYieldMutex->GetThreadId() ==
515cdf0e10cSrcweir vos::OThread::getCurrentIdentifier() )
516cdf0e10cSrcweir {
517cdf0e10cSrcweir sal_uLong nCount = pYieldMutex->GetAcquireCount();
518cdf0e10cSrcweir sal_uLong n = nCount;
519cdf0e10cSrcweir while ( n )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir pYieldMutex->release();
522cdf0e10cSrcweir n--;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir
525cdf0e10cSrcweir return nCount;
526cdf0e10cSrcweir }
527cdf0e10cSrcweir else
528cdf0e10cSrcweir return 0;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
531cdf0e10cSrcweir // -----------------------------------------------------------------------
532cdf0e10cSrcweir
AcquireYieldMutex(sal_uLong nCount)533cdf0e10cSrcweir void AquaSalInstance::AcquireYieldMutex( sal_uLong nCount )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir SalYieldMutex* pYieldMutex = mpSalYieldMutex;
536cdf0e10cSrcweir while ( nCount )
537cdf0e10cSrcweir {
538cdf0e10cSrcweir pYieldMutex->acquire();
539cdf0e10cSrcweir nCount--;
540cdf0e10cSrcweir }
541cdf0e10cSrcweir }
542cdf0e10cSrcweir
543cdf0e10cSrcweir // -----------------------------------------------------------------------
544cdf0e10cSrcweir
CheckYieldMutex()545cdf0e10cSrcweir bool AquaSalInstance::CheckYieldMutex()
546cdf0e10cSrcweir {
547cdf0e10cSrcweir bool bRet = true;
548cdf0e10cSrcweir
549cdf0e10cSrcweir SalYieldMutex* pYieldMutex = mpSalYieldMutex;
550cdf0e10cSrcweir if ( pYieldMutex->GetThreadId() !=
551cdf0e10cSrcweir vos::OThread::getCurrentIdentifier() )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir bRet = false;
554cdf0e10cSrcweir }
555cdf0e10cSrcweir
556cdf0e10cSrcweir return bRet;
557cdf0e10cSrcweir }
558cdf0e10cSrcweir
559cdf0e10cSrcweir // -----------------------------------------------------------------------
560cdf0e10cSrcweir
isNSAppThread() const561cdf0e10cSrcweir bool AquaSalInstance::isNSAppThread() const
562cdf0e10cSrcweir {
563cdf0e10cSrcweir return vos::OThread::getCurrentIdentifier() == maMainThread;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir
566cdf0e10cSrcweir // -----------------------------------------------------------------------
567cdf0e10cSrcweir
handleAppDefinedEvent(NSEvent * pEvent)568cdf0e10cSrcweir void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir switch( [pEvent subtype] )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir case AppStartTimerEvent:
573cdf0e10cSrcweir AquaSalTimer::handleStartTimerEvent( pEvent );
574cdf0e10cSrcweir break;
575cdf0e10cSrcweir case AppEndLoopEvent:
576cdf0e10cSrcweir [NSApp stop: NSApp];
577cdf0e10cSrcweir break;
578cdf0e10cSrcweir case AppExecuteSVMain:
579cdf0e10cSrcweir {
580cdf0e10cSrcweir sal_Bool bResult = ImplSVMain();
581cdf0e10cSrcweir if( gpbInit )
582cdf0e10cSrcweir *gpbInit = bResult;
583cdf0e10cSrcweir [NSApp stop: NSApp];
584cdf0e10cSrcweir bLeftMain = true;
585cdf0e10cSrcweir if( pDockMenu )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir [pDockMenu release];
588cdf0e10cSrcweir pDockMenu = nil;
589cdf0e10cSrcweir }
590cdf0e10cSrcweir }
591cdf0e10cSrcweir break;
592cdf0e10cSrcweir case AppleRemoteEvent:
593cdf0e10cSrcweir {
594cdf0e10cSrcweir sal_Int16 nCommand = 0;
595cdf0e10cSrcweir SalData* pSalData = GetSalData();
596cdf0e10cSrcweir bool bIsFullScreenMode = false;
597cdf0e10cSrcweir
598cdf0e10cSrcweir std::list<AquaSalFrame*>::iterator it = pSalData->maFrames.begin();
5995e27b86bSHerbert Dürr for(; it != pSalData->maFrames.end(); ++it )
600cdf0e10cSrcweir {
601a9ab3c7bSHerbert Dürr if( (*it)->mbFullScreen )
602cdf0e10cSrcweir bIsFullScreenMode = true;
603cdf0e10cSrcweir }
604cdf0e10cSrcweir
605cdf0e10cSrcweir switch ([pEvent data1])
606cdf0e10cSrcweir {
607cdf0e10cSrcweir case kRemoteButtonPlay:
608cdf0e10cSrcweir nCommand = ( bIsFullScreenMode == true ) ? MEDIA_COMMAND_PLAY_PAUSE : MEDIA_COMMAND_PLAY;
609cdf0e10cSrcweir break;
610cdf0e10cSrcweir
611cdf0e10cSrcweir // kept for experimentation purpose (scheduled for future implementation)
612cdf0e10cSrcweir // case kRemoteButtonMenu: nCommand = MEDIA_COMMAND_MENU; break;
613cdf0e10cSrcweir
614cdf0e10cSrcweir case kRemoteButtonPlus: nCommand = MEDIA_COMMAND_VOLUME_UP; break;
615cdf0e10cSrcweir
616cdf0e10cSrcweir case kRemoteButtonMinus: nCommand = MEDIA_COMMAND_VOLUME_DOWN; break;
617cdf0e10cSrcweir
618cdf0e10cSrcweir case kRemoteButtonRight: nCommand = MEDIA_COMMAND_NEXTTRACK; break;
619cdf0e10cSrcweir
620cdf0e10cSrcweir case kRemoteButtonRight_Hold: nCommand = MEDIA_COMMAND_NEXTTRACK_HOLD; break;
621cdf0e10cSrcweir
622cdf0e10cSrcweir case kRemoteButtonLeft: nCommand = MEDIA_COMMAND_PREVIOUSTRACK; break;
623cdf0e10cSrcweir
624cdf0e10cSrcweir case kRemoteButtonLeft_Hold: nCommand = MEDIA_COMMAND_REWIND; break;
625cdf0e10cSrcweir
626cdf0e10cSrcweir case kRemoteButtonPlay_Hold: nCommand = MEDIA_COMMAND_PLAY_HOLD; break;
627cdf0e10cSrcweir
628cdf0e10cSrcweir case kRemoteButtonMenu_Hold: nCommand = MEDIA_COMMAND_STOP; break;
629cdf0e10cSrcweir
630cdf0e10cSrcweir // FIXME : not detected
631cdf0e10cSrcweir case kRemoteButtonPlus_Hold:
632cdf0e10cSrcweir case kRemoteButtonMinus_Hold:
633cdf0e10cSrcweir break;
634cdf0e10cSrcweir
635cdf0e10cSrcweir default:
636cdf0e10cSrcweir break;
637cdf0e10cSrcweir }
638cdf0e10cSrcweir AquaSalFrame* pFrame = pSalData->maFrames.front();
6395e27b86bSHerbert Dürr Window* pWindow = pFrame ? pFrame->GetWindow() : NULL;
640cdf0e10cSrcweir
641cdf0e10cSrcweir if( pWindow )
642cdf0e10cSrcweir {
643cdf0e10cSrcweir const Point aPoint;
644cdf0e10cSrcweir CommandEvent aCEvt( aPoint, COMMAND_MEDIA, FALSE, &nCommand );
645cdf0e10cSrcweir NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
646cdf0e10cSrcweir
647cdf0e10cSrcweir if ( !ImplCallPreNotify( aNCmdEvt ) )
648cdf0e10cSrcweir pWindow->Command( aCEvt );
649cdf0e10cSrcweir }
650cdf0e10cSrcweir
651cdf0e10cSrcweir }
652cdf0e10cSrcweir break;
653cdf0e10cSrcweir
654cdf0e10cSrcweir case YieldWakeupEvent:
655cdf0e10cSrcweir // do nothing, fall out of Yield
656cdf0e10cSrcweir break;
657cdf0e10cSrcweir
658cdf0e10cSrcweir default:
659cdf0e10cSrcweir DBG_ERROR( "unhandled NSApplicationDefined event" );
660cdf0e10cSrcweir break;
661cdf0e10cSrcweir };
662cdf0e10cSrcweir }
663cdf0e10cSrcweir
664cdf0e10cSrcweir // -----------------------------------------------------------------------
665cdf0e10cSrcweir
666cdf0e10cSrcweir class ReleasePoolHolder
667cdf0e10cSrcweir {
668cdf0e10cSrcweir NSAutoreleasePool* mpPool;
669cdf0e10cSrcweir public:
ReleasePoolHolder()670cdf0e10cSrcweir ReleasePoolHolder() : mpPool( [[NSAutoreleasePool alloc] init] ) {}
~ReleasePoolHolder()671cdf0e10cSrcweir ~ReleasePoolHolder() { [mpPool release]; }
672cdf0e10cSrcweir };
673cdf0e10cSrcweir
Yield(bool bWait,bool bHandleAllCurrentEvents)674cdf0e10cSrcweir void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
675cdf0e10cSrcweir {
676cdf0e10cSrcweir // ensure that the per thread autorelease pool is top level and
677cdf0e10cSrcweir // will therefore not be destroyed by cocoa implicitly
678cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
679cdf0e10cSrcweir
680cdf0e10cSrcweir // NSAutoreleasePool documentation suggests we should have
681cdf0e10cSrcweir // an own pool for each yield level
682cdf0e10cSrcweir ReleasePoolHolder aReleasePool;
683cdf0e10cSrcweir
684cdf0e10cSrcweir // Release all locks so that we don't deadlock when we pull pending
685cdf0e10cSrcweir // events from the event queue
686cdf0e10cSrcweir bool bDispatchUser = true;
687cdf0e10cSrcweir while( bDispatchUser )
688cdf0e10cSrcweir {
689cdf0e10cSrcweir sal_uLong nCount = ReleaseYieldMutex();
690cdf0e10cSrcweir
691cdf0e10cSrcweir // get one user event
692cdf0e10cSrcweir osl_acquireMutex( maUserEventListMutex );
693cdf0e10cSrcweir SalUserEvent aEvent( NULL, NULL, 0 );
694cdf0e10cSrcweir if( ! maUserEvents.empty() )
695cdf0e10cSrcweir {
696cdf0e10cSrcweir aEvent = maUserEvents.front();
697cdf0e10cSrcweir maUserEvents.pop_front();
698cdf0e10cSrcweir }
699cdf0e10cSrcweir else
700cdf0e10cSrcweir bDispatchUser = false;
701cdf0e10cSrcweir osl_releaseMutex( maUserEventListMutex );
702cdf0e10cSrcweir
703cdf0e10cSrcweir AcquireYieldMutex( nCount );
704cdf0e10cSrcweir
705cdf0e10cSrcweir // dispatch it
706cdf0e10cSrcweir if( aEvent.mpFrame && AquaSalFrame::isAlive( aEvent.mpFrame ) )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData );
709cdf0e10cSrcweir osl_setCondition( maWaitingYieldCond );
710cdf0e10cSrcweir // return if only one event is asked for
711cdf0e10cSrcweir if( ! bHandleAllCurrentEvents )
712cdf0e10cSrcweir return;
713cdf0e10cSrcweir }
714cdf0e10cSrcweir }
715cdf0e10cSrcweir
716cdf0e10cSrcweir // handle cocoa event queue
717cdf0e10cSrcweir // cocoa events mye be only handled in the thread the NSApp was created
718cdf0e10cSrcweir if( isNSAppThread() && mnActivePrintJobs == 0 )
719cdf0e10cSrcweir {
720cdf0e10cSrcweir // we need to be woken up by a cocoa-event
721cdf0e10cSrcweir // if a user event should be posted by the event handling below
722cdf0e10cSrcweir bool bOldWaitingYield = mbWaitingYield;
723cdf0e10cSrcweir mbWaitingYield = bWait;
724cdf0e10cSrcweir
725cdf0e10cSrcweir // handle available events
726cdf0e10cSrcweir NSEvent* pEvent = nil;
727cdf0e10cSrcweir bool bHadEvent = false;
728cdf0e10cSrcweir do
729cdf0e10cSrcweir {
730cdf0e10cSrcweir sal_uLong nCount = ReleaseYieldMutex();
731cdf0e10cSrcweir
732cdf0e10cSrcweir pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: nil
733cdf0e10cSrcweir inMode: NSDefaultRunLoopMode dequeue: YES];
734cdf0e10cSrcweir if( pEvent )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir [NSApp sendEvent: pEvent];
737cdf0e10cSrcweir bHadEvent = true;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir [NSApp updateWindows];
740cdf0e10cSrcweir
741cdf0e10cSrcweir AcquireYieldMutex( nCount );
742cdf0e10cSrcweir } while( bHandleAllCurrentEvents && pEvent );
743cdf0e10cSrcweir
744cdf0e10cSrcweir // if we had no event yet, wait for one if requested
745cdf0e10cSrcweir if( bWait && ! bHadEvent )
746cdf0e10cSrcweir {
747cdf0e10cSrcweir sal_uLong nCount = ReleaseYieldMutex();
748cdf0e10cSrcweir
749cdf0e10cSrcweir NSDate* pDt = AquaSalTimer::pRunningTimer ? [AquaSalTimer::pRunningTimer fireDate] : [NSDate distantFuture];
750cdf0e10cSrcweir pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: pDt
751cdf0e10cSrcweir inMode: NSDefaultRunLoopMode dequeue: YES];
752cdf0e10cSrcweir if( pEvent )
753cdf0e10cSrcweir [NSApp sendEvent: pEvent];
754cdf0e10cSrcweir [NSApp updateWindows];
755cdf0e10cSrcweir
756cdf0e10cSrcweir AcquireYieldMutex( nCount );
757cdf0e10cSrcweir
758cdf0e10cSrcweir // #i86581#
759cdf0e10cSrcweir // FIXME: sometimes the NSTimer will never fire. Firing it by hand then
760cdf0e10cSrcweir // fixes the problem even seems to set the correct next firing date
761cdf0e10cSrcweir // Why oh why ?
762cdf0e10cSrcweir if( ! pEvent && AquaSalTimer::pRunningTimer )
763cdf0e10cSrcweir {
764cdf0e10cSrcweir // this cause crashes on MacOSX 10.4
765cdf0e10cSrcweir // [AquaSalTimer::pRunningTimer fire];
766cdf0e10cSrcweir ImplGetSVData()->mpSalTimer->CallCallback();
767cdf0e10cSrcweir }
768cdf0e10cSrcweir }
769cdf0e10cSrcweir
770cdf0e10cSrcweir mbWaitingYield = bOldWaitingYield;
771cdf0e10cSrcweir
772cdf0e10cSrcweir // collect update rectangles
773cdf0e10cSrcweir const std::list< AquaSalFrame* > rFrames( GetSalData()->maFrames );
774cdf0e10cSrcweir for( std::list< AquaSalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir if( (*it)->mbShown && ! (*it)->maInvalidRect.IsEmpty() )
777cdf0e10cSrcweir {
778cdf0e10cSrcweir (*it)->Flush( (*it)->maInvalidRect );
779cdf0e10cSrcweir (*it)->maInvalidRect.SetEmpty();
780cdf0e10cSrcweir }
781cdf0e10cSrcweir }
782cdf0e10cSrcweir osl_setCondition( maWaitingYieldCond );
783cdf0e10cSrcweir }
784946b634eSJim Jagielski else if( bWait )
785cdf0e10cSrcweir {
786cdf0e10cSrcweir // #i103162#
787cdf0e10cSrcweir // wait until any thread (most likely the main thread)
788*92af7284SJim Jagielski // has dispatched an event, cop out at 250 ms
789*92af7284SJim Jagielski TimeValue aVal = { 0, 250000000 };
790cdf0e10cSrcweir osl_resetCondition( maWaitingYieldCond );
791*92af7284SJim Jagielski sal_uLong nCount = ReleaseYieldMutex();
792cdf0e10cSrcweir osl_waitCondition( maWaitingYieldCond, &aVal );
793cdf0e10cSrcweir AcquireYieldMutex( nCount );
794cdf0e10cSrcweir }
795cdf0e10cSrcweir // we get some apple events way too early
796cdf0e10cSrcweir // before the application is ready to handle them,
797cdf0e10cSrcweir // so their corresponding application events need to be delayed
798cdf0e10cSrcweir // now is a good time to handle at least one of them
799cdf0e10cSrcweir if( bWait && !aAppEventList.empty() && ImplGetSVData()->maAppData.mbInAppExecute )
800cdf0e10cSrcweir {
801cdf0e10cSrcweir // make sure that only one application event is active at a time
802cdf0e10cSrcweir static bool bInAppEvent = false;
803cdf0e10cSrcweir if( !bInAppEvent )
804cdf0e10cSrcweir {
805cdf0e10cSrcweir bInAppEvent = true;
806cdf0e10cSrcweir // get the next delayed application event
807cdf0e10cSrcweir const ApplicationEvent* pAppEvent = aAppEventList.front();
808cdf0e10cSrcweir aAppEventList.pop_front();
809cdf0e10cSrcweir // handle one application event (no recursion)
810cdf0e10cSrcweir const ImplSVData* pSVData = ImplGetSVData();
811cdf0e10cSrcweir pSVData->mpApp->AppEvent( *pAppEvent );
812cdf0e10cSrcweir delete pAppEvent;
813cdf0e10cSrcweir // allow the next delayed application event
814cdf0e10cSrcweir bInAppEvent = false;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir }
817cdf0e10cSrcweir }
818cdf0e10cSrcweir
819cdf0e10cSrcweir // -----------------------------------------------------------------------
820cdf0e10cSrcweir
AnyInput(sal_uInt16 nType)821cdf0e10cSrcweir bool AquaSalInstance::AnyInput( sal_uInt16 nType )
822cdf0e10cSrcweir {
823cdf0e10cSrcweir if( nType & INPUT_APPEVENT )
824cdf0e10cSrcweir {
825cdf0e10cSrcweir if( ! aAppEventList.empty() )
826cdf0e10cSrcweir return true;
827cdf0e10cSrcweir if( nType == INPUT_APPEVENT )
828cdf0e10cSrcweir return false;
829cdf0e10cSrcweir }
830cdf0e10cSrcweir
831cdf0e10cSrcweir if( nType & INPUT_TIMER )
832cdf0e10cSrcweir {
833cdf0e10cSrcweir if( AquaSalTimer::pRunningTimer )
834cdf0e10cSrcweir {
835cdf0e10cSrcweir NSDate* pDt = [AquaSalTimer::pRunningTimer fireDate];
836cdf0e10cSrcweir if( pDt && [pDt timeIntervalSinceNow] < 0 )
837cdf0e10cSrcweir {
838cdf0e10cSrcweir return true;
839cdf0e10cSrcweir }
840cdf0e10cSrcweir }
841cdf0e10cSrcweir }
842cdf0e10cSrcweir
843cdf0e10cSrcweir unsigned/*NSUInteger*/ nEventMask = 0;
844cdf0e10cSrcweir if( nType & INPUT_MOUSE)
845cdf0e10cSrcweir nEventMask |=
846cdf0e10cSrcweir NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask |
847cdf0e10cSrcweir NSLeftMouseUpMask | NSRightMouseUpMask | NSOtherMouseUpMask |
848cdf0e10cSrcweir NSLeftMouseDraggedMask | NSRightMouseDraggedMask | NSOtherMouseDraggedMask |
849cdf0e10cSrcweir NSScrollWheelMask |
850cdf0e10cSrcweir // NSMouseMovedMask |
851cdf0e10cSrcweir NSMouseEnteredMask | NSMouseExitedMask;
852cdf0e10cSrcweir if( nType & INPUT_KEYBOARD)
853cdf0e10cSrcweir nEventMask |= NSKeyDownMask | NSKeyUpMask | NSFlagsChangedMask;
854cdf0e10cSrcweir if( nType & INPUT_OTHER)
855cdf0e10cSrcweir nEventMask |= NSTabletPoint;
856cdf0e10cSrcweir // TODO: INPUT_PAINT / more INPUT_OTHER
857cdf0e10cSrcweir if( !nType)
858cdf0e10cSrcweir return false;
859cdf0e10cSrcweir
860cdf0e10cSrcweir NSEvent* pEvent = [NSApp nextEventMatchingMask: nEventMask untilDate: nil
861cdf0e10cSrcweir inMode: NSDefaultRunLoopMode dequeue: NO];
862cdf0e10cSrcweir return (pEvent != NULL);
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
865cdf0e10cSrcweir // -----------------------------------------------------------------------
866cdf0e10cSrcweir
CreateChildFrame(SystemParentData *,sal_uLong)867cdf0e10cSrcweir SalFrame* AquaSalInstance::CreateChildFrame( SystemParentData*, sal_uLong /*nSalFrameStyle*/ )
868cdf0e10cSrcweir {
869cdf0e10cSrcweir return NULL;
870cdf0e10cSrcweir }
871cdf0e10cSrcweir
872cdf0e10cSrcweir // -----------------------------------------------------------------------
873cdf0e10cSrcweir
CreateFrame(SalFrame * pParent,sal_uLong nSalFrameStyle)874cdf0e10cSrcweir SalFrame* AquaSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nSalFrameStyle )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
877cdf0e10cSrcweir
878cdf0e10cSrcweir SalFrame* pFrame = new AquaSalFrame( pParent, nSalFrameStyle );
879cdf0e10cSrcweir return pFrame;
880cdf0e10cSrcweir }
881cdf0e10cSrcweir
882cdf0e10cSrcweir // -----------------------------------------------------------------------
883cdf0e10cSrcweir
DestroyFrame(SalFrame * pFrame)884cdf0e10cSrcweir void AquaSalInstance::DestroyFrame( SalFrame* pFrame )
885cdf0e10cSrcweir {
886cdf0e10cSrcweir delete pFrame;
887cdf0e10cSrcweir }
888cdf0e10cSrcweir
889cdf0e10cSrcweir // -----------------------------------------------------------------------
890cdf0e10cSrcweir
CreateObject(SalFrame * pParent,SystemWindowData *,sal_Bool)891cdf0e10cSrcweir SalObject* AquaSalInstance::CreateObject( SalFrame* pParent, SystemWindowData* /* pWindowData */, sal_Bool /* bShow */ )
892cdf0e10cSrcweir {
893cdf0e10cSrcweir // SystemWindowData is meaningless on Mac OS X
894cdf0e10cSrcweir AquaSalObject *pObject = NULL;
895cdf0e10cSrcweir
896cdf0e10cSrcweir if ( pParent )
897cdf0e10cSrcweir pObject = new AquaSalObject( static_cast<AquaSalFrame*>(pParent) );
898cdf0e10cSrcweir
899cdf0e10cSrcweir return pObject;
900cdf0e10cSrcweir }
901cdf0e10cSrcweir
902cdf0e10cSrcweir // -----------------------------------------------------------------------
903cdf0e10cSrcweir
DestroyObject(SalObject * pObject)904cdf0e10cSrcweir void AquaSalInstance::DestroyObject( SalObject* pObject )
905cdf0e10cSrcweir {
906cdf0e10cSrcweir delete ( pObject );
907cdf0e10cSrcweir }
908cdf0e10cSrcweir
909cdf0e10cSrcweir // -----------------------------------------------------------------------
910cdf0e10cSrcweir
CreatePrinter(SalInfoPrinter * pInfoPrinter)911cdf0e10cSrcweir SalPrinter* AquaSalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
912cdf0e10cSrcweir {
913cdf0e10cSrcweir return new AquaSalPrinter( dynamic_cast<AquaSalInfoPrinter*>(pInfoPrinter) );
914cdf0e10cSrcweir }
915cdf0e10cSrcweir
916cdf0e10cSrcweir // -----------------------------------------------------------------------
917cdf0e10cSrcweir
DestroyPrinter(SalPrinter * pPrinter)918cdf0e10cSrcweir void AquaSalInstance::DestroyPrinter( SalPrinter* pPrinter )
919cdf0e10cSrcweir {
920cdf0e10cSrcweir delete pPrinter;
921cdf0e10cSrcweir }
922cdf0e10cSrcweir
923cdf0e10cSrcweir // -----------------------------------------------------------------------
924cdf0e10cSrcweir
GetPrinterQueueInfo(ImplPrnQueueList * pList)925cdf0e10cSrcweir void AquaSalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
926cdf0e10cSrcweir {
927cdf0e10cSrcweir NSArray* pNames = [NSPrinter printerNames];
928cdf0e10cSrcweir NSArray* pTypes = [NSPrinter printerTypes];
929cdf0e10cSrcweir unsigned int nNameCount = pNames ? [pNames count] : 0;
930cdf0e10cSrcweir unsigned int nTypeCount = pTypes ? [pTypes count] : 0;
931cdf0e10cSrcweir DBG_ASSERT( nTypeCount == nNameCount, "type count not equal to printer count" );
932cdf0e10cSrcweir for( unsigned int i = 0; i < nNameCount; i++ )
933cdf0e10cSrcweir {
934cdf0e10cSrcweir NSString* pName = [pNames objectAtIndex: i];
935cdf0e10cSrcweir NSString* pType = i < nTypeCount ? [pTypes objectAtIndex: i] : nil;
936cdf0e10cSrcweir if( pName )
937cdf0e10cSrcweir {
938cdf0e10cSrcweir SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
939cdf0e10cSrcweir pInfo->maPrinterName = GetOUString( pName );
940cdf0e10cSrcweir if( pType )
941cdf0e10cSrcweir pInfo->maDriver = GetOUString( pType );
942cdf0e10cSrcweir pInfo->mnStatus = 0;
943cdf0e10cSrcweir pInfo->mnJobs = 0;
944cdf0e10cSrcweir pInfo->mpSysData = NULL;
945cdf0e10cSrcweir
946cdf0e10cSrcweir pList->Add( pInfo );
947cdf0e10cSrcweir }
948cdf0e10cSrcweir }
949cdf0e10cSrcweir }
950cdf0e10cSrcweir
951cdf0e10cSrcweir // -----------------------------------------------------------------------
952cdf0e10cSrcweir
GetPrinterQueueState(SalPrinterQueueInfo *)953cdf0e10cSrcweir void AquaSalInstance::GetPrinterQueueState( SalPrinterQueueInfo* )
954cdf0e10cSrcweir {
955cdf0e10cSrcweir }
956cdf0e10cSrcweir
957cdf0e10cSrcweir // -----------------------------------------------------------------------
958cdf0e10cSrcweir
DeletePrinterQueueInfo(SalPrinterQueueInfo * pInfo)959cdf0e10cSrcweir void AquaSalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
960cdf0e10cSrcweir {
961cdf0e10cSrcweir delete pInfo;
962cdf0e10cSrcweir }
963cdf0e10cSrcweir
964cdf0e10cSrcweir // -----------------------------------------------------------------------
965cdf0e10cSrcweir
GetDefaultPrinter()966cdf0e10cSrcweir XubString AquaSalInstance::GetDefaultPrinter()
967cdf0e10cSrcweir {
968cdf0e10cSrcweir // #i113170# may not be the main thread if called from UNO API
969cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
970cdf0e10cSrcweir
971cdf0e10cSrcweir if( ! maDefaultPrinter.getLength() )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir NSPrintInfo* pPI = [NSPrintInfo sharedPrintInfo];
974cdf0e10cSrcweir DBG_ASSERT( pPI, "no print info" );
975cdf0e10cSrcweir if( pPI )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir NSPrinter* pPr = [pPI printer];
978cdf0e10cSrcweir DBG_ASSERT( pPr, "no printer in default info" );
979cdf0e10cSrcweir if( pPr )
980cdf0e10cSrcweir {
981cdf0e10cSrcweir NSString* pDefName = [pPr name];
982cdf0e10cSrcweir DBG_ASSERT( pDefName, "printer has no name" );
983cdf0e10cSrcweir maDefaultPrinter = GetOUString( pDefName );
984cdf0e10cSrcweir }
985cdf0e10cSrcweir }
986cdf0e10cSrcweir }
987cdf0e10cSrcweir return maDefaultPrinter;
988cdf0e10cSrcweir }
989cdf0e10cSrcweir
990cdf0e10cSrcweir // -----------------------------------------------------------------------
991cdf0e10cSrcweir
CreateInfoPrinter(SalPrinterQueueInfo * pQueueInfo,ImplJobSetup * pSetupData)992cdf0e10cSrcweir SalInfoPrinter* AquaSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
993cdf0e10cSrcweir ImplJobSetup* pSetupData )
994cdf0e10cSrcweir {
995cdf0e10cSrcweir // #i113170# may not be the main thread if called from UNO API
996cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
997cdf0e10cSrcweir
998cdf0e10cSrcweir SalInfoPrinter* pNewInfoPrinter = NULL;
999cdf0e10cSrcweir if( pQueueInfo )
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir pNewInfoPrinter = new AquaSalInfoPrinter( *pQueueInfo );
1002cdf0e10cSrcweir if( pSetupData )
1003cdf0e10cSrcweir pNewInfoPrinter->SetPrinterData( pSetupData );
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir
1006cdf0e10cSrcweir return pNewInfoPrinter;
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir // -----------------------------------------------------------------------
1010cdf0e10cSrcweir
DestroyInfoPrinter(SalInfoPrinter * pPrinter)1011cdf0e10cSrcweir void AquaSalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir // #i113170# may not be the main thread if called from UNO API
1014cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir delete pPrinter;
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir // -----------------------------------------------------------------------
1020cdf0e10cSrcweir
CreateSystem()1021cdf0e10cSrcweir SalSystem* AquaSalInstance::CreateSystem()
1022cdf0e10cSrcweir {
1023cdf0e10cSrcweir return new AquaSalSystem();
1024cdf0e10cSrcweir }
1025cdf0e10cSrcweir
1026cdf0e10cSrcweir // -----------------------------------------------------------------------
1027cdf0e10cSrcweir
DestroySystem(SalSystem * pSystem)1028cdf0e10cSrcweir void AquaSalInstance::DestroySystem( SalSystem* pSystem )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir delete pSystem;
1031cdf0e10cSrcweir }
1032cdf0e10cSrcweir
1033cdf0e10cSrcweir // -----------------------------------------------------------------------
1034cdf0e10cSrcweir
SetEventCallback(void *,bool (*)(void *,void *,int))1035cdf0e10cSrcweir void AquaSalInstance::SetEventCallback( void*, bool(*)(void*,void*,int) )
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir }
1038cdf0e10cSrcweir
1039cdf0e10cSrcweir // -----------------------------------------------------------------------
1040cdf0e10cSrcweir
SetErrorEventCallback(void *,bool (*)(void *,void *,int))1041cdf0e10cSrcweir void AquaSalInstance::SetErrorEventCallback( void*, bool(*)(void*,void*,int) )
1042cdf0e10cSrcweir {
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir
1045cdf0e10cSrcweir // -----------------------------------------------------------------------
1046cdf0e10cSrcweir
GetConnectionIdentifier(ConnectionIdentifierType & rReturnedType,int & rReturnedBytes)1047cdf0e10cSrcweir void* AquaSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
1048cdf0e10cSrcweir {
1049cdf0e10cSrcweir rReturnedBytes = 1;
1050cdf0e10cSrcweir rReturnedType = AsciiCString;
1051cdf0e10cSrcweir return (void*)"";
1052cdf0e10cSrcweir }
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir // We need to re-encode file urls because osl_getFileURLFromSystemPath converts
1055cdf0e10cSrcweir // to UTF-8 before encoding non ascii characters, which is not what other apps expect.
translateToExternalUrl(const rtl::OUString & internalUrl)1056cdf0e10cSrcweir static rtl::OUString translateToExternalUrl(const rtl::OUString& internalUrl)
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir rtl::OUString extUrl;
1059cdf0e10cSrcweir
1060cdf0e10cSrcweir uno::Reference< lang::XMultiServiceFactory > sm = comphelper::getProcessServiceFactory();
1061cdf0e10cSrcweir if (sm.is())
1062cdf0e10cSrcweir {
1063cdf0e10cSrcweir uno::Reference< beans::XPropertySet > pset;
1064cdf0e10cSrcweir sm->queryInterface( getCppuType( &pset )) >>= pset;
1065cdf0e10cSrcweir if (pset.is())
1066cdf0e10cSrcweir {
1067cdf0e10cSrcweir uno::Reference< uno::XComponentContext > context;
1068cdf0e10cSrcweir static const rtl::OUString DEFAULT_CONTEXT( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) );
1069cdf0e10cSrcweir pset->getPropertyValue(DEFAULT_CONTEXT) >>= context;
1070cdf0e10cSrcweir if (context.is())
1071cdf0e10cSrcweir extUrl = uri::ExternalUriReferenceTranslator::create(context)->translateToExternal(internalUrl);
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir return extUrl;
1075cdf0e10cSrcweir }
1076cdf0e10cSrcweir
1077cdf0e10cSrcweir // #i104525# many versions of OSX have problems with some URLs:
1078cdf0e10cSrcweir // when an app requests OSX to add one of these URLs to the "Recent Items" list
1079cdf0e10cSrcweir // then this app gets killed (TextEdit, Preview, etc. and also OOo)
isDangerousUrl(const rtl::OUString & rUrl)1080cdf0e10cSrcweir static bool isDangerousUrl( const rtl::OUString& rUrl )
1081cdf0e10cSrcweir {
1082cdf0e10cSrcweir // use a heuristic that detects all known cases since there is no official comment
1083cdf0e10cSrcweir // on the exact impact and root cause of the OSX bug
1084cdf0e10cSrcweir const int nLen = rUrl.getLength();
1085cdf0e10cSrcweir const sal_Unicode* p = rUrl.getStr();
1086cdf0e10cSrcweir for( int i = 0; i < nLen-3; ++i, ++p ) {
1087cdf0e10cSrcweir if( p[0] != '%' )
1088cdf0e10cSrcweir continue;
1089cdf0e10cSrcweir // escaped percent?
1090cdf0e10cSrcweir if( (p[1] == '2') && (p[2] == '5') )
1091cdf0e10cSrcweir return true;
1092cdf0e10cSrcweir // escapes are considered to be UTF-8 encoded
1093cdf0e10cSrcweir // => check for invalid UTF-8 leading byte
1094cdf0e10cSrcweir if( (p[1] != 'f') && (p[1] != 'F') )
1095cdf0e10cSrcweir continue;
1096cdf0e10cSrcweir int cLowNibble = p[2];
1097cdf0e10cSrcweir if( (cLowNibble >= '0' ) && (cLowNibble <= '9'))
1098cdf0e10cSrcweir return false;
1099cdf0e10cSrcweir if( cLowNibble >= 'a' )
1100cdf0e10cSrcweir cLowNibble -= 'a' - 'A';
1101cdf0e10cSrcweir if( (cLowNibble < 'A') || (cLowNibble >= 'C'))
1102cdf0e10cSrcweir return true;
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir return false;
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir
AddToRecentDocumentList(const rtl::OUString & rFileUrl,const rtl::OUString &)1108cdf0e10cSrcweir void AquaSalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& /*rMimeType*/)
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir // Convert file URL for external use (see above)
1111cdf0e10cSrcweir rtl::OUString externalUrl = translateToExternalUrl(rFileUrl);
1112cdf0e10cSrcweir if( 0 == externalUrl.getLength() )
1113cdf0e10cSrcweir externalUrl = rFileUrl;
1114cdf0e10cSrcweir
1115cdf0e10cSrcweir if( externalUrl.getLength() && !isDangerousUrl( externalUrl ) )
1116cdf0e10cSrcweir {
1117cdf0e10cSrcweir NSString* pString = CreateNSString( externalUrl );
1118cdf0e10cSrcweir NSURL* pURL = [NSURL URLWithString: pString];
1119cdf0e10cSrcweir
1120cdf0e10cSrcweir if( pURL )
1121cdf0e10cSrcweir {
1122cdf0e10cSrcweir NSDocumentController* pCtrl = [NSDocumentController sharedDocumentController];
1123cdf0e10cSrcweir [pCtrl noteNewRecentDocumentURL: pURL];
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir if( pString )
1126cdf0e10cSrcweir [pString release];
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir }
1129cdf0e10cSrcweir
1130cdf0e10cSrcweir
1131cdf0e10cSrcweir // -----------------------------------------------------------------------
1132cdf0e10cSrcweir
CreateSalTimer()1133cdf0e10cSrcweir SalTimer* AquaSalInstance::CreateSalTimer()
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir return new AquaSalTimer();
1136cdf0e10cSrcweir }
1137cdf0e10cSrcweir
1138cdf0e10cSrcweir // -----------------------------------------------------------------------
1139cdf0e10cSrcweir
CreateSalSystem()1140cdf0e10cSrcweir SalSystem* AquaSalInstance::CreateSalSystem()
1141cdf0e10cSrcweir {
1142cdf0e10cSrcweir return new AquaSalSystem();
1143cdf0e10cSrcweir }
1144cdf0e10cSrcweir
1145cdf0e10cSrcweir // -----------------------------------------------------------------------
1146cdf0e10cSrcweir
CreateSalBitmap()1147cdf0e10cSrcweir SalBitmap* AquaSalInstance::CreateSalBitmap()
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir return new AquaSalBitmap();
1150cdf0e10cSrcweir }
1151cdf0e10cSrcweir
1152cdf0e10cSrcweir // -----------------------------------------------------------------------
1153cdf0e10cSrcweir
CreateSalSession()1154cdf0e10cSrcweir SalSession* AquaSalInstance::CreateSalSession()
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir return NULL;
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir
1159cdf0e10cSrcweir // -----------------------------------------------------------------------
1160cdf0e10cSrcweir
1161cdf0e10cSrcweir class MacImeStatus : public SalI18NImeStatus
1162cdf0e10cSrcweir {
1163cdf0e10cSrcweir public:
MacImeStatus()1164cdf0e10cSrcweir MacImeStatus() {}
~MacImeStatus()1165cdf0e10cSrcweir virtual ~MacImeStatus() {}
1166cdf0e10cSrcweir
1167cdf0e10cSrcweir // asks whether there is a status window available
1168cdf0e10cSrcweir // to toggle into menubar
canToggle()1169cdf0e10cSrcweir virtual bool canToggle() { return false; }
toggle()1170cdf0e10cSrcweir virtual void toggle() {}
1171cdf0e10cSrcweir };
1172cdf0e10cSrcweir
1173cdf0e10cSrcweir // -----------------------------------------------------------------------
1174cdf0e10cSrcweir
CreateI18NImeStatus()1175cdf0e10cSrcweir SalI18NImeStatus* AquaSalInstance::CreateI18NImeStatus()
1176cdf0e10cSrcweir {
1177cdf0e10cSrcweir return new MacImeStatus();
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir
1180cdf0e10cSrcweir // YieldMutexReleaser
YieldMutexReleaser()1181cdf0e10cSrcweir YieldMutexReleaser::YieldMutexReleaser() : mnCount( 0 )
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir SalData* pSalData = GetSalData();
1184cdf0e10cSrcweir if( ! pSalData->mpFirstInstance->isNSAppThread() )
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir SalData::ensureThreadAutoreleasePool();
1187cdf0e10cSrcweir mnCount = pSalData->mpFirstInstance->ReleaseYieldMutex();
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir
~YieldMutexReleaser()1191cdf0e10cSrcweir YieldMutexReleaser::~YieldMutexReleaser()
1192cdf0e10cSrcweir {
1193cdf0e10cSrcweir if( mnCount != 0 )
1194cdf0e10cSrcweir GetSalData()->mpFirstInstance->AcquireYieldMutex( mnCount );
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir
1197cdf0e10cSrcweir //////////////////////////////////////////////////////////////
GetOUString(CFStringRef rStr)1198cdf0e10cSrcweir rtl::OUString GetOUString( CFStringRef rStr )
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir if( rStr == 0 )
1201cdf0e10cSrcweir return rtl::OUString();
1202cdf0e10cSrcweir CFIndex nLength = CFStringGetLength( rStr );
1203cdf0e10cSrcweir if( nLength == 0 )
1204cdf0e10cSrcweir return rtl::OUString();
1205cdf0e10cSrcweir const UniChar* pConstStr = CFStringGetCharactersPtr( rStr );
1206cdf0e10cSrcweir if( pConstStr )
1207cdf0e10cSrcweir return rtl::OUString( pConstStr, nLength );
1208cdf0e10cSrcweir UniChar* pStr = reinterpret_cast<UniChar*>( rtl_allocateMemory( sizeof(UniChar)*nLength ) );
1209cdf0e10cSrcweir CFRange aRange = { 0, nLength };
1210cdf0e10cSrcweir CFStringGetCharacters( rStr, aRange, pStr );
1211cdf0e10cSrcweir rtl::OUString aRet( pStr, nLength );
1212cdf0e10cSrcweir rtl_freeMemory( pStr );
1213cdf0e10cSrcweir return aRet;
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir
GetOUString(NSString * pStr)1216cdf0e10cSrcweir rtl::OUString GetOUString( NSString* pStr )
1217cdf0e10cSrcweir {
1218cdf0e10cSrcweir if( ! pStr )
1219cdf0e10cSrcweir return rtl::OUString();
1220cdf0e10cSrcweir int nLen = [pStr length];
1221cdf0e10cSrcweir if( nLen == 0 )
1222cdf0e10cSrcweir return rtl::OUString();
1223cdf0e10cSrcweir
1224cdf0e10cSrcweir rtl::OUStringBuffer aBuf( nLen+1 );
1225cdf0e10cSrcweir aBuf.setLength( nLen );
1226cdf0e10cSrcweir [pStr getCharacters: const_cast<sal_Unicode*>(aBuf.getStr())];
1227cdf0e10cSrcweir return aBuf.makeStringAndClear();
1228cdf0e10cSrcweir }
1229cdf0e10cSrcweir
CreateCFString(const rtl::OUString & rStr)1230cdf0e10cSrcweir CFStringRef CreateCFString( const rtl::OUString& rStr )
1231cdf0e10cSrcweir {
1232cdf0e10cSrcweir return CFStringCreateWithCharacters(kCFAllocatorDefault, rStr.getStr(), rStr.getLength() );
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir
CreateNSString(const rtl::OUString & rStr)1235cdf0e10cSrcweir NSString* CreateNSString( const rtl::OUString& rStr )
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir return [[NSString alloc] initWithCharacters: rStr.getStr() length: rStr.getLength()];
1238cdf0e10cSrcweir }
1239cdf0e10cSrcweir
CreateCGImage(const Image & rImage)1240cdf0e10cSrcweir CGImageRef CreateCGImage( const Image& rImage )
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir BitmapEx aBmpEx( rImage.GetBitmapEx() );
1243cdf0e10cSrcweir Bitmap aBmp( aBmpEx.GetBitmap() );
1244cdf0e10cSrcweir
1245cdf0e10cSrcweir if( ! aBmp || ! aBmp.ImplGetImpBitmap() )
1246cdf0e10cSrcweir return NULL;
1247cdf0e10cSrcweir
1248cdf0e10cSrcweir // simple case, no transparency
1249cdf0e10cSrcweir AquaSalBitmap* pSalBmp = static_cast<AquaSalBitmap*>(aBmp.ImplGetImpBitmap()->ImplGetSalBitmap());
1250cdf0e10cSrcweir
1251cdf0e10cSrcweir if( ! pSalBmp )
1252cdf0e10cSrcweir return NULL;
1253cdf0e10cSrcweir
1254cdf0e10cSrcweir CGImageRef xImage = NULL;
1255cdf0e10cSrcweir if( ! (aBmpEx.IsAlpha() || aBmpEx.IsTransparent() ) )
1256cdf0e10cSrcweir xImage = pSalBmp->CreateCroppedImage( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
1257cdf0e10cSrcweir else if( aBmpEx.IsAlpha() )
1258cdf0e10cSrcweir {
1259cdf0e10cSrcweir AlphaMask aAlphaMask( aBmpEx.GetAlpha() );
1260cdf0e10cSrcweir Bitmap aMask( aAlphaMask.GetBitmap() );
1261cdf0e10cSrcweir AquaSalBitmap* pMaskBmp = static_cast<AquaSalBitmap*>(aMask.ImplGetImpBitmap()->ImplGetSalBitmap());
1262cdf0e10cSrcweir if( pMaskBmp )
1263cdf0e10cSrcweir xImage = pSalBmp->CreateWithMask( *pMaskBmp, 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
1264cdf0e10cSrcweir else
1265cdf0e10cSrcweir xImage = pSalBmp->CreateCroppedImage( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir else if( aBmpEx.GetTransparentType() == TRANSPARENT_BITMAP )
1268cdf0e10cSrcweir {
1269cdf0e10cSrcweir Bitmap aMask( aBmpEx.GetMask() );
1270cdf0e10cSrcweir AquaSalBitmap* pMaskBmp = static_cast<AquaSalBitmap*>(aMask.ImplGetImpBitmap()->ImplGetSalBitmap());
1271cdf0e10cSrcweir if( pMaskBmp )
1272cdf0e10cSrcweir xImage = pSalBmp->CreateWithMask( *pMaskBmp, 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
1273cdf0e10cSrcweir else
1274cdf0e10cSrcweir xImage = pSalBmp->CreateCroppedImage( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
1275cdf0e10cSrcweir }
1276cdf0e10cSrcweir else if( aBmpEx.GetTransparentType() == TRANSPARENT_COLOR )
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir Color aTransColor( aBmpEx.GetTransparentColor() );
1279cdf0e10cSrcweir SalColor nTransColor = MAKE_SALCOLOR( aTransColor.GetRed(), aTransColor.GetGreen(), aTransColor.GetBlue() );
1280cdf0e10cSrcweir xImage = pSalBmp->CreateColorMask( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight, nTransColor );
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir
1283cdf0e10cSrcweir return xImage;
1284cdf0e10cSrcweir }
1285cdf0e10cSrcweir
CreateNSImage(const Image & rImage)1286cdf0e10cSrcweir NSImage* CreateNSImage( const Image& rImage )
1287cdf0e10cSrcweir {
1288cdf0e10cSrcweir CGImageRef xImage = CreateCGImage( rImage );
1289cdf0e10cSrcweir
1290cdf0e10cSrcweir if( ! xImage )
1291cdf0e10cSrcweir return nil;
1292cdf0e10cSrcweir
1293cdf0e10cSrcweir Size aSize( rImage.GetSizePixel() );
1294cdf0e10cSrcweir NSImage* pImage = [[NSImage alloc] initWithSize: NSMakeSize( aSize.Width(), aSize.Height() )];
1295cdf0e10cSrcweir if( pImage )
1296cdf0e10cSrcweir {
1297cdf0e10cSrcweir [pImage setFlipped: YES];
1298cdf0e10cSrcweir [pImage lockFocus];
1299cdf0e10cSrcweir
1300cdf0e10cSrcweir NSGraphicsContext* pContext = [NSGraphicsContext currentContext];
1301cdf0e10cSrcweir CGContextRef rCGContext = reinterpret_cast<CGContextRef>([pContext graphicsPort]);
1302cdf0e10cSrcweir
1303cd426cceSHerbert Dürr const CGRect aDstRect = CGRectMake( 0, 0, aSize.Width(), aSize.Height());
1304cdf0e10cSrcweir CGContextDrawImage( rCGContext, aDstRect, xImage );
1305cdf0e10cSrcweir
1306cdf0e10cSrcweir [pImage unlockFocus];
1307cdf0e10cSrcweir }
1308cdf0e10cSrcweir
1309cdf0e10cSrcweir CGImageRelease( xImage );
1310cdf0e10cSrcweir
1311cdf0e10cSrcweir return pImage;
1312cdf0e10cSrcweir }
1313