summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2007-08-03 13:00:41 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2007-08-03 13:00:41 +0000
commitcfd6238db11c324d75af90a36b24e26f2db9e805 (patch)
tree863401663134ff722b53318a1f88a79636ef61ca
parentb2f15a2089b909716d7bea7e852d8bd2a4b5f601 (diff)
INTEGRATION: CWS aquavcl02 (1.34.262); FILE MERGED
2007/07/22 16:41:26 pjanik 1.34.262.14: Whitespace cleanup. 2007/07/13 08:27:49 hdu 1.34.262.13: #i78358# queue new application events also while handling old application events 2007/07/12 19:31:22 ericb 1.34.262.12: #i79553# add TPT in AquaSalInstance constructor to make testtool receive events + put it in foreground 2007/07/12 14:30:37 hdu 1.34.262.11: #i78358# handle only one delayed AppleEvent at a time 2007/07/12 14:23:03 hdu 1.34.262.10: #i78358# handle aqua's AppleEvents immediately in the SVMainHook 2007/07/11 17:14:31 pl 1.34.262.9: #i79487# improve native progress bar 2007/07/11 11:18:15 pjanik 1.34.262.8: #i10000#: Adapt VCL header paths. 2007/07/11 10:49:53 pjanik 1.34.262.7: RESYNC: (1.34-1.37); FILE MERGED 2007/07/06 11:11:22 isma87 1.34.262.6: center tabs and ask for native size 2007/07/06 10:57:26 isma87 1.34.262.5: remove bold text for focused tab 2007/07/05 14:08:47 hdu 1.34.262.4: #i78358# Aqua AppleEvents: handle multiple open/print files at once 2007/07/05 11:07:18 hdu 1.34.262.3: #i78358# handle AppleEvents: OpenDoc and PrintDoc 2007/07/03 15:40:49 hdu 1.34.262.2: #i78358# handle AppleEvents: AEQuitApplication 2007/07/02 11:53:45 pl 1.34.262.1: join from aquavcl01
-rw-r--r--vcl/aqua/source/app/salinst.cxx193
1 files changed, 180 insertions, 13 deletions
diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx
index 96668632c47d..092c582335ee 100644
--- a/vcl/aqua/source/app/salinst.cxx
+++ b/vcl/aqua/source/app/salinst.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: salinst.cxx,v $
*
- * $Revision: 1.37 $
+ * $Revision: 1.38 $
*
- * last change: $Author: rt $ $Date: 2007-07-05 15:59:02 $
+ * last change: $Author: hr $ $Date: 2007-08-03 14:00:41 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -53,7 +53,6 @@
#ifndef _SV_SALOBJ_HXX
#include <vcl/salobj.hxx>
#endif
-#include <salobj.h>
#ifndef _SV_SALOBJ_H
#include <salobj.h>
#endif
@@ -79,6 +78,8 @@
#include <vcl/salimestatus.hxx>
#endif
+#include <vcl/svapp.hxx>
+
#include <salprn.h>
#include <vcl/print.h>
@@ -89,8 +90,20 @@
#include <aquavclevents.hxx>
+#include <premac.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <postmac.h>
+
using namespace std;
+// -----------------------------------------------------------------------
+
+// the AppEventList must be available before any SalData/SalInst/etc. objects are ready
+typedef std::list<const ApplicationEvent*> AppEventList;
+static AppEventList aAppEventList;
+
+// -----------------------------------------------------------------------
+
FILE* SalData::s_pLog = NULL;
void AquaLog( const char* pFormat, ... )
@@ -143,11 +156,11 @@ void DeInitSalData()
// -----------------------------------------------------------------------
-#ifdef QUARTZ
extern "C" {
#include <crt_externs.h>
}
-#endif
+
+// -----------------------------------------------------------------------
void InitSalMain()
{
@@ -305,17 +318,20 @@ SalInstance* CreateSalInstance()
else
SalData::s_pLog = fopen( pLogEnv, "w" );
- SalData* pSalData = GetSalData();
- AquaSalInstance* pInst = new AquaSalInstance;
+ AquaSalInstance* pInst = new AquaSalInstance;
- EventLoopTimerUPP eventLoopTimer = NewEventLoopTimerUPP(AquaSalInstance::TimerEventHandler);
- InstallEventLoopTimer(GetMainEventLoop(), 1, 0, eventLoopTimer, pInst, &pInst->mEventLoopTimerRef);
+ EventLoopTimerUPP eventLoopTimer = NewEventLoopTimerUPP(AquaSalInstance::TimerEventHandler);
+ InstallEventLoopTimer(GetMainEventLoop(), 1, 0, eventLoopTimer, pInst, &pInst->mEventLoopTimerRef);
- // init instance (only one instance in this version !!!)
- pSalData->mpFirstInstance = pInst;
- ImplGetSVData()->maNWFData.mbNoFocusRects = true;
+ // init instance (only one instance in this version !!!)
+ SalData* pSalData = GetSalData();
+ pSalData->mpFirstInstance = pInst;
+ ImplGetSVData()->maNWFData.mbNoFocusRects = true;
+ ImplGetSVData()->maNWFData.mbNoBoldTabFocus = true;
+ ImplGetSVData()->maNWFData.mbCenteredTabs = true;
+ ImplGetSVData()->maNWFData.mbProgressNeedsErase = true;
- return pInst;
+ return pInst;
}
// -----------------------------------------------------------------------
@@ -338,6 +354,12 @@ AquaSalInstance::AquaSalInstance()
mEventLoopTimerRef = NULL;
mbForceDispatchPaintEvents = false;
mpSalYieldMutex->acquire();
+
+ // In order to receive events, we put the application in foreground
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
}
// -----------------------------------------------------------------------
@@ -480,6 +502,29 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
// Reset all locks
AcquireYieldMutex( nCount );
+
+ // we get some apple events way too early
+ // before the application is ready to handle them,
+ // so their corresponding application events need to be delayed
+ // now is a good time to handle at least one of them
+ if( bWait && !aAppEventList.empty() )
+ {
+ // make sure that only one application event is active at a time
+ static bool bInAppEvent = false;
+ if( !bInAppEvent )
+ {
+ bInAppEvent = true;
+ // get the next delayed application event
+ const ApplicationEvent* pAppEvent = aAppEventList.front();
+ aAppEventList.pop_front();
+ // handle one application event (no recursion)
+ const ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpApp->AppEvent( *pAppEvent );
+ delete pAppEvent;
+ // allow the next delayed application event
+ bInAppEvent = false;
+ }
+ }
}
// -----------------------------------------------------------------------
@@ -747,7 +792,129 @@ SalI18NImeStatus* AquaSalInstance::CreateI18NImeStatus()
return new MacImeStatus();
}
+// =======================================================================
+
+static OSErr OpenOrPrintDoc( const AppleEvent* pAEvent, bool bPrint )
+{
+ // get the list of document URLs
+ AEDescList aAEDocList;
+ OSErr eErr = AEGetParamDesc( pAEvent, keyDirectObject, typeAEList, &aAEDocList );
+ if( eErr != noErr )
+ return errAEEventNotHandled;
+
+ // prepare the URL-names string for the ApplicationEvent parameter
+ long nFullLength = 0;
+ std::vector<char> aNameBuffer;
+ for( int i = 1;; ++i )
+ {
+ AEKeyword aAEKeyword;
+ DescType aDescType;
+ // get the URL's encoded name length
+ long nNeedLength = 0;
+ if( AEGetNthPtr( &aAEDocList, i, typeFileURL, &aAEKeyword, &aDescType,
+ NULL, 0, &nNeedLength ) != noErr )
+ break;
+ // resize the name buffer for the new URL+delimiter
+ if( nFullLength )
+ aNameBuffer[ nFullLength++ ] = APPEVENT_PARAM_DELIMITER;
+ aNameBuffer.resize( nFullLength + nNeedLength + 1 );
+ // get the URL's encoded name data
+ long nNewLength = 0;
+ if( AEGetNthPtr( &aAEDocList, i, typeFileURL, &aAEKeyword, &aDescType,
+ (void*)&aNameBuffer[nFullLength], nNeedLength, &nNewLength ) != noErr )
+ break;
+ nFullLength += nNewLength;
+ aNameBuffer[ nFullLength ] = '\0';
+ }
+
+ // the AEdescriptor is no longer needed
+ AEDisposeDesc( &aAEDocList );
+
+ // convert the URL names to unicode
+ // TODO: is the original encoding always UTF8?
+ const String aUrlNames( (sal_Char*)&aNameBuffer[0], RTL_TEXTENCODING_UTF8 );
+ // create and send the event to the application
+ // send an open or print event to the application
+ const String aEmptySender;
+ const ApplicationAddress aEmptyAddr;
+ const char* pEvtType = bPrint ? APPEVENT_PRINT_STRING : APPEVENT_OPEN_STRING;
+ const ApplicationEvent* pAppEvent = new ApplicationEvent( aEmptySender, aEmptyAddr, pEvtType, aUrlNames );
+ aAppEventList.push_back( pAppEvent );
+
+ return noErr;
+}
+
+// -----------------------------------------------------------------------
+
+OSErr HandleAEventOpenDoc( const AppleEvent* pAEvent,
+ AppleEvent* /*pAEReply*/, long /*nHandlerRefConstant*/ )
+{
+ return OpenOrPrintDoc( pAEvent, false );
+}
+
+// -----------------------------------------------------------------------
+
+OSErr HandleAEventPrintDoc( const AppleEvent* pAEvent,
+ AppleEvent* /*pAEReply*/, long /*nHandlerRefConstant*/ )
+{
+ return OpenOrPrintDoc( pAEvent, true );
+}
+
+// -----------------------------------------------------------------------
+
+OSErr HandleAEventOpenApp( const AppleEvent* /*pAEvent*/,
+ AppleEvent* /*pAEReply*/, long /*nHandlerRefConstant*/ )
+{
+ const SalData* pSalData = GetSalData();
+ if( !pSalData->maFrames.empty() )
+ pSalData->maFrames.front()->CallCallback( SALEVENT_SHUTDOWN, NULL );
+ return noErr;
+}
+
+// -----------------------------------------------------------------------
+
+OSErr HandleAEventQuitApp( const AppleEvent* pAEvent,
+ AppleEvent* /*pAEReply*/, long /*nHandlerRefConstant*/ )
+{
+ const SalData* pSalData = GetSalData();
+ if( !pSalData->maFrames.empty() )
+ pSalData->maFrames.front()->CallCallback( SALEVENT_SHUTDOWN, NULL );
+ return noErr;
+}
+
+// -----------------------------------------------------------------------
+
+extern void InstallAEHandlers()
+{
+ // check if it is possible to install AppleEvent handlers
+ long nGestaltAttrs;
+ OSStatus eStatus = Gestalt( gestaltAppleEventsAttr, &nGestaltAttrs );
+ if( eStatus != noErr )
+ return;
+ if( ((nGestaltAttrs >> gestaltAppleEventsPresent) & 1) == 0 )
+ return;
+
+ // prepare to handle "open document" events
+ AEEventHandlerUPP aAEHandler = NewAEEventHandlerUPP( HandleAEventOpenDoc );
+ AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, aAEHandler, 0L, false );
+
+ // prepare to handle "print document" events
+ aAEHandler = NewAEEventHandlerUPP( HandleAEventPrintDoc );
+ AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, aAEHandler, 0L, false );
+
+ // prepare to handle "open application" events
+ aAEHandler = NewAEEventHandlerUPP( HandleAEventOpenApp );
+ AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, aAEHandler, 0L, false );
+
+ // prepare to handle "quit application" events
+ aAEHandler = NewAEEventHandlerUPP( HandleAEventQuitApp );
+ AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, aAEHandler, 0L, false );
+
+ // TODO: handle other events from the AppleEventManager too
+}
+
//////////////////////////////////////////////////////////////
+// TODO: are these debug-convenience functions still needed?
rtl::OUString GetOUString( CFStringRef rStr )
{
if( rStr == 0 )