@@ -120,13 +120,13 @@ using namespace JUCE_NAMESPACE; | |||||
#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) | #define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) | ||||
static int numPendingMessages = 0; | static int numPendingMessages = 0; | ||||
static bool flushingMessages = false; | |||||
@interface JuceAppDelegate : NSObject | @interface JuceAppDelegate : NSObject | ||||
{ | { | ||||
@private | @private | ||||
id oldDelegate; | id oldDelegate; | ||||
AppDelegateRedirector* redirector; | AppDelegateRedirector* redirector; | ||||
bool flushingMessages; | |||||
} | } | ||||
- (JuceAppDelegate*) init; | - (JuceAppDelegate*) init; | ||||
@@ -218,6 +218,7 @@ static bool flushingMessages = false; | |||||
- (void) customEvent: (id) n | - (void) customEvent: (id) n | ||||
{ | { | ||||
atomicDecrement (numPendingMessages); | atomicDecrement (numPendingMessages); | ||||
[self release]; | |||||
NSData* data = (NSData*) n; | NSData* data = (NSData*) n; | ||||
void* message = 0; | void* message = 0; | ||||
@@ -398,23 +399,27 @@ void MessageManager::doPlatformSpecificInitialisation() | |||||
void MessageManager::doPlatformSpecificShutdown() | void MessageManager::doPlatformSpecificShutdown() | ||||
{ | { | ||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; | |||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; | |||||
// Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages | |||||
// sent by performSelectorOnMainThread, so need to manually flush these before quitting.. | |||||
flushingMessages = true; | |||||
if (JUCEApplication::getInstance() != 0) // (must avoid blocking here when running as a plugin) | |||||
for (int i = 100; --i >= 0 && numPendingMessages > 0;) | |||||
getInstance()->runDispatchLoopUntil (10); | |||||
[juceAppDelegate release]; | |||||
juceAppDelegate = 0; | |||||
if (juceAppDelegate != 0) | |||||
{ | |||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; | |||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; | |||||
// Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages | |||||
// sent by performSelectorOnMainThread, so need to manually flush these before quitting.. | |||||
juceAppDelegate->flushingMessages = true; | |||||
if (JUCEApplication::getInstance() != 0) // (must avoid blocking here when running as a plugin) | |||||
for (int i = 100; --i >= 0 && numPendingMessages > 0;) | |||||
getInstance()->runDispatchLoopUntil (10); | |||||
[juceAppDelegate release]; | |||||
juceAppDelegate = 0; | |||||
} | |||||
} | } | ||||
bool juce_postMessageToSystemQueue (void* message) | bool juce_postMessageToSystemQueue (void* message) | ||||
{ | { | ||||
atomicIncrement (numPendingMessages); | atomicIncrement (numPendingMessages); | ||||
[juceAppDelegate retain]; | |||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) | [juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) | ||||
withObject: (id) [[NSData alloc] initWithBytes: &message | withObject: (id) [[NSData alloc] initWithBytes: &message | ||||
@@ -1193,6 +1193,7 @@ private: | |||||
#if ! JucePlugin_EditorRequiresKeyboardFocus | #if ! JucePlugin_EditorRequiresKeyboardFocus | ||||
addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); | addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); | ||||
setWantsKeyboardFocus (false); | setWantsKeyboardFocus (false); | ||||
setComponentProperty ("juce_disallowFocus", true); | |||||
#else | #else | ||||
addToDesktop (ComponentPeer::windowIsTemporary); | addToDesktop (ComponentPeer::windowIsTemporary); | ||||
setWantsKeyboardFocus (true); | setWantsKeyboardFocus (true); | ||||
@@ -118,7 +118,7 @@ NPError NP_GetValue (void* future, NPPVariable variable, void* value) | |||||
NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* funcs) | NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* funcs) | ||||
{ | { | ||||
#if JUCE_WIN32 | #if JUCE_WIN32 | ||||
#pragma EXPORTED_FUNCTION | |||||
#pragma EXPORTED_FUNCTION | |||||
#endif | #endif | ||||
log ("NP_GetEntryPoints"); | log ("NP_GetEntryPoints"); | ||||
@@ -157,7 +157,7 @@ NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs | |||||
) | ) | ||||
{ | { | ||||
#if JUCE_WIN32 | #if JUCE_WIN32 | ||||
#pragma EXPORTED_FUNCTION | |||||
#pragma EXPORTED_FUNCTION | |||||
#endif | #endif | ||||
log ("NP_Initialize"); | log ("NP_Initialize"); | ||||
@@ -167,51 +167,8 @@ NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs | |||||
if (((funcs->version >> 8) & 0xff) > NP_VERSION_MAJOR) | if (((funcs->version >> 8) & 0xff) > NP_VERSION_MAJOR) | ||||
return NPERR_INCOMPATIBLE_VERSION_ERROR; | return NPERR_INCOMPATIBLE_VERSION_ERROR; | ||||
if (funcs->size < sizeof (NPNetscapeFuncs)) | |||||
return NPERR_INVALID_FUNCTABLE_ERROR; | |||||
browser.size = funcs->size; | |||||
browser.version = funcs->version; | |||||
browser.geturlnotify = funcs->geturlnotify; | |||||
browser.geturl = funcs->geturl; | |||||
browser.posturlnotify = funcs->posturlnotify; | |||||
browser.posturl = funcs->posturl; | |||||
browser.requestread = funcs->requestread; | |||||
browser.newstream = funcs->newstream; | |||||
browser.write = funcs->write; | |||||
browser.destroystream = funcs->destroystream; | |||||
browser.status = funcs->status; | |||||
browser.uagent = funcs->uagent; | |||||
browser.memalloc = funcs->memalloc; | |||||
browser.memfree = funcs->memfree; | |||||
browser.memflush = funcs->memflush; | |||||
browser.reloadplugins = funcs->reloadplugins; | |||||
browser.getJavaEnv = funcs->getJavaEnv; | |||||
browser.getJavaPeer = funcs->getJavaPeer; | |||||
browser.getvalue = funcs->getvalue; | |||||
browser.setvalue = funcs->setvalue; | |||||
browser.invalidaterect = funcs->invalidaterect; | |||||
browser.invalidateregion = funcs->invalidateregion; | |||||
browser.forceredraw = funcs->forceredraw; | |||||
browser.getstringidentifier = funcs->getstringidentifier; | |||||
browser.getstringidentifiers = funcs->getstringidentifiers; | |||||
browser.getintidentifier = funcs->getintidentifier; | |||||
browser.identifierisstring = funcs->identifierisstring; | |||||
browser.utf8fromidentifier = funcs->utf8fromidentifier; | |||||
browser.intfromidentifier = funcs->intfromidentifier; | |||||
browser.createobject = funcs->createobject; | |||||
browser.retainobject = funcs->retainobject; | |||||
browser.releaseobject = funcs->releaseobject; | |||||
browser.invoke = funcs->invoke; | |||||
browser.invokeDefault = funcs->invokeDefault; | |||||
browser.evaluate = funcs->evaluate; | |||||
browser.getproperty = funcs->getproperty; | |||||
browser.setproperty = funcs->setproperty; | |||||
browser.removeproperty = funcs->removeproperty; | |||||
browser.hasproperty = funcs->hasproperty; | |||||
browser.hasmethod = funcs->hasmethod; | |||||
browser.releasevariantvalue = funcs->releasevariantvalue; | |||||
browser.setexception = funcs->setexception; | |||||
zerostruct (browser); | |||||
memcpy (&browser, funcs, jmin (funcs->size, sizeof (browser))); | |||||
#ifdef XP_UNIX | #ifdef XP_UNIX | ||||
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; | pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; | ||||
@@ -239,7 +196,7 @@ NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs | |||||
NPError OSCALL NP_Shutdown() | NPError OSCALL NP_Shutdown() | ||||
{ | { | ||||
#if JUCE_WIN32 | #if JUCE_WIN32 | ||||
#pragma EXPORTED_FUNCTION | |||||
#pragma EXPORTED_FUNCTION | |||||
#endif | #endif | ||||
log ("NP_Shutdown"); | log ("NP_Shutdown"); | ||||
@@ -866,11 +823,14 @@ static void createNPVariantFromValue (NPP npp, NPVariant& out, const var& v) | |||||
else if (v.isDouble()) | else if (v.isDouble()) | ||||
DOUBLE_TO_NPVARIANT ((double) v, out); | DOUBLE_TO_NPVARIANT ((double) v, out); | ||||
else if (v.isString()) | else if (v.isString()) | ||||
#if JUCE_MAC | |||||
STRINGZ_TO_NPVARIANT (strdup (v.toString().toUTF8()), out); | |||||
#else | |||||
STRINGZ_TO_NPVARIANT (_strdup (v.toString().toUTF8()), out); | |||||
#endif | |||||
{ | |||||
const String s (v.toString()); | |||||
const char* const utf8 = s.toUTF8(); | |||||
const int utf8Len = strlen (utf8) + 1; | |||||
char* const stringCopy = (char*) browser.memalloc (utf8Len); | |||||
memcpy (stringCopy, utf8, utf8Len); | |||||
STRINGZ_TO_NPVARIANT (stringCopy, out); | |||||
} | |||||
else if (v.isObject()) | else if (v.isObject()) | ||||
OBJECT_TO_NPVARIANT (NPObjectWrappingDynamicObject::create (npp, v), out); | OBJECT_TO_NPVARIANT (NPObjectWrappingDynamicObject::create (npp, v), out); | ||||
else | else | ||||
@@ -272262,13 +272262,13 @@ using namespace JUCE_NAMESPACE; | |||||
#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) | #define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) | ||||
static int numPendingMessages = 0; | static int numPendingMessages = 0; | ||||
static bool flushingMessages = false; | |||||
@interface JuceAppDelegate : NSObject | @interface JuceAppDelegate : NSObject | ||||
{ | { | ||||
@private | @private | ||||
id oldDelegate; | id oldDelegate; | ||||
AppDelegateRedirector* redirector; | AppDelegateRedirector* redirector; | ||||
bool flushingMessages; | |||||
} | } | ||||
- (JuceAppDelegate*) init; | - (JuceAppDelegate*) init; | ||||
@@ -272360,6 +272360,7 @@ static bool flushingMessages = false; | |||||
- (void) customEvent: (id) n | - (void) customEvent: (id) n | ||||
{ | { | ||||
atomicDecrement (numPendingMessages); | atomicDecrement (numPendingMessages); | ||||
[self release]; | |||||
NSData* data = (NSData*) n; | NSData* data = (NSData*) n; | ||||
void* message = 0; | void* message = 0; | ||||
@@ -272539,23 +272540,27 @@ void MessageManager::doPlatformSpecificInitialisation() | |||||
void MessageManager::doPlatformSpecificShutdown() | void MessageManager::doPlatformSpecificShutdown() | ||||
{ | { | ||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; | |||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; | |||||
if (juceAppDelegate != 0) | |||||
{ | |||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; | |||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; | |||||
// Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages | |||||
// sent by performSelectorOnMainThread, so need to manually flush these before quitting.. | |||||
flushingMessages = true; | |||||
if (JUCEApplication::getInstance() != 0) // (must avoid blocking here when running as a plugin) | |||||
for (int i = 100; --i >= 0 && numPendingMessages > 0;) | |||||
getInstance()->runDispatchLoopUntil (10); | |||||
// Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages | |||||
// sent by performSelectorOnMainThread, so need to manually flush these before quitting.. | |||||
juceAppDelegate->flushingMessages = true; | |||||
if (JUCEApplication::getInstance() != 0) // (must avoid blocking here when running as a plugin) | |||||
for (int i = 100; --i >= 0 && numPendingMessages > 0;) | |||||
getInstance()->runDispatchLoopUntil (10); | |||||
[juceAppDelegate release]; | |||||
juceAppDelegate = 0; | |||||
[juceAppDelegate release]; | |||||
juceAppDelegate = 0; | |||||
} | |||||
} | } | ||||
bool juce_postMessageToSystemQueue (void* message) | bool juce_postMessageToSystemQueue (void* message) | ||||
{ | { | ||||
atomicIncrement (numPendingMessages); | atomicIncrement (numPendingMessages); | ||||
[juceAppDelegate retain]; | |||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) | [juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) | ||||
withObject: (id) [[NSData alloc] initWithBytes: &message | withObject: (id) [[NSData alloc] initWithBytes: &message | ||||
@@ -34533,7 +34533,18 @@ public: | |||||
/** Returns the currently-active audio device. */ | /** Returns the currently-active audio device. */ | ||||
AudioIODevice* getCurrentAudioDevice() const throw() { return currentAudioDevice; } | AudioIODevice* getCurrentAudioDevice() const throw() { return currentAudioDevice; } | ||||
/** Returns the type of audio device currently in use. | |||||
@see setCurrentAudioDeviceType | |||||
*/ | |||||
const String getCurrentAudioDeviceType() const throw() { return currentDeviceType; } | const String getCurrentAudioDeviceType() const throw() { return currentDeviceType; } | ||||
/** Changes the class of audio device being used. | |||||
This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call | |||||
this because there's only one type: CoreAudio. | |||||
For a list of types, see getAvailableDeviceTypes(). | |||||
*/ | |||||
void setCurrentAudioDeviceType (const String& type, | void setCurrentAudioDeviceType (const String& type, | ||||
const bool treatAsChosenDevice); | const bool treatAsChosenDevice); | ||||
@@ -34657,7 +34668,7 @@ public: | |||||
*/ | */ | ||||
MidiOutput* getDefaultMidiOutput() const throw() { return defaultMidiOutput; } | MidiOutput* getDefaultMidiOutput() const throw() { return defaultMidiOutput; } | ||||
/** | |||||
/** Returns a list of the types of device supported. | |||||
*/ | */ | ||||
const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes(); | const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes(); | ||||
@@ -225,7 +225,18 @@ public: | |||||
/** Returns the currently-active audio device. */ | /** Returns the currently-active audio device. */ | ||||
AudioIODevice* getCurrentAudioDevice() const throw() { return currentAudioDevice; } | AudioIODevice* getCurrentAudioDevice() const throw() { return currentAudioDevice; } | ||||
/** Returns the type of audio device currently in use. | |||||
@see setCurrentAudioDeviceType | |||||
*/ | |||||
const String getCurrentAudioDeviceType() const throw() { return currentDeviceType; } | const String getCurrentAudioDeviceType() const throw() { return currentDeviceType; } | ||||
/** Changes the class of audio device being used. | |||||
This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call | |||||
this because there's only one type: CoreAudio. | |||||
For a list of types, see getAvailableDeviceTypes(). | |||||
*/ | |||||
void setCurrentAudioDeviceType (const String& type, | void setCurrentAudioDeviceType (const String& type, | ||||
const bool treatAsChosenDevice); | const bool treatAsChosenDevice); | ||||
@@ -353,7 +364,7 @@ public: | |||||
*/ | */ | ||||
MidiOutput* getDefaultMidiOutput() const throw() { return defaultMidiOutput; } | MidiOutput* getDefaultMidiOutput() const throw() { return defaultMidiOutput; } | ||||
/** | |||||
/** Returns a list of the types of device supported. | |||||
*/ | */ | ||||
const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes(); | const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes(); | ||||