| @@ -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; | |||