diff --git a/build/linux/platform_specific_code/juce_linux_Audio.cpp b/build/linux/platform_specific_code/juce_linux_Audio.cpp index 2ed65f6248..2af70ee6e0 100644 --- a/build/linux/platform_specific_code/juce_linux_Audio.cpp +++ b/build/linux/platform_specific_code/juce_linux_Audio.cpp @@ -448,7 +448,7 @@ public: } if (! outputDevice->setParameters ((unsigned int) sampleRate, - currentOutputChans.getHighestBit() + 1, + jlimit (minChansOut, maxChansOut, currentOutputChans.getHighestBit() + 1), bufferSize)) { error = outputDevice->error; @@ -469,7 +469,7 @@ public: } if (! inputDevice->setParameters ((unsigned int) sampleRate, - currentInputChans.getHighestBit() + 1, + jlimit (minChansIn, maxChansIn, currentInputChans.getHighestBit() + 1), bufferSize)) { error = inputDevice->error; diff --git a/build/macosx/platform_specific_code/juce_mac_Files.mm b/build/macosx/platform_specific_code/juce_mac_Files.mm index 1d1be48c4f..3b12105a07 100644 --- a/build/macosx/platform_specific_code/juce_mac_Files.mm +++ b/build/macosx/platform_specific_code/juce_mac_Files.mm @@ -1,611 +1,614 @@ -/* - ============================================================================== - - 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! -*/ - -//============================================================================== -static File executableFile; - -const unsigned int macTimeToUnixTimeDiff = 0x7c25be90; - -static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw() -{ - if (d.highSeconds == 0 && d.lowSeconds == 0 && d.fraction == 0) - return 0; - - return (((((uint64) d.highSeconds) << 32) | (uint64) d.lowSeconds) * 1000) - + ((d.fraction * 1000) >> 16) - - 2082844800000ll; -} - -static void unixTimeToUtcDateTime (uint64 t, UTCDateTime& d) throw() -{ - if (t != 0) - t += 2082844800000ll; - - d.highSeconds = (t / 1000) >> 32; - d.lowSeconds = (t / 1000) & (uint64) 0xffffffff; - d.fraction = ((t % 1000) << 16) / 1000; -} - -void juce_getFileTimes (const String& fileName, - int64& modificationTime, - int64& accessTime, - int64& creationTime) throw() -{ - modificationTime = 0; - accessTime = 0; - creationTime = 0; - - FSRef fileRef; - if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName)) - { - FSRefParam info; - zerostruct (info); - - info.ref = &fileRef; - info.whichInfo = kFSCatInfoAllDates; - - FSCatalogInfo catInfo; - info.catInfo = &catInfo; - - if (PBGetCatalogInfoSync (&info) == noErr) - { - creationTime = utcDateTimeToUnixTime (catInfo.createDate); - accessTime = utcDateTimeToUnixTime (catInfo.accessDate); - modificationTime = utcDateTimeToUnixTime (catInfo.contentModDate); - } - } -} - -bool juce_setFileTimes (const String& fileName, - int64 modificationTime, - int64 accessTime, - int64 creationTime) throw() -{ - FSRef fileRef; - if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName)) - { - FSRefParam info; - zerostruct (info); - - info.ref = &fileRef; - info.whichInfo = kFSCatInfoAllDates; - - FSCatalogInfo catInfo; - info.catInfo = &catInfo; - - if (PBGetCatalogInfoSync (&info) == noErr) - { - if (creationTime != 0) - unixTimeToUtcDateTime (creationTime, catInfo.createDate); - - if (modificationTime != 0) - unixTimeToUtcDateTime (modificationTime, catInfo.contentModDate); - - if (accessTime != 0) - unixTimeToUtcDateTime (accessTime, catInfo.accessDate); - - return PBSetCatalogInfoSync (&info) == noErr; - } - } - - return false; -} - -bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw() -{ - const char* const fileNameUTF8 = fileName.toUTF8(); - - struct stat info; - const int res = stat (fileNameUTF8, &info); - - bool ok = false; - - if (res == 0) - { - info.st_mode &= 0777; // Just permissions - - if (isReadOnly) - info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - else - // Give everybody write permission? - info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; - - ok = chmod (fileNameUTF8, info.st_mode) == 0; - } - - return ok; -} - -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) - toPath: juceStringToNS (dst) - handler: nil]; -} - -const StringArray juce_getFileSystemRoots() throw() -{ - StringArray s; - s.add (T("/")); - return s; -} - -//============================================================================== -static bool isFileOnDriveType (const File* const f, const char** types) throw() -{ - struct statfs buf; - - if (doStatFS (f, buf)) - { - const String type (buf.f_fstypename); - - while (*types != 0) - if (type.equalsIgnoreCase (*types++)) - return true; - } - - return false; -} - -bool File::isOnCDRomDrive() const throw() -{ - static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; - - return isFileOnDriveType (this, (const char**) cdTypes); -} - -bool File::isOnHardDisk() const throw() -{ - static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; - - return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes)); -} - -bool File::isOnRemovableDrive() const throw() -{ - const ScopedAutoReleasePool pool; - BOOL removable = false; - - [[NSWorkspace sharedWorkspace] - getFileSystemInfoForPath: juceStringToNS (getFullPathName()) - isRemovable: &removable - isWritable: nil - isUnmountable: nil - description: nil - type: nil]; - - return removable; -} - -static bool juce_isHiddenFile (const String& path) throw() -{ - FSRef ref; - if (! PlatformUtilities::makeFSRefFromPath (&ref, path)) - return false; - - FSCatalogInfo info; - FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0); - - if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0) - return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; - - return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; -} - -bool File::isHidden() const throw() -{ - return juce_isHiddenFile (getFullPathName()); -} - -//============================================================================== -const File File::getSpecialLocation (const SpecialLocationType type) -{ - const ScopedAutoReleasePool pool; - - String resultPath; - - switch (type) - { - case userHomeDirectory: - resultPath = nsStringToJuce (NSHomeDirectory()); - break; - - case userDocumentsDirectory: - resultPath = "~/Documents"; - break; - - case userDesktopDirectory: - resultPath = "~/Desktop"; - break; - - case userApplicationDataDirectory: - resultPath = "~/Library"; - break; - - case commonApplicationDataDirectory: - resultPath = "/Library"; - break; - - case globalApplicationsDirectory: - resultPath = "/Applications"; - break; - - case userMusicDirectory: - resultPath = "~/Music"; - break; - - case userMoviesDirectory: - resultPath = "~/Movies"; - break; - - case tempDirectory: - { - File tmp (T("~/Library/Caches/") + executableFile.getFileNameWithoutExtension()); - - tmp.createDirectory(); - return tmp.getFullPathName(); - } - - case currentExecutableFile: - return executableFile; - - case currentApplicationFile: - { - const File parent (executableFile.getParentDirectory()); - - return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS")) - ? parent.getParentDirectory().getParentDirectory() - : executableFile; - } - - default: - jassertfalse // unknown type? - break; - } - - if (resultPath != 0) - return File (PlatformUtilities::convertToPrecomposedUnicode (resultPath)); - - return File::nonexistent; -} - -void juce_setCurrentExecutableFileName (const String& filename) throw() -{ - executableFile = File::getCurrentWorkingDirectory() - .getChildFile (PlatformUtilities::convertToPrecomposedUnicode (filename)); -} - -void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) throw() -{ - const ScopedAutoReleasePool pool; - - NSBundle* b = [NSBundle bundleWithIdentifier: juceStringToNS (bundleId)]; - - if (b != nil) - executableFile = nsStringToJuce ([b executablePath]); -} - -//============================================================================== -const File File::getCurrentWorkingDirectory() throw() -{ - char buf [2048]; - getcwd (buf, sizeof(buf)); - - return File (PlatformUtilities::convertToPrecomposedUnicode (buf)); -} - -bool File::setAsCurrentWorkingDirectory() const throw() -{ - return chdir (getFullPathName().toUTF8()) == 0; -} - -//============================================================================== -const String File::getVersion() const throw() -{ - const ScopedAutoReleasePool pool; - String result; - - NSBundle* bundle = [NSBundle bundleWithPath: juceStringToNS (getFullPathName())]; - - if (bundle != 0) - { - NSDictionary* info = [bundle infoDictionary]; - - if (info != 0) - { - NSString* name = [info valueForKey: @"CFBundleShortVersionString"]; - - if (name != nil) - result = nsStringToJuce (name); - } - } - - return result; -} - -//============================================================================== -const File File::getLinkedTarget() const throw() -{ - FSRef ref; - Boolean targetIsAFolder, wasAliased; - - if (PlatformUtilities::makeFSRefFromPath (&ref, getFullPathName()) - && (FSResolveAliasFileWithMountFlags (&ref, true, &targetIsAFolder, &wasAliased, 0) == noErr) - && wasAliased) - { - return File (PlatformUtilities::makePathFromFSRef (&ref)); - } - - return *this; -} - -//============================================================================== -bool File::moveToTrash() const throw() -{ - if (! exists()) - return true; - - const ScopedAutoReleasePool pool; - - NSString* p = juceStringToNS (getFullPathName()); - - return [[NSWorkspace sharedWorkspace] - performFileOperation: NSWorkspaceRecycleOperation - source: [p stringByDeletingLastPathComponent] - destination: @"" - files: [NSArray arrayWithObject: [p lastPathComponent]] - tag: nil ]; -} - -//============================================================================== -struct FindFileStruct -{ - String parentDir, wildCard; - DIR* dir; - - bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) throw() - { - const char* const wildCardUTF8 = wildCard.toUTF8(); - - for (;;) - { - struct dirent* const de = readdir (dir); - - if (de == 0) - break; - - if (fnmatch (wildCardUTF8, de->d_name, 0) == 0) - { - result = String::fromUTF8 ((const uint8*) de->d_name); - - const String path (parentDir + result); - - if (isDir != 0 || fileSize != 0) - { - struct stat info; - const bool statOk = juce_stat (path, info); - - if (isDir != 0) - *isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0)); - - if (isHidden != 0) - *isHidden = (de->d_name[0] == '.') - || juce_isHiddenFile (path); - - if (fileSize != 0) - *fileSize = statOk ? info.st_size : 0; - } - - if (modTime != 0 || creationTime != 0) - { - int64 m, a, c; - juce_getFileTimes (path, m, a, c); - - if (modTime != 0) - *modTime = m; - - if (creationTime != 0) - *creationTime = c; - } - - if (isReadOnly != 0) - *isReadOnly = ! juce_canWriteToFile (path); - - return true; - } - } - - return false; - } -}; - -// returns 0 on failure -void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, - Time* creationTime, bool* isReadOnly) throw() -{ - DIR* const d = opendir (directory.toUTF8()); - - if (d != 0) - { - FindFileStruct* const ff = new FindFileStruct(); - ff->parentDir = directory; - - if (!ff->parentDir.endsWithChar (File::separator)) - ff->parentDir += File::separator; - - ff->wildCard = wildCard; - ff->dir = d; - - if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) - { - return ff; - } - else - { - firstResultFile = String::empty; - isDir = false; - closedir (d); - delete ff; - } - } - - return 0; -} - -bool juce_findFileNext (void* handle, String& resultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw() -{ - FindFileStruct* const ff = (FindFileStruct*) handle; - - if (ff != 0) - return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); - - return false; -} - -void juce_findFileClose (void* handle) throw() -{ - FindFileStruct* const ff = (FindFileStruct*)handle; - - if (ff != 0) - { - closedir (ff->dir); - delete ff; - } -} - -//============================================================================== -bool juce_launchExecutable (const String& pathAndArguments) throw() -{ - char* const argv[4] = { "/bin/sh", "-c", (char*) (const char*) pathAndArguments, 0 }; - - const int cpid = fork(); - - if (cpid == 0) - { - // Child process - if (execve (argv[0], argv, 0) < 0) - exit (0); - } - else - { - if (cpid < 0) - return false; - } - - return true; -} - -bool juce_launchFile (const String& fileName, - const String& parameters) throw() -{ - const ScopedAutoReleasePool pool; - - if (parameters.isEmpty()) - return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)]; - - bool ok = false; - - FSRef ref; - if (PlatformUtilities::makeFSRefFromPath (&ref, fileName)) - { - if (PlatformUtilities::isBundle (fileName)) - { - NSMutableArray* urls = [NSMutableArray array]; - - StringArray docs; - docs.addTokens (parameters, true); - for (int i = 0; i < docs.size(); ++i) - [urls addObject: juceStringToNS (docs[i])]; - - ok = [[NSWorkspace sharedWorkspace] openURLs: urls - withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] - options: nil - additionalEventParamDescriptor: nil - launchIdentifiers: nil]; - } - else - { - ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters); - } - } - - return ok; -} - -//============================================================================== -bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) -{ - return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr; -} - -const String PlatformUtilities::makePathFromFSRef (FSRef* file) -{ - uint8 path [2048]; - zeromem (path, sizeof (path)); - - String result; - - if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr) - result = String::fromUTF8 (path); - - return PlatformUtilities::convertToPrecomposedUnicode (result); -} - -//============================================================================== -OSType PlatformUtilities::getTypeOfFile (const String& filename) -{ - const ScopedAutoReleasePool pool; - return NSHFSTypeCodeFromFileType (NSHFSTypeOfFile (juceStringToNS (filename))); -} - -bool PlatformUtilities::isBundle (const String& filename) -{ - const ScopedAutoReleasePool pool; - return [[NSWorkspace sharedWorkspace] isFilePackageAtPath: juceStringToNS (filename)]; -} - -#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! +*/ + +//============================================================================== +static File executableFile; + +const unsigned int macTimeToUnixTimeDiff = 0x7c25be90; + +static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw() +{ + if (d.highSeconds == 0 && d.lowSeconds == 0 && d.fraction == 0) + return 0; + + return (((((uint64) d.highSeconds) << 32) | (uint64) d.lowSeconds) * 1000) + + ((d.fraction * 1000) >> 16) + - 2082844800000ll; +} + +static void unixTimeToUtcDateTime (uint64 t, UTCDateTime& d) throw() +{ + if (t != 0) + t += 2082844800000ll; + + d.highSeconds = (t / 1000) >> 32; + d.lowSeconds = (t / 1000) & (uint64) 0xffffffff; + d.fraction = ((t % 1000) << 16) / 1000; +} + +void juce_getFileTimes (const String& fileName, + int64& modificationTime, + int64& accessTime, + int64& creationTime) throw() +{ + modificationTime = 0; + accessTime = 0; + creationTime = 0; + + FSRef fileRef; + if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName)) + { + FSRefParam info; + zerostruct (info); + + info.ref = &fileRef; + info.whichInfo = kFSCatInfoAllDates; + + FSCatalogInfo catInfo; + info.catInfo = &catInfo; + + if (PBGetCatalogInfoSync (&info) == noErr) + { + creationTime = utcDateTimeToUnixTime (catInfo.createDate); + accessTime = utcDateTimeToUnixTime (catInfo.accessDate); + modificationTime = utcDateTimeToUnixTime (catInfo.contentModDate); + } + } +} + +bool juce_setFileTimes (const String& fileName, + int64 modificationTime, + int64 accessTime, + int64 creationTime) throw() +{ + FSRef fileRef; + if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName)) + { + FSRefParam info; + zerostruct (info); + + info.ref = &fileRef; + info.whichInfo = kFSCatInfoAllDates; + + FSCatalogInfo catInfo; + info.catInfo = &catInfo; + + if (PBGetCatalogInfoSync (&info) == noErr) + { + if (creationTime != 0) + unixTimeToUtcDateTime (creationTime, catInfo.createDate); + + if (modificationTime != 0) + unixTimeToUtcDateTime (modificationTime, catInfo.contentModDate); + + if (accessTime != 0) + unixTimeToUtcDateTime (accessTime, catInfo.accessDate); + + return PBSetCatalogInfoSync (&info) == noErr; + } + } + + return false; +} + +bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw() +{ + const char* const fileNameUTF8 = fileName.toUTF8(); + + struct stat info; + const int res = stat (fileNameUTF8, &info); + + bool ok = false; + + if (res == 0) + { + info.st_mode &= 0777; // Just permissions + + if (isReadOnly) + info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + else + // Give everybody write permission? + info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + + ok = chmod (fileNameUTF8, info.st_mode) == 0; + } + + return ok; +} + +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) + toPath: juceStringToNS (dst) + handler: nil]; +} + +const StringArray juce_getFileSystemRoots() throw() +{ + StringArray s; + s.add (T("/")); + return s; +} + +//============================================================================== +static bool isFileOnDriveType (const File* const f, const char** types) throw() +{ + struct statfs buf; + + if (doStatFS (f, buf)) + { + const String type (buf.f_fstypename); + + while (*types != 0) + if (type.equalsIgnoreCase (*types++)) + return true; + } + + return false; +} + +bool File::isOnCDRomDrive() const throw() +{ + static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; + + return isFileOnDriveType (this, (const char**) cdTypes); +} + +bool File::isOnHardDisk() const throw() +{ + static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; + + return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes)); +} + +bool File::isOnRemovableDrive() const throw() +{ + const ScopedAutoReleasePool pool; + BOOL removable = false; + + [[NSWorkspace sharedWorkspace] + getFileSystemInfoForPath: juceStringToNS (getFullPathName()) + isRemovable: &removable + isWritable: nil + isUnmountable: nil + description: nil + type: nil]; + + return removable; +} + +static bool juce_isHiddenFile (const String& path) throw() +{ + FSRef ref; + if (! PlatformUtilities::makeFSRefFromPath (&ref, path)) + return false; + + FSCatalogInfo info; + FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0); + + if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0) + return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; + + return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; +} + +bool File::isHidden() const throw() +{ + return juce_isHiddenFile (getFullPathName()); +} + +//============================================================================== +const File File::getSpecialLocation (const SpecialLocationType type) +{ + const ScopedAutoReleasePool pool; + + String resultPath; + + switch (type) + { + case userHomeDirectory: + resultPath = nsStringToJuce (NSHomeDirectory()); + break; + + case userDocumentsDirectory: + resultPath = "~/Documents"; + break; + + case userDesktopDirectory: + resultPath = "~/Desktop"; + break; + + case userApplicationDataDirectory: + resultPath = "~/Library"; + break; + + case commonApplicationDataDirectory: + resultPath = "/Library"; + break; + + case globalApplicationsDirectory: + resultPath = "/Applications"; + break; + + case userMusicDirectory: + resultPath = "~/Music"; + break; + + case userMoviesDirectory: + resultPath = "~/Movies"; + break; + + case tempDirectory: + { + File tmp (T("~/Library/Caches/") + executableFile.getFileNameWithoutExtension()); + + tmp.createDirectory(); + return tmp.getFullPathName(); + } + + case currentExecutableFile: + return executableFile; + + case currentApplicationFile: + { + const File parent (executableFile.getParentDirectory()); + + return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS")) + ? parent.getParentDirectory().getParentDirectory() + : executableFile; + } + + default: + jassertfalse // unknown type? + break; + } + + if (resultPath != 0) + return File (PlatformUtilities::convertToPrecomposedUnicode (resultPath)); + + return File::nonexistent; +} + +void juce_setCurrentExecutableFileName (const String& filename) throw() +{ + executableFile = File::getCurrentWorkingDirectory() + .getChildFile (PlatformUtilities::convertToPrecomposedUnicode (filename)); +} + +void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) throw() +{ + const ScopedAutoReleasePool pool; + + NSBundle* b = [NSBundle bundleWithIdentifier: juceStringToNS (bundleId)]; + + if (b != nil) + executableFile = nsStringToJuce ([b executablePath]); +} + +//============================================================================== +const File File::getCurrentWorkingDirectory() throw() +{ + char buf [2048]; + getcwd (buf, sizeof(buf)); + + return File (PlatformUtilities::convertToPrecomposedUnicode (buf)); +} + +bool File::setAsCurrentWorkingDirectory() const throw() +{ + return chdir (getFullPathName().toUTF8()) == 0; +} + +//============================================================================== +const String File::getVersion() const throw() +{ + const ScopedAutoReleasePool pool; + String result; + + NSBundle* bundle = [NSBundle bundleWithPath: juceStringToNS (getFullPathName())]; + + if (bundle != 0) + { + NSDictionary* info = [bundle infoDictionary]; + + if (info != 0) + { + NSString* name = [info valueForKey: @"CFBundleShortVersionString"]; + + if (name != nil) + result = nsStringToJuce (name); + } + } + + return result; +} + +//============================================================================== +const File File::getLinkedTarget() const throw() +{ + FSRef ref; + Boolean targetIsAFolder, wasAliased; + + if (PlatformUtilities::makeFSRefFromPath (&ref, getFullPathName()) + && (FSResolveAliasFileWithMountFlags (&ref, true, &targetIsAFolder, &wasAliased, 0) == noErr) + && wasAliased) + { + return File (PlatformUtilities::makePathFromFSRef (&ref)); + } + + return *this; +} + +//============================================================================== +bool File::moveToTrash() const throw() +{ + if (! exists()) + return true; + + const ScopedAutoReleasePool pool; + + NSString* p = juceStringToNS (getFullPathName()); + + return [[NSWorkspace sharedWorkspace] + performFileOperation: NSWorkspaceRecycleOperation + source: [p stringByDeletingLastPathComponent] + destination: @"" + files: [NSArray arrayWithObject: [p lastPathComponent]] + tag: nil ]; +} + +//============================================================================== +struct FindFileStruct +{ + String parentDir, wildCard; + DIR* dir; + + bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize, + Time* const modTime, Time* const creationTime, bool* const isReadOnly) throw() + { + const char* const wildCardUTF8 = wildCard.toUTF8(); + + for (;;) + { + struct dirent* const de = readdir (dir); + + if (de == 0) + break; + + if (fnmatch (wildCardUTF8, de->d_name, 0) == 0) + { + result = String::fromUTF8 ((const uint8*) de->d_name); + + const String path (parentDir + result); + + if (isDir != 0 || fileSize != 0) + { + struct stat info; + const bool statOk = juce_stat (path, info); + + if (isDir != 0) + *isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0)); + + if (isHidden != 0) + *isHidden = (de->d_name[0] == '.') + || juce_isHiddenFile (path); + + if (fileSize != 0) + *fileSize = statOk ? info.st_size : 0; + } + + if (modTime != 0 || creationTime != 0) + { + int64 m, a, c; + juce_getFileTimes (path, m, a, c); + + if (modTime != 0) + *modTime = m; + + if (creationTime != 0) + *creationTime = c; + } + + if (isReadOnly != 0) + *isReadOnly = ! juce_canWriteToFile (path); + + return true; + } + } + + return false; + } +}; + +// returns 0 on failure +void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, + bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, + Time* creationTime, bool* isReadOnly) throw() +{ + DIR* const d = opendir (directory.toUTF8()); + + if (d != 0) + { + FindFileStruct* const ff = new FindFileStruct(); + ff->parentDir = directory; + + if (!ff->parentDir.endsWithChar (File::separator)) + ff->parentDir += File::separator; + + ff->wildCard = wildCard; + ff->dir = d; + + if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) + { + return ff; + } + else + { + firstResultFile = String::empty; + isDir = false; + closedir (d); + delete ff; + } + } + + return 0; +} + +bool juce_findFileNext (void* handle, String& resultFile, + bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw() +{ + FindFileStruct* const ff = (FindFileStruct*) handle; + + if (ff != 0) + return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); + + return false; +} + +void juce_findFileClose (void* handle) throw() +{ + FindFileStruct* const ff = (FindFileStruct*)handle; + + if (ff != 0) + { + closedir (ff->dir); + delete ff; + } +} + +//============================================================================== +bool juce_launchExecutable (const String& pathAndArguments) throw() +{ + char* const argv[4] = { "/bin/sh", "-c", (char*) (const char*) pathAndArguments, 0 }; + + const int cpid = fork(); + + if (cpid == 0) + { + // Child process + if (execve (argv[0], argv, 0) < 0) + exit (0); + } + else + { + if (cpid < 0) + return false; + } + + return true; +} + +bool juce_launchFile (const String& fileName, + const String& parameters) throw() +{ + const ScopedAutoReleasePool pool; + + if (parameters.isEmpty()) + { + return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)] + || [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: juceStringToNS (fileName)]]; + } + + bool ok = false; + + FSRef ref; + if (PlatformUtilities::makeFSRefFromPath (&ref, fileName)) + { + if (PlatformUtilities::isBundle (fileName)) + { + NSMutableArray* urls = [NSMutableArray array]; + + StringArray docs; + docs.addTokens (parameters, true); + for (int i = 0; i < docs.size(); ++i) + [urls addObject: juceStringToNS (docs[i])]; + + ok = [[NSWorkspace sharedWorkspace] openURLs: urls + withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] + options: nil + additionalEventParamDescriptor: nil + launchIdentifiers: nil]; + } + else + { + ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters); + } + } + + return ok; +} + +//============================================================================== +bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) +{ + return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr; +} + +const String PlatformUtilities::makePathFromFSRef (FSRef* file) +{ + uint8 path [2048]; + zeromem (path, sizeof (path)); + + String result; + + if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr) + result = String::fromUTF8 (path); + + return PlatformUtilities::convertToPrecomposedUnicode (result); +} + +//============================================================================== +OSType PlatformUtilities::getTypeOfFile (const String& filename) +{ + const ScopedAutoReleasePool pool; + return NSHFSTypeCodeFromFileType (NSHFSTypeOfFile (juceStringToNS (filename))); +} + +bool PlatformUtilities::isBundle (const String& filename) +{ + const ScopedAutoReleasePool pool; + return [[NSWorkspace sharedWorkspace] isFilePackageAtPath: juceStringToNS (filename)]; +} + +#endif diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 881e7233db..fe1e38c1db 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -61350,7 +61350,7 @@ void LookAndFeel::drawImageButton (Graphics& g, Image* image, int imageX, int imageY, int imageW, int imageH, const Colour& overlayColour, float imageOpacity, - ImageButton& button) + ImageButton& /*button*/) { if (! overlayColour.isOpaque()) { @@ -257180,7 +257180,7 @@ public: } if (! outputDevice->setParameters ((unsigned int) sampleRate, - currentOutputChans.getHighestBit() + 1, + jmax (minChansOut, currentOutputChans.getHighestBit() + 1), bufferSize)) { error = outputDevice->error; @@ -257201,7 +257201,7 @@ public: } if (! inputDevice->setParameters ((unsigned int) sampleRate, - currentInputChans.getHighestBit() + 1, + jmax (minChansIn, currentInputChans.getHighestBit() + 1), bufferSize)) { error = inputDevice->error; @@ -265545,7 +265545,10 @@ bool juce_launchFile (const String& fileName, const ScopedAutoReleasePool pool; if (parameters.isEmpty()) - return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)]; + { + return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)] + || [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: juceStringToNS (fileName)]]; + } bool ok = false; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index f75b4fafca..cfd6647c6a 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -34011,7 +34011,7 @@ public: @see AudioDeviceManager::setAudioDeviceSetup() */ - struct AudioDeviceSetup + struct JUCE_API AudioDeviceSetup { AudioDeviceSetup(); bool operator== (const AudioDeviceSetup& other) const; diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h index 8b7caaf135..6a7b400e0a 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h @@ -99,7 +99,7 @@ public: @see AudioDeviceManager::setAudioDeviceSetup() */ - struct AudioDeviceSetup + struct JUCE_API AudioDeviceSetup { AudioDeviceSetup(); bool operator== (const AudioDeviceSetup& other) const; diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp index 96bb43dfcf..444f537774 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp @@ -1626,7 +1626,7 @@ void LookAndFeel::drawImageButton (Graphics& g, Image* image, int imageX, int imageY, int imageW, int imageH, const Colour& overlayColour, float imageOpacity, - ImageButton& button) + ImageButton& /*button*/) { if (! overlayColour.isOpaque()) {