mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-31 03:00:05 +00:00
This commit is contained in:
parent
567fe9b1e7
commit
485b6b7e57
27 changed files with 2455 additions and 2455 deletions
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_USE_CDBURNER
|
||||
|
||||
|
|
@ -69,25 +69,25 @@ END_JUCE_NAMESPACE
|
|||
- (void) setupTrackProperties: (DRTrack*) track;
|
||||
|
||||
- (void) cleanupTrackAfterBurn: (DRTrack*) track;
|
||||
- (BOOL) cleanupTrackAfterVerification:(DRTrack*)track;
|
||||
- (BOOL) cleanupTrackAfterVerification:(DRTrack*)track;
|
||||
- (uint64_t) estimateLengthOfTrack:(DRTrack*)track;
|
||||
- (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
|
||||
toMedia:(NSDictionary*)mediaInfo;
|
||||
- (BOOL) prepareTrackForVerification:(DRTrack*)track;
|
||||
- (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
- (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
|
||||
toMedia:(NSDictionary*)mediaInfo;
|
||||
- (BOOL) prepareTrackForVerification:(DRTrack*)track;
|
||||
- (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags;
|
||||
- (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags;
|
||||
- (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags;
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -110,8 +110,8 @@ END_JUCE_NAMESPACE
|
|||
|
||||
- (bool) isDiskPresent
|
||||
{
|
||||
return [device isValid]
|
||||
&& [[[device status] objectForKey: DRDeviceMediaStateKey]
|
||||
return [device isValid]
|
||||
&& [[[device status] objectForKey: DRDeviceMediaStateKey]
|
||||
isEqualTo: DRDeviceMediaStateMediaPresent];
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ END_JUCE_NAMESPACE
|
|||
[p release];
|
||||
}
|
||||
|
||||
- (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error
|
||||
- (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error
|
||||
ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting
|
||||
{
|
||||
DRBurn* burn = [DRBurn burnForDevice: device];
|
||||
|
|
@ -150,7 +150,7 @@ END_JUCE_NAMESPACE
|
|||
[d autorelease];
|
||||
[d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey];
|
||||
[d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey];
|
||||
[d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount)
|
||||
[d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount)
|
||||
forKey: DRBurnCompletionActionKey];
|
||||
[burn setProperties: d];
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ NSLog ([[burn status] description]);
|
|||
break;
|
||||
}
|
||||
|
||||
NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey]
|
||||
NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey]
|
||||
objectForKey: DRErrorStatusErrorStringKey];
|
||||
|
||||
if ([err length] > 0)
|
||||
|
|
@ -214,7 +214,7 @@ NSLog ([[burn status] description]);
|
|||
[p setObject:[NSNumber numberWithInt:0] forKey: DRBlockTypeKey];
|
||||
[p setObject:[NSNumber numberWithInt:0] forKey: DRTrackModeKey];
|
||||
[p setObject:[NSNumber numberWithInt:0] forKey: DRSessionFormatKey];
|
||||
|
||||
|
||||
|
||||
[track setProperties: p];
|
||||
[p release];
|
||||
|
|
@ -255,7 +255,7 @@ NSLog ([[burn status] description]);
|
|||
return lengthInFrames;
|
||||
}
|
||||
|
||||
- (BOOL) prepareTrack: (DRTrack*) track forBurn: (DRBurn*) burn
|
||||
- (BOOL) prepareTrack: (DRTrack*) track forBurn: (DRBurn*) burn
|
||||
toMedia: (NSDictionary*) mediaInfo
|
||||
{
|
||||
if (source != 0)
|
||||
|
|
@ -273,8 +273,8 @@ NSLog ([[burn status] description]);
|
|||
return true;
|
||||
}
|
||||
|
||||
- (uint32_t) produceDataForTrack: (DRTrack*) track intoBuffer: (char*) buffer
|
||||
length: (uint32_t) bufferLength atAddress: (uint64_t) address
|
||||
- (uint32_t) produceDataForTrack: (DRTrack*) track intoBuffer: (char*) buffer
|
||||
length: (uint32_t) bufferLength atAddress: (uint64_t) address
|
||||
blockSize: (uint32_t) blockSize ioFlags: (uint32_t*) flags
|
||||
{
|
||||
if (source != 0)
|
||||
|
|
@ -306,17 +306,17 @@ NSLog ([[burn status] description]);
|
|||
return 0;
|
||||
}
|
||||
|
||||
- (uint32_t) producePreGapForTrack: (DRTrack*) track
|
||||
intoBuffer: (char*) buffer length: (uint32_t) bufferLength
|
||||
atAddress: (uint64_t) address blockSize: (uint32_t) blockSize
|
||||
- (uint32_t) producePreGapForTrack: (DRTrack*) track
|
||||
intoBuffer: (char*) buffer length: (uint32_t) bufferLength
|
||||
atAddress: (uint64_t) address blockSize: (uint32_t) blockSize
|
||||
ioFlags: (uint32_t*) flags
|
||||
{
|
||||
zeromem (buffer, bufferLength);
|
||||
return bufferLength;
|
||||
}
|
||||
|
||||
- (BOOL) verifyDataForTrack: (DRTrack*) track inBuffer: (const char*) buffer
|
||||
length: (uint32_t) bufferLength atAddress: (uint64_t) address
|
||||
- (BOOL) verifyDataForTrack: (DRTrack*) track inBuffer: (const char*) buffer
|
||||
length: (uint32_t) bufferLength atAddress: (uint64_t) address
|
||||
blockSize: (uint32_t) blockSize ioFlags: (uint32_t*) flags
|
||||
{
|
||||
return true;
|
||||
|
|
@ -424,8 +424,8 @@ const String AudioCDBurner::burn (JUCE_NAMESPACE::AudioCDBurner::BurnProgressLis
|
|||
if (dev != 0)
|
||||
{
|
||||
error = String::empty;
|
||||
[dev burn: listener
|
||||
errorString: &error
|
||||
[dev burn: listener
|
||||
errorString: &error
|
||||
ejectAfterwards: ejectDiscAfterwards
|
||||
isFake: peformFakeBurnForTesting];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results,
|
|||
[panel setDelegate: delegate];
|
||||
|
||||
String directory, filename;
|
||||
|
||||
|
||||
if (currentFileOrDirectory.isDirectory())
|
||||
{
|
||||
directory = currentFileOrDirectory.getFullPathName();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
@ -157,9 +157,9 @@ bool juce_copyFile (const String& src, const String& dst) throw()
|
|||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
NSFileManager* fm = [NSFileManager defaultManager];
|
||||
|
||||
|
||||
return [fm fileExistsAtPath: juceStringToNS (src)]
|
||||
&& [fm copyPath: juceStringToNS (src)
|
||||
&& [fm copyPath: juceStringToNS (src)
|
||||
toPath: juceStringToNS (dst)
|
||||
handler: nil];
|
||||
}
|
||||
|
|
@ -309,7 +309,7 @@ void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) thro
|
|||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSBundle* b = [NSBundle bundleWithIdentifier: juceStringToNS (bundleId)];
|
||||
|
||||
|
||||
if (b != nil)
|
||||
executableFile = nsStringToJuce ([b executablePath]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
|
|||
|
|
@ -1,429 +1,429 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
#define JuceMenuCallback MakeObjCClassName(JuceMenuCallback)
|
||||
|
||||
@interface JuceMenuCallback : NSObject
|
||||
{
|
||||
JuceMainMenuHandler* owner;
|
||||
}
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_;
|
||||
- (void) dealloc;
|
||||
- (void) menuItemInvoked: (id) menu;
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler : private MenuBarModelListener,
|
||||
private DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
static JuceMainMenuHandler* instance;
|
||||
|
||||
//==============================================================================
|
||||
JuceMainMenuHandler() throw()
|
||||
: currentModel (0)
|
||||
{
|
||||
callback = [[JuceMenuCallback alloc] initWithOwner: this];
|
||||
}
|
||||
|
||||
~JuceMainMenuHandler() throw()
|
||||
{
|
||||
setMenu (0);
|
||||
|
||||
jassert (instance == this);
|
||||
instance = 0;
|
||||
|
||||
[callback release];
|
||||
}
|
||||
|
||||
void setMenu (MenuBarModel* const newMenuBarModel) throw()
|
||||
{
|
||||
if (currentModel != newMenuBarModel)
|
||||
{
|
||||
if (currentModel != 0)
|
||||
currentModel->removeListener (this);
|
||||
|
||||
currentModel = newMenuBarModel;
|
||||
|
||||
if (currentModel != 0)
|
||||
currentModel->addListener (this);
|
||||
|
||||
menuBarItemsChanged (0);
|
||||
}
|
||||
}
|
||||
|
||||
void addSubMenu (NSMenu* parent, const PopupMenu& child,
|
||||
const String& name, int& menuId, int& tag)
|
||||
{
|
||||
NSMenuItem* item = [parent addItemWithTitle: juceStringToNS (name)
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
[item setTag: tag];
|
||||
|
||||
NSMenu* sub = createMenu (child, name, menuId, tag);
|
||||
|
||||
[parent setSubmenu: sub forItem: item];
|
||||
[sub setAutoenablesItems: false];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
void menuBarItemsChanged (MenuBarModel*)
|
||||
{
|
||||
NSMenu* menuBar = [NSApp mainMenu];
|
||||
while ([menuBar numberOfItems] > 1)
|
||||
[menuBar removeItemAtIndex: 1];
|
||||
|
||||
if (currentModel != 0)
|
||||
{
|
||||
const StringArray menuNames (currentModel->getMenuBarNames());
|
||||
int menuId = 1;
|
||||
|
||||
for (int i = 0; i < menuNames.size(); ++i)
|
||||
{
|
||||
const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i]));
|
||||
addSubMenu (menuBar, menu, menuNames [i], menuId, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flashMenuBar (NSMenu* menu)
|
||||
{
|
||||
const unichar f35Key = NSF35FunctionKey;
|
||||
NSString* f35String = [NSString stringWithCharacters: &f35Key length: 1];
|
||||
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"x"
|
||||
action: nil
|
||||
keyEquivalent: f35String];
|
||||
[item setTarget: nil];
|
||||
[menu insertItem: item atIndex: [menu numberOfItems]];
|
||||
[item release];
|
||||
|
||||
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
|
||||
location: NSZeroPoint
|
||||
modifierFlags: NSCommandKeyMask
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: [NSGraphicsContext currentContext]
|
||||
characters: f35String
|
||||
charactersIgnoringModifiers: f35String
|
||||
isARepeat: NO
|
||||
keyCode: 0];
|
||||
|
||||
[menu performKeyEquivalent: f35Event];
|
||||
[menu removeItem: item];
|
||||
}
|
||||
|
||||
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
|
||||
{
|
||||
NSMenuItem* item = [[NSApp mainMenu] itemWithTag: info.commandID];
|
||||
|
||||
if (item != 0)
|
||||
flashMenuBar ([item menu]);
|
||||
}
|
||||
|
||||
void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
|
||||
{
|
||||
if (currentModel != 0)
|
||||
{
|
||||
if (commandManager != 0)
|
||||
{
|
||||
ApplicationCommandTarget::InvocationInfo info (commandId);
|
||||
info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
|
||||
|
||||
commandManager->invoke (info, true);
|
||||
}
|
||||
|
||||
currentModel->menuItemSelected (commandId, topLevelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* currentModel;
|
||||
|
||||
private:
|
||||
JuceMenuCallback* callback;
|
||||
|
||||
NSMenu* createMenu (const PopupMenu menu,
|
||||
const String& menuName,
|
||||
int& id,
|
||||
const int topLevelIndex)
|
||||
{
|
||||
NSMenu* m = [[NSMenu alloc] initWithTitle: juceStringToNS (menuName)];
|
||||
|
||||
[m setAutoenablesItems: false];
|
||||
|
||||
PopupMenu::MenuItemIterator iter (menu);
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
|
||||
|
||||
if (iter.isSeparator)
|
||||
{
|
||||
[m addItem: [NSMenuItem separatorItem]];
|
||||
}
|
||||
else if (iter.isSectionHeader)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setEnabled: iter.isEnabled];
|
||||
}
|
||||
else if (iter.subMenu != 0)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
|
||||
NSMenu* sub = createMenu (*iter.subMenu, iter.itemName, id, topLevelIndex);
|
||||
[m setSubmenu: sub forItem: item];
|
||||
[sub release];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: @selector (menuItemInvoked:)
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
[item setState: iter.isTicked ? NSOnState : NSOffState];
|
||||
[item setTarget: (id) callback];
|
||||
|
||||
NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_int) (void*) iter.commandManager]];
|
||||
[info addObject: [NSNumber numberWithInt: topLevelIndex]];
|
||||
[item setRepresentedObject: info];
|
||||
|
||||
if (iter.commandManager != 0)
|
||||
{
|
||||
const Array <KeyPress> keyPresses (iter.commandManager->getKeyMappings()
|
||||
->getKeyPressesAssignedToCommand (iter.itemId));
|
||||
|
||||
if (keyPresses.size() > 0)
|
||||
{
|
||||
const KeyPress& kp = keyPresses.getReference(0);
|
||||
|
||||
juce_wchar key = kp.getTextCharacter();
|
||||
|
||||
if (kp.getKeyCode() == KeyPress::backspaceKey)
|
||||
key = NSBackspaceCharacter;
|
||||
else if (kp.getKeyCode() == KeyPress::deleteKey)
|
||||
key = NSDeleteCharacter;
|
||||
else if (key == 0)
|
||||
key = (juce_wchar) kp.getKeyCode();
|
||||
|
||||
unsigned int mods = 0;
|
||||
if (kp.getModifiers().isShiftDown())
|
||||
mods |= NSShiftKeyMask;
|
||||
if (kp.getModifiers().isCtrlDown())
|
||||
mods |= NSControlKeyMask;
|
||||
if (kp.getModifiers().isAltDown())
|
||||
mods |= NSAlternateKeyMask;
|
||||
if (kp.getModifiers().isCommandDown())
|
||||
mods |= NSCommandKeyMask;
|
||||
|
||||
[item setKeyEquivalent: juceStringToNS (String::charToString (key))];
|
||||
[item setKeyEquivalentModifierMask: mods];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[m update];
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
JuceMainMenuHandler* JuceMainMenuHandler::instance = 0;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
@implementation JuceMenuCallback
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_
|
||||
{
|
||||
[super init];
|
||||
owner = owner_;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) menuItemInvoked: (id) menu
|
||||
{
|
||||
NSMenuItem* item = (NSMenuItem*) menu;
|
||||
|
||||
if ([[item representedObject] isKindOfClass: [NSArray class]])
|
||||
{
|
||||
NSArray* info = (NSArray*) [item representedObject];
|
||||
|
||||
owner->invoke ([item tag],
|
||||
(ApplicationCommandManager*) (pointer_sized_int)
|
||||
[((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue],
|
||||
(int) [((NSNumber*) [info objectAtIndex: 1]) intValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw()
|
||||
{
|
||||
if (getMacMainMenu() != newMenuBarModel)
|
||||
{
|
||||
if (newMenuBarModel == 0)
|
||||
{
|
||||
delete JuceMainMenuHandler::instance;
|
||||
jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JuceMainMenuHandler::instance == 0)
|
||||
JuceMainMenuHandler::instance = new JuceMainMenuHandler();
|
||||
|
||||
JuceMainMenuHandler::instance->setMenu (newMenuBarModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* MenuBarModel::getMacMainMenu() throw()
|
||||
{
|
||||
return JuceMainMenuHandler::instance != 0
|
||||
? JuceMainMenuHandler::instance->currentModel : 0;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName)
|
||||
{
|
||||
NSMenuItem* item;
|
||||
|
||||
// xxx should allow the 'about' and 'preferences' items to be turned on programatically...
|
||||
/* item = [menu addItemWithTitle: juceStringToNS ("About " + appName)]
|
||||
action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
/* item = [menu addItemWithTitle: NSLocalizedString (@"Preferences...", nil)
|
||||
action: nil keyEquivalent: @","];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
// Services...
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Services", nil)
|
||||
action: nil keyEquivalent: @""];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle: @"Services"];
|
||||
[menu setSubmenu: servicesMenu forItem: item];
|
||||
[NSApp setServicesMenu: servicesMenu];
|
||||
[servicesMenu release];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Hide + Show stuff...
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Hide " + appName)
|
||||
action: @selector (hide:) keyEquivalent: @"h"];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Hide Others", nil)
|
||||
action: @selector (hideOtherApplications:) keyEquivalent: @"h"];
|
||||
[item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Show All", nil)
|
||||
action: @selector (unhideAllApplications:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Quit item....
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Quit " + appName)
|
||||
action: @selector (terminate:) keyEquivalent: @"q"];
|
||||
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Since our app has no NIB, this initialises a standard app menu...
|
||||
void initialiseMainMenu()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0) // only needed in an app
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: @"MainMenu"];
|
||||
NSMenuItem* item = [mainMenu addItemWithTitle: @"Apple" action: nil keyEquivalent: @""];
|
||||
|
||||
NSMenu* appMenu = [[NSMenu alloc] initWithTitle: @"Apple"];
|
||||
|
||||
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
|
||||
[mainMenu setSubmenu: appMenu forItem: item];
|
||||
|
||||
[NSApp setMainMenu: mainMenu];
|
||||
createStandardAppMenu (appMenu, JUCEApplication::getInstance()->getApplicationName());
|
||||
|
||||
[appMenu release];
|
||||
[mainMenu release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
#define JuceMenuCallback MakeObjCClassName(JuceMenuCallback)
|
||||
|
||||
@interface JuceMenuCallback : NSObject
|
||||
{
|
||||
JuceMainMenuHandler* owner;
|
||||
}
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_;
|
||||
- (void) dealloc;
|
||||
- (void) menuItemInvoked: (id) menu;
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler : private MenuBarModelListener,
|
||||
private DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
static JuceMainMenuHandler* instance;
|
||||
|
||||
//==============================================================================
|
||||
JuceMainMenuHandler() throw()
|
||||
: currentModel (0)
|
||||
{
|
||||
callback = [[JuceMenuCallback alloc] initWithOwner: this];
|
||||
}
|
||||
|
||||
~JuceMainMenuHandler() throw()
|
||||
{
|
||||
setMenu (0);
|
||||
|
||||
jassert (instance == this);
|
||||
instance = 0;
|
||||
|
||||
[callback release];
|
||||
}
|
||||
|
||||
void setMenu (MenuBarModel* const newMenuBarModel) throw()
|
||||
{
|
||||
if (currentModel != newMenuBarModel)
|
||||
{
|
||||
if (currentModel != 0)
|
||||
currentModel->removeListener (this);
|
||||
|
||||
currentModel = newMenuBarModel;
|
||||
|
||||
if (currentModel != 0)
|
||||
currentModel->addListener (this);
|
||||
|
||||
menuBarItemsChanged (0);
|
||||
}
|
||||
}
|
||||
|
||||
void addSubMenu (NSMenu* parent, const PopupMenu& child,
|
||||
const String& name, int& menuId, int& tag)
|
||||
{
|
||||
NSMenuItem* item = [parent addItemWithTitle: juceStringToNS (name)
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
[item setTag: tag];
|
||||
|
||||
NSMenu* sub = createMenu (child, name, menuId, tag);
|
||||
|
||||
[parent setSubmenu: sub forItem: item];
|
||||
[sub setAutoenablesItems: false];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
void menuBarItemsChanged (MenuBarModel*)
|
||||
{
|
||||
NSMenu* menuBar = [NSApp mainMenu];
|
||||
while ([menuBar numberOfItems] > 1)
|
||||
[menuBar removeItemAtIndex: 1];
|
||||
|
||||
if (currentModel != 0)
|
||||
{
|
||||
const StringArray menuNames (currentModel->getMenuBarNames());
|
||||
int menuId = 1;
|
||||
|
||||
for (int i = 0; i < menuNames.size(); ++i)
|
||||
{
|
||||
const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i]));
|
||||
addSubMenu (menuBar, menu, menuNames [i], menuId, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flashMenuBar (NSMenu* menu)
|
||||
{
|
||||
const unichar f35Key = NSF35FunctionKey;
|
||||
NSString* f35String = [NSString stringWithCharacters: &f35Key length: 1];
|
||||
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"x"
|
||||
action: nil
|
||||
keyEquivalent: f35String];
|
||||
[item setTarget: nil];
|
||||
[menu insertItem: item atIndex: [menu numberOfItems]];
|
||||
[item release];
|
||||
|
||||
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
|
||||
location: NSZeroPoint
|
||||
modifierFlags: NSCommandKeyMask
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: [NSGraphicsContext currentContext]
|
||||
characters: f35String
|
||||
charactersIgnoringModifiers: f35String
|
||||
isARepeat: NO
|
||||
keyCode: 0];
|
||||
|
||||
[menu performKeyEquivalent: f35Event];
|
||||
[menu removeItem: item];
|
||||
}
|
||||
|
||||
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
|
||||
{
|
||||
NSMenuItem* item = [[NSApp mainMenu] itemWithTag: info.commandID];
|
||||
|
||||
if (item != 0)
|
||||
flashMenuBar ([item menu]);
|
||||
}
|
||||
|
||||
void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
|
||||
{
|
||||
if (currentModel != 0)
|
||||
{
|
||||
if (commandManager != 0)
|
||||
{
|
||||
ApplicationCommandTarget::InvocationInfo info (commandId);
|
||||
info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
|
||||
|
||||
commandManager->invoke (info, true);
|
||||
}
|
||||
|
||||
currentModel->menuItemSelected (commandId, topLevelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* currentModel;
|
||||
|
||||
private:
|
||||
JuceMenuCallback* callback;
|
||||
|
||||
NSMenu* createMenu (const PopupMenu menu,
|
||||
const String& menuName,
|
||||
int& id,
|
||||
const int topLevelIndex)
|
||||
{
|
||||
NSMenu* m = [[NSMenu alloc] initWithTitle: juceStringToNS (menuName)];
|
||||
|
||||
[m setAutoenablesItems: false];
|
||||
|
||||
PopupMenu::MenuItemIterator iter (menu);
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
|
||||
|
||||
if (iter.isSeparator)
|
||||
{
|
||||
[m addItem: [NSMenuItem separatorItem]];
|
||||
}
|
||||
else if (iter.isSectionHeader)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setEnabled: iter.isEnabled];
|
||||
}
|
||||
else if (iter.subMenu != 0)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
|
||||
NSMenu* sub = createMenu (*iter.subMenu, iter.itemName, id, topLevelIndex);
|
||||
[m setSubmenu: sub forItem: item];
|
||||
[sub release];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: @selector (menuItemInvoked:)
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
[item setState: iter.isTicked ? NSOnState : NSOffState];
|
||||
[item setTarget: (id) callback];
|
||||
|
||||
NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_int) (void*) iter.commandManager]];
|
||||
[info addObject: [NSNumber numberWithInt: topLevelIndex]];
|
||||
[item setRepresentedObject: info];
|
||||
|
||||
if (iter.commandManager != 0)
|
||||
{
|
||||
const Array <KeyPress> keyPresses (iter.commandManager->getKeyMappings()
|
||||
->getKeyPressesAssignedToCommand (iter.itemId));
|
||||
|
||||
if (keyPresses.size() > 0)
|
||||
{
|
||||
const KeyPress& kp = keyPresses.getReference(0);
|
||||
|
||||
juce_wchar key = kp.getTextCharacter();
|
||||
|
||||
if (kp.getKeyCode() == KeyPress::backspaceKey)
|
||||
key = NSBackspaceCharacter;
|
||||
else if (kp.getKeyCode() == KeyPress::deleteKey)
|
||||
key = NSDeleteCharacter;
|
||||
else if (key == 0)
|
||||
key = (juce_wchar) kp.getKeyCode();
|
||||
|
||||
unsigned int mods = 0;
|
||||
if (kp.getModifiers().isShiftDown())
|
||||
mods |= NSShiftKeyMask;
|
||||
if (kp.getModifiers().isCtrlDown())
|
||||
mods |= NSControlKeyMask;
|
||||
if (kp.getModifiers().isAltDown())
|
||||
mods |= NSAlternateKeyMask;
|
||||
if (kp.getModifiers().isCommandDown())
|
||||
mods |= NSCommandKeyMask;
|
||||
|
||||
[item setKeyEquivalent: juceStringToNS (String::charToString (key))];
|
||||
[item setKeyEquivalentModifierMask: mods];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[m update];
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
JuceMainMenuHandler* JuceMainMenuHandler::instance = 0;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
@implementation JuceMenuCallback
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_
|
||||
{
|
||||
[super init];
|
||||
owner = owner_;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) menuItemInvoked: (id) menu
|
||||
{
|
||||
NSMenuItem* item = (NSMenuItem*) menu;
|
||||
|
||||
if ([[item representedObject] isKindOfClass: [NSArray class]])
|
||||
{
|
||||
NSArray* info = (NSArray*) [item representedObject];
|
||||
|
||||
owner->invoke ([item tag],
|
||||
(ApplicationCommandManager*) (pointer_sized_int)
|
||||
[((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue],
|
||||
(int) [((NSNumber*) [info objectAtIndex: 1]) intValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw()
|
||||
{
|
||||
if (getMacMainMenu() != newMenuBarModel)
|
||||
{
|
||||
if (newMenuBarModel == 0)
|
||||
{
|
||||
delete JuceMainMenuHandler::instance;
|
||||
jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JuceMainMenuHandler::instance == 0)
|
||||
JuceMainMenuHandler::instance = new JuceMainMenuHandler();
|
||||
|
||||
JuceMainMenuHandler::instance->setMenu (newMenuBarModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* MenuBarModel::getMacMainMenu() throw()
|
||||
{
|
||||
return JuceMainMenuHandler::instance != 0
|
||||
? JuceMainMenuHandler::instance->currentModel : 0;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName)
|
||||
{
|
||||
NSMenuItem* item;
|
||||
|
||||
// xxx should allow the 'about' and 'preferences' items to be turned on programatically...
|
||||
/* item = [menu addItemWithTitle: juceStringToNS ("About " + appName)]
|
||||
action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
/* item = [menu addItemWithTitle: NSLocalizedString (@"Preferences...", nil)
|
||||
action: nil keyEquivalent: @","];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
// Services...
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Services", nil)
|
||||
action: nil keyEquivalent: @""];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle: @"Services"];
|
||||
[menu setSubmenu: servicesMenu forItem: item];
|
||||
[NSApp setServicesMenu: servicesMenu];
|
||||
[servicesMenu release];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Hide + Show stuff...
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Hide " + appName)
|
||||
action: @selector (hide:) keyEquivalent: @"h"];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Hide Others", nil)
|
||||
action: @selector (hideOtherApplications:) keyEquivalent: @"h"];
|
||||
[item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Show All", nil)
|
||||
action: @selector (unhideAllApplications:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Quit item....
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Quit " + appName)
|
||||
action: @selector (terminate:) keyEquivalent: @"q"];
|
||||
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Since our app has no NIB, this initialises a standard app menu...
|
||||
void initialiseMainMenu()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0) // only needed in an app
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: @"MainMenu"];
|
||||
NSMenuItem* item = [mainMenu addItemWithTitle: @"Apple" action: nil keyEquivalent: @""];
|
||||
|
||||
NSMenu* appMenu = [[NSMenu alloc] initWithTitle: @"Apple"];
|
||||
|
||||
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
|
||||
[mainMenu setSubmenu: appMenu forItem: item];
|
||||
|
||||
[NSApp setMainMenu: mainMenu];
|
||||
createStandardAppMenu (appMenu, JUCEApplication::getInstance()->getApplicationName());
|
||||
|
||||
[appMenu release];
|
||||
[mainMenu release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,341 +1,341 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
/* When you use multiple DLLs which share similarly-named obj-c classes - like
|
||||
for example having more than one juce plugin loaded into a host, then when a
|
||||
method is called, the actual code that runs might actually be in a different module
|
||||
than the one you expect... So any calls to library functions or statics that are
|
||||
made inside obj-c methods will probably end up getting executed in a different DLL's
|
||||
memory space. Not a great thing to happen - this obviously leads to bizarre crashes.
|
||||
|
||||
To work around this insanity, I'm only allowing obj-c methods to make calls to
|
||||
virtual methods of an object that's known to live inside the right module's space.
|
||||
*/
|
||||
class AppDelegateRedirector
|
||||
{
|
||||
public:
|
||||
AppDelegateRedirector() {}
|
||||
virtual ~AppDelegateRedirector() {}
|
||||
|
||||
virtual NSApplicationTerminateReply shouldTerminate()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
virtual BOOL openFile (const NSString* filename)
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
virtual void openFiles (NSArray* filenames)
|
||||
{
|
||||
StringArray files;
|
||||
for (int i = 0; i < [filenames count]; ++i)
|
||||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i]));
|
||||
|
||||
if (files.size() > 0 && JUCEApplication::getInstance() != 0)
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
|
||||
}
|
||||
|
||||
virtual void focusChanged()
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
virtual void deliverMessage (void* message)
|
||||
{
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
}
|
||||
|
||||
virtual void deleteSelf()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
typedef void (*juce_HandleProcessFocusChangeFunction)();
|
||||
|
||||
#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate)
|
||||
|
||||
@interface JuceAppDelegate : NSObject
|
||||
{
|
||||
@private
|
||||
id oldDelegate;
|
||||
AppDelegateRedirector* redirector;
|
||||
}
|
||||
|
||||
- (JuceAppDelegate*) init;
|
||||
- (void) dealloc;
|
||||
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification;
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification;
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification;
|
||||
- (void) customEvent: (id) data;
|
||||
- (void) performCallback: (id) info;
|
||||
- (void) dummyMethod;
|
||||
@end
|
||||
|
||||
@implementation JuceAppDelegate
|
||||
|
||||
- (JuceAppDelegate*) init
|
||||
{
|
||||
[super init];
|
||||
|
||||
redirector = new AppDelegateRedirector();
|
||||
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
oldDelegate = [NSApp delegate];
|
||||
[NSApp setDelegate: self];
|
||||
}
|
||||
else
|
||||
{
|
||||
oldDelegate = 0;
|
||||
[center addObserver: self selector: @selector (applicationDidResignActive:)
|
||||
name: NSApplicationDidResignActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationDidBecomeActive:)
|
||||
name: NSApplicationDidBecomeActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationWillUnhide:)
|
||||
name: NSApplicationWillUnhideNotification object: NSApp];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (oldDelegate != 0)
|
||||
[NSApp setDelegate: oldDelegate];
|
||||
|
||||
redirector->deleteSelf();
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app
|
||||
{
|
||||
return redirector->shouldTerminate();
|
||||
}
|
||||
|
||||
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
|
||||
{
|
||||
return redirector->openFile (filename);
|
||||
}
|
||||
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames
|
||||
{
|
||||
return redirector->openFiles (filenames);
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) customEvent: (id) n
|
||||
{
|
||||
NSData* data = (NSData*) n;
|
||||
void* message = 0;
|
||||
[data getBytes: &message length: sizeof (message)];
|
||||
|
||||
if (message != 0)
|
||||
redirector->deliverMessage (message);
|
||||
|
||||
[data release];
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
CallbackMessagePayload* pl = (CallbackMessagePayload*) info;
|
||||
|
||||
if (pl != 0)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dummyMethod {} // (used as a way of running a dummy thread)
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
static JuceAppDelegate* juceAppDelegate = 0;
|
||||
|
||||
void MessageManager::runDispatchLoop()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
MessageManagerLock mml;
|
||||
|
||||
// must only be called by the message thread!
|
||||
jassert (isThisTheMessageThread());
|
||||
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void MessageManager::stopDispatchLoop()
|
||||
{
|
||||
quitMessagePosted = true;
|
||||
[NSApp stop: nil];
|
||||
}
|
||||
|
||||
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
jassert (isThisTheMessageThread()); // must only be called by the message thread
|
||||
|
||||
uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
|
||||
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
|
||||
|
||||
while (Time::getMillisecondCounter() < endTime)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: endDate];
|
||||
|
||||
NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: endDate
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
[NSApp sendEvent: e];
|
||||
}
|
||||
|
||||
return ! quitMessagePosted;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
if (juceAppDelegate == 0)
|
||||
juceAppDelegate = [[JuceAppDelegate alloc] init];
|
||||
|
||||
// This launches a dummy thread, which forces Cocoa to initialise NSThreads
|
||||
// correctly (needed prior to 10.5)
|
||||
if (! [NSThread isMultiThreaded])
|
||||
[NSThread detachNewThreadSelector: @selector (dummyMethod)
|
||||
toTarget: juceAppDelegate
|
||||
withObject: nil];
|
||||
|
||||
initialiseMainMenu();
|
||||
}
|
||||
|
||||
void MessageManager::doPlatformSpecificShutdown()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate];
|
||||
[juceAppDelegate release];
|
||||
juceAppDelegate = 0;
|
||||
}
|
||||
|
||||
bool juce_postMessageToSystemQueue (void* message)
|
||||
{
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:)
|
||||
withObject: (id) [[NSData alloc] initWithBytes: &message
|
||||
length: (int) sizeof (message)]
|
||||
waitUntilDone: NO];
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value) throw()
|
||||
{
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
|
||||
void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: (id) &cmp
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
/* When you use multiple DLLs which share similarly-named obj-c classes - like
|
||||
for example having more than one juce plugin loaded into a host, then when a
|
||||
method is called, the actual code that runs might actually be in a different module
|
||||
than the one you expect... So any calls to library functions or statics that are
|
||||
made inside obj-c methods will probably end up getting executed in a different DLL's
|
||||
memory space. Not a great thing to happen - this obviously leads to bizarre crashes.
|
||||
|
||||
To work around this insanity, I'm only allowing obj-c methods to make calls to
|
||||
virtual methods of an object that's known to live inside the right module's space.
|
||||
*/
|
||||
class AppDelegateRedirector
|
||||
{
|
||||
public:
|
||||
AppDelegateRedirector() {}
|
||||
virtual ~AppDelegateRedirector() {}
|
||||
|
||||
virtual NSApplicationTerminateReply shouldTerminate()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
virtual BOOL openFile (const NSString* filename)
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
virtual void openFiles (NSArray* filenames)
|
||||
{
|
||||
StringArray files;
|
||||
for (int i = 0; i < [filenames count]; ++i)
|
||||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i]));
|
||||
|
||||
if (files.size() > 0 && JUCEApplication::getInstance() != 0)
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
|
||||
}
|
||||
|
||||
virtual void focusChanged()
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
virtual void deliverMessage (void* message)
|
||||
{
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
}
|
||||
|
||||
virtual void deleteSelf()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
typedef void (*juce_HandleProcessFocusChangeFunction)();
|
||||
|
||||
#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate)
|
||||
|
||||
@interface JuceAppDelegate : NSObject
|
||||
{
|
||||
@private
|
||||
id oldDelegate;
|
||||
AppDelegateRedirector* redirector;
|
||||
}
|
||||
|
||||
- (JuceAppDelegate*) init;
|
||||
- (void) dealloc;
|
||||
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification;
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification;
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification;
|
||||
- (void) customEvent: (id) data;
|
||||
- (void) performCallback: (id) info;
|
||||
- (void) dummyMethod;
|
||||
@end
|
||||
|
||||
@implementation JuceAppDelegate
|
||||
|
||||
- (JuceAppDelegate*) init
|
||||
{
|
||||
[super init];
|
||||
|
||||
redirector = new AppDelegateRedirector();
|
||||
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
oldDelegate = [NSApp delegate];
|
||||
[NSApp setDelegate: self];
|
||||
}
|
||||
else
|
||||
{
|
||||
oldDelegate = 0;
|
||||
[center addObserver: self selector: @selector (applicationDidResignActive:)
|
||||
name: NSApplicationDidResignActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationDidBecomeActive:)
|
||||
name: NSApplicationDidBecomeActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationWillUnhide:)
|
||||
name: NSApplicationWillUnhideNotification object: NSApp];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (oldDelegate != 0)
|
||||
[NSApp setDelegate: oldDelegate];
|
||||
|
||||
redirector->deleteSelf();
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app
|
||||
{
|
||||
return redirector->shouldTerminate();
|
||||
}
|
||||
|
||||
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
|
||||
{
|
||||
return redirector->openFile (filename);
|
||||
}
|
||||
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames
|
||||
{
|
||||
return redirector->openFiles (filenames);
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) customEvent: (id) n
|
||||
{
|
||||
NSData* data = (NSData*) n;
|
||||
void* message = 0;
|
||||
[data getBytes: &message length: sizeof (message)];
|
||||
|
||||
if (message != 0)
|
||||
redirector->deliverMessage (message);
|
||||
|
||||
[data release];
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
CallbackMessagePayload* pl = (CallbackMessagePayload*) info;
|
||||
|
||||
if (pl != 0)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dummyMethod {} // (used as a way of running a dummy thread)
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
static JuceAppDelegate* juceAppDelegate = 0;
|
||||
|
||||
void MessageManager::runDispatchLoop()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
MessageManagerLock mml;
|
||||
|
||||
// must only be called by the message thread!
|
||||
jassert (isThisTheMessageThread());
|
||||
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void MessageManager::stopDispatchLoop()
|
||||
{
|
||||
quitMessagePosted = true;
|
||||
[NSApp stop: nil];
|
||||
}
|
||||
|
||||
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
jassert (isThisTheMessageThread()); // must only be called by the message thread
|
||||
|
||||
uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
|
||||
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
|
||||
|
||||
while (Time::getMillisecondCounter() < endTime)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: endDate];
|
||||
|
||||
NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: endDate
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
[NSApp sendEvent: e];
|
||||
}
|
||||
|
||||
return ! quitMessagePosted;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
if (juceAppDelegate == 0)
|
||||
juceAppDelegate = [[JuceAppDelegate alloc] init];
|
||||
|
||||
// This launches a dummy thread, which forces Cocoa to initialise NSThreads
|
||||
// correctly (needed prior to 10.5)
|
||||
if (! [NSThread isMultiThreaded])
|
||||
[NSThread detachNewThreadSelector: @selector (dummyMethod)
|
||||
toTarget: juceAppDelegate
|
||||
withObject: nil];
|
||||
|
||||
initialiseMainMenu();
|
||||
}
|
||||
|
||||
void MessageManager::doPlatformSpecificShutdown()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate];
|
||||
[juceAppDelegate release];
|
||||
juceAppDelegate = 0;
|
||||
}
|
||||
|
||||
bool juce_postMessageToSystemQueue (void* message)
|
||||
{
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:)
|
||||
withObject: (id) [[NSData alloc] initWithBytes: &message
|
||||
length: (int) sizeof (message)]
|
||||
waitUntilDone: NO];
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value) throw()
|
||||
{
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
|
||||
void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: (id) &cmp
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,238 +1,238 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
ScopedAutoReleasePool::ScopedAutoReleasePool()
|
||||
{
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
ScopedAutoReleasePool::~ScopedAutoReleasePool()
|
||||
{
|
||||
[((NSAutoreleasePool*) pool) release];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PlatformUtilities::beep()
|
||||
{
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool AlertWindow::showNativeDialogBox (const String& title,
|
||||
const String& bodyText,
|
||||
bool isOkCancel)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
return NSRunAlertPanel (juceStringToNS (title),
|
||||
juceStringToNS (bodyText),
|
||||
@"Ok",
|
||||
isOkCancel ? @"Cancel" : nil,
|
||||
nil) == 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
return false;
|
||||
|
||||
Component* sourceComp = Component::getComponentUnderMouse();
|
||||
|
||||
if (sourceComp == 0)
|
||||
{
|
||||
jassertfalse // this method must be called in response to a
|
||||
// component's mouseDrag event!
|
||||
return false;
|
||||
}
|
||||
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSView* view = (NSView*) sourceComp->getWindowHandle();
|
||||
|
||||
if (view == 0)
|
||||
return false;
|
||||
|
||||
NSPasteboard* pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
|
||||
[pboard declareTypes: [NSArray arrayWithObject: NSFilenamesPboardType]
|
||||
owner: nil];
|
||||
|
||||
NSMutableArray* filesArray = [NSMutableArray arrayWithCapacity: 4];
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
[filesArray addObject: juceStringToNS (files[i])];
|
||||
|
||||
[pboard setPropertyList: filesArray
|
||||
forType: NSFilenamesPboardType];
|
||||
|
||||
NSPoint dragPosition = [view convertPoint: [[[view window] currentEvent] locationInWindow]
|
||||
fromView: nil];
|
||||
dragPosition.x -= 16;
|
||||
dragPosition.y -= 16;
|
||||
|
||||
[view dragImage: [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (files[0])]
|
||||
at: dragPosition
|
||||
offset: NSMakeSize (0, 0)
|
||||
event: [[view window] currentEvent]
|
||||
pasteboard: pboard
|
||||
source: view
|
||||
slideBack: YES];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
||||
{
|
||||
jassertfalse // not implemented!
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Desktop::canUseSemiTransparentWindows() throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Desktop::getMousePosition (int& x, int& y) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
const NSPoint p ([NSEvent mouseLocation]);
|
||||
x = roundFloatToInt (p.x);
|
||||
y = roundFloatToInt ([[NSScreen mainScreen] frame].size.height - p.y);
|
||||
}
|
||||
|
||||
void Desktop::setMousePosition (int x, int y) throw()
|
||||
{
|
||||
// this rubbish needs to be done around the warp call, to avoid causing a
|
||||
// bizarre glitch..
|
||||
CGAssociateMouseAndMouseCursorPosition (false);
|
||||
CGSetLocalEventsSuppressionInterval (0);
|
||||
|
||||
CGPoint pos = { x, y };
|
||||
CGWarpMouseCursorPosition (pos);
|
||||
|
||||
CGAssociateMouseAndMouseCursorPosition (true);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
class ScreenSaverDefeater : public Timer,
|
||||
public DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
ScreenSaverDefeater() throw()
|
||||
{
|
||||
startTimer (10000);
|
||||
timerCallback();
|
||||
}
|
||||
|
||||
~ScreenSaverDefeater() {}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
if (Process::isForegroundProcess())
|
||||
UpdateSystemActivity (UsrActivity);
|
||||
}
|
||||
};
|
||||
|
||||
static ScreenSaverDefeater* screenSaverDefeater = 0;
|
||||
|
||||
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
|
||||
{
|
||||
if (screenSaverDefeater == 0)
|
||||
screenSaverDefeater = new ScreenSaverDefeater();
|
||||
}
|
||||
|
||||
bool Desktop::isScreenSaverEnabled() throw()
|
||||
{
|
||||
return screenSaverDefeater == 0;
|
||||
}
|
||||
|
||||
#else
|
||||
//==============================================================================
|
||||
static IOPMAssertionID screenSaverDisablerID = 0;
|
||||
|
||||
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
if (screenSaverDisablerID != 0)
|
||||
{
|
||||
IOPMAssertionRelease (screenSaverDisablerID);
|
||||
screenSaverDisablerID = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screenSaverDisablerID == 0)
|
||||
{
|
||||
IOPMAssertionCreate (kIOPMAssertionTypeNoIdleSleep,
|
||||
kIOPMAssertionLevelOn, &screenSaverDisablerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Desktop::isScreenSaverEnabled() throw()
|
||||
{
|
||||
return screenSaverDisablerID == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
monitorCoords.clear();
|
||||
NSArray* screens = [NSScreen screens];
|
||||
const float mainScreenBottom = [[NSScreen mainScreen] frame].size.height;
|
||||
|
||||
for (int i = 0; i < [screens count]; ++i)
|
||||
{
|
||||
NSScreen* s = (NSScreen*) [screens objectAtIndex: i];
|
||||
|
||||
NSRect r = clipToWorkArea ? [s visibleFrame]
|
||||
: [s frame];
|
||||
|
||||
monitorCoords.add (Rectangle ((int) r.origin.x,
|
||||
(int) (mainScreenBottom - (r.origin.y + r.size.height)),
|
||||
(int) r.size.width,
|
||||
(int) r.size.height));
|
||||
}
|
||||
|
||||
jassert (monitorCoords.size() > 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
ScopedAutoReleasePool::ScopedAutoReleasePool()
|
||||
{
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
ScopedAutoReleasePool::~ScopedAutoReleasePool()
|
||||
{
|
||||
[((NSAutoreleasePool*) pool) release];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PlatformUtilities::beep()
|
||||
{
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool AlertWindow::showNativeDialogBox (const String& title,
|
||||
const String& bodyText,
|
||||
bool isOkCancel)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
return NSRunAlertPanel (juceStringToNS (title),
|
||||
juceStringToNS (bodyText),
|
||||
@"Ok",
|
||||
isOkCancel ? @"Cancel" : nil,
|
||||
nil) == 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
return false;
|
||||
|
||||
Component* sourceComp = Component::getComponentUnderMouse();
|
||||
|
||||
if (sourceComp == 0)
|
||||
{
|
||||
jassertfalse // this method must be called in response to a
|
||||
// component's mouseDrag event!
|
||||
return false;
|
||||
}
|
||||
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSView* view = (NSView*) sourceComp->getWindowHandle();
|
||||
|
||||
if (view == 0)
|
||||
return false;
|
||||
|
||||
NSPasteboard* pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
|
||||
[pboard declareTypes: [NSArray arrayWithObject: NSFilenamesPboardType]
|
||||
owner: nil];
|
||||
|
||||
NSMutableArray* filesArray = [NSMutableArray arrayWithCapacity: 4];
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
[filesArray addObject: juceStringToNS (files[i])];
|
||||
|
||||
[pboard setPropertyList: filesArray
|
||||
forType: NSFilenamesPboardType];
|
||||
|
||||
NSPoint dragPosition = [view convertPoint: [[[view window] currentEvent] locationInWindow]
|
||||
fromView: nil];
|
||||
dragPosition.x -= 16;
|
||||
dragPosition.y -= 16;
|
||||
|
||||
[view dragImage: [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (files[0])]
|
||||
at: dragPosition
|
||||
offset: NSMakeSize (0, 0)
|
||||
event: [[view window] currentEvent]
|
||||
pasteboard: pboard
|
||||
source: view
|
||||
slideBack: YES];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
||||
{
|
||||
jassertfalse // not implemented!
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Desktop::canUseSemiTransparentWindows() throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Desktop::getMousePosition (int& x, int& y) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
const NSPoint p ([NSEvent mouseLocation]);
|
||||
x = roundFloatToInt (p.x);
|
||||
y = roundFloatToInt ([[NSScreen mainScreen] frame].size.height - p.y);
|
||||
}
|
||||
|
||||
void Desktop::setMousePosition (int x, int y) throw()
|
||||
{
|
||||
// this rubbish needs to be done around the warp call, to avoid causing a
|
||||
// bizarre glitch..
|
||||
CGAssociateMouseAndMouseCursorPosition (false);
|
||||
CGSetLocalEventsSuppressionInterval (0);
|
||||
|
||||
CGPoint pos = { x, y };
|
||||
CGWarpMouseCursorPosition (pos);
|
||||
|
||||
CGAssociateMouseAndMouseCursorPosition (true);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
class ScreenSaverDefeater : public Timer,
|
||||
public DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
ScreenSaverDefeater() throw()
|
||||
{
|
||||
startTimer (10000);
|
||||
timerCallback();
|
||||
}
|
||||
|
||||
~ScreenSaverDefeater() {}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
if (Process::isForegroundProcess())
|
||||
UpdateSystemActivity (UsrActivity);
|
||||
}
|
||||
};
|
||||
|
||||
static ScreenSaverDefeater* screenSaverDefeater = 0;
|
||||
|
||||
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
|
||||
{
|
||||
if (screenSaverDefeater == 0)
|
||||
screenSaverDefeater = new ScreenSaverDefeater();
|
||||
}
|
||||
|
||||
bool Desktop::isScreenSaverEnabled() throw()
|
||||
{
|
||||
return screenSaverDefeater == 0;
|
||||
}
|
||||
|
||||
#else
|
||||
//==============================================================================
|
||||
static IOPMAssertionID screenSaverDisablerID = 0;
|
||||
|
||||
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
if (screenSaverDisablerID != 0)
|
||||
{
|
||||
IOPMAssertionRelease (screenSaverDisablerID);
|
||||
screenSaverDisablerID = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screenSaverDisablerID == 0)
|
||||
{
|
||||
IOPMAssertionCreate (kIOPMAssertionTypeNoIdleSleep,
|
||||
kIOPMAssertionLevelOn, &screenSaverDisablerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Desktop::isScreenSaverEnabled() throw()
|
||||
{
|
||||
return screenSaverDisablerID == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
monitorCoords.clear();
|
||||
NSArray* screens = [NSScreen screens];
|
||||
const float mainScreenBottom = [[NSScreen mainScreen] frame].size.height;
|
||||
|
||||
for (int i = 0; i < [screens count]; ++i)
|
||||
{
|
||||
NSScreen* s = (NSScreen*) [screens objectAtIndex: i];
|
||||
|
||||
NSRect r = clipToWorkArea ? [s visibleFrame]
|
||||
: [s frame];
|
||||
|
||||
monitorCoords.add (Rectangle ((int) r.origin.x,
|
||||
(int) (mainScreenBottom - (r.origin.y + r.size.height)),
|
||||
(int) r.size.width,
|
||||
(int) r.size.height));
|
||||
}
|
||||
|
||||
jassert (monitorCoords.size() > 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
@ -38,21 +38,21 @@ static NSImage* juceImageToNSImage (const Image& image)
|
|||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
int lineStride, pixelStride;
|
||||
const uint8* pixels = image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(),
|
||||
const uint8* pixels = image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(),
|
||||
lineStride, pixelStride);
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: image.getWidth()
|
||||
pixelsHigh: image.getHeight()
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
|
||||
hasAlpha: image.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: image.getWidth()
|
||||
pixelsHigh: image.getHeight()
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
|
||||
hasAlpha: image.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: lineStride
|
||||
bitsPerPixel: pixelStride * 8];
|
||||
bytesPerRow: lineStride
|
||||
bitsPerPixel: pixelStride * 8];
|
||||
|
||||
unsigned char* newData = [rep bitmapData];
|
||||
memcpy (newData, pixels, lineStride * image.getHeight());
|
||||
|
|
@ -69,7 +69,7 @@ static NSImage* juceImageToNSImage (const Image& image)
|
|||
void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
|
||||
{
|
||||
NSImage* im = juceImageToNSImage (image);
|
||||
NSCursor* c = [[NSCursor alloc] initWithImage: im
|
||||
NSCursor* c = [[NSCursor alloc] initWithImage: im
|
||||
hotSpot: NSMakePoint (hotspotX, hotspotY)];
|
||||
[im release];
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ static void* juce_cursorFromData (const unsigned char* data, const int size, flo
|
|||
if (im == 0)
|
||||
return 0;
|
||||
|
||||
void* const curs = juce_createMouseCursorFromImage (*im,
|
||||
void* const curs = juce_createMouseCursorFromImage (*im,
|
||||
(int) (hx * im->getWidth()),
|
||||
(int) (hy * im->getHeight()));
|
||||
delete im;
|
||||
|
|
@ -98,7 +98,7 @@ static void* juce_cursorFromWebKitFile (const char* filename, float hx, float hy
|
|||
MemoryBlock mb;
|
||||
if (f.getChildFile (filename).loadFileAsData (mb))
|
||||
return juce_cursorFromData ((const unsigned char*) mb.getData(), mb.getSize(), hx, hy);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
@ -67,12 +67,12 @@ public:
|
|||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
||||
{
|
||||
Component* const topComp = owner->getTopLevelComponent();
|
||||
|
||||
|
||||
if (topComp->getPeer() != 0)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
owner->relativePositionToOtherComponent (topComp, x, y);
|
||||
|
||||
|
||||
NSRect r;
|
||||
r.origin.x = (float) x;
|
||||
r.origin.y = (float) y;
|
||||
|
|
@ -87,7 +87,7 @@ public:
|
|||
void componentPeerChanged()
|
||||
{
|
||||
NSViewComponentPeer* const peer = dynamic_cast <NSViewComponentPeer*> (owner->getPeer());
|
||||
|
||||
|
||||
if (currentPeer != peer)
|
||||
{
|
||||
[view removeFromSuperview];
|
||||
|
|
|
|||
|
|
@ -1,117 +1,117 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
This file wraps together all the mac-specific code, so that
|
||||
we can include all the native headers just once, and compile all our
|
||||
platform-specific stuff in one big lump, keeping it out of the way of
|
||||
the rest of the codebase.
|
||||
*/
|
||||
|
||||
#include "juce_mac_NativeIncludes.h"
|
||||
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
#include "../../../src/juce_core/basics/juce_Singleton.h"
|
||||
#include "../../../src/juce_core/basics/juce_Random.h"
|
||||
#include "../../../src/juce_core/basics/juce_SystemStats.h"
|
||||
#include "../../../src/juce_core/threads/juce_Process.h"
|
||||
#include "../../../src/juce_core/threads/juce_Thread.h"
|
||||
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
|
||||
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
|
||||
#include "../../../src/juce_core/io/network/juce_URL.h"
|
||||
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../src/juce_core/text/juce_LocalisedStrings.h"
|
||||
#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
|
||||
#include "../../../src/juce_appframework/application/juce_Application.h"
|
||||
#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"
|
||||
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
|
||||
#include "../../../src/juce_appframework/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
|
||||
#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h"
|
||||
#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
|
||||
#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
|
||||
#include "../../../src/juce_appframework/gui/components/menus/juce_MenuBarModel.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
|
||||
#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPressMappingSet.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_NSViewComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
|
||||
#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h"
|
||||
#include "../../../src/juce_appframework/audio/audio_sources/juce_AudioSource.h"
|
||||
#include "../../../src/juce_appframework/audio/dsp/juce_AudioDataConverters.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_MidiOutput.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
|
||||
#undef Point
|
||||
|
||||
//==============================================================================
|
||||
#define ObjCExtraSuffix 1
|
||||
#define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
|
||||
#define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d)
|
||||
#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, ObjCExtraSuffix)
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_INCLUDED_FILE 1
|
||||
|
||||
// Now include the actual code files..
|
||||
|
||||
#include "juce_mac_Strings.mm"
|
||||
#include "juce_mac_SystemStats.mm"
|
||||
#include "juce_mac_Network.mm"
|
||||
#include "juce_mac_Threads.mm"
|
||||
#include "juce_posix_SharedCode.h"
|
||||
#include "juce_mac_Files.mm"
|
||||
#include "juce_mac_MiscUtilities.mm"
|
||||
#include "juce_mac_Debugging.mm"
|
||||
|
||||
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
#include "juce_mac_NSViewComponentPeer.mm"
|
||||
#include "juce_mac_MouseCursor.mm"
|
||||
#include "juce_mac_NSViewComponent.mm"
|
||||
#include "juce_mac_AppleRemote.mm"
|
||||
#include "juce_mac_OpenGLComponent.mm"
|
||||
#include "juce_mac_MainMenu.mm"
|
||||
#include "juce_mac_FileChooser.mm"
|
||||
#include "juce_mac_QuickTimeMovieComponent.mm"
|
||||
#include "juce_mac_AudioCDBurner.mm"
|
||||
#include "juce_mac_Fonts.mm"
|
||||
#include "juce_mac_MessageManager.mm"
|
||||
#include "juce_mac_WebBrowserComponent.mm"
|
||||
#include "juce_mac_CoreAudio.cpp"
|
||||
#include "juce_mac_CoreMidi.cpp"
|
||||
#endif
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
This file wraps together all the mac-specific code, so that
|
||||
we can include all the native headers just once, and compile all our
|
||||
platform-specific stuff in one big lump, keeping it out of the way of
|
||||
the rest of the codebase.
|
||||
*/
|
||||
|
||||
#include "juce_mac_NativeIncludes.h"
|
||||
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
#include "../../../src/juce_core/basics/juce_Singleton.h"
|
||||
#include "../../../src/juce_core/basics/juce_Random.h"
|
||||
#include "../../../src/juce_core/basics/juce_SystemStats.h"
|
||||
#include "../../../src/juce_core/threads/juce_Process.h"
|
||||
#include "../../../src/juce_core/threads/juce_Thread.h"
|
||||
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
|
||||
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
|
||||
#include "../../../src/juce_core/io/network/juce_URL.h"
|
||||
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../src/juce_core/text/juce_LocalisedStrings.h"
|
||||
#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
|
||||
#include "../../../src/juce_appframework/application/juce_Application.h"
|
||||
#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"
|
||||
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
|
||||
#include "../../../src/juce_appframework/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
|
||||
#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h"
|
||||
#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
|
||||
#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
|
||||
#include "../../../src/juce_appframework/gui/components/menus/juce_MenuBarModel.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
|
||||
#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPressMappingSet.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_NSViewComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h"
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
|
||||
#include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
|
||||
#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h"
|
||||
#include "../../../src/juce_appframework/audio/audio_sources/juce_AudioSource.h"
|
||||
#include "../../../src/juce_appframework/audio/dsp/juce_AudioDataConverters.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_MidiOutput.h"
|
||||
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
|
||||
#undef Point
|
||||
|
||||
//==============================================================================
|
||||
#define ObjCExtraSuffix 1
|
||||
#define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
|
||||
#define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d)
|
||||
#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, ObjCExtraSuffix)
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_INCLUDED_FILE 1
|
||||
|
||||
// Now include the actual code files..
|
||||
|
||||
#include "juce_mac_Strings.mm"
|
||||
#include "juce_mac_SystemStats.mm"
|
||||
#include "juce_mac_Network.mm"
|
||||
#include "juce_mac_Threads.mm"
|
||||
#include "juce_posix_SharedCode.h"
|
||||
#include "juce_mac_Files.mm"
|
||||
#include "juce_mac_MiscUtilities.mm"
|
||||
#include "juce_mac_Debugging.mm"
|
||||
|
||||
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
#include "juce_mac_NSViewComponentPeer.mm"
|
||||
#include "juce_mac_MouseCursor.mm"
|
||||
#include "juce_mac_NSViewComponent.mm"
|
||||
#include "juce_mac_AppleRemote.mm"
|
||||
#include "juce_mac_OpenGLComponent.mm"
|
||||
#include "juce_mac_MainMenu.mm"
|
||||
#include "juce_mac_FileChooser.mm"
|
||||
#include "juce_mac_QuickTimeMovieComponent.mm"
|
||||
#include "juce_mac_AudioCDBurner.mm"
|
||||
#include "juce_mac_Fonts.mm"
|
||||
#include "juce_mac_MessageManager.mm"
|
||||
#include "juce_mac_WebBrowserComponent.mm"
|
||||
#include "juce_mac_CoreAudio.cpp"
|
||||
#include "juce_mac_CoreMidi.cpp"
|
||||
#endif
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,464 +1,464 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
static bool getEthernetIterator (io_iterator_t* matchingServices) throw()
|
||||
{
|
||||
mach_port_t masterPort;
|
||||
|
||||
if (IOMasterPort (MACH_PORT_NULL, &masterPort) == KERN_SUCCESS)
|
||||
{
|
||||
CFMutableDictionaryRef dict = IOServiceMatching (kIOEthernetInterfaceClass);
|
||||
|
||||
if (dict != 0)
|
||||
{
|
||||
CFMutableDictionaryRef propDict = CFDictionaryCreateMutable (kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
if (propDict != 0)
|
||||
{
|
||||
CFDictionarySetValue (propDict, CFSTR (kIOPrimaryInterface), kCFBooleanTrue);
|
||||
|
||||
CFDictionarySetValue (dict, CFSTR (kIOPropertyMatchKey), propDict);
|
||||
CFRelease (propDict);
|
||||
}
|
||||
}
|
||||
|
||||
return IOServiceGetMatchingServices (masterPort, dict, matchingServices) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
|
||||
{
|
||||
int numResults = 0;
|
||||
io_iterator_t it;
|
||||
|
||||
if (getEthernetIterator (&it))
|
||||
{
|
||||
io_object_t i;
|
||||
|
||||
while ((i = IOIteratorNext (it)) != 0)
|
||||
{
|
||||
io_object_t controller;
|
||||
|
||||
if (IORegistryEntryGetParentEntry (i, kIOServicePlane, &controller) == KERN_SUCCESS)
|
||||
{
|
||||
CFTypeRef data = IORegistryEntryCreateCFProperty (controller,
|
||||
CFSTR (kIOMACAddress),
|
||||
kCFAllocatorDefault,
|
||||
0);
|
||||
if (data != 0)
|
||||
{
|
||||
UInt8 addr [kIOEthernetAddressSize];
|
||||
zeromem (addr, sizeof (addr));
|
||||
|
||||
CFDataGetBytes ((CFDataRef) data, CFRangeMake (0, sizeof (addr)), addr);
|
||||
CFRelease (data);
|
||||
|
||||
int64 a = 0;
|
||||
for (int i = 6; --i >= 0;)
|
||||
a = (a << 8) | addr[i];
|
||||
|
||||
if (! littleEndian)
|
||||
a = (int64) swapByteOrder ((uint64) a);
|
||||
|
||||
if (numResults < maxNum)
|
||||
{
|
||||
*addresses++ = a;
|
||||
++numResults;
|
||||
}
|
||||
}
|
||||
|
||||
IOObjectRelease (controller);
|
||||
}
|
||||
|
||||
IOObjectRelease (i);
|
||||
}
|
||||
|
||||
IOObjectRelease (it);
|
||||
}
|
||||
|
||||
return numResults;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
|
||||
const String& emailSubject,
|
||||
const String& bodyText,
|
||||
const StringArray& filesToAttach)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
String script;
|
||||
script << "tell application \"Mail\"\r\n"
|
||||
"set newMessage to make new outgoing message with properties {subject:\""
|
||||
<< emailSubject.replace (T("\""), T("\\\""))
|
||||
<< "\", content:\""
|
||||
<< bodyText.replace (T("\""), T("\\\""))
|
||||
<< "\" & return & return}\r\n"
|
||||
"tell newMessage\r\n"
|
||||
"set visible to true\r\n"
|
||||
"set sender to \"sdfsdfsdfewf\"\r\n"
|
||||
"make new to recipient at end of to recipients with properties {address:\""
|
||||
<< targetEmailAddress
|
||||
<< "\"}\r\n";
|
||||
|
||||
for (int i = 0; i < filesToAttach.size(); ++i)
|
||||
{
|
||||
script << "tell content\r\n"
|
||||
"make new attachment with properties {file name:\""
|
||||
<< filesToAttach[i].replace (T("\""), T("\\\""))
|
||||
<< "\"} at after the last paragraph\r\n"
|
||||
"end tell\r\n";
|
||||
}
|
||||
|
||||
script << "end tell\r\n"
|
||||
"end tell\r\n";
|
||||
|
||||
NSAppleScript* s = [[NSAppleScript alloc]
|
||||
initWithSource: juceStringToNS (script)];
|
||||
NSDictionary* error = 0;
|
||||
const bool ok = [s executeAndReturnError: &error] != nil;
|
||||
[s release];
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
//==============================================================================
|
||||
#define JuceURLConnection MakeObjCClassName(JuceURLConnection)
|
||||
|
||||
@interface JuceURLConnection : NSObject
|
||||
{
|
||||
NSURLRequest* request;
|
||||
NSURLConnection* connection;
|
||||
NSMutableData* data;
|
||||
Thread* runLoopThread;
|
||||
bool initialised, hasFailed, hasFinished;
|
||||
int position;
|
||||
NSLock* dataLock;
|
||||
}
|
||||
|
||||
- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req withCallback: (URL::OpenStreamProgressCallback*) callback withContext: (void*) context;
|
||||
- (void) dealloc;
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response;
|
||||
- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error;
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) data;
|
||||
- (void) connectionDidFinishLoading: (NSURLConnection*) connection;
|
||||
|
||||
- (BOOL) isOpen;
|
||||
- (int) read: (char*) dest numBytes: (int) num;
|
||||
- (int) readPosition;
|
||||
- (void) stop;
|
||||
- (void) createConnection;
|
||||
|
||||
@end
|
||||
|
||||
class JuceURLConnectionMessageThread : public Thread
|
||||
{
|
||||
JuceURLConnection* owner;
|
||||
|
||||
public:
|
||||
JuceURLConnectionMessageThread (JuceURLConnection* owner_)
|
||||
: Thread (T("http connection")),
|
||||
owner (owner_)
|
||||
{
|
||||
startThread();
|
||||
}
|
||||
|
||||
~JuceURLConnectionMessageThread()
|
||||
{
|
||||
stopThread (10000);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
[owner createConnection];
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@implementation JuceURLConnection
|
||||
|
||||
- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req
|
||||
withCallback: (URL::OpenStreamProgressCallback*) callback
|
||||
withContext: (void*) context;
|
||||
{
|
||||
[super init];
|
||||
request = req;
|
||||
[request retain];
|
||||
data = [[NSMutableData data] retain];
|
||||
dataLock = [[NSLock alloc] init];
|
||||
connection = 0;
|
||||
initialised = false;
|
||||
hasFailed = false;
|
||||
hasFinished = false;
|
||||
|
||||
runLoopThread = new JuceURLConnectionMessageThread (self);
|
||||
|
||||
while (runLoopThread->isThreadRunning() && ! initialised)
|
||||
{
|
||||
if (callback != 0)
|
||||
callback (context, -1, [[request HTTPBody] length]);
|
||||
|
||||
Thread::sleep (1);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self stop];
|
||||
|
||||
delete runLoopThread;
|
||||
[connection release];
|
||||
[data release];
|
||||
[dataLock release];
|
||||
[request release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) createConnection
|
||||
{
|
||||
connection = [[NSURLConnection alloc] initWithRequest: request
|
||||
delegate: self];
|
||||
|
||||
if (connection == nil)
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response
|
||||
{
|
||||
[dataLock lock];
|
||||
[data setLength: 0];
|
||||
[dataLock unlock];
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error
|
||||
{
|
||||
NSLog ([error description]);
|
||||
hasFailed = true;
|
||||
initialised = true;
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) newData
|
||||
{
|
||||
[dataLock lock];
|
||||
[data appendData: newData];
|
||||
[dataLock unlock];
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
|
||||
{
|
||||
hasFinished = true;
|
||||
initialised = true;
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (BOOL) isOpen
|
||||
{
|
||||
return connection != 0 && ! hasFailed;
|
||||
}
|
||||
|
||||
- (int) readPosition
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
- (int) read: (char*) dest numBytes: (int) numNeeded
|
||||
{
|
||||
int numDone = 0;
|
||||
|
||||
while (numNeeded > 0)
|
||||
{
|
||||
int available = jmin (numNeeded, [data length]);
|
||||
|
||||
if (available > 0)
|
||||
{
|
||||
[dataLock lock];
|
||||
[data getBytes: dest length: available];
|
||||
[data replaceBytesInRange: NSMakeRange (0, available) withBytes: nil length: 0];
|
||||
[dataLock unlock];
|
||||
|
||||
numDone += available;
|
||||
numNeeded -= available;
|
||||
dest += available;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasFailed || hasFinished)
|
||||
break;
|
||||
|
||||
Thread::sleep (1);
|
||||
}
|
||||
}
|
||||
|
||||
position += numDone;
|
||||
return numDone;
|
||||
}
|
||||
|
||||
- (void) stop
|
||||
{
|
||||
[connection cancel];
|
||||
runLoopThread->stopThread (10000);
|
||||
}
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
bool juce_isOnLine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* juce_openInternetFile (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext,
|
||||
int timeOutMs)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMutableURLRequest* req = [NSMutableURLRequest
|
||||
requestWithURL: [NSURL URLWithString: juceStringToNS (url)]
|
||||
cachePolicy: NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval: timeOutMs <= 0 ? 60.0 : (timeOutMs / 1000.0)];
|
||||
|
||||
if (req == nil)
|
||||
return 0;
|
||||
|
||||
[req setHTTPMethod: isPost ? @"POST" : @"GET"];
|
||||
//[req setCachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
|
||||
|
||||
StringArray headerLines;
|
||||
headerLines.addLines (headers);
|
||||
headerLines.removeEmptyStrings (true);
|
||||
|
||||
for (int i = 0; i < headerLines.size(); ++i)
|
||||
{
|
||||
const String key (headerLines[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
|
||||
const String value (headerLines[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
|
||||
|
||||
if (key.isNotEmpty() && value.isNotEmpty())
|
||||
[req addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)];
|
||||
}
|
||||
|
||||
if (isPost && postData.getSize() > 0)
|
||||
{
|
||||
[req setHTTPBody: [NSData dataWithBytes: postData.getData()
|
||||
length: postData.getSize()]];
|
||||
}
|
||||
|
||||
JuceURLConnection* const s = [[JuceURLConnection alloc] initWithRequest: req
|
||||
withCallback: callback
|
||||
withContext: callbackContext];
|
||||
|
||||
if ([s isOpen])
|
||||
return s;
|
||||
|
||||
[s release];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
[s stop];
|
||||
[s release];
|
||||
}
|
||||
}
|
||||
|
||||
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
return [s read: (char*) buffer numBytes: bytesToRead];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_getInternetFileContentLength (void* handle)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
//xxx todo
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_seekInInternetFile (void* handle, int newPosition)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return [s readPosition];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
static bool getEthernetIterator (io_iterator_t* matchingServices) throw()
|
||||
{
|
||||
mach_port_t masterPort;
|
||||
|
||||
if (IOMasterPort (MACH_PORT_NULL, &masterPort) == KERN_SUCCESS)
|
||||
{
|
||||
CFMutableDictionaryRef dict = IOServiceMatching (kIOEthernetInterfaceClass);
|
||||
|
||||
if (dict != 0)
|
||||
{
|
||||
CFMutableDictionaryRef propDict = CFDictionaryCreateMutable (kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
if (propDict != 0)
|
||||
{
|
||||
CFDictionarySetValue (propDict, CFSTR (kIOPrimaryInterface), kCFBooleanTrue);
|
||||
|
||||
CFDictionarySetValue (dict, CFSTR (kIOPropertyMatchKey), propDict);
|
||||
CFRelease (propDict);
|
||||
}
|
||||
}
|
||||
|
||||
return IOServiceGetMatchingServices (masterPort, dict, matchingServices) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
|
||||
{
|
||||
int numResults = 0;
|
||||
io_iterator_t it;
|
||||
|
||||
if (getEthernetIterator (&it))
|
||||
{
|
||||
io_object_t i;
|
||||
|
||||
while ((i = IOIteratorNext (it)) != 0)
|
||||
{
|
||||
io_object_t controller;
|
||||
|
||||
if (IORegistryEntryGetParentEntry (i, kIOServicePlane, &controller) == KERN_SUCCESS)
|
||||
{
|
||||
CFTypeRef data = IORegistryEntryCreateCFProperty (controller,
|
||||
CFSTR (kIOMACAddress),
|
||||
kCFAllocatorDefault,
|
||||
0);
|
||||
if (data != 0)
|
||||
{
|
||||
UInt8 addr [kIOEthernetAddressSize];
|
||||
zeromem (addr, sizeof (addr));
|
||||
|
||||
CFDataGetBytes ((CFDataRef) data, CFRangeMake (0, sizeof (addr)), addr);
|
||||
CFRelease (data);
|
||||
|
||||
int64 a = 0;
|
||||
for (int i = 6; --i >= 0;)
|
||||
a = (a << 8) | addr[i];
|
||||
|
||||
if (! littleEndian)
|
||||
a = (int64) swapByteOrder ((uint64) a);
|
||||
|
||||
if (numResults < maxNum)
|
||||
{
|
||||
*addresses++ = a;
|
||||
++numResults;
|
||||
}
|
||||
}
|
||||
|
||||
IOObjectRelease (controller);
|
||||
}
|
||||
|
||||
IOObjectRelease (i);
|
||||
}
|
||||
|
||||
IOObjectRelease (it);
|
||||
}
|
||||
|
||||
return numResults;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
|
||||
const String& emailSubject,
|
||||
const String& bodyText,
|
||||
const StringArray& filesToAttach)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
String script;
|
||||
script << "tell application \"Mail\"\r\n"
|
||||
"set newMessage to make new outgoing message with properties {subject:\""
|
||||
<< emailSubject.replace (T("\""), T("\\\""))
|
||||
<< "\", content:\""
|
||||
<< bodyText.replace (T("\""), T("\\\""))
|
||||
<< "\" & return & return}\r\n"
|
||||
"tell newMessage\r\n"
|
||||
"set visible to true\r\n"
|
||||
"set sender to \"sdfsdfsdfewf\"\r\n"
|
||||
"make new to recipient at end of to recipients with properties {address:\""
|
||||
<< targetEmailAddress
|
||||
<< "\"}\r\n";
|
||||
|
||||
for (int i = 0; i < filesToAttach.size(); ++i)
|
||||
{
|
||||
script << "tell content\r\n"
|
||||
"make new attachment with properties {file name:\""
|
||||
<< filesToAttach[i].replace (T("\""), T("\\\""))
|
||||
<< "\"} at after the last paragraph\r\n"
|
||||
"end tell\r\n";
|
||||
}
|
||||
|
||||
script << "end tell\r\n"
|
||||
"end tell\r\n";
|
||||
|
||||
NSAppleScript* s = [[NSAppleScript alloc]
|
||||
initWithSource: juceStringToNS (script)];
|
||||
NSDictionary* error = 0;
|
||||
const bool ok = [s executeAndReturnError: &error] != nil;
|
||||
[s release];
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
//==============================================================================
|
||||
#define JuceURLConnection MakeObjCClassName(JuceURLConnection)
|
||||
|
||||
@interface JuceURLConnection : NSObject
|
||||
{
|
||||
NSURLRequest* request;
|
||||
NSURLConnection* connection;
|
||||
NSMutableData* data;
|
||||
Thread* runLoopThread;
|
||||
bool initialised, hasFailed, hasFinished;
|
||||
int position;
|
||||
NSLock* dataLock;
|
||||
}
|
||||
|
||||
- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req withCallback: (URL::OpenStreamProgressCallback*) callback withContext: (void*) context;
|
||||
- (void) dealloc;
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response;
|
||||
- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error;
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) data;
|
||||
- (void) connectionDidFinishLoading: (NSURLConnection*) connection;
|
||||
|
||||
- (BOOL) isOpen;
|
||||
- (int) read: (char*) dest numBytes: (int) num;
|
||||
- (int) readPosition;
|
||||
- (void) stop;
|
||||
- (void) createConnection;
|
||||
|
||||
@end
|
||||
|
||||
class JuceURLConnectionMessageThread : public Thread
|
||||
{
|
||||
JuceURLConnection* owner;
|
||||
|
||||
public:
|
||||
JuceURLConnectionMessageThread (JuceURLConnection* owner_)
|
||||
: Thread (T("http connection")),
|
||||
owner (owner_)
|
||||
{
|
||||
startThread();
|
||||
}
|
||||
|
||||
~JuceURLConnectionMessageThread()
|
||||
{
|
||||
stopThread (10000);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
[owner createConnection];
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@implementation JuceURLConnection
|
||||
|
||||
- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req
|
||||
withCallback: (URL::OpenStreamProgressCallback*) callback
|
||||
withContext: (void*) context;
|
||||
{
|
||||
[super init];
|
||||
request = req;
|
||||
[request retain];
|
||||
data = [[NSMutableData data] retain];
|
||||
dataLock = [[NSLock alloc] init];
|
||||
connection = 0;
|
||||
initialised = false;
|
||||
hasFailed = false;
|
||||
hasFinished = false;
|
||||
|
||||
runLoopThread = new JuceURLConnectionMessageThread (self);
|
||||
|
||||
while (runLoopThread->isThreadRunning() && ! initialised)
|
||||
{
|
||||
if (callback != 0)
|
||||
callback (context, -1, [[request HTTPBody] length]);
|
||||
|
||||
Thread::sleep (1);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self stop];
|
||||
|
||||
delete runLoopThread;
|
||||
[connection release];
|
||||
[data release];
|
||||
[dataLock release];
|
||||
[request release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) createConnection
|
||||
{
|
||||
connection = [[NSURLConnection alloc] initWithRequest: request
|
||||
delegate: self];
|
||||
|
||||
if (connection == nil)
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response
|
||||
{
|
||||
[dataLock lock];
|
||||
[data setLength: 0];
|
||||
[dataLock unlock];
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error
|
||||
{
|
||||
NSLog ([error description]);
|
||||
hasFailed = true;
|
||||
initialised = true;
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) newData
|
||||
{
|
||||
[dataLock lock];
|
||||
[data appendData: newData];
|
||||
[dataLock unlock];
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
|
||||
{
|
||||
hasFinished = true;
|
||||
initialised = true;
|
||||
runLoopThread->signalThreadShouldExit();
|
||||
}
|
||||
|
||||
- (BOOL) isOpen
|
||||
{
|
||||
return connection != 0 && ! hasFailed;
|
||||
}
|
||||
|
||||
- (int) readPosition
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
- (int) read: (char*) dest numBytes: (int) numNeeded
|
||||
{
|
||||
int numDone = 0;
|
||||
|
||||
while (numNeeded > 0)
|
||||
{
|
||||
int available = jmin (numNeeded, [data length]);
|
||||
|
||||
if (available > 0)
|
||||
{
|
||||
[dataLock lock];
|
||||
[data getBytes: dest length: available];
|
||||
[data replaceBytesInRange: NSMakeRange (0, available) withBytes: nil length: 0];
|
||||
[dataLock unlock];
|
||||
|
||||
numDone += available;
|
||||
numNeeded -= available;
|
||||
dest += available;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasFailed || hasFinished)
|
||||
break;
|
||||
|
||||
Thread::sleep (1);
|
||||
}
|
||||
}
|
||||
|
||||
position += numDone;
|
||||
return numDone;
|
||||
}
|
||||
|
||||
- (void) stop
|
||||
{
|
||||
[connection cancel];
|
||||
runLoopThread->stopThread (10000);
|
||||
}
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
bool juce_isOnLine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* juce_openInternetFile (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext,
|
||||
int timeOutMs)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMutableURLRequest* req = [NSMutableURLRequest
|
||||
requestWithURL: [NSURL URLWithString: juceStringToNS (url)]
|
||||
cachePolicy: NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval: timeOutMs <= 0 ? 60.0 : (timeOutMs / 1000.0)];
|
||||
|
||||
if (req == nil)
|
||||
return 0;
|
||||
|
||||
[req setHTTPMethod: isPost ? @"POST" : @"GET"];
|
||||
//[req setCachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
|
||||
|
||||
StringArray headerLines;
|
||||
headerLines.addLines (headers);
|
||||
headerLines.removeEmptyStrings (true);
|
||||
|
||||
for (int i = 0; i < headerLines.size(); ++i)
|
||||
{
|
||||
const String key (headerLines[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
|
||||
const String value (headerLines[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
|
||||
|
||||
if (key.isNotEmpty() && value.isNotEmpty())
|
||||
[req addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)];
|
||||
}
|
||||
|
||||
if (isPost && postData.getSize() > 0)
|
||||
{
|
||||
[req setHTTPBody: [NSData dataWithBytes: postData.getData()
|
||||
length: postData.getSize()]];
|
||||
}
|
||||
|
||||
JuceURLConnection* const s = [[JuceURLConnection alloc] initWithRequest: req
|
||||
withCallback: callback
|
||||
withContext: callbackContext];
|
||||
|
||||
if ([s isOpen])
|
||||
return s;
|
||||
|
||||
[s release];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
[s stop];
|
||||
[s release];
|
||||
}
|
||||
}
|
||||
|
||||
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
return [s read: (char*) buffer numBytes: bytesToRead];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_getInternetFileContentLength (void* handle)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
{
|
||||
//xxx todo
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_seekInInternetFile (void* handle, int newPosition)
|
||||
{
|
||||
JuceURLConnection* const s = (JuceURLConnection*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return [s readPosition];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,246 +1,246 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_OPENGL
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class WindowedGLContext : public OpenGLContext
|
||||
{
|
||||
public:
|
||||
WindowedGLContext (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat_,
|
||||
NSOpenGLContext* sharedContext)
|
||||
: renderContext (0),
|
||||
pixelFormat (pixelFormat_)
|
||||
{
|
||||
jassert (component != 0);
|
||||
|
||||
NSOpenGLPixelFormatAttribute attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = NSOpenGLPFADoubleBuffer;
|
||||
attribs[n++] = NSOpenGLPFAAccelerated;
|
||||
attribs[n++] = NSOpenGLPFAColorSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
|
||||
pixelFormat.greenBits,
|
||||
pixelFormat.blueBits);
|
||||
attribs[n++] = NSOpenGLPFAAlphaSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.alphaBits;
|
||||
attribs[n++] = NSOpenGLPFADepthSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.depthBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAStencilSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.stencilBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAAccumSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.accumulationBufferRedBits,
|
||||
pixelFormat.accumulationBufferGreenBits,
|
||||
pixelFormat.accumulationBufferBlueBits,
|
||||
pixelFormat.accumulationBufferAlphaBits);
|
||||
|
||||
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
|
||||
|
||||
attribs[n++] = NSOpenGLPFASampleBuffers;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
attribs[n++] = NSOpenGLPFAClosestPolicy;
|
||||
attribs[n++] = NSOpenGLPFANoRecovery;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
NSOpenGLPixelFormat* format
|
||||
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
|
||||
|
||||
NSOpenGLView* view
|
||||
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
|
||||
pixelFormat: format];
|
||||
|
||||
if (sharedContext != 0)
|
||||
{
|
||||
renderContext = [[NSOpenGLContext alloc] initWithFormat: format
|
||||
shareContext: sharedContext];
|
||||
[view setOpenGLContext: renderContext];
|
||||
[renderContext setView: view];
|
||||
}
|
||||
else
|
||||
{
|
||||
renderContext = [view openGLContext];
|
||||
}
|
||||
|
||||
[format release];
|
||||
|
||||
viewHolder = new NSViewComponentInternal (view, component);
|
||||
}
|
||||
|
||||
~WindowedGLContext()
|
||||
{
|
||||
makeInactive();
|
||||
[renderContext setView: nil];
|
||||
delete viewHolder;
|
||||
}
|
||||
|
||||
bool makeActive() const throw()
|
||||
{
|
||||
jassert (renderContext != 0);
|
||||
[renderContext makeCurrentContext];
|
||||
return renderContext != 0;
|
||||
}
|
||||
|
||||
bool makeInactive() const throw()
|
||||
{
|
||||
if (! isActive())
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive() const throw()
|
||||
{
|
||||
return [NSOpenGLContext currentContext] == renderContext;
|
||||
}
|
||||
|
||||
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
|
||||
void* getRawContext() const throw() { return renderContext; }
|
||||
|
||||
void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
|
||||
{
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
glFlush();
|
||||
[renderContext flushBuffer];
|
||||
}
|
||||
|
||||
bool setSwapInterval (const int numFramesPerSwap)
|
||||
{
|
||||
[renderContext setValues: (const GLint*) &numFramesPerSwap
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return true;
|
||||
}
|
||||
|
||||
int getSwapInterval() const
|
||||
{
|
||||
GLint numFrames = 0;
|
||||
[renderContext getValues: &numFrames
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
void repaint()
|
||||
{
|
||||
// we need to invalidate the juce view that holds this gl view, to make it
|
||||
// cause a repaint callback
|
||||
NSView* v = (NSView*) viewHolder->view;
|
||||
NSRect r = [v frame];
|
||||
|
||||
// bit of a bodge here.. if we only invalidate the area of the gl component,
|
||||
// it's completely covered by the NSOpenGLView, so the OS throws away the
|
||||
// repaint message, thus never causing our paint() callback, and never repainting
|
||||
// the comp. So invalidating just a little bit around the edge helps..
|
||||
[[v superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
|
||||
}
|
||||
|
||||
void* getNativeWindowHandle() const { return viewHolder->view; }
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
NSOpenGLContext* renderContext;
|
||||
|
||||
private:
|
||||
OpenGLPixelFormat pixelFormat;
|
||||
NSViewComponentInternal* viewHolder;
|
||||
|
||||
//==============================================================================
|
||||
WindowedGLContext (const WindowedGLContext&);
|
||||
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat,
|
||||
const OpenGLContext* const contextToShareWith)
|
||||
{
|
||||
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||
contextToShareWith != 0 ? (NSOpenGLContext*) contextToShareWith->getRawContext() : 0);
|
||||
|
||||
if (c->renderContext == 0)
|
||||
deleteAndZero (c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void* OpenGLComponent::getNativeWindowHandle() const
|
||||
{
|
||||
return context != 0 ? ((WindowedGLContext*) context)->getNativeWindowHandle()
|
||||
: 0;
|
||||
}
|
||||
|
||||
void juce_glViewport (const int w, const int h)
|
||||
{
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
|
||||
OwnedArray <OpenGLPixelFormat>& results)
|
||||
{
|
||||
/* GLint attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = AGL_RGBA;
|
||||
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||
attribs[n++] = AGL_ACCELERATED;
|
||||
attribs[n++] = AGL_NO_RECOVERY;
|
||||
attribs[n++] = AGL_NONE;
|
||||
|
||||
AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
|
||||
|
||||
while (p != 0)
|
||||
{
|
||||
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
|
||||
pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
|
||||
pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
|
||||
pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
|
||||
pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
|
||||
pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
|
||||
pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
|
||||
pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
|
||||
pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
|
||||
pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
|
||||
pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
|
||||
|
||||
results.add (pf);
|
||||
|
||||
p = aglNextPixelFormat (p);
|
||||
}*/
|
||||
|
||||
//jassertfalse //xxx can't see how you do this in cocoa!
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_OPENGL
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class WindowedGLContext : public OpenGLContext
|
||||
{
|
||||
public:
|
||||
WindowedGLContext (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat_,
|
||||
NSOpenGLContext* sharedContext)
|
||||
: renderContext (0),
|
||||
pixelFormat (pixelFormat_)
|
||||
{
|
||||
jassert (component != 0);
|
||||
|
||||
NSOpenGLPixelFormatAttribute attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = NSOpenGLPFADoubleBuffer;
|
||||
attribs[n++] = NSOpenGLPFAAccelerated;
|
||||
attribs[n++] = NSOpenGLPFAColorSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
|
||||
pixelFormat.greenBits,
|
||||
pixelFormat.blueBits);
|
||||
attribs[n++] = NSOpenGLPFAAlphaSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.alphaBits;
|
||||
attribs[n++] = NSOpenGLPFADepthSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.depthBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAStencilSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.stencilBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAAccumSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.accumulationBufferRedBits,
|
||||
pixelFormat.accumulationBufferGreenBits,
|
||||
pixelFormat.accumulationBufferBlueBits,
|
||||
pixelFormat.accumulationBufferAlphaBits);
|
||||
|
||||
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
|
||||
|
||||
attribs[n++] = NSOpenGLPFASampleBuffers;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
attribs[n++] = NSOpenGLPFAClosestPolicy;
|
||||
attribs[n++] = NSOpenGLPFANoRecovery;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
NSOpenGLPixelFormat* format
|
||||
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
|
||||
|
||||
NSOpenGLView* view
|
||||
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
|
||||
pixelFormat: format];
|
||||
|
||||
if (sharedContext != 0)
|
||||
{
|
||||
renderContext = [[NSOpenGLContext alloc] initWithFormat: format
|
||||
shareContext: sharedContext];
|
||||
[view setOpenGLContext: renderContext];
|
||||
[renderContext setView: view];
|
||||
}
|
||||
else
|
||||
{
|
||||
renderContext = [view openGLContext];
|
||||
}
|
||||
|
||||
[format release];
|
||||
|
||||
viewHolder = new NSViewComponentInternal (view, component);
|
||||
}
|
||||
|
||||
~WindowedGLContext()
|
||||
{
|
||||
makeInactive();
|
||||
[renderContext setView: nil];
|
||||
delete viewHolder;
|
||||
}
|
||||
|
||||
bool makeActive() const throw()
|
||||
{
|
||||
jassert (renderContext != 0);
|
||||
[renderContext makeCurrentContext];
|
||||
return renderContext != 0;
|
||||
}
|
||||
|
||||
bool makeInactive() const throw()
|
||||
{
|
||||
if (! isActive())
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive() const throw()
|
||||
{
|
||||
return [NSOpenGLContext currentContext] == renderContext;
|
||||
}
|
||||
|
||||
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
|
||||
void* getRawContext() const throw() { return renderContext; }
|
||||
|
||||
void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
|
||||
{
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
glFlush();
|
||||
[renderContext flushBuffer];
|
||||
}
|
||||
|
||||
bool setSwapInterval (const int numFramesPerSwap)
|
||||
{
|
||||
[renderContext setValues: (const GLint*) &numFramesPerSwap
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return true;
|
||||
}
|
||||
|
||||
int getSwapInterval() const
|
||||
{
|
||||
GLint numFrames = 0;
|
||||
[renderContext getValues: &numFrames
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
void repaint()
|
||||
{
|
||||
// we need to invalidate the juce view that holds this gl view, to make it
|
||||
// cause a repaint callback
|
||||
NSView* v = (NSView*) viewHolder->view;
|
||||
NSRect r = [v frame];
|
||||
|
||||
// bit of a bodge here.. if we only invalidate the area of the gl component,
|
||||
// it's completely covered by the NSOpenGLView, so the OS throws away the
|
||||
// repaint message, thus never causing our paint() callback, and never repainting
|
||||
// the comp. So invalidating just a little bit around the edge helps..
|
||||
[[v superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
|
||||
}
|
||||
|
||||
void* getNativeWindowHandle() const { return viewHolder->view; }
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
NSOpenGLContext* renderContext;
|
||||
|
||||
private:
|
||||
OpenGLPixelFormat pixelFormat;
|
||||
NSViewComponentInternal* viewHolder;
|
||||
|
||||
//==============================================================================
|
||||
WindowedGLContext (const WindowedGLContext&);
|
||||
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat,
|
||||
const OpenGLContext* const contextToShareWith)
|
||||
{
|
||||
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||
contextToShareWith != 0 ? (NSOpenGLContext*) contextToShareWith->getRawContext() : 0);
|
||||
|
||||
if (c->renderContext == 0)
|
||||
deleteAndZero (c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void* OpenGLComponent::getNativeWindowHandle() const
|
||||
{
|
||||
return context != 0 ? ((WindowedGLContext*) context)->getNativeWindowHandle()
|
||||
: 0;
|
||||
}
|
||||
|
||||
void juce_glViewport (const int w, const int h)
|
||||
{
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
|
||||
OwnedArray <OpenGLPixelFormat>& results)
|
||||
{
|
||||
/* GLint attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = AGL_RGBA;
|
||||
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||
attribs[n++] = AGL_ACCELERATED;
|
||||
attribs[n++] = AGL_NO_RECOVERY;
|
||||
attribs[n++] = AGL_NONE;
|
||||
|
||||
AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
|
||||
|
||||
while (p != 0)
|
||||
{
|
||||
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
|
||||
pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
|
||||
pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
|
||||
pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
|
||||
pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
|
||||
pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
|
||||
pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
|
||||
pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
|
||||
pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
|
||||
pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
|
||||
pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
|
||||
|
||||
results.add (pf);
|
||||
|
||||
p = aglNextPixelFormat (p);
|
||||
}*/
|
||||
|
||||
//jassertfalse //xxx can't see how you do this in cocoa!
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_QUICKTIME
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ QuickTimeMovieComponent::QuickTimeMovieComponent()
|
|||
{
|
||||
setOpaque (true);
|
||||
setVisible (true);
|
||||
|
||||
|
||||
QTMovieView* view = [[QTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)];
|
||||
setView (view);
|
||||
}
|
||||
|
|
@ -73,12 +73,12 @@ static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile)
|
|||
{
|
||||
MemoryBlock temp;
|
||||
movieStream->readIntoMemoryBlock (temp);
|
||||
|
||||
|
||||
const char* const suffixesToTry[] = { ".mov", ".mp3", ".avi", ".m4a" };
|
||||
|
||||
|
||||
for (int i = 0; i < numElementsInArray (suffixesToTry); ++i)
|
||||
{
|
||||
movie = [QTMovie movieWithDataReference: [QTDataReference dataReferenceWithReferenceToData: [NSData dataWithBytes: temp.getData()
|
||||
movie = [QTMovie movieWithDataReference: [QTDataReference dataReferenceWithReferenceToData: [NSData dataWithBytes: temp.getData()
|
||||
length: temp.getSize()]
|
||||
name: [NSString stringWithCString: suffixesToTry[i]]
|
||||
MIMEType: @""]
|
||||
|
|
@ -88,7 +88,7 @@ static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return movie;
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ double QuickTimeMovieComponent::getMovieDuration() const
|
|||
{
|
||||
if (movie == 0)
|
||||
return 0.0;
|
||||
|
||||
|
||||
QTTime t = [theMovie duration];
|
||||
return t.timeValue / (double) t.timeScale;
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ void QuickTimeMovieComponent::setLooping (const bool shouldLoop)
|
|||
{
|
||||
looping = shouldLoop;
|
||||
|
||||
[theMovie setAttribute: [NSNumber numberWithBool: shouldLoop]
|
||||
[theMovie setAttribute: [NSNumber numberWithBool: shouldLoop]
|
||||
forKey: QTMovieLoopsAttribute];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
|
|
|
|||
|
|
@ -1,308 +1,308 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
static int64 highResTimerFrequency;
|
||||
|
||||
#if JUCE_INTEL
|
||||
|
||||
static void juce_getCpuVendor (char* const v) throw()
|
||||
{
|
||||
int vendor[4];
|
||||
zerostruct (vendor);
|
||||
int dummy = 0;
|
||||
|
||||
asm ("mov %%ebx, %%esi \n\t"
|
||||
"cpuid \n\t"
|
||||
"xchg %%esi, %%ebx"
|
||||
: "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0));
|
||||
|
||||
memcpy (v, vendor, 16);
|
||||
}
|
||||
|
||||
static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) throw()
|
||||
{
|
||||
unsigned int cpu = 0;
|
||||
unsigned int ext = 0;
|
||||
unsigned int family = 0;
|
||||
unsigned int dummy = 0;
|
||||
|
||||
asm ("mov %%ebx, %%esi \n\t"
|
||||
"cpuid \n\t"
|
||||
"xchg %%esi, %%ebx"
|
||||
: "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
|
||||
|
||||
familyModel = family;
|
||||
extFeatures = ext;
|
||||
return cpu;
|
||||
}
|
||||
|
||||
struct CPUFlags
|
||||
{
|
||||
bool hasMMX : 1;
|
||||
bool hasSSE : 1;
|
||||
bool hasSSE2 : 1;
|
||||
bool has3DNow : 1;
|
||||
};
|
||||
|
||||
static CPUFlags cpuFlags;
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
void SystemStats::initialiseStats() throw()
|
||||
{
|
||||
static bool initialised = false;
|
||||
|
||||
if (! initialised)
|
||||
{
|
||||
initialised = true;
|
||||
|
||||
// etremely annoying: adding this line stops the apple menu items from working. Of
|
||||
// course, not adding it means that carbon windows (e.g. in plugins) won't get
|
||||
// any events.
|
||||
//NSApplicationLoad();
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
#if JUCE_INTEL
|
||||
{
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
highResTimerFrequency = (int64) AudioGetHostClockFrequency();
|
||||
|
||||
String s (SystemStats::getJUCEVersion());
|
||||
|
||||
rlimit lim;
|
||||
getrlimit (RLIMIT_NOFILE, &lim);
|
||||
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
|
||||
setrlimit (RLIMIT_NOFILE, &lim);
|
||||
}
|
||||
}
|
||||
|
||||
static const String getCpuInfo (const char* key, bool lastOne = false) throw()
|
||||
{
|
||||
String info;
|
||||
char buf [256];
|
||||
|
||||
FILE* f = fopen ("/proc/cpuinfo", "r");
|
||||
|
||||
while (f != 0 && fgets (buf, sizeof(buf), f))
|
||||
{
|
||||
if (strncmp (buf, key, strlen (key)) == 0)
|
||||
{
|
||||
char* p = buf;
|
||||
|
||||
while (*p && *p != '\n')
|
||||
++p;
|
||||
|
||||
if (*p != 0)
|
||||
*p = 0;
|
||||
|
||||
p = buf;
|
||||
|
||||
while (*p != 0 && *p != ':')
|
||||
++p;
|
||||
|
||||
if (*p != 0 && *(p + 1) != 0)
|
||||
info = p + 2;
|
||||
|
||||
if (! lastOne)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
return info;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw()
|
||||
{
|
||||
return MacOSX;
|
||||
}
|
||||
|
||||
const String SystemStats::getOperatingSystemName() throw()
|
||||
{
|
||||
return T("Mac OS X");
|
||||
}
|
||||
|
||||
bool SystemStats::isOperatingSystem64Bit() throw()
|
||||
{
|
||||
#if JUCE_64BIT
|
||||
return true;
|
||||
#else
|
||||
//xxx not sure how to find this out?..
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getMemorySizeInMegabytes() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
long bytes;
|
||||
if (Gestalt (gestaltPhysicalRAMSize, &bytes) == noErr)
|
||||
return (int) (((unsigned long) bytes) / (1024 * 1024));
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return (int) ([[NSProcessInfo processInfo] physicalMemory] / (1024 * 1024));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasMMX() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasMMX;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasSSE() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasSSE;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasSSE2() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasSSE2;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::has3DNow() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.has3DNow;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const String SystemStats::getCpuVendor() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
char v [16];
|
||||
juce_getCpuVendor (v);
|
||||
return String (v, 16);
|
||||
#else
|
||||
return String::empty;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getCpuSpeedInMegaherz() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
return GetCPUSpeed();
|
||||
#else
|
||||
return roundDoubleToInt (getCpuInfo ("cpu MHz").getDoubleValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getNumCpus() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
return MPProcessors();
|
||||
#else
|
||||
return [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static int64 juce_getMicroseconds() throw()
|
||||
{
|
||||
UnsignedWide t;
|
||||
Microseconds (&t);
|
||||
return (((int64) t.hi) << 32) | t.lo;
|
||||
}
|
||||
|
||||
uint32 juce_millisecondsSinceStartup() throw()
|
||||
{
|
||||
return (uint32) (juce_getMicroseconds() / 1000);
|
||||
}
|
||||
|
||||
double Time::getMillisecondCounterHiRes() throw()
|
||||
{
|
||||
// xxx might be more accurate to use a scaled AudioGetCurrentHostTime?
|
||||
return juce_getMicroseconds() * 0.001;
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicks() throw()
|
||||
{
|
||||
return (int64) AudioGetCurrentHostTime();
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() throw()
|
||||
{
|
||||
return highResTimerFrequency;
|
||||
}
|
||||
|
||||
int64 SystemStats::getClockCycleCounter() throw()
|
||||
{
|
||||
jassertfalse
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Time::setSystemTimeToThisTime() const throw()
|
||||
{
|
||||
jassertfalse
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int SystemStats::getPageSize() throw()
|
||||
{
|
||||
return NSPageSize();
|
||||
}
|
||||
|
||||
void PlatformUtilities::fpuReset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
static int64 highResTimerFrequency;
|
||||
|
||||
#if JUCE_INTEL
|
||||
|
||||
static void juce_getCpuVendor (char* const v) throw()
|
||||
{
|
||||
int vendor[4];
|
||||
zerostruct (vendor);
|
||||
int dummy = 0;
|
||||
|
||||
asm ("mov %%ebx, %%esi \n\t"
|
||||
"cpuid \n\t"
|
||||
"xchg %%esi, %%ebx"
|
||||
: "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0));
|
||||
|
||||
memcpy (v, vendor, 16);
|
||||
}
|
||||
|
||||
static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) throw()
|
||||
{
|
||||
unsigned int cpu = 0;
|
||||
unsigned int ext = 0;
|
||||
unsigned int family = 0;
|
||||
unsigned int dummy = 0;
|
||||
|
||||
asm ("mov %%ebx, %%esi \n\t"
|
||||
"cpuid \n\t"
|
||||
"xchg %%esi, %%ebx"
|
||||
: "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
|
||||
|
||||
familyModel = family;
|
||||
extFeatures = ext;
|
||||
return cpu;
|
||||
}
|
||||
|
||||
struct CPUFlags
|
||||
{
|
||||
bool hasMMX : 1;
|
||||
bool hasSSE : 1;
|
||||
bool hasSSE2 : 1;
|
||||
bool has3DNow : 1;
|
||||
};
|
||||
|
||||
static CPUFlags cpuFlags;
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
void SystemStats::initialiseStats() throw()
|
||||
{
|
||||
static bool initialised = false;
|
||||
|
||||
if (! initialised)
|
||||
{
|
||||
initialised = true;
|
||||
|
||||
// etremely annoying: adding this line stops the apple menu items from working. Of
|
||||
// course, not adding it means that carbon windows (e.g. in plugins) won't get
|
||||
// any events.
|
||||
//NSApplicationLoad();
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
#if JUCE_INTEL
|
||||
{
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
highResTimerFrequency = (int64) AudioGetHostClockFrequency();
|
||||
|
||||
String s (SystemStats::getJUCEVersion());
|
||||
|
||||
rlimit lim;
|
||||
getrlimit (RLIMIT_NOFILE, &lim);
|
||||
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
|
||||
setrlimit (RLIMIT_NOFILE, &lim);
|
||||
}
|
||||
}
|
||||
|
||||
static const String getCpuInfo (const char* key, bool lastOne = false) throw()
|
||||
{
|
||||
String info;
|
||||
char buf [256];
|
||||
|
||||
FILE* f = fopen ("/proc/cpuinfo", "r");
|
||||
|
||||
while (f != 0 && fgets (buf, sizeof(buf), f))
|
||||
{
|
||||
if (strncmp (buf, key, strlen (key)) == 0)
|
||||
{
|
||||
char* p = buf;
|
||||
|
||||
while (*p && *p != '\n')
|
||||
++p;
|
||||
|
||||
if (*p != 0)
|
||||
*p = 0;
|
||||
|
||||
p = buf;
|
||||
|
||||
while (*p != 0 && *p != ':')
|
||||
++p;
|
||||
|
||||
if (*p != 0 && *(p + 1) != 0)
|
||||
info = p + 2;
|
||||
|
||||
if (! lastOne)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
return info;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw()
|
||||
{
|
||||
return MacOSX;
|
||||
}
|
||||
|
||||
const String SystemStats::getOperatingSystemName() throw()
|
||||
{
|
||||
return T("Mac OS X");
|
||||
}
|
||||
|
||||
bool SystemStats::isOperatingSystem64Bit() throw()
|
||||
{
|
||||
#if JUCE_64BIT
|
||||
return true;
|
||||
#else
|
||||
//xxx not sure how to find this out?..
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getMemorySizeInMegabytes() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
long bytes;
|
||||
if (Gestalt (gestaltPhysicalRAMSize, &bytes) == noErr)
|
||||
return (int) (((unsigned long) bytes) / (1024 * 1024));
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return (int) ([[NSProcessInfo processInfo] physicalMemory] / (1024 * 1024));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasMMX() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasMMX;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasSSE() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasSSE;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::hasSSE2() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.hasSSE2;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemStats::has3DNow() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
return cpuFlags.has3DNow;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const String SystemStats::getCpuVendor() throw()
|
||||
{
|
||||
#if JUCE_INTEL
|
||||
char v [16];
|
||||
juce_getCpuVendor (v);
|
||||
return String (v, 16);
|
||||
#else
|
||||
return String::empty;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getCpuSpeedInMegaherz() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
return GetCPUSpeed();
|
||||
#else
|
||||
return roundDoubleToInt (getCpuInfo ("cpu MHz").getDoubleValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getNumCpus() throw()
|
||||
{
|
||||
#if MACOS_10_4_OR_EARLIER
|
||||
return MPProcessors();
|
||||
#else
|
||||
return [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static int64 juce_getMicroseconds() throw()
|
||||
{
|
||||
UnsignedWide t;
|
||||
Microseconds (&t);
|
||||
return (((int64) t.hi) << 32) | t.lo;
|
||||
}
|
||||
|
||||
uint32 juce_millisecondsSinceStartup() throw()
|
||||
{
|
||||
return (uint32) (juce_getMicroseconds() / 1000);
|
||||
}
|
||||
|
||||
double Time::getMillisecondCounterHiRes() throw()
|
||||
{
|
||||
// xxx might be more accurate to use a scaled AudioGetCurrentHostTime?
|
||||
return juce_getMicroseconds() * 0.001;
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicks() throw()
|
||||
{
|
||||
return (int64) AudioGetCurrentHostTime();
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() throw()
|
||||
{
|
||||
return highResTimerFrequency;
|
||||
}
|
||||
|
||||
int64 SystemStats::getClockCycleCounter() throw()
|
||||
{
|
||||
jassertfalse
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Time::setSystemTimeToThisTime() const throw()
|
||||
{
|
||||
jassertfalse
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int SystemStats::getPageSize() throw()
|
||||
{
|
||||
return NSPageSize();
|
||||
}
|
||||
|
||||
void PlatformUtilities::fpuReset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,129 +1,129 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
Note that a lot of methods that you'd expect to find in this file actually
|
||||
live in juce_posix_SharedCode.h!
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
void JUCE_API juce_threadEntryPoint (void*);
|
||||
|
||||
void* threadEntryProc (void* userData) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
juce_threadEntryPoint (userData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* juce_createThread (void* userData) throw()
|
||||
{
|
||||
pthread_t handle = 0;
|
||||
|
||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
|
||||
{
|
||||
pthread_detach (handle);
|
||||
return (void*) handle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_killThread (void* handle) throw()
|
||||
{
|
||||
if (handle != 0)
|
||||
pthread_cancel ((pthread_t) handle);
|
||||
}
|
||||
|
||||
void juce_setCurrentThreadName (const String& /*name*/) throw()
|
||||
{
|
||||
}
|
||||
|
||||
int64 Thread::getCurrentThreadId() throw()
|
||||
{
|
||||
return (int64) pthread_self();
|
||||
}
|
||||
|
||||
void juce_setThreadPriority (void* handle, int priority) throw()
|
||||
{
|
||||
if (handle == 0)
|
||||
handle = (void*) pthread_self();
|
||||
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
pthread_getschedparam ((pthread_t) handle, &policy, ¶m);
|
||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
|
||||
pthread_setschedparam ((pthread_t) handle, policy, ¶m);
|
||||
}
|
||||
|
||||
void Thread::yield() throw()
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
|
||||
{
|
||||
// xxx
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Process::isForegroundProcess() throw()
|
||||
{
|
||||
return [NSApp isActive];
|
||||
}
|
||||
|
||||
void Process::raisePrivilege()
|
||||
{
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
void Process::lowerPrivilege()
|
||||
{
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
void Process::terminate()
|
||||
{
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void Process::setPriority (ProcessPriority p)
|
||||
{
|
||||
// xxx
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
Note that a lot of methods that you'd expect to find in this file actually
|
||||
live in juce_posix_SharedCode.h!
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
void JUCE_API juce_threadEntryPoint (void*);
|
||||
|
||||
void* threadEntryProc (void* userData) throw()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
juce_threadEntryPoint (userData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* juce_createThread (void* userData) throw()
|
||||
{
|
||||
pthread_t handle = 0;
|
||||
|
||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
|
||||
{
|
||||
pthread_detach (handle);
|
||||
return (void*) handle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_killThread (void* handle) throw()
|
||||
{
|
||||
if (handle != 0)
|
||||
pthread_cancel ((pthread_t) handle);
|
||||
}
|
||||
|
||||
void juce_setCurrentThreadName (const String& /*name*/) throw()
|
||||
{
|
||||
}
|
||||
|
||||
int64 Thread::getCurrentThreadId() throw()
|
||||
{
|
||||
return (int64) pthread_self();
|
||||
}
|
||||
|
||||
void juce_setThreadPriority (void* handle, int priority) throw()
|
||||
{
|
||||
if (handle == 0)
|
||||
handle = (void*) pthread_self();
|
||||
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
pthread_getschedparam ((pthread_t) handle, &policy, ¶m);
|
||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
|
||||
pthread_setschedparam ((pthread_t) handle, policy, ¶m);
|
||||
}
|
||||
|
||||
void Thread::yield() throw()
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
|
||||
{
|
||||
// xxx
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Process::isForegroundProcess() throw()
|
||||
{
|
||||
return [NSApp isActive];
|
||||
}
|
||||
|
||||
void Process::raisePrivilege()
|
||||
{
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
void Process::lowerPrivilege()
|
||||
{
|
||||
jassertfalse
|
||||
}
|
||||
|
||||
void Process::terminate()
|
||||
{
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void Process::setPriority (ProcessPriority p)
|
||||
{
|
||||
// xxx
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER
|
||||
|
||||
|
|
@ -62,9 +62,9 @@ END_JUCE_NAMESPACE
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation
|
||||
request: (NSURLRequest*) request
|
||||
frame: (WebFrame*) frame
|
||||
- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation
|
||||
request: (NSURLRequest*) request
|
||||
frame: (WebFrame*) frame
|
||||
decisionListener: (id <WebPolicyDecisionListener>) listener
|
||||
{
|
||||
NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];
|
||||
|
|
@ -86,7 +86,7 @@ public:
|
|||
WebBrowserComponentInternal (WebBrowserComponent* owner)
|
||||
{
|
||||
webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
|
||||
frameName: @""
|
||||
frameName: @""
|
||||
groupName: @""];
|
||||
setView (webView);
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ public:
|
|||
setView (0);
|
||||
}
|
||||
|
||||
void goToURL (const String& url,
|
||||
void goToURL (const String& url,
|
||||
const StringArray* headers,
|
||||
const MemoryBlock* postData)
|
||||
{
|
||||
NSMutableURLRequest* r
|
||||
NSMutableURLRequest* r
|
||||
= [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)]
|
||||
cachePolicy: NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval: 30.0];
|
||||
|
|
@ -113,7 +113,7 @@ public:
|
|||
if (postData != 0 && postData->getSize() > 0)
|
||||
{
|
||||
[r setHTTPMethod: @"POST"];
|
||||
[r setHTTPBody: [NSData dataWithBytes: postData->getData()
|
||||
[r setHTTPBody: [NSData dataWithBytes: postData->getData()
|
||||
length: postData->getSize()]];
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ WebBrowserComponent::~WebBrowserComponent()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void WebBrowserComponent::goToURL (const String& url,
|
||||
void WebBrowserComponent::goToURL (const String& url,
|
||||
const StringArray* headers,
|
||||
const MemoryBlock* postData)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
/*
|
||||
/*
|
||||
This file includes the entire juce source tree via the amalgamated file.
|
||||
|
||||
You could add the amalgamated file directly to your project, but doing it
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
the source code.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class JuceAUView;
|
|||
- (void) dealloc;
|
||||
- (unsigned) interfaceVersion;
|
||||
- (NSString *) description;
|
||||
- (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit
|
||||
- (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit
|
||||
withSize: (NSSize) inPreferredSize;
|
||||
@end
|
||||
|
||||
|
|
@ -951,7 +951,7 @@ private:
|
|||
return [NSString stringWithString: @JucePlugin_Name];
|
||||
}
|
||||
|
||||
- (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit
|
||||
- (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit
|
||||
withSize: (NSSize) inPreferredSize
|
||||
{
|
||||
void* pointers[2];
|
||||
|
|
@ -972,7 +972,7 @@ private:
|
|||
return 0;
|
||||
|
||||
AudioProcessorEditor* editorComp = filter->createEditorIfNeeded();
|
||||
|
||||
|
||||
if (editorComp == 0)
|
||||
return 0;
|
||||
DBG (String (inPreferredSize.width) + " " + String (inPreferredSize.height));
|
||||
|
|
|
|||
|
|
@ -1,82 +1,82 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
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 <Cocoa/Cocoa.h>
|
||||
#include "../../../../../juce.h"
|
||||
|
||||
//==============================================================================
|
||||
void* attachSubWindow (void* hostWindowRef, Component* comp)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: hostWindowRef];
|
||||
[hostWindow retain];
|
||||
|
||||
NSView* content = [hostWindow contentView];
|
||||
NSRect f = [content frame];
|
||||
f.size.width = comp->getWidth();
|
||||
f.size.height = comp->getHeight();
|
||||
[content setFrame: f];
|
||||
|
||||
NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin];
|
||||
windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height);
|
||||
|
||||
comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y);
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
|
||||
#else
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary);
|
||||
#endif
|
||||
|
||||
comp->setVisible (true);
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
return hostWindow;
|
||||
}
|
||||
|
||||
void removeSubWindow (void* nsWindow, Component* comp)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* hostWindow = (NSWindow*) nsWindow;
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[hostWindow removeChildWindow: pluginWindow];
|
||||
comp->removeFromDesktop();
|
||||
[hostWindow release];
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 <Cocoa/Cocoa.h>
|
||||
#include "../../../../../juce.h"
|
||||
|
||||
//==============================================================================
|
||||
void* attachSubWindow (void* hostWindowRef, Component* comp)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: hostWindowRef];
|
||||
[hostWindow retain];
|
||||
|
||||
NSView* content = [hostWindow contentView];
|
||||
NSRect f = [content frame];
|
||||
f.size.width = comp->getWidth();
|
||||
f.size.height = comp->getHeight();
|
||||
[content setFrame: f];
|
||||
|
||||
NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin];
|
||||
windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height);
|
||||
|
||||
comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y);
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
|
||||
#else
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary);
|
||||
#endif
|
||||
|
||||
comp->setVisible (true);
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
return hostWindow;
|
||||
}
|
||||
|
||||
void removeSubWindow (void* nsWindow, Component* comp)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* hostWindow = (NSWindow*) nsWindow;
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[hostWindow removeChildWindow: pluginWindow];
|
||||
comp->removeFromDesktop();
|
||||
[hostWindow release];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ public:
|
|||
}
|
||||
|
||||
juce_DeclareSingleton (SharedMessageThread, false)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ void* attachComponentToWindowRef (Component* comp, void* windowRef)
|
|||
NSWindow* pluginWindow = [pluginView window];
|
||||
[pluginWindow setExcludedFromWindowsMenu: YES];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
[pluginWindow orderFront: nil];
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
/*
|
||||
/*
|
||||
This file includes the entire juce source tree via the amalgamated file.
|
||||
|
||||
You could add the amalgamated file directly to your project, but doing it
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
the source code.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
/*
|
||||
/*
|
||||
This file includes the entire juce source tree via the amalgamated file.
|
||||
|
||||
You could add the amalgamated file directly to your project, but doing it
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
like this allows you to put your app's config settings in the
|
||||
juce_AppConfig.h file and have them applied to both the juce headers and
|
||||
the source code.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
|
||||
if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
|
||||
0, &dataSize, &isWritable) != noErr)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -768,7 +768,7 @@ private:
|
|||
NSView* pluginView = 0;
|
||||
AudioUnitCocoaViewInfo* info = (AudioUnitCocoaViewInfo*) juce_calloc (dataSize);
|
||||
|
||||
if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
|
||||
if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
|
||||
0, info, &dataSize) == noErr)
|
||||
{
|
||||
NSString* viewClassName = (NSString*) (info->mCocoaAUViewClass[0]);
|
||||
|
|
@ -781,7 +781,7 @@ private:
|
|||
&& [viewClass instancesRespondToSelector: @selector (uiViewForAudioUnit: withSize:)])
|
||||
{
|
||||
id factory = [[[viewClass alloc] init] autorelease];
|
||||
pluginView = [factory uiViewForAudioUnit: plugin.audioUnit
|
||||
pluginView = [factory uiViewForAudioUnit: plugin.audioUnit
|
||||
withSize: NSMakeSize (getWidth(), getHeight())];
|
||||
}
|
||||
|
||||
|
|
@ -811,7 +811,7 @@ public:
|
|||
viewComponent (0)
|
||||
{
|
||||
addAndMakeVisible (innerWrapper = new InnerWrapperComponent (this));
|
||||
|
||||
|
||||
activeWindows.add (this);
|
||||
|
||||
setOpaque (true);
|
||||
|
|
@ -877,7 +877,7 @@ public:
|
|||
|
||||
return viewComponent;
|
||||
}
|
||||
|
||||
|
||||
void closeViewComponent()
|
||||
{
|
||||
if (viewComponent != 0)
|
||||
|
|
@ -923,12 +923,12 @@ private:
|
|||
|
||||
HIViewRef pluginView = 0;
|
||||
|
||||
AudioUnitCarbonViewCreate (viewComponent,
|
||||
AudioUnitCarbonViewCreate (viewComponent,
|
||||
owner->getAudioUnit(),
|
||||
windowRef,
|
||||
windowRef,
|
||||
rootView,
|
||||
&pos,
|
||||
&size,
|
||||
&size,
|
||||
(ControlRef*) &pluginView);
|
||||
|
||||
return pluginView;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue