mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-13 07:03:54 +00:00
filesystem: Implement SDL_GetExeName() for all platforms.
(cherry picked from commit d7ba3efe6b)
This commit is contained in:
@@ -266,7 +266,9 @@ extern "C" {
|
||||
anything calling it without an extremely good reason. */
|
||||
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
|
||||
|
||||
// Get just the process's binary name, no path. Calculates and caches the string on first call. String lives until SDL_Quit(). This is not a public API right now!
|
||||
// Get just the process's binary name, no path. NULL if it doesn't make sense for a platform.
|
||||
// Can be something not a file, like a package ID on Android. Meant to be human-readable, not appended to a path, etc.
|
||||
// Calculates and caches the string on first call. String lives until SDL_Quit(). This is not a public API right now!
|
||||
extern const char *SDL_GetExeName(void);
|
||||
|
||||
#ifdef HAVE_LIBC
|
||||
|
||||
@@ -2848,6 +2848,43 @@ int SDL_GetAndroidSDKVersion(void)
|
||||
return sdk_version;
|
||||
}
|
||||
|
||||
char *SDL_GetAndroidPackageName(void)
|
||||
{
|
||||
// this doesn't currently cache this, because it's only used by SDL_GetExeName, which _does_ cache it.
|
||||
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(SDL_FUNCTION);
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
if (!LocalReferenceHolder_Init(&refs, env)) {
|
||||
LocalReferenceHolder_Cleanup(&refs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// context = SDLActivity.getContext();
|
||||
jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
|
||||
if (!context) {
|
||||
SDL_SetError("Couldn't get Android context!");
|
||||
LocalReferenceHolder_Cleanup(&refs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// fileObj = context.getFilesDir();
|
||||
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), "getPackageName", "()Ljava/lang/String;");
|
||||
jstring jstr = (jstring)(*env)->CallObjectMethod(env, context, mid);
|
||||
if (Android_JNI_ExceptionOccurred(false)) {
|
||||
LocalReferenceHolder_Cleanup(&refs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
|
||||
char *retval = cstr ? SDL_strdup(cstr) : NULL;
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, cstr);
|
||||
|
||||
LocalReferenceHolder_Cleanup(&refs);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
bool SDL_IsAndroidTablet(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
|
||||
@@ -153,6 +153,8 @@ int SDL_GetAndroidSDKVersion(void);
|
||||
bool SDL_IsAndroidTablet(void);
|
||||
bool SDL_IsAndroidTV(void);
|
||||
|
||||
char *SDL_GetAndroidPackageName(void); // this is a SDL_malloc'd string the caller will own.
|
||||
|
||||
// File Dialogs
|
||||
bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void *userdata,
|
||||
const SDL_DialogFileFilter *filters, int nfilters, bool forwrite,
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
// System dependent filesystem routines
|
||||
|
||||
#include "../SDL_sysfilesystem.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
char *SDL_SYS_GetBasePath(void)
|
||||
{
|
||||
@@ -36,7 +35,7 @@ char *SDL_SYS_GetBasePath(void)
|
||||
|
||||
char *SDL_SYS_GetExeName(void)
|
||||
{
|
||||
return NULL; // !!! FIXME: probably just use the Linux path?
|
||||
return SDL_GetAndroidPackageName();
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
|
||||
@@ -47,7 +47,7 @@ char *SDL_SYS_GetBasePath(void)
|
||||
} else if (SDL_strcasecmp(baseType, "parent") == 0) {
|
||||
base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation];
|
||||
} else {
|
||||
// this returns the exedir for non-bundled and the resourceDir for bundled apps
|
||||
// this returns the exedir for non-bundled and the resourceDir for bundled apps
|
||||
base = [[bundle resourcePath] fileSystemRepresentation];
|
||||
}
|
||||
|
||||
@@ -65,8 +65,24 @@ char *SDL_SYS_GetBasePath(void)
|
||||
|
||||
char *SDL_SYS_GetExeName(void)
|
||||
{
|
||||
SDL_Unsupported(); // !!! FIXME
|
||||
return NULL;
|
||||
@autoreleasepool {
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
const char *name = [[[bundle infoDictionary] objectForKey:@"CFBundleIdentifier"] UTF8String];
|
||||
if (!name) {
|
||||
name = [[[bundle infoDictionary] objectForKey:@"CFBundleDisplayName"] UTF8String];
|
||||
if (!name) {
|
||||
name = [[[bundle infoDictionary] objectForKey:@"CFBundleName"] UTF8String];
|
||||
if (!name) {
|
||||
name = [[[bundle infoDictionary] objectForKey:@"CFBundleExecutable"] UTF8String];
|
||||
if (!name) {
|
||||
name = [[[NSProcessInfo processInfo] processName] UTF8String]; // oh well.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name ? SDL_strdup(name) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
|
||||
@@ -44,6 +44,7 @@ char *SDL_SYS_GetBasePath(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// !!! FIXME: if find_path promises an absolute path, can we dump this and just do SDL_strrchr(name, '/')?
|
||||
BEntry entry(name, true);
|
||||
BPath path;
|
||||
status_t rc = entry.GetPath(&path); // (path) now has binary's path.
|
||||
@@ -66,8 +67,12 @@ char *SDL_SYS_GetBasePath(void)
|
||||
|
||||
char *SDL_SYS_GetExeName(void)
|
||||
{
|
||||
SDL_Unsupported(); // !!! FIXME: Move most of SDL_SYS_GetBasePath to a separate function and reuse it here.
|
||||
return NULL;
|
||||
char name[MAXPATHLEN];
|
||||
if (find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, name, sizeof(name)) != B_OK) {
|
||||
return NULL;
|
||||
}
|
||||
char *ptr = SDL_strrchr(name, '/');
|
||||
return SDL_strdup(ptr ? ptr + 1 : name);
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "SDL_internal.h"
|
||||
|
||||
extern void NGAGE_GetAppPath(char *path);
|
||||
extern void NGAGE_GetExeName(char *path);
|
||||
|
||||
char *SDL_SYS_GetBasePath(void)
|
||||
{
|
||||
@@ -32,8 +33,9 @@ char *SDL_SYS_GetBasePath(void)
|
||||
|
||||
char *SDL_SYS_GetExeName(void)
|
||||
{
|
||||
SDL_Unsupported(); // !!! FIXME: see code in NGAGE_GetAppPath
|
||||
return NULL;
|
||||
char exe_name[512];
|
||||
NGAGE_GetExeName(exe_name);
|
||||
return SDL_strdup(exe_name);
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
|
||||
@@ -63,6 +63,23 @@ void NGAGE_GetAppPath(char *path)
|
||||
}
|
||||
}
|
||||
|
||||
void NGAGE_GetExeName(char *path)
|
||||
{
|
||||
TBuf<512> aPath;
|
||||
|
||||
TFileName fullExePath = RProcess().FileName();
|
||||
|
||||
TParsePtrC parser(fullExePath);
|
||||
aPath.Copy(parser.NameAndExt());
|
||||
|
||||
TBuf8<512> utf8Path; // Temporary buffer for UTF-8 data.
|
||||
CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8Path, aPath);
|
||||
|
||||
// Copy UTF-8 data to the provided char* buffer.
|
||||
strncpy(path, (const char *)utf8Path.Ptr(), utf8Path.Length());
|
||||
path[utf8Path.Length()] = '\0';
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -154,8 +154,25 @@ char *SDL_SYS_GetBasePath(void)
|
||||
|
||||
char *SDL_SYS_GetExeName(void)
|
||||
{
|
||||
SDL_Unsupported(); // !!! FIXME: see code in SDL_SYS_GetBasePath.
|
||||
return NULL;
|
||||
_kernel_swi_regs regs;
|
||||
_kernel_oserror *error;
|
||||
char *canon, *ptr, *retval;
|
||||
|
||||
error = _kernel_swi(OS_GetEnv, ®s, ®s);
|
||||
if (error) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
canon = canonicalisePath((const char *)regs.r[0], "Run$Path");
|
||||
if (!canon) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// find filename.
|
||||
ptr = SDL_strrchr(canon, '.');
|
||||
retval = SDL_strdup(ptr ? ptr + 1 : canon);
|
||||
SDL_free(canon);
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
|
||||
@@ -94,6 +94,9 @@ int main(int argc, char *argv[])
|
||||
char *curdir;
|
||||
const char *base_path;
|
||||
|
||||
/* this will be SDL's best guess at the human-readable exe name (or bundle id, or whatever) by default. */
|
||||
SDL_Log("Default app name: '%s'", SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING));
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, 0);
|
||||
if (!state) {
|
||||
|
||||
Reference in New Issue
Block a user