|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the
- GNU General Public License, as published by the Free Software Foundation;
- either version 2 of the License, or (at your option) any later version.
-
- JUCE is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- #include "../../../src/juce_core/basics/juce_StandardHeader.h"
- #include <Carbon/Carbon.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #include "../../../src/juce_appframework/events/juce_MessageManager.h"
- #include "../../../src/juce_appframework/application/juce_Application.h"
- #include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
- #include "../../../src/juce_core/text/juce_StringArray.h"
- #include "../../../src/juce_core/threads/juce_Thread.h"
- #include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
-
- #undef Point
-
- static int kJUCEClass = FOUR_CHAR_CODE ('JUCE');
- const int kJUCEKind = 1;
- const int kCallbackKind = 2;
-
- extern void juce_HandleProcessFocusChange();
- extern void juce_maximiseAllMinimisedWindows();
- extern void juce_InvokeMainMenuCommand (const HICommand& command);
- extern void juce_MainMenuAboutToBeUsed();
-
- static pascal OSStatus EventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- void* event = 0;
- GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof (void*), 0, &event);
-
- if (event != 0)
- MessageManager::getInstance()->deliverMessage (event);
-
- return noErr;
- }
-
- struct CallbackMessagePayload
- {
- MessageCallbackFunction* function;
- void* parameter;
- void* volatile result;
- bool volatile hasBeenExecuted;
- };
-
- static pascal OSStatus CallbackHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- CallbackMessagePayload* pl = 0;
- GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof(pl), 0, &pl);
-
- if (pl != 0)
- {
- pl->result = (*pl->function) (pl->parameter);
- pl->hasBeenExecuted = true;
- }
-
- return noErr;
- }
-
- static pascal OSStatus MouseClickHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- ::Point where;
- GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, 0, sizeof(::Point), 0, &where);
- WindowRef window;
- if (FindWindow (where, &window) == inMenuBar)
- {
- // turn off the wait cursor before going in here..
- const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor();
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
-
- if (Component::getCurrentlyModalComponent() != 0)
- Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
-
- juce_MainMenuAboutToBeUsed();
- MenuSelect (where);
- HiliteMenu (0);
-
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor);
- return noErr;
- }
-
- return eventNotHandledErr;
- }
-
- static pascal OSErr QuitAppleEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
- {
- if (JUCEApplication::getInstance() != 0)
- JUCEApplication::getInstance()->systemRequestedQuit();
-
- return noErr;
- }
-
- static pascal OSErr OpenDocEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
- {
- AEDescList docs;
- StringArray files;
-
- if (AEGetParamDesc (appleEvt, keyDirectObject, typeAEList, &docs) == noErr)
- {
- long num;
- if (AECountItems (&docs, &num) == noErr)
- {
- for (int i = 1; i <= num; ++i)
- {
- FSRef file;
- AEKeyword keyword;
- DescType type;
- Size size;
-
- if (AEGetNthPtr (&docs, i, typeFSRef, &keyword, &type,
- &file, sizeof (file), &size) == noErr)
- {
- const String path (PlatformUtilities::makePathFromFSRef (&file));
-
- if (path.isNotEmpty())
- files.add (path.quoted());
- }
- }
-
- if (files.size() > 0
- && JUCEApplication::getInstance() != 0)
- {
- JUCE_TRY
- {
- JUCEApplication::getInstance()
- ->anotherInstanceStarted (files.joinIntoString (T(" ")));
- }
- JUCE_CATCH_ALL
- }
- }
-
- AEDisposeDesc (&docs);
- };
-
- return noErr;
- }
-
- static pascal OSStatus AppEventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- const UInt32 eventClass = GetEventClass (theEvent);
-
- if (eventClass == kEventClassCommand)
- {
- HICommand command;
-
- if (GetEventParameter (theEvent, kEventParamHICommand, typeHICommand, 0, sizeof (command), 0, &command) == noErr
- || GetEventParameter (theEvent, kEventParamDirectObject, typeHICommand, 0, sizeof (command), 0, &command) == noErr)
- {
- if (command.commandID == kHICommandQuit)
- {
- if (JUCEApplication::getInstance() != 0)
- JUCEApplication::getInstance()->systemRequestedQuit();
-
- return noErr;
- }
- else if (command.commandID == kHICommandMaximizeAll
- || command.commandID == kHICommandMaximizeWindow
- || command.commandID == kHICommandBringAllToFront)
- {
- juce_maximiseAllMinimisedWindows();
- return noErr;
- }
- else
- {
- juce_InvokeMainMenuCommand (command);
- }
- }
- }
- else if (eventClass == kEventClassApplication)
- {
- if (GetEventKind (theEvent) == kEventAppFrontSwitched)
- {
- juce_HandleProcessFocusChange();
- }
- else if (GetEventKind (theEvent) == kEventAppShown)
- {
- // this seems to blank the windows, so we need to do a repaint..
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* const c = Desktop::getInstance().getComponent (i);
-
- if (c != 0)
- c->repaint();
- }
- }
- }
-
- return eventNotHandledErr;
- }
-
- static EventQueueRef mainQueue;
- static EventHandlerRef juceEventHandler = 0;
- static EventHandlerRef callbackEventHandler = 0;
-
- //==============================================================================
- void MessageManager::doPlatformSpecificInitialisation()
- {
- static bool initialised = false;
-
- if (! initialised)
- {
- initialised = true;
-
- #if MACOS_10_3_OR_EARLIER
- // work-around for a bug in MacOS 10.2..
- ProcessSerialNumber junkPSN;
- (void) GetCurrentProcess (&junkPSN);
- #endif
-
- mainQueue = GetMainEventQueue();
-
- // if we're linking a Juce app to one or more dynamic libraries, we'll need different values
- // for this so each module doesn't interfere with the others.
- UnsignedWide t;
- Microseconds (&t);
- kJUCEClass ^= t.lo;
- }
-
- const EventTypeSpec type1 = { kJUCEClass, kJUCEKind };
- InstallApplicationEventHandler (NewEventHandlerUPP (EventHandlerProc), 1, &type1, 0, &juceEventHandler);
-
- const EventTypeSpec type2 = { kJUCEClass, kCallbackKind };
- InstallApplicationEventHandler (NewEventHandlerUPP (CallbackHandlerProc), 1, &type2, 0, &callbackEventHandler);
-
- // only do this stuff if we're running as an application rather than a library..
- if (JUCEApplication::getInstance() != 0)
- {
- const EventTypeSpec type3 = { kEventClassMouse, kEventMouseDown };
- InstallApplicationEventHandler (NewEventHandlerUPP (MouseClickHandlerProc), 1, &type3, 0, 0);
-
- const EventTypeSpec type4[] = { { kEventClassApplication, kEventAppShown },
- { kEventClassApplication, kEventAppFrontSwitched },
- { kEventClassCommand, kEventProcessCommand } };
-
- InstallApplicationEventHandler (NewEventHandlerUPP (AppEventHandlerProc), 3, type4, 0, 0);
-
- AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerUPP (QuitAppleEventHandler), 0, false);
-
- AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerUPP (OpenDocEventHandler), 0, false);
- }
- }
-
- void MessageManager::doPlatformSpecificShutdown()
- {
- if (juceEventHandler != 0)
- {
- RemoveEventHandler (juceEventHandler);
- juceEventHandler = 0;
- }
-
- if (callbackEventHandler != 0)
- {
- RemoveEventHandler (callbackEventHandler);
- callbackEventHandler = 0;
- }
- }
-
- bool juce_postMessageToSystemQueue (void* message)
- {
- jassert (mainQueue == GetMainEventQueue());
-
- EventRef event;
- if (CreateEvent (0, kJUCEClass, kJUCEKind, 0, kEventAttributeUserEvent, &event) == noErr)
- {
- SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &message);
- const bool ok = PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr;
- ReleaseEvent (event);
- return ok;
- }
-
- return false;
- }
-
- void MessageManager::broadcastMessage (const String& value) throw()
- {
- }
-
- void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
- void* data)
- {
- if (isThisTheMessageThread())
- {
- return (*callback) (data);
- }
- else
- {
- jassert (mainQueue == GetMainEventQueue());
-
- CallbackMessagePayload cmp;
- cmp.function = callback;
- cmp.parameter = data;
- cmp.result = 0;
- cmp.hasBeenExecuted = false;
-
- EventRef event;
- if (CreateEvent (0, kJUCEClass, kCallbackKind, 0, kEventAttributeUserEvent, &event) == noErr)
- {
- void* v = &cmp;
- SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &v);
-
- if (PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr)
- {
- while (! cmp.hasBeenExecuted)
- Thread::yield();
-
- return cmp.result;
- }
- }
-
- return 0;
- }
- }
-
- END_JUCE_NAMESPACE
|