2011-02-25 11:28:33 +00:00
|
|
|
/*
|
2011-01-05 14:00:14 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2018-06-04 18:47:57 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2011-01-05 14:00:14 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup GHOST
|
2011-02-25 11:28:33 +00:00
|
|
|
*/
|
|
|
|
|
Ghost: Support queries for special user directories (desktop, documents, etc.)
When we had to get special user directories, we'd usually do it in varying,
rather ad-hoc ways. It would be done with a bunch of `#ifdef`s for the
different operating systems. Also, some of the used Win32 functions were legacy
ones and the API docs recommend using newer ones.
Further, seems `BKE_appdir_folder_default()` used `XDG_DOCUMENTS_DIR` wrong.
It's not supposed to be an environment variable but a value inside a config
file.
This adds the platform dependent logic to Ghost, so we can abstract it away
nicely using the `GHOST_ISystemPaths` interface. Getting the desktop directory
for example can now easily be done with:
`GHOST_getUserSpecialDir(GHOST_kUserSpecialDirDesktop).`
For now I added the logic for desktop, documents, downloads, videos, images and
music directories, even though we only use the Documents one. We can extend/
change this as needed, it's easy to do now.
On Windows and macOS, it uses pretty much the same way to access the
directories as elsewhere already. On Linux, it uses the `xdg-user-dir` command
that seems to be available by default on most Linux systems.
No functional changes. The new queries are not actually used yet.
Differential Revision: https://developer.blender.org/D9800
Reviewed by: Brecht Van Lommel
2020-12-11 15:36:29 +01:00
|
|
|
#include <cstdio>
|
|
|
|
#include <sstream>
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
#include "GHOST_SystemPathsUnix.h"
|
2011-01-05 14:00:14 +00:00
|
|
|
|
|
|
|
#include "GHOST_Debug.h"
|
|
|
|
|
|
|
|
// For timing
|
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2012-07-21 22:58:08 +00:00
|
|
|
#include <cstdlib> /* for exit */
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <stdio.h> /* for fprintf only */
|
2011-01-05 14:00:14 +00:00
|
|
|
|
2012-07-21 22:58:08 +00:00
|
|
|
#include <pwd.h> /* for get home without use getenv() */
|
2013-08-20 08:33:04 +00:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
using std::string;
|
2011-11-02 22:00:22 +00:00
|
|
|
|
2011-08-07 17:38:36 +00:00
|
|
|
#ifdef PREFIX
|
2012-05-18 20:13:40 +00:00
|
|
|
static const char *static_path = PREFIX "/share";
|
2011-08-07 17:38:36 +00:00
|
|
|
#else
|
2012-05-18 20:13:40 +00:00
|
|
|
static const char *static_path = NULL;
|
2011-08-07 17:38:36 +00:00
|
|
|
#endif
|
2011-01-05 14:00:14 +00:00
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
GHOST_SystemPathsUnix::GHOST_SystemPathsUnix()
|
2011-01-05 14:00:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
GHOST_SystemPathsUnix::~GHOST_SystemPathsUnix()
|
2011-01-05 14:00:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
const GHOST_TUns8 *GHOST_SystemPathsUnix::getSystemDir(int, const char *versionstr) const
|
2011-01-05 14:00:14 +00:00
|
|
|
{
|
2011-03-25 05:23:58 +00:00
|
|
|
/* no prefix assumes a portable build which only uses bundled scripts */
|
2012-06-23 23:22:19 +00:00
|
|
|
if (static_path) {
|
2013-08-20 08:33:04 +00:00
|
|
|
static string system_path = string(static_path) + "/blender/" + versionstr;
|
|
|
|
return (GHOST_TUns8 *)system_path.c_str();
|
2012-05-25 12:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2011-01-05 14:00:14 +00:00
|
|
|
}
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *versionstr) const
|
2011-01-05 14:00:14 +00:00
|
|
|
{
|
2013-08-20 08:33:04 +00:00
|
|
|
static string user_path = "";
|
2013-10-07 16:06:15 +00:00
|
|
|
static int last_version = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-25 12:08:29 +00:00
|
|
|
/* in blender 2.64, we migrate to XDG. to ensure the copy previous settings
|
|
|
|
* operator works we give a different path depending on the requested version */
|
2012-06-23 23:22:19 +00:00
|
|
|
if (version < 264) {
|
2013-10-07 16:06:15 +00:00
|
|
|
if (user_path.empty() || last_version != version) {
|
2013-08-20 08:33:04 +00:00
|
|
|
const char *home = getenv("HOME");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-10-07 16:06:15 +00:00
|
|
|
last_version = version;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-20 08:33:04 +00:00
|
|
|
if (home) {
|
|
|
|
user_path = string(home) + "/.blender/" + versionstr;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-05-25 12:08:29 +00:00
|
|
|
}
|
2013-08-20 08:33:04 +00:00
|
|
|
return (GHOST_TUns8 *)user_path.c_str();
|
2011-11-02 22:00:22 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-10-07 16:06:15 +00:00
|
|
|
if (user_path.empty() || last_version != version) {
|
2013-08-20 08:33:04 +00:00
|
|
|
const char *home = getenv("XDG_CONFIG_HOME");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-10-07 16:06:15 +00:00
|
|
|
last_version = version;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-20 08:33:04 +00:00
|
|
|
if (home) {
|
|
|
|
user_path = string(home) + "/blender/" + versionstr;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
home = getenv("HOME");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-04 11:35:28 +10:00
|
|
|
if (home == NULL)
|
2013-08-20 08:33:04 +00:00
|
|
|
home = getpwuid(getuid())->pw_dir;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-20 08:33:04 +00:00
|
|
|
user_path = string(home) + "/.config/blender/" + versionstr;
|
|
|
|
}
|
2011-11-02 22:00:22 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-20 08:33:04 +00:00
|
|
|
return (const GHOST_TUns8 *)user_path.c_str();
|
2011-11-02 22:00:22 +00:00
|
|
|
}
|
2011-01-05 14:00:14 +00:00
|
|
|
}
|
|
|
|
|
Ghost: Support queries for special user directories (desktop, documents, etc.)
When we had to get special user directories, we'd usually do it in varying,
rather ad-hoc ways. It would be done with a bunch of `#ifdef`s for the
different operating systems. Also, some of the used Win32 functions were legacy
ones and the API docs recommend using newer ones.
Further, seems `BKE_appdir_folder_default()` used `XDG_DOCUMENTS_DIR` wrong.
It's not supposed to be an environment variable but a value inside a config
file.
This adds the platform dependent logic to Ghost, so we can abstract it away
nicely using the `GHOST_ISystemPaths` interface. Getting the desktop directory
for example can now easily be done with:
`GHOST_getUserSpecialDir(GHOST_kUserSpecialDirDesktop).`
For now I added the logic for desktop, documents, downloads, videos, images and
music directories, even though we only use the Documents one. We can extend/
change this as needed, it's easy to do now.
On Windows and macOS, it uses pretty much the same way to access the
directories as elsewhere already. On Linux, it uses the `xdg-user-dir` command
that seems to be available by default on most Linux systems.
No functional changes. The new queries are not actually used yet.
Differential Revision: https://developer.blender.org/D9800
Reviewed by: Brecht Van Lommel
2020-12-11 15:36:29 +01:00
|
|
|
const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const
|
|
|
|
{
|
|
|
|
const char *type_str;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case GHOST_kUserSpecialDirDesktop:
|
|
|
|
type_str = "DESKTOP";
|
|
|
|
break;
|
|
|
|
case GHOST_kUserSpecialDirDocuments:
|
|
|
|
type_str = "DOCUMENTS";
|
|
|
|
break;
|
|
|
|
case GHOST_kUserSpecialDirDownloads:
|
|
|
|
type_str = "DOWNLOAD";
|
|
|
|
break;
|
|
|
|
case GHOST_kUserSpecialDirMusic:
|
|
|
|
type_str = "MUSIC";
|
|
|
|
break;
|
|
|
|
case GHOST_kUserSpecialDirPictures:
|
|
|
|
type_str = "PICTURES";
|
|
|
|
break;
|
|
|
|
case GHOST_kUserSpecialDirVideos:
|
|
|
|
type_str = "VIDEOS";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
GHOST_ASSERT(
|
|
|
|
false,
|
|
|
|
"GHOST_SystemPathsUnix::getUserSpecialDir(): Invalid enum value for type parameter");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static string path = "";
|
|
|
|
string command = string("xdg-user-dir ") + type_str;
|
|
|
|
|
|
|
|
FILE *fstream = popen(command.c_str(), "r");
|
|
|
|
if (fstream == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
std::stringstream path_stream;
|
|
|
|
while (!feof(fstream)) {
|
|
|
|
char c = fgetc(fstream);
|
|
|
|
/* xdg-user-dir ends the path with '\n'. */
|
|
|
|
if (c == '\n') {
|
2020-12-15 12:01:45 +01:00
|
|
|
break;
|
Ghost: Support queries for special user directories (desktop, documents, etc.)
When we had to get special user directories, we'd usually do it in varying,
rather ad-hoc ways. It would be done with a bunch of `#ifdef`s for the
different operating systems. Also, some of the used Win32 functions were legacy
ones and the API docs recommend using newer ones.
Further, seems `BKE_appdir_folder_default()` used `XDG_DOCUMENTS_DIR` wrong.
It's not supposed to be an environment variable but a value inside a config
file.
This adds the platform dependent logic to Ghost, so we can abstract it away
nicely using the `GHOST_ISystemPaths` interface. Getting the desktop directory
for example can now easily be done with:
`GHOST_getUserSpecialDir(GHOST_kUserSpecialDirDesktop).`
For now I added the logic for desktop, documents, downloads, videos, images and
music directories, even though we only use the Documents one. We can extend/
change this as needed, it's easy to do now.
On Windows and macOS, it uses pretty much the same way to access the
directories as elsewhere already. On Linux, it uses the `xdg-user-dir` command
that seems to be available by default on most Linux systems.
No functional changes. The new queries are not actually used yet.
Differential Revision: https://developer.blender.org/D9800
Reviewed by: Brecht Van Lommel
2020-12-11 15:36:29 +01:00
|
|
|
}
|
|
|
|
path_stream << c;
|
|
|
|
}
|
|
|
|
if (pclose(fstream) == -1) {
|
|
|
|
perror("GHOST_SystemPathsUnix::getUserSpecialDir failed at pclose()");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = path_stream.str();
|
|
|
|
return (const GHOST_TUns8 *)path.c_str();
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const
|
2011-01-05 14:00:14 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:57:05 +11:00
|
|
|
void GHOST_SystemPathsUnix::addToSystemRecentFiles(const char * /*filename*/) const
|
2011-01-05 14:56:10 +00:00
|
|
|
{
|
2019-06-01 20:03:09 +02:00
|
|
|
/* TODO: implement for X11 */
|
2011-01-05 14:56:10 +00:00
|
|
|
}
|