xref: /trunk/main/vcl/aqua/source/app/salinst.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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