1 /*
2  * This file is part of Siril, an astronomy image processor.
3  * Copyright (C) 2005-2011 Francois Meyer (dulle at free.fr)
4  * Copyright (C) 2012-2021 team free-astro (see more in AUTHORS file)
5  * Reference site is https://free-astro.org/index.php/Siril
6  *
7  * Siril is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Siril is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Siril. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "core/siril.h"
22 #include "core/proto.h"
23 
24 #include "siril_app_dirs.h"
25 
26 static GUserDirectory sdir[] = { G_USER_DIRECTORY_PICTURES,
27 		G_USER_DIRECTORY_DOCUMENTS };
28 
29 static const gchar *siril_share_dir = NULL;
30 static const gchar *siril_config_dir = NULL;
31 static const gchar *siril_startup_dir = NULL;
32 static const gchar *siril_locale_dir = NULL;
33 
34 /* To set the data dir we are looking for the glade file */
search_for_data_dir()35 static void search_for_data_dir() {
36 	gchar *path;
37 
38 	/* First we are looking for in the package_data_dir */
39 #ifdef _WIN32 // in the case where the app is started with double click on seq file
40 	gchar *execname = g_win32_get_package_installation_directory_of_module(NULL);
41 	path = g_build_filename(execname, "share", PACKAGE, NULL);
42 	g_free(execname);
43 	if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
44 		siril_share_dir = g_strdup(path);
45 	}
46 	g_free(path);
47 #elif defined(ENABLE_RELOCATABLE_RESOURCES) && defined(OS_OSX)
48 	const gchar *relocated_path = g_getenv("SIRIL_RELOCATED_RES_DIR");
49 	if (relocated_path != NULL) {
50 		path = g_build_filename(relocated_path, "share", PACKAGE, NULL);
51 		if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
52 			siril_share_dir = g_strdup(path);
53 		}
54 		g_free(path);
55 	}
56 #elif defined(ENABLE_RELOCATABLE_RESOURCES) && defined(__linux__) // appimage
57 	/* For AppImage */
58 	const gchar *relocated_path = g_getenv("APPDIR");
59 	if (relocated_path != NULL) {
60 		siril_share_dir = g_strdup(g_build_filename(relocated_path, "usr", "share", PACKAGE, NULL));
61 	}
62 #else
63 	path = g_build_filename(PACKAGE_DATA_DIR, NULL);
64 	if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
65 		siril_share_dir = g_strdup(path);
66 	}
67 	g_free(path);
68 #endif
69 	/* if not found we are looking for in the common dirs */
70 	if (siril_share_dir == NULL) {
71 		int i = 0;
72 		const gchar *const*system_data_dirs;
73 
74 		system_data_dirs = g_get_system_data_dirs();
75 
76 		do {
77 			path = g_build_filename(system_data_dirs[i], PACKAGE, NULL);
78 			gchar *gladefile = g_build_filename(path, GLADE_FILE, NULL);
79 
80 			/* data dir is the dir when a glade file is found */
81 			if (g_file_test(gladefile, G_FILE_TEST_EXISTS)) {
82 				siril_share_dir = g_strdup(path);
83 
84 				g_free(path);
85 				g_free(gladefile);
86 				break;
87 			}
88 			g_free(path);
89 			g_free(gladefile);
90 
91 			i++;
92 		} while (system_data_dirs[i] != NULL);
93 	}
94 }
95 
search_for_config_dir()96 static void search_for_config_dir() {
97 	siril_config_dir = g_get_user_config_dir();
98 }
99 
100 /** This function tries to set a startup directory. It first looks at the "Pictures" directory,
101  *  then if it does not exist, the "Document" one, Finally, if it fails on some UNIX systems
102  *  the dir is set to the home directory.
103  *  @return a working directory path if success, NULL if error
104  */
105 
search_for_startup_dir()106 static void search_for_startup_dir() {
107 	const gchar *dir = NULL;
108 	gint i = 0;
109 	size_t size;
110 
111 	size = sizeof(sdir) / sizeof(GUserDirectory);
112 
113 	while (dir == NULL && i < size) {
114 		dir = g_get_user_special_dir(sdir[i]);
115 		i++;
116 	}
117 	/* Not every platform has a directory for these logical id */
118 	if (dir == NULL) {
119 		dir = g_get_home_dir();
120 	}
121 	if (dir)
122 		siril_startup_dir = g_strdup(dir);
123 }
124 
125 /**
126  * This function search for the locale dir
127  * @return the locale dir
128  */
search_for_locale_dir()129 static void search_for_locale_dir() {
130 #ifdef _WIN32
131 	gchar *win32_dir;
132 
133 	win32_dir = g_win32_get_package_installation_directory_of_module(NULL);
134 	gchar *locale_dir = g_build_filename(win32_dir, "share", "locale", NULL);
135 
136 	g_free(win32_dir);
137 
138 	siril_locale_dir = locale_dir;
139 #elif defined(ENABLE_RELOCATABLE_RESOURCES) && defined(OS_OSX)
140 	const gchar *relocated_path = g_getenv("SIRIL_RELOCATED_RES_DIR");
141 	if (relocated_path != NULL) {
142 		siril_locale_dir = g_build_filename(relocated_path, "share", "locale", NULL);
143 	} else {
144 		gchar *path = g_build_filename(LOCALEDIR, NULL);
145 		if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
146 			siril_locale_dir = g_strdup(path);
147 		}
148 		g_free(path);
149 	}
150 #elif defined(ENABLE_RELOCATABLE_RESOURCES) && defined(__linux__) // appimage
151 	const gchar *relocated_path = g_getenv("APPDIR");
152 	if (relocated_path != NULL) {
153 		siril_locale_dir = g_build_filename(relocated_path, "usr", "share", "locale", NULL);
154 	}
155 #else
156 	gchar *path = g_build_filename(LOCALEDIR, NULL);
157 	if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
158 		siril_locale_dir = g_strdup(path);
159 	}
160 	g_free(path);
161 #endif
162 }
163 
164 /** Public functions **/
165 
siril_get_locale_dir()166 const gchar* siril_get_locale_dir() {
167 	return siril_locale_dir;
168 }
siril_get_startup_dir()169 const gchar* siril_get_startup_dir() {
170 	return siril_startup_dir;
171 }
172 
siril_get_system_data_dir()173 const gchar* siril_get_system_data_dir() {
174 	return siril_share_dir;
175 }
176 
siril_get_config_dir()177 const gchar* siril_get_config_dir() {
178 	return siril_config_dir;
179 }
180 
initialize_siril_directories()181 void initialize_siril_directories() {
182 	search_for_data_dir();
183 	search_for_locale_dir();
184 	search_for_startup_dir();
185 	search_for_config_dir();
186 }
187 
188