~midori/midori/trunk

5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
1
/*
2
 Copyright (C) 2012 Christian Dywan <christian@twotoasts.de>
3
4
 This library is free software; you can redistribute it and/or
5
 modify it under the terms of the GNU Lesser General Public
6
 License as published by the Free Software Foundation; either
7
 version 2.1 of the License, or (at your option) any later version.
8
9
 See the file COPYING for the full license text.
10
*/
11
12
namespace GLib {
13
    #if HAVE_WIN32
14
    extern static string win32_get_package_installation_directory_of_module (void* hmodule = null);
15
    #endif
16
}
17
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
18
extern const string LIBDIR;
19
extern const string MDATADIR;
20
extern const string PACKAGE_NAME;
21
extern const string SYSCONFDIR;
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
22
extern const string MIDORI_VERSION_SUFFIX;
5558 by Christian Dywan
Introduce get_extension_config_dir/ _get_preset_filename
23
const string MODULE_PREFIX = "lib";
24
const string MODULE_SUFFIX = "." + GLib.Module.SUFFIX;
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
25
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
26
namespace Midori {
27
    public enum RuntimeMode {
28
        UNDEFINED,
29
        NORMAL,
30
        APP,
31
        PRIVATE,
32
        PORTABLE
33
    }
34
35
    namespace Paths {
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
36
        static string? exec_path = null;
37
        static string[] command_line = null;
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
38
        static string? runtime_dir = null;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
39
        static RuntimeMode mode = RuntimeMode.UNDEFINED;
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
40
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
41
        static string? config_dir = null;
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
42
        static string? readonly_dir = null;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
43
        static string? cache_dir = null;
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
44
        static string? cache_dir_for_reading = null;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
45
        static string? user_data_dir = null;
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
46
        static string? user_data_dir_for_reading = null;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
47
        static string? tmp_dir = null;
48
5544 by Christian Dywan
Move normal, web and private app to frontend
49
        namespace Test {
50
            public void reset_runtime_mode () {
51
                mode = RuntimeMode.UNDEFINED;
52
            }
53
        }
54
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
55
        public static string get_config_dir_for_reading () {
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
56
            assert (mode != RuntimeMode.UNDEFINED);
57
            return readonly_dir ?? config_dir;
58
        }
59
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
60
        /* returns the path to a user configuration file whose contents should not be modified.
61
        to get the path to save settings, use get_config_filename() */
62
        public static string get_config_filename_for_reading (string filename) {
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
63
            assert (mode != RuntimeMode.UNDEFINED);
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
64
            return Path.build_path (Path.DIR_SEPARATOR_S,
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
65
                readonly_dir ?? config_dir, filename);
66
        }
67
68
        public bool is_readonly () {
69
            assert (mode != RuntimeMode.UNDEFINED);
70
            return readonly_dir != null;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
71
        }
72
5381 by Christian Dywan
Make 'special' a property and add test cases
73
        public RuntimeMode get_runtime_mode () {
74
            assert (mode != RuntimeMode.UNDEFINED);
75
            return mode;
76
        }
77
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
78
        public static unowned string get_runtime_dir () {
79
            if (runtime_dir != null)
80
                return runtime_dir;
81
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
82
            #if HAVE_WIN32
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
83
            runtime_dir = Environment.get_variable ("XDG_RUNTIME_DIR");
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
84
            if (runtime_dir == null || runtime_dir == "")
85
                runtime_dir = Environment.get_user_data_dir ();
86
            #else
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
87
            runtime_dir = Environment.get_variable ("XDG_RUNTIME_DIR");
88
            if (runtime_dir == null || runtime_dir == "") {
89
                runtime_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
90
                    Environment.get_tmp_dir (), PACKAGE_NAME + "-" + Environment.get_user_name ());
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
91
                mkdir_with_parents (runtime_dir);
92
                return runtime_dir;
93
            }
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
94
            #endif
5942 by Christian Dywan
Add 'Show last crash log' button to diagnostic dialog
95
            runtime_dir = Path.build_path (Path.DIR_SEPARATOR_S, runtime_dir, PACKAGE_NAME);
96
            mkdir_with_parents (runtime_dir);
97
            return runtime_dir;
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
98
        }
99
5542 by Christian Dywan
Handle relative config in Midori.Paths.init
100
        public static void init (RuntimeMode new_mode, string? config) {
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
101
            assert (mode == RuntimeMode.UNDEFINED);
102
            assert (new_mode != RuntimeMode.UNDEFINED);
103
            mode = new_mode;
5508 by Christian Dywan
Handle recent files disabling in Midori.Paths
104
            if (mode == RuntimeMode.PORTABLE || mode == RuntimeMode.PRIVATE)
105
                Gtk.Settings.get_default ().gtk_recent_files_max_age = 0;
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
106
            if (mode == RuntimeMode.PORTABLE) {
107
                config_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
108
                    exec_path, "profile", "config");
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
109
                cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
110
                    exec_path, "profile", "cache");
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
111
                user_data_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
112
                    exec_path, "profile", "misc");
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
113
                tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
114
                    exec_path, "profile", "tmp");
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
115
            }
6172.3.2 by Christian Dywan
Store data of app mode based on URL in ~/.local/share/midori/apps
116
            else if (mode == RuntimeMode.APP) {
117
                config_dir = Path.build_path (Path.DIR_SEPARATOR_S,
118
                    Environment.get_user_data_dir (), PACKAGE_NAME, "apps",
119
                    Checksum.compute_for_string (ChecksumType.MD5, config, -1));
120
                cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
121
                    Environment.get_user_cache_dir (), PACKAGE_NAME);
122
                user_data_dir_for_reading = Environment.get_user_data_dir ();
123
                tmp_dir = get_runtime_dir ();
124
            }
125
            else if (mode == RuntimeMode.PRIVATE) {
5542 by Christian Dywan
Handle relative config in Midori.Paths.init
126
                string? real_config = config != null && !Path.is_absolute (config)
127
                    ? Path.build_filename (Environment.get_current_dir (), config) : config;
128
                readonly_dir = real_config ?? Path.build_path (Path.DIR_SEPARATOR_S,
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
129
                    Environment.get_user_config_dir (), PACKAGE_NAME);
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
130
                cache_dir_for_reading = Path.build_path (Path.DIR_SEPARATOR_S,
131
                    Environment.get_user_cache_dir (), PACKAGE_NAME);
132
                user_data_dir_for_reading = Environment.get_user_data_dir ();
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
133
                tmp_dir = get_runtime_dir ();
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
134
            }
135
            else {
5542 by Christian Dywan
Handle relative config in Midori.Paths.init
136
                string? real_config = config != null && !Path.is_absolute (config)
137
                    ? Path.build_filename (Environment.get_current_dir (), config) : config;
138
                config_dir = real_config ?? Path.build_path (Path.DIR_SEPARATOR_S,
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
139
                    Environment.get_user_config_dir (), PACKAGE_NAME);
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
140
                cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
141
                    Environment.get_user_cache_dir (), PACKAGE_NAME);
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
142
                user_data_dir = Environment.get_user_data_dir ();
6306.2.1 by Christian Dywan
Enable set_disk_cache_directory with WebKit2
143
#if HAVE_WEBKIT2
6026 by Christian Dywan
Implement view-based favicon handling for WebKit2
144
                WebKit.WebContext.get_default ().set_disk_cache_directory (
145
                    Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "web"));
6050 by Christian Dywan
Enable rudimentary cookie storage with WebKit2
146
                var cookie_manager = WebKit.WebContext.get_default ().get_cookie_manager ();
147
                cookie_manager.set_persistent_storage (Path.build_filename (config, "cookies.db"),
148
                    WebKit.CookiePersistentStorage.SQLITE);
149
#endif
5914 by Christian Dywan
Use XDG_RUNTIME_DIR for temporary files
150
                tmp_dir = get_runtime_dir ();
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
151
            }
5678 by Christian Dywan
Optimize icon lookups and tag received icon-loaded
152
            if (user_data_dir != null) {
153
                string folder = Path.build_filename (user_data_dir, "webkit", "icondatabase");
6026 by Christian Dywan
Implement view-based favicon handling for WebKit2
154
#if HAVE_WEBKIT2
155
                WebKit.WebContext.get_default ().set_favicon_database_directory (folder);
6216.1.9 by Christian Dywan
Drop unneeded WebKit < 1.8 version guards
156
#else
5678 by Christian Dywan
Optimize icon lookups and tag received icon-loaded
157
                WebKit.get_favicon_database ().set_path (folder);
158
#endif
159
            }
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
160
            if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
161
                stdout.printf ("config: %s\ncache: %s\nuser_data: %s\ntmp: %s\n",
162
                               config_dir, cache_dir, user_data_dir, tmp_dir);
163
            }
164
        }
165
5444 by Christian Dywan
Consistent xdg and tmp folder setup for unit tests
166
        public static void mkdir_with_parents (string path, int mode = 0700) {
167
            /* Use g_access instead of g_file_test for better performance */
168
            if (Posix.access (path, Posix.F_OK) == 0)
169
                return;
170
            int i = path.index_of_char (Path.DIR_SEPARATOR, 0);
171
            do {
172
                string fn = path.substring (i, -1);
173
                if (Posix.access (fn, Posix.F_OK) != 0) {
5558 by Christian Dywan
Introduce get_extension_config_dir/ _get_preset_filename
174
                    if (DirUtils.create (fn, mode) == -1) {
175
                        /* Slow fallback; if this fails we fail */
176
                        DirUtils.create_with_parents (path, mode);
177
                        return;
178
                    }
5444 by Christian Dywan
Consistent xdg and tmp folder setup for unit tests
179
                }
180
                else if (!FileUtils.test (fn, FileTest.IS_SYMLINK))
181
                    return; /* Failed */
182
183
                i = path.index_of_char (Path.DIR_SEPARATOR, i);
184
            }
185
            while (i != -1);
186
        }
187
5493 by Christian Dywan
Converge private data registration and dialog
188
        public static void remove_path (string path) {
189
            try {
190
                var dir = Dir.open (path, 0);
191
                string? name;
192
                while (true) {
193
                    name = dir.read_name ();
194
                    if (name == null)
195
                        break;
196
                    remove_path (Path.build_filename (path, name));
197
                }
198
            }
199
            catch (Error error) {
200
                FileUtils.remove (path);
201
            }
202
        }
203
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
204
        public static unowned string get_config_dir_for_writing () {
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
205
            assert (config_dir != null);
5444 by Christian Dywan
Consistent xdg and tmp folder setup for unit tests
206
            mkdir_with_parents (config_dir);
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
207
            return config_dir;
208
        }
209
5558 by Christian Dywan
Introduce get_extension_config_dir/ _get_preset_filename
210
        public static string get_extension_config_dir (string extension) {
211
            assert (config_dir != null);
212
            string folder;
213
            if ("." in extension)
214
                folder = Path.build_filename (config_dir, "extensions", extension);
215
            else
216
                folder = Path.build_filename (config_dir, "extensions",
217
                    MODULE_PREFIX + extension + "." + GLib.Module.SUFFIX);
218
            mkdir_with_parents (folder);
219
            return folder;
220
        }
221
222
        public static string get_extension_preset_filename (string extension, string filename) {
223
            assert (exec_path != null);
224
            string preset_filename = extension;
225
            if (extension.has_prefix (MODULE_PREFIX))
226
                preset_filename = extension.split (MODULE_PREFIX)[1];
227
            if (extension.has_suffix (MODULE_SUFFIX))
228
                preset_filename = preset_filename.split (MODULE_SUFFIX)[0];
229
            return get_preset_filename (Path.build_filename ("extensions", preset_filename), filename);
230
        }
231
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
232
        /* returns the path to a user configuration file to which it is permitted to write.
233
        this is also necessary for files whose state is synchronized to disk by a manager,
234
        e.g. cookies. */
235
        public static string get_config_filename_for_writing (string filename) {
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
236
            assert (mode != RuntimeMode.UNDEFINED);
237
            assert (config_dir != null);
5511 by Christian Dywan
Further align bookmarks and history
238
            mkdir_with_parents (config_dir);
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
239
            return Path.build_path (Path.DIR_SEPARATOR_S, config_dir, filename);
240
        }
241
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
242
        public static unowned string get_cache_dir () {
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
243
            assert (cache_dir != null);
244
            return cache_dir;
245
        }
246
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
247
        public static unowned string get_user_data_dir () {
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
248
            assert (user_data_dir != null);
249
            return user_data_dir;
250
        }
251
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
252
        public static unowned string get_user_data_dir_for_reading () {
253
            assert (user_data_dir_for_reading != null || user_data_dir != null);
254
            if (user_data_dir != null)
255
                return user_data_dir;
256
            return user_data_dir_for_reading;
257
        }
258
259
        public static unowned string get_cache_dir_for_reading () {
260
            assert (cache_dir_for_reading != null || cache_dir != null);
261
            if (cache_dir != null)
262
                return cache_dir;
263
            return cache_dir_for_reading;
264
        }
265
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
266
        public static unowned string get_tmp_dir () {
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
267
            assert (tmp_dir != null);
268
            return tmp_dir;
269
        }
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
270
5486 by Christian Dywan
Add make_tmp_dir to Midori.Paths API
271
        public static string make_tmp_dir (string tmpl) {
272
            assert (tmp_dir != null);
273
            try {
274
                return DirUtils.make_tmp (tmpl);
275
            }
276
            catch (Error error) {
277
                GLib.error (error.message);
278
            }
279
        }
280
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
281
        public static void init_exec_path (string[] new_command_line) {
282
            assert (command_line == null);
283
            command_line = new_command_line;
284
            #if HAVE_WIN32
5647 by Christian Dywan
Set MIDORI_EXEC_PATH to PREFIX under Wine
285
            exec_path = Environment.get_variable ("MIDORI_EXEC_PATH") ??
286
                win32_get_package_installation_directory_of_module ();
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
287
            #else
288
            string? executable;
289
            try {
290
                if (!Path.is_absolute (command_line[0])) {
291
                    string program = Environment.find_program_in_path (command_line[0]);
292
                    if (FileUtils.test (program, FileTest.IS_SYMLINK))
293
                        executable = FileUtils.read_link (program);
294
                    else
295
                        executable = program;
296
                }
297
                else
298
                    executable = FileUtils.read_link (command_line[0]);
299
            }
300
            catch (Error error) {
301
                executable = command_line[0];
302
            }
303
304
            exec_path = File.new_for_path (executable).get_parent ().get_parent ().get_path ();
305
            #endif
306
            if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
307
                stdout.printf ("command_line: %s\nexec_path: %s\nres: %s\nlib: %s\n",
5761 by Christian Dywan
Add --debug/ -g switch to run Midori in gdb
308
                               get_command_line_str (true), exec_path,
6312.2.25 by Christian Dywan
Require a filename passes to get_res_filename for best results
309
                               get_res_filename ("about.css"), get_lib_path (PACKAGE_NAME));
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
310
            }
311
        }
312
313
        public static unowned string[] get_command_line () {
314
            assert (command_line != null);
315
            return command_line;
316
        }
317
5761 by Christian Dywan
Add --debug/ -g switch to run Midori in gdb
318
        public static string get_command_line_str (bool for_display) {
5224 by Christian Dywan
Add get_command_line_str for debugging output
319
            assert (command_line != null);
5761 by Christian Dywan
Add --debug/ -g switch to run Midori in gdb
320
            if (for_display)
321
                return string.joinv (" ", command_line).replace (Environment.get_home_dir (), "~");
5958 by Christian Dywan
Implement 'Run in debugger' button in diagnostic dialog
322
            return string.joinv (" ", command_line).replace ("--debug", "").replace ("-g", "")
323
                .replace ("--diagnostic-dialog", "").replace ("-d", "");
5224 by Christian Dywan
Add get_command_line_str for debugging output
324
        }
325
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
326
        public static string get_lib_path (string package) {
327
            assert (command_line != null);
5248 by Christian Dywan
Always use exec_path based paths on Win32
328
            #if HAVE_WIN32
329
            return Path.build_filename (exec_path, "lib", package);
330
            #else
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
331
            string path = Path.build_filename (exec_path, "lib", package);
332
            if (Posix.access (path, Posix.F_OK) == 0)
333
                return path;
334
335
            if (package == PACKAGE_NAME) {
336
                /* Fallback to build folder */
337
                path = Path.build_filename ((File.new_for_path (exec_path).get_path ()), "extensions");
338
                if (Posix.access (path, Posix.F_OK) == 0)
339
                    return path;
340
            }
341
342
            return Path.build_filename (LIBDIR, PACKAGE_NAME);
5248 by Christian Dywan
Always use exec_path based paths on Win32
343
            #endif
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
344
        }
345
346
        public static string get_res_filename (string filename) {
347
            assert (command_line != null);
6312.2.25 by Christian Dywan
Require a filename passes to get_res_filename for best results
348
            assert (filename != "");
5248 by Christian Dywan
Always use exec_path based paths on Win32
349
            #if HAVE_WIN32
350
            return Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
351
            #else
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
352
            string path = Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
353
            if (Posix.access (path, Posix.F_OK) == 0)
354
                return path;
355
356
            /* Fallback to build folder */
6312.2.23 by Christian Dywan
Make get_res_filename work with different hierarchies
357
            File? parent = File.new_for_path (exec_path).get_parent ();
358
            while (parent != null) {
359
                var data = parent.get_child ("data");
6312.2.24 by Christian Dywan
Check for res filename to exist within data, not just the folder
360
                var child = data.get_child (filename);
361
                if (child.query_exists ())
362
                    return child.get_path ();
6312.2.23 by Christian Dywan
Make get_res_filename work with different hierarchies
363
                parent = parent.get_parent ();
364
            }
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
365
            return Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename);
5248 by Christian Dywan
Always use exec_path based paths on Win32
366
            #endif
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
367
        }
368
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
369
        /* returns the path to a file containing read-only data installed with the application
370
        if @res is true, looks in the midori resource folder specifically */
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
371
        public static string get_data_filename (string filename, bool res) {
372
            assert (command_line != null);
373
            string res1 = res ? PACKAGE_NAME : "";
374
            string res2 = res ? "res" : "";
375
376
            #if HAVE_WIN32
5248 by Christian Dywan
Always use exec_path based paths on Win32
377
            return Path.build_filename (exec_path, "share", res1, res2, filename);
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
378
            #else
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
379
            string path = Path.build_filename (get_user_data_dir_for_reading (), res1, res2, filename);
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
380
            if (Posix.access (path, Posix.F_OK) == 0)
381
                return path;
382
383
            foreach (string data_dir in Environment.get_system_data_dirs ()) {
384
                path = Path.build_filename (data_dir, res1, res2, filename);
385
                if (Posix.access (path, Posix.F_OK) == 0)
386
                    return path;
387
            }
388
389
            return Path.build_filename (MDATADIR, res1, res2, filename);
5248 by Christian Dywan
Always use exec_path based paths on Win32
390
            #endif
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
391
        }
392
5367 by Christian Dywan
Rename Paths.get_config_dir/filename _for_reading/writing
393
        /* returns the path to a file containing system default configuration */
5313 by Christian Dywan
Consistently use readonly_config_filename for loading
394
        public static string get_preset_filename (string? folder, string filename) {
5371 by Christian Dywan
Introduce _for_reading versions for cache and data
395
            assert (exec_path != null);
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
396
5248 by Christian Dywan
Always use exec_path based paths on Win32
397
            #if HAVE_WIN32
398
            return Path.build_filename (exec_path, "etc", "xdg", PACKAGE_NAME, folder ?? "", filename);
399
            #else
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
400
            foreach (string config_dir in Environment.get_system_config_dirs ()) {
401
                string path = Path.build_filename (config_dir, PACKAGE_NAME, folder ?? "", filename);
402
                if (Posix.access (path, Posix.F_OK) == 0)
403
                    return path;
404
            }
405
406
            return Path.build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder ?? "", filename);
5248 by Christian Dywan
Always use exec_path based paths on Win32
407
            #endif
5219 by Christian Dywan
Move config/ data/ res_filename/ lib_path to Midori.Paths
408
        }
5565 by Christian Dywan
Supersede Katze.load_cached_icon by Midori.Paths.get_icon
409
5578 by Christian Dywan
Move icon path setup and clearing into Midori.Paths
410
        public static void clear_icons () {
411
            assert (cache_dir != null);
412
            assert (user_data_dir != null);
6043 by Christian Dywan
Implement WebKit2 code path of clearing page icons
413
#if HAVE_WEBKIT2
414
            WebKit.WebContext.get_default ().get_favicon_database ().clear ();
6216.1.9 by Christian Dywan
Drop unneeded WebKit < 1.8 version guards
415
#else
5578 by Christian Dywan
Move icon path setup and clearing into Midori.Paths
416
            WebKit.get_favicon_database ().clear ();
417
#endif
418
            /* FIXME: Exclude search engine icons */
419
            remove_path (Path.build_filename (user_data_dir, "webkit", "icondatabase"));
420
        }
421
5565 by Christian Dywan
Supersede Katze.load_cached_icon by Midori.Paths.get_icon
422
        public static Gdk.Pixbuf? get_icon (string? uri, Gtk.Widget? widget) {
423
            if (!Midori.URI.is_resource (uri))
424
                return null;
5595 by Christian Dywan
Add 1.3.13 IconDatabase code path equivalent to 1.8.0
425
            int icon_width = 16, icon_height = 16;
426
            if (widget != null)
427
                Gtk.icon_size_lookup_for_settings (widget.get_settings (),
428
                    Gtk.IconSize.MENU, out icon_width, out icon_height);
6196.1.3 by Christian Dywan
Save biggest available favicon for app launchers
429
            else
430
                icon_width = icon_height = 0 /* maximum size */;
6026 by Christian Dywan
Implement view-based favicon handling for WebKit2
431
#if HAVE_WEBKIT2
432
            /* TODO async
433
            var database = WebKit.WebContext.get_default ().get_favicon_database ();
434
            database.get_favicon.begin (uri, null); */
6216.1.9 by Christian Dywan
Drop unneeded WebKit < 1.8 version guards
435
#else
5565 by Christian Dywan
Supersede Katze.load_cached_icon by Midori.Paths.get_icon
436
            Gdk.Pixbuf? pixbuf = WebKit.get_favicon_database ()
5595 by Christian Dywan
Add 1.3.13 IconDatabase code path equivalent to 1.8.0
437
                .try_get_favicon_pixbuf (uri, icon_width, icon_height);
5565 by Christian Dywan
Supersede Katze.load_cached_icon by Midori.Paths.get_icon
438
            if (pixbuf != null)
439
                return pixbuf;
440
#endif
5599 by Christian Dywan
Merge katze_load_cached_icon into Midori.Paths.get_icon
441
            if (widget != null)
442
                return widget.render_icon (Gtk.STOCK_FILE, Gtk.IconSize.MENU, null);
443
            return null;
5565 by Christian Dywan
Supersede Katze.load_cached_icon by Midori.Paths.get_icon
444
        }
5206 by Christian Dywan
Introduce Midori.Paths and Midori.RuntimeMode
445
    }
446
}