1 | /* GTK - The GIMP Toolkit |
2 | * Copyright 1998-2002 Tim Janik, Red Hat, Inc., and others. |
3 | * Copyright (C) 2003 Alex Graveley |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include "config.h" |
20 | |
21 | #include <string.h> |
22 | |
23 | #include "gtksettings.h" |
24 | #include "gtkdebug.h" |
25 | #include "gtkprivate.h" |
26 | #include "gtkmodulesprivate.h" |
27 | #include "gtkintl.h" |
28 | |
29 | #include <gmodule.h> |
30 | |
31 | static char * |
32 | gtk_trim_string (const char *str) |
33 | { |
34 | int len; |
35 | |
36 | g_return_val_if_fail (str != NULL, NULL); |
37 | |
38 | while (*str && g_ascii_isspace (*str)) |
39 | str++; |
40 | |
41 | len = strlen (s: str); |
42 | while (len > 0 && g_ascii_isspace (str[len - 1])) |
43 | len--; |
44 | |
45 | return g_strndup (str, n: len); |
46 | } |
47 | |
48 | static char ** |
49 | split_file_list (const char *str) |
50 | { |
51 | int i = 0; |
52 | int j; |
53 | char **files; |
54 | |
55 | files = g_strsplit (string: str, G_SEARCHPATH_SEPARATOR_S, max_tokens: -1); |
56 | |
57 | while (files[i]) |
58 | { |
59 | char *file = gtk_trim_string (str: files[i]); |
60 | |
61 | /* If the resulting file is empty, skip it */ |
62 | if (file[0] == '\0') |
63 | { |
64 | g_free (mem: file); |
65 | g_free (mem: files[i]); |
66 | |
67 | for (j = i + 1; files[j]; j++) |
68 | files[j - 1] = files[j]; |
69 | |
70 | files[j - 1] = NULL; |
71 | |
72 | continue; |
73 | } |
74 | |
75 | #ifndef G_OS_WIN32 |
76 | /* '~' is a quite normal and common character in file names on |
77 | * Windows, especially in the 8.3 versions of long file names, which |
78 | * still occur now and then. Also, few Windows user are aware of the |
79 | * Unix shell convention that '~' stands for the home directory, |
80 | * even if they happen to have a home directory. |
81 | */ |
82 | if (file[0] == '~' && file[1] == G_DIR_SEPARATOR) |
83 | { |
84 | char *tmp = g_strconcat (string1: g_get_home_dir(), file + 1, NULL); |
85 | g_free (mem: file); |
86 | file = tmp; |
87 | } |
88 | else if (file[0] == '~' && file[1] == '\0') |
89 | { |
90 | g_free (mem: file); |
91 | file = g_strdup (str: g_get_home_dir ()); |
92 | } |
93 | #endif |
94 | |
95 | g_free (mem: files[i]); |
96 | files[i] = file; |
97 | |
98 | i++; |
99 | } |
100 | |
101 | return files; |
102 | } |
103 | |
104 | static char ** |
105 | get_module_path (void) |
106 | { |
107 | const char *module_path_env; |
108 | const char *exe_prefix; |
109 | char *module_path; |
110 | char *default_dir; |
111 | static char **result = NULL; |
112 | |
113 | if (result) |
114 | return result; |
115 | |
116 | module_path_env = g_getenv (variable: "GTK_PATH" ); |
117 | exe_prefix = g_getenv (variable: "GTK_EXE_PREFIX" ); |
118 | |
119 | if (exe_prefix) |
120 | default_dir = g_build_filename (first_element: exe_prefix, "lib" , "gtk-4.0" , NULL); |
121 | else |
122 | default_dir = g_build_filename (first_element: _gtk_get_libdir (), "gtk-4.0" , NULL); |
123 | |
124 | if (module_path_env) |
125 | module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, |
126 | first_element: module_path_env, default_dir, NULL); |
127 | else |
128 | module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, |
129 | first_element: default_dir, NULL); |
130 | |
131 | g_free (mem: default_dir); |
132 | |
133 | result = split_file_list (str: module_path); |
134 | g_free (mem: module_path); |
135 | |
136 | return result; |
137 | } |
138 | |
139 | /** |
140 | * _gtk_get_module_path: |
141 | * @type: the type of the module, for instance 'modules', 'engines', immodules' |
142 | * |
143 | * Determines the search path for a particular type of module. |
144 | * |
145 | * Returns: the search path for the module type. Free with g_strfreev(). |
146 | **/ |
147 | char ** |
148 | _gtk_get_module_path (const char *type) |
149 | { |
150 | char **paths = get_module_path(); |
151 | char **path; |
152 | char **result; |
153 | int count = 0; |
154 | |
155 | for (path = paths; *path; path++) |
156 | count++; |
157 | |
158 | result = g_new (char *, count * 4 + 1); |
159 | |
160 | count = 0; |
161 | for (path = get_module_path (); *path; path++) |
162 | { |
163 | result[count++] = g_build_filename (first_element: *path, GTK_BINARY_VERSION, GTK_HOST, type, NULL); |
164 | result[count++] = g_build_filename (first_element: *path, GTK_BINARY_VERSION, type, NULL); |
165 | result[count++] = g_build_filename (first_element: *path, GTK_HOST, type, NULL); |
166 | result[count++] = g_build_filename (first_element: *path, type, NULL); |
167 | } |
168 | |
169 | result[count++] = NULL; |
170 | |
171 | return result; |
172 | } |
173 | |