From 982411ec8a02cd8e1aa8339fcd4700c95ed17d87 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 8 Aug 2017 03:36:56 -0400 Subject: [PATCH] apple: Start using some Cocoa APIs, clean up a few related things. --- CMakeLists.txt | 2 +- docs/INSTALL.txt | 5 +- src/physfs_platform_apple.m | 126 ++++++++++++++---------------------- src/physfs_platforms.h | 4 +- 4 files changed, 55 insertions(+), 82 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 37113aae..4635f97a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ endif() include_directories(./src) if(APPLE) - set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework CoreFoundation -framework IOKit") + set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework IOKit -framework Foundation") set(PHYSFS_M_SRCS src/physfs_platform_apple.m) endif() diff --git a/docs/INSTALL.txt b/docs/INSTALL.txt index b279336f..781b9735 100644 --- a/docs/INSTALL.txt +++ b/docs/INSTALL.txt @@ -29,7 +29,9 @@ ANSI C compiler, should build cleanly even with excessive compiler warnings enabled, needs no extra configuration, and allows static linking. WinRT and Haiku need C++ compilers for their system APIs, but if you aren't on these platforms and don't have a C++ compiler, don't build the .cpp files. -Everything you need is in the .c sources. +Likewise: Apple platforms (macOS, iOS, etc) need an Objective-C compiler, but +if you aren't on these platforms and don't have a Objective-C compiler, don't +build the .m file. Everything you need is in the .c sources. If this all worked for your specific project, you can stop reading now. @@ -101,7 +103,6 @@ options, and set the system name to "WindowsPhone" or "WindowsStore" and the correct OS version (8.0 or later). - PocketPC/WindowsCE: Support for PocketPC was removed in PhysicsFS 2.1.0. This was known to work diff --git a/src/physfs_platform_apple.m b/src/physfs_platform_apple.m index 64f8ecd1..6822d82f 100644 --- a/src/physfs_platform_apple.m +++ b/src/physfs_platform_apple.m @@ -1,5 +1,5 @@ /* - * macOS (iOS, etc) support routines for PhysicsFS. + * Apple platform (macOS, iOS, watchOS, etc) support routines for PhysicsFS. * * Please see the file LICENSE.txt in the source's root directory. * @@ -9,17 +9,13 @@ #define __PHYSICSFS_INTERNAL__ #include "physfs_internal.h" -#ifdef PHYSFS_PLATFORM_MACOS +#ifdef PHYSFS_PLATFORM_APPLE -#include +/* Foundation.h steps on these. :( */ +#undef malloc +#undef free -#if !defined(PHYSFS_NO_CDROM_SUPPORT) -#include -#include -#include -#include -#include -#endif +#include int __PHYSFS_platformInit(void) { @@ -33,6 +29,41 @@ void __PHYSFS_platformDeinit(void) } /* __PHYSFS_platformDeinit */ +char *__PHYSFS_platformCalcBaseDir(const char *argv0) +{ + @autoreleasepool + { + NSString *path = [[NSBundle mainBundle] bundlePath]; + BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL); + size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + char *retval = (char *) allocator.Malloc(len + 2); + BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL); + [path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding]; + retval[len] = '/'; + retval[len+1] = '\0'; + return retval; /* whew. */ + } /* @autoreleasepool */ +} /* __PHYSFS_platformCalcBaseDir */ + + +char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) +{ + @autoreleasepool + { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE); + BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL); + NSString *path = paths[0]; + BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL); + size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + const size_t applen = strlen(app); + char *retval = (char *) allocator.Malloc(len + applen + 3); + BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL); + [path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding]; + snprintf(retval + len, applen + 3, "/%s/", app); + return retval; /* whew. */ + } /* @autoreleasepool */ +} /* __PHYSFS_platformCalcPrefDir */ + /* CD-ROM detection code... */ @@ -43,6 +74,12 @@ void __PHYSFS_platformDeinit(void) #if !defined(PHYSFS_NO_CDROM_SUPPORT) +#include +#include +#include +#include +#include + static int darwinIsWholeMedia(io_service_t service) { int retval = 0; @@ -147,72 +184,7 @@ void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data) #endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */ } /* __PHYSFS_platformDetectAvailableCDs */ +#endif /* PHYSFS_PLATFORM_APPLE */ -static char *convertCFString(CFStringRef cfstr) -{ - CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), - kCFStringEncodingUTF8) + 1; - char *retval = (char *) allocator.Malloc(len); - BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL); - - if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8)) - { - /* shrink overallocated buffer if possible... */ - CFIndex newlen = strlen(retval) + 1; - if (newlen < len) - { - void *ptr = allocator.Realloc(retval, newlen); - if (ptr != NULL) - retval = (char *) ptr; - } /* if */ - } /* if */ - - else /* probably shouldn't fail, but just in case... */ - { - allocator.Free(retval); - BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL); - } /* else */ - - return retval; -} /* convertCFString */ - - -char *__PHYSFS_platformCalcBaseDir(const char *argv0) -{ - CFURLRef cfurl = NULL; - CFStringRef cfstr = NULL; - CFMutableStringRef cfmutstr = NULL; - char *retval = NULL; - - cfurl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - BAIL_IF(cfurl == NULL, PHYSFS_ERR_OS_ERROR, NULL); - cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle); - CFRelease(cfurl); - BAIL_IF(!cfstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL); - cfmutstr = CFStringCreateMutableCopy(NULL, 0, cfstr); - CFRelease(cfstr); - BAIL_IF(!cfmutstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL); - CFStringAppendCString(cfmutstr, "/", kCFStringEncodingUTF8); - retval = convertCFString(cfmutstr); - CFRelease(cfmutstr); - - return retval; /* whew. */ -} /* __PHYSFS_platformCalcBaseDir */ - - -char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) -{ - /* !!! FIXME-3.0: there's a real API to determine this */ - const char *userdir = __PHYSFS_getUserDir(); - const char *append = "Library/Application Support/"; - const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2; - char *retval = allocator.Malloc(len); - BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL); - snprintf(retval, len, "%s%s%s/", userdir, append, app); - return retval; -} /* __PHYSFS_platformCalcPrefDir */ - -#endif /* PHYSFS_PLATFORM_MACOS */ - -/* end of physfs_platform_macos.c ... */ +/* end of physfs_platform_apple.m ... */ diff --git a/src/physfs_platforms.h b/src/physfs_platforms.h index 7c7d94a7..734e1118 100644 --- a/src/physfs_platforms.h +++ b/src/physfs_platforms.h @@ -33,12 +33,12 @@ #elif defined(__OS2__) || defined(OS2) # define PHYSFS_PLATFORM_OS2 1 #elif ((defined __MACH__) && (defined __APPLE__)) -/* To check if iphone or not, we need to include this file */ +/* To check if iOS or not, we need to include this file */ # include # if ((TARGET_IPHONE_SIMULATOR) || (TARGET_OS_IPHONE)) # define PHYSFS_NO_CDROM_SUPPORT 1 # endif -# define PHYSFS_PLATFORM_MACOS 1 +# define PHYSFS_PLATFORM_APPLE 1 # define PHYSFS_PLATFORM_POSIX 1 #elif defined(macintosh) # error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.