XDG Base Dir Spec followup #383
* Add XDG Base Dir Spec for other Unix alike platform. * Add XDG Base Dir support for the fallback on SDL port. * Add migration for Unix configuration file. We migrate from 'vbam.conf' to 'vbam.ini' automatically. * Refactor code for portability of dir creation functions. * Fix for MacOS compilation directive.
This commit is contained in:
parent
39fd3f6580
commit
36453885fc
60
src/Util.cpp
60
src/Util.cpp
|
@ -64,6 +64,66 @@ bool FileExists(const char *filename)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Get user-specific config dir manually.
|
||||
// apple: ~/Library/Application Support/
|
||||
// windows: %APPDATA%
|
||||
// unix: ${XDG_CONFIG_HOME:-~/.config}
|
||||
std::string get_xdg_user_config_home()
|
||||
{
|
||||
std::string path;
|
||||
#ifdef __APPLE__
|
||||
std::string home(getenv("HOME"));
|
||||
path = home + "/Library/Application Support/";
|
||||
#elif _WIN32
|
||||
std::string app_data(getenv("LOCALAPPDATA"));
|
||||
path = app_data + '\\';
|
||||
#else // Unix
|
||||
char *xdg_var = getenv("XDG_CONFIG_HOME");
|
||||
if (!xdg_var || !*xdg_var)
|
||||
{
|
||||
std::string xdg_default(getenv("HOME"));
|
||||
xdg_default += "/.config";
|
||||
path = xdg_default;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = xdg_var;
|
||||
}
|
||||
path += '/';
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
// Get user-specific data dir manually.
|
||||
// apple: ~/Library/Application Support/
|
||||
// windows: %APPDATA%
|
||||
// unix: ${XDG_DATA_HOME:-~/.local/share}
|
||||
std::string get_xdg_user_data_home()
|
||||
{
|
||||
std::string path;
|
||||
#ifdef __APPLE__
|
||||
std::string home(getenv("HOME"));
|
||||
path = home + "/Library/Application Support/";
|
||||
#elif _WIN32
|
||||
std::string app_data(getenv("LOCALAPPDATA"));
|
||||
path = app_data + '\\';
|
||||
#else // Unix
|
||||
char *xdg_var = getenv("XDG_DATA_HOME");
|
||||
if (!xdg_var || !*xdg_var)
|
||||
{
|
||||
std::string xdg_default(getenv("HOME"));
|
||||
xdg_default += "/.local/share";
|
||||
path = xdg_default;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = xdg_var;
|
||||
}
|
||||
path += '/';
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
void utilReadScreenPixels(uint8_t *dest, int w, int h)
|
||||
{
|
||||
uint8_t *b = dest;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <string>
|
||||
#include "System.h"
|
||||
|
||||
enum IMAGE_TYPE { IMAGE_UNKNOWN = -1, IMAGE_GBA = 0, IMAGE_GB = 1 };
|
||||
|
@ -13,6 +14,9 @@ typedef struct {
|
|||
|
||||
bool FileExists(const char *filename);
|
||||
|
||||
std::string get_xdg_user_config_home();
|
||||
std::string get_xdg_user_data_home();
|
||||
|
||||
void utilReadScreenPixels(uint8_t *dest, int w, int h);
|
||||
bool utilWritePNGFile(const char *, int, int, uint8_t *);
|
||||
bool utilWriteBMPFile(const char *, int, int, uint8_t *);
|
||||
|
|
|
@ -38,6 +38,9 @@ extern "C" {
|
|||
#include <direct.h>
|
||||
#define GETCWD _getcwd
|
||||
#define snprintf sprintf
|
||||
#define stat _stat
|
||||
#define mkdir(X,Y) (_mkdir(X))
|
||||
#define S_ISDIR _S_IFDIR
|
||||
#endif // _WIN32
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
@ -647,7 +650,7 @@ const char* FindConfigFile(const char *name)
|
|||
}
|
||||
|
||||
if (homeDir) {
|
||||
sprintf(path, "%s%c%s%c%s", homeDir, FILE_SEP, DOT_DIR, FILE_SEP, name);
|
||||
sprintf(path, "%s%c%s", homeDir, FILE_SEP, name);
|
||||
if (FileExists(path))
|
||||
{
|
||||
return path;
|
||||
|
@ -717,11 +720,11 @@ const char* FindConfigFile(const char *name)
|
|||
|
||||
void LoadConfigFile()
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
homeDir = getenv("HOME");
|
||||
#else
|
||||
homeDir = 0;
|
||||
#endif
|
||||
struct stat s;
|
||||
std::string homeDirTmp = get_xdg_user_config_home() + FILE_SEP + DOT_DIR;
|
||||
homeDir = (char *)homeDirTmp.c_str();
|
||||
if (stat(homeDir, &s) == -1 || !S_ISDIR(s.st_mode))
|
||||
mkdir(homeDir, 0755);
|
||||
|
||||
if (preferences == NULL)
|
||||
{
|
||||
|
@ -738,11 +741,11 @@ void LoadConfigFile()
|
|||
|
||||
void SaveConfigFile()
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
homeDir = getenv("HOME");
|
||||
#else
|
||||
homeDir = 0;
|
||||
#endif
|
||||
struct stat s;
|
||||
std::string homeDirTmp = get_xdg_user_config_home() + FILE_SEP + DOT_DIR;
|
||||
homeDir = (char *)homeDirTmp.c_str();
|
||||
if (stat(homeDir, &s) == -1 || !S_ISDIR(s.st_mode))
|
||||
mkdir(homeDir, 0755);
|
||||
|
||||
const char* configFile = FindConfigFile("vbam.ini");
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ extern const char *saveDir;
|
|||
extern const char *batteryDir;
|
||||
|
||||
// Directory within homedir to use for default save location.
|
||||
#define DOT_DIR ".vbam"
|
||||
#define DOT_DIR "visualboyadvance-m"
|
||||
|
||||
void SetHome(char *_arg0);
|
||||
void SaveConfigFile();
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
#include <direct.h>
|
||||
#define GETCWD _getcwd
|
||||
#define snprintf sprintf
|
||||
#define stat _stat
|
||||
#define mkdir(X,Y) (_mkdir(X))
|
||||
#define S_ISDIR _S_IFDIR
|
||||
#endif // _WIN32
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
@ -202,6 +205,7 @@ int sdlMirroringEnable = 1;
|
|||
void systemConsoleMessage(const char*);
|
||||
|
||||
char* home;
|
||||
char homeDataDir[2048];
|
||||
|
||||
char screenMessageBuffer[21];
|
||||
uint32_t screenMessageTime = 0;
|
||||
|
@ -246,7 +250,7 @@ void StartLirc(void)
|
|||
fprintf(stdout, "Success\n");
|
||||
//read the config file
|
||||
char LIRCConfigLoc[2048];
|
||||
sprintf(LIRCConfigLoc, "%s/%s/%s", homeDir, DOT_DIR, "lircrc");
|
||||
sprintf(LIRCConfigLoc, "%s/%s", homeDataDir, "lircrc");
|
||||
fprintf(stdout, "LIRC Config file:");
|
||||
if (lirc_readconfig(LIRCConfigLoc, &LIRCConfigInfo, NULL) == 0) {
|
||||
//check vbam dir for lircrc
|
||||
|
@ -366,8 +370,8 @@ FILE* sdlFindFile(const char* name)
|
|||
}
|
||||
|
||||
if (homeDir) {
|
||||
fprintf(stdout, "Searching home directory: %s%c%s\n", homeDir, FILE_SEP, DOT_DIR);
|
||||
sprintf(path, "%s%c%s%c%s", homeDir, FILE_SEP, DOT_DIR, FILE_SEP, name);
|
||||
fprintf(stdout, "Searching home directory: %s\n", homeDataDir);
|
||||
sprintf(path, "%s%c%s", homeDataDir, FILE_SEP, name);
|
||||
f = fopen(path, "r");
|
||||
if (f != NULL)
|
||||
return f;
|
||||
|
@ -659,7 +663,7 @@ static char* sdlStateName(int num)
|
|||
sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
||||
num + 1);
|
||||
else if (homeDir)
|
||||
sprintf(stateName, "%s/%s/%s%d.sgm", homeDir, DOT_DIR, sdlGetFilename(filename), num + 1);
|
||||
sprintf(stateName, "%s/%s%d.sgm", homeDataDir, sdlGetFilename(filename), num + 1);
|
||||
else
|
||||
sprintf(stateName, "%s%d.sgm", filename, num + 1);
|
||||
|
||||
|
@ -758,7 +762,7 @@ void sdlWriteBattery()
|
|||
if (batteryDir)
|
||||
sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s/%s.sav", homeDir, DOT_DIR, sdlGetFilename(filename));
|
||||
sprintf(buffer, "%s/%s.sav", homeDataDir, sdlGetFilename(filename));
|
||||
else
|
||||
sprintf(buffer, "%s.sav", filename);
|
||||
|
||||
|
@ -774,7 +778,7 @@ void sdlReadBattery()
|
|||
if (batteryDir)
|
||||
sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s/%s.sav", homeDir, DOT_DIR, sdlGetFilename(filename));
|
||||
sprintf(buffer, "%s/%s.sav", homeDataDir, sdlGetFilename(filename));
|
||||
else
|
||||
sprintf(buffer, "%s.sav", filename);
|
||||
|
||||
|
@ -1637,12 +1641,21 @@ void handleRewinds()
|
|||
}
|
||||
}
|
||||
|
||||
void SetHomeDataDir()
|
||||
{
|
||||
sprintf(homeDataDir, "%s%s", get_xdg_user_data_home().c_str(), DOT_DIR);
|
||||
struct stat s;
|
||||
if (stat(homeDataDir, &s) == -1 || !S_ISDIR(s.st_mode))
|
||||
mkdir(homeDataDir, 0755);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
fprintf(stdout, "%s\n", VBA_NAME_AND_SUBVERSION);
|
||||
|
||||
home = argv[0];
|
||||
SetHome(home);
|
||||
SetHomeDataDir();
|
||||
|
||||
frameSkip = 2;
|
||||
gbBorderOn = 0;
|
||||
|
@ -2213,7 +2226,7 @@ void systemScreenCapture(int a)
|
|||
if (screenShotDir)
|
||||
sprintf(buffer, "%s/%s%02d.bmp", screenShotDir, sdlGetFilename(filename), a);
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s/%s%02d.bmp", homeDir, DOT_DIR, sdlGetFilename(filename), a);
|
||||
sprintf(buffer, "%s/%s%02d.bmp", homeDataDir, sdlGetFilename(filename), a);
|
||||
else
|
||||
sprintf(buffer, "%s%02d.bmp", filename, a);
|
||||
|
||||
|
@ -2222,7 +2235,7 @@ void systemScreenCapture(int a)
|
|||
if (screenShotDir)
|
||||
sprintf(buffer, "%s/%s%02d.png", screenShotDir, sdlGetFilename(filename), a);
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s/%s%02d.png", homeDir, DOT_DIR, sdlGetFilename(filename), a);
|
||||
sprintf(buffer, "%s/%s%02d.png", homeDataDir, sdlGetFilename(filename), a);
|
||||
else
|
||||
sprintf(buffer, "%s%02d.png", filename, a);
|
||||
emulator.emuWritePNG(buffer);
|
||||
|
|
|
@ -32,26 +32,6 @@
|
|||
IMPLEMENT_APP(wxvbamApp)
|
||||
IMPLEMENT_DYNAMIC_CLASS(MainFrame, wxFrame)
|
||||
|
||||
// Get XDG_CONFIG_HOME dir manually
|
||||
// only native support for XDG config when wxWidgets >= 3.1
|
||||
static wxString get_xdg_user_config_home()
|
||||
{
|
||||
wxString path;
|
||||
char *xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
// Default for XDG_CONFIG_HOME is '$HOME/.config'
|
||||
if (!xdg_config_home || !*xdg_config_home)
|
||||
{
|
||||
wxString xdg_default(getenv("HOME"));
|
||||
xdg_default += "/.config";
|
||||
path = xdg_default;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = xdg_config_home;
|
||||
}
|
||||
return path + "/";
|
||||
}
|
||||
|
||||
// generate config file path
|
||||
static void get_config_path(wxPathList& path, bool exists = true)
|
||||
{
|
||||
|
@ -79,7 +59,7 @@ static void get_config_path(wxPathList& path, bool exists = true)
|
|||
wxLogDebug(wxT("GetDataDir(): %s"), stdp.GetDataDir().mb_str());
|
||||
wxLogDebug(wxT("GetLocalDataDir(): %s"), stdp.GetLocalDataDir().mb_str());
|
||||
wxLogDebug(wxT("GetPluginsDir(): %s"), stdp.GetPluginsDir().mb_str());
|
||||
#if defined(__LINUX__)
|
||||
#if defined(__WXGTK__)
|
||||
wxLogDebug(wxT("XdgConfigDir: %s"), get_xdg_user_config_home() + current_app_name);
|
||||
#endif
|
||||
debug_dumped = true;
|
||||
|
@ -87,11 +67,11 @@ static void get_config_path(wxPathList& path, bool exists = true)
|
|||
|
||||
// When native support for XDG dirs is available (wxWidgets >= 3.1),
|
||||
// this will be no longer necessary
|
||||
#if defined(__LINUX__)
|
||||
#if defined(__WXGTK__)
|
||||
// XDG spec manual support
|
||||
// ${XDG_CONFIG_HOME:-$HOME/.config}/`appname`
|
||||
wxString old_config = wxString(getenv("HOME")) + "/.vbam";
|
||||
wxString new_config = get_xdg_user_config_home();
|
||||
wxString new_config(get_xdg_user_config_home());
|
||||
if (!wxDirExists(old_config) && wxIsWritable(new_config))
|
||||
{
|
||||
path.Add(new_config + current_app_name);
|
||||
|
@ -253,12 +233,20 @@ bool wxvbamApp::OnInit()
|
|||
// this needs to be in a subdir to support other config as well
|
||||
// but subdir flag behaves differently 2.8 vs. 2.9. Oh well.
|
||||
// NOTE: this does not support XDG (freedesktop.org) paths
|
||||
#if defined(__WXMSW__) || defined(__APPLE__)
|
||||
wxString confname("vbam.ini");
|
||||
#else
|
||||
wxString confname("vbam.conf");
|
||||
#endif
|
||||
wxFileName vbamconf(GetConfigurationPath(), confname);
|
||||
// /MIGRATION
|
||||
// migrate from 'vbam.conf' to 'vbam.ini' to manage a single config
|
||||
// file for all platforms.
|
||||
#if !defined(__WXMSW__) && !defined(__APPLE__)
|
||||
wxString oldConf(GetConfigurationPath() + "/vbam.conf");
|
||||
wxString newConf(GetConfigurationPath() + "/vbam.ini");
|
||||
if (wxFileExists(oldConf))
|
||||
{
|
||||
wxRenameFile(oldConf, newConf, false);
|
||||
}
|
||||
#endif
|
||||
// /END_MIGRATION
|
||||
cfg = new wxFileConfig(wxT("vbam"), wxEmptyString,
|
||||
vbamconf.GetFullPath(),
|
||||
wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
|
||||
|
|
Loading…
Reference in New Issue