Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] XDG Base Dir Spec followup. #383

Merged
merged 5 commits into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/Util.h
Original file line number Diff line number Diff line change
@@ -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 };
Expand All @@ -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 *);
Expand Down
25 changes: 14 additions & 11 deletions src/common/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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");

Expand Down
2 changes: 1 addition & 1 deletion src/common/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
29 changes: 21 additions & 8 deletions src/sdl/SDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down Expand Up @@ -202,6 +205,7 @@ int sdlMirroringEnable = 1;
void systemConsoleMessage(const char*);

char* home;
char homeDataDir[2048];

char screenMessageBuffer[21];
uint32_t screenMessageTime = 0;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand Down
42 changes: 15 additions & 27 deletions src/wx/wxvbam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -79,19 +59,19 @@ 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;
}

// 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);
Expand Down Expand Up @@ -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);
Expand Down