X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fenvironment.cpp;h=e9cf2dc513e6f40f5cb986055fea64049435ab7b;hb=a1d293b87ead6c7e47140d041813ccbc6f159db4;hp=74de78b64e825171756cfd650984f8635237b6b1;hpb=fe73dd74d0e40a33c090993390e4d5721a1f9e05;p=xonotic%2Fnetradiant.git diff --git a/radiant/environment.cpp b/radiant/environment.cpp index 74de78b6..e9cf2dc5 100644 --- a/radiant/environment.cpp +++ b/radiant/environment.cpp @@ -20,6 +20,7 @@ */ #include "environment.h" +#include "globaldefs.h" #include "stream/textstream.h" #include "string/string.h" @@ -30,22 +31,26 @@ #include "cmdlib.h" int g_argc; -char** g_argv; +char const** g_argv; -void args_init( int argc, char* argv[] ){ +void args_init( int argc, char const* argv[] ){ int i, j, k; for ( i = 1; i < argc; i++ ) { for ( k = i; k < argc; k++ ) + { if ( argv[k] != 0 ) { break; } + } if ( k > i ) { k -= i; for ( j = i + k; j < argc; j++ ) + { argv[j - k] = argv[j]; + } argc -= k; } } @@ -54,8 +59,9 @@ void args_init( int argc, char* argv[] ){ g_argv = argv; } -char *gamedetect_argv_buffer[1024]; -void gamedetect_found_game( char *game, char *path ){ +char const *gamedetect_argv_buffer[1024]; + +void gamedetect_found_game( char const *game, char *path ){ int argc; static char buf[128]; @@ -79,7 +85,7 @@ void gamedetect_found_game( char *game, char *path ){ g_argv = gamedetect_argv_buffer; } -bool gamedetect_check_game( char *gamefile, const char *checkfile1, const char *checkfile2, char *buf /* must have 64 bytes free after bufpos */, int bufpos ){ +bool gamedetect_check_game( char const *gamefile, const char *checkfile1, const char *checkfile2, char *buf /* must have 64 bytes free after bufpos */, int bufpos ){ buf[bufpos] = '/'; strcpy( buf + bufpos + 1, checkfile1 ); @@ -108,12 +114,14 @@ void gamedetect(){ bool nogamedetect = true; int i; for ( i = 1; i < g_argc - 1; ++i ) + { if ( g_argv[i][0] == '-' ) { if ( !strcmp( g_argv[i], "-gamedetect" ) ) { nogamedetect = !strcmp( g_argv[i + 1], "false" ); } ++i; } + } if ( !nogamedetect ) { static char buf[1024 + 64]; strncpy( buf, environment_get_app_path(), sizeof( buf ) ); @@ -128,17 +136,19 @@ void gamedetect(){ // TODO add more games to this // try to detect Nexuiz installs -#if defined( WIN32 ) +#if GDEF_OS_WINDOWS if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "nexuiz.exe", buf, p - buf ) ) -#elif defined( __APPLE__ ) +#elif GDEF_OS_MACOS if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "Nexuiz.app/Contents/Info.plist", buf, p - buf ) ) -#else +#elif GDEF_OS_LINUX if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "nexuiz-linux-glx.sh", buf, p - buf ) ) +#else + if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", NULL, buf, p - buf ) ) #endif { return; } - // try to detect Q2World installs - if ( gamedetect_check_game( "q2w.game", "default/quake2world.version", NULL, buf, p - buf ) ) { + // try to detect Quetoo installs + if ( gamedetect_check_game( "quetoo.game", "default/icons/quetoo.png", NULL, buf, p - buf ) ) { return; } @@ -158,8 +168,17 @@ void gamedetect(){ namespace { -CopiedString home_path; -CopiedString app_path; + // executable file path + CopiedString app_filepath; + // directory paths + CopiedString home_path; + CopiedString app_path; + CopiedString lib_path; + CopiedString data_path; +} + +const char* environment_get_app_filepath(){ + return app_filepath.c_str(); } const char* environment_get_home_path(){ @@ -170,17 +189,27 @@ const char* environment_get_app_path(){ return app_path.c_str(); } +const char *environment_get_lib_path() +{ + return lib_path.c_str(); +} + +const char *environment_get_data_path() +{ + return data_path.c_str(); +} + bool portable_app_setup(){ StringOutputStream confdir( 256 ); confdir << app_path.c_str() << "settings/"; - if ( file_exists( confdir.c_str() ) ) { + if ( file_is_directory( confdir.c_str() ) ) { home_path = confdir.c_str(); return true; } return false; } -#if defined( POSIX ) +#if GDEF_OS_POSIX #include #include @@ -189,30 +218,34 @@ bool portable_app_setup(){ #include const char* LINK_NAME = -#if defined ( __linux__ ) +#if GDEF_OS_LINUX "/proc/self/exe" -#else // FreeBSD and OSX +#else // FreeBSD and macOS "/proc/curproc/file" #endif ; -/// brief Returns the filename of the executable belonging to the current process, or 0 if not found. -char* getexename( char *buf ){ +/// brief Returns the filename of the executable belonging to the current process, or empty string if not found. +char const* getexename( char *buf ){ /* Now read the symbolic link */ - int ret = readlink( LINK_NAME, buf, PATH_MAX ); + const int ret = readlink( LINK_NAME, buf, PATH_MAX ); if ( ret == -1 ) { globalOutputStream() << "getexename: falling back to argv[0]: " << makeQuoted( g_argv[0] ); - const char* path = realpath( g_argv[0], buf ); - if ( path == 0 ) { + if( realpath( g_argv[0], buf ) == 0 ) { /* In case of an error, leave the handling up to the caller */ - return ""; + *buf = '\0'; } } + else { + /* Ensure proper NUL termination */ + buf[ret] = 0; + } - /* Ensure proper NUL termination */ - buf[ret] = 0; + return buf; +} +char const* getexepath( char *buf ) { /* delete the program name */ *( strrchr( buf, '/' ) ) = '\0'; @@ -225,7 +258,7 @@ char* getexename( char *buf ){ return buf; } -void environment_init( int argc, char* argv[] ){ +void environment_init( int argc, char const* argv[] ){ // Give away unnecessary root privileges. // Important: must be done before calling gtk_init(). char *loginname; @@ -240,30 +273,102 @@ void environment_init( int argc, char* argv[] ){ { char real[PATH_MAX]; - app_path = getexename( real ); - ASSERT_MESSAGE( !string_empty( app_path.c_str() ), "failed to deduce app path" ); + app_filepath = getexename( real ); + ASSERT_MESSAGE( !string_empty( app_filepath.c_str() ), "failed to deduce app path" ); + + strncpy( real, app_filepath.c_str(), strlen( app_filepath.c_str() ) ); + app_path = getexepath( real ); + } + + { +#if defined(RADIANT_FHS_INSTALL) + StringOutputStream buffer; + #if defined(RADIANT_ADDONS_DIR) + buffer << RADIANT_ADDONS_DIR << "/"; + #else + buffer << app_path.c_str() << "../lib/"; + buffer << RADIANT_LIB_ARCH << "/"; + buffer << RADIANT_BASENAME << "/"; + #endif + lib_path = buffer.c_str(); +#else + lib_path = app_path.c_str(); +#endif + } + + { +#if defined(RADIANT_FHS_INSTALL) + StringOutputStream buffer; + #if defined(RADIANT_DATA_DIR) + buffer << RADIANT_DATA_DIR << "/"; + #else + buffer << app_path.c_str() << "../share/"; + buffer << RADIANT_BASENAME << "/"; + #endif + data_path = buffer.c_str(); +#else + data_path = app_path.c_str(); +#endif } if ( !portable_app_setup() ) { StringOutputStream home( 256 ); - home << DirectoryCleaned( g_get_home_dir() ) << ".netradiant/"; +#if GDEF_OS_MACOS + /* This is used on macOS, this will produce + ~/Library/Application Support/NetRadiant folder. */ + home << DirectoryCleaned( g_get_home_dir() ); + Q_mkdir( home.c_str() ); + home << "Library/"; + Q_mkdir( home.c_str() ); + home << "Application Support/"; + Q_mkdir( home.c_str() ); + home << RADIANT_NAME << "/"; +#else // if GDEF_OS_XDG + /* This is used on both Linux and FreeBSD, + this will produce ~/.config/netradiant folder + when environment has default settings, the + XDG_CONFIG_HOME variable modifies it. */ + home << DirectoryCleaned( g_get_user_config_dir() ); + Q_mkdir( home.c_str() ); + home << RADIANT_BASENAME << "/"; +#endif // ! GDEF_OS_MACOS Q_mkdir( home.c_str() ); home_path = home.c_str(); } + gamedetect(); } -#elif defined( WIN32 ) +#elif GDEF_OS_WINDOWS #include -void environment_init( int argc, char* argv[] ){ +char openCmdMap[260]; + +void cmdMap(){ + openCmdMap[0] = '\0'; + for ( int i = 1; i < g_argc; ++i ) + { + if ( !stricmp( g_argv[i] + strlen(g_argv[i]) - 4, ".map" ) ){ + strcpy( openCmdMap, g_argv[i] ); + } + } +} + +void environment_init( int argc, char const* argv[] ){ args_init( argc, argv ); { // get path to the editor char filename[MAX_PATH + 1]; + StringOutputStream app_filepath_stream( 256 ); + StringOutputStream app_path_stream( 256 ); + GetModuleFileName( 0, filename, MAX_PATH ); + + app_filepath_stream << PathCleaned( filename ); + app_filepath = app_filepath_stream.c_str(); + char* last_separator = strrchr( filename, '\\' ); if ( last_separator != 0 ) { *( last_separator + 1 ) = '\0'; @@ -272,28 +377,28 @@ void environment_init( int argc, char* argv[] ){ { filename[0] = '\0'; } - StringOutputStream app( 256 ); - app << PathCleaned( filename ); - app_path = app.c_str(); + + app_path_stream << PathCleaned( filename ); + app_path = app_path_stream.c_str(); + + lib_path = app_path; + data_path = app_path; } if ( !portable_app_setup() ) { char *appdata = getenv( "APPDATA" ); + StringOutputStream home( 256 ); - if ( !appdata || string_empty( appdata ) ) { - ERROR_MESSAGE( "Application Data folder not available.\n" - "Radiant will use C:\\ for user preferences.\n" ); - home << "C:"; - } - else - { - home << PathCleaned( appdata ); - } - home << "/NetRadiantSettings/"; + home << PathCleaned( appdata ); + home << "/"; + home << RADIANT_NAME; + home << "/"; + Q_mkdir( home.c_str() ); home_path = home.c_str(); } gamedetect(); + cmdMap(); } #else