1/* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25#include "config.h"
26
27#include <locale.h>
28#include <stdlib.h>
29
30#include "gdk/gdk.h"
31
32#include "gtkprivate.h"
33#include "gtkresources.h"
34
35
36#if !defined G_OS_WIN32 && !(defined GDK_WINDOWING_MACOS && defined QUARTZ_RELOCATION)
37
38const char *
39_gtk_get_datadir (void)
40{
41 return GTK_DATADIR;
42}
43
44const char *
45_gtk_get_libdir (void)
46{
47 return GTK_LIBDIR;
48}
49
50const char *
51_gtk_get_sysconfdir (void)
52{
53 return GTK_SYSCONFDIR;
54}
55
56const char *
57_gtk_get_localedir (void)
58{
59 return GTK_LOCALEDIR;
60}
61
62const char *
63_gtk_get_data_prefix (void)
64{
65 return GTK_DATA_PREFIX;
66}
67
68#endif
69
70/* _gtk_get_lc_ctype:
71 *
72 * Return the Unix-style locale string for the language currently in
73 * effect. On Unix systems, this is the return value from
74 * `setlocale(LC_CTYPE, NULL)`, and the user can
75 * affect this through the environment variables LC_ALL, LC_CTYPE or
76 * LANG (checked in that order). The locale strings typically is in
77 * the form lang_COUNTRY, where lang is an ISO-639 language code, and
78 * COUNTRY is an ISO-3166 country code. For instance, sv_FI for
79 * Swedish as written in Finland or pt_BR for Portuguese as written in
80 * Brazil.
81 *
82 * On Windows, the C library doesn’t use any such environment
83 * variables, and setting them won’t affect the behaviour of functions
84 * like ctime(). The user sets the locale through the Regional Options
85 * in the Control Panel. The C library (in the setlocale() function)
86 * does not use country and language codes, but country and language
87 * names spelled out in English.
88 * However, this function does check the above environment
89 * variables, and does return a Unix-style locale string based on
90 * either said environment variables or the thread’s current locale.
91 *
92 * Returns: a dynamically allocated string, free with g_free().
93 */
94
95char *
96_gtk_get_lc_ctype (void)
97{
98#ifdef G_OS_WIN32
99 /* Somebody might try to set the locale for this process using the
100 * LANG or LC_ environment variables. The Microsoft C library
101 * doesn't know anything about them. You set the locale in the
102 * Control Panel. Setting these env vars won't have any affect on
103 * locale-dependent C library functions like ctime(). But just for
104 * kicks, do obey LC_ALL, LC_CTYPE and LANG in GTK. (This also makes
105 * it easier to test GTK and Pango in various default languages, you
106 * don't have to clickety-click in the Control Panel, you can simply
107 * start the program with LC_ALL=something on the command line.)
108 */
109 char *p;
110
111 p = getenv ("LC_ALL");
112 if (p != NULL)
113 return g_strdup (p);
114
115 p = getenv ("LC_CTYPE");
116 if (p != NULL)
117 return g_strdup (p);
118
119 p = getenv ("LANG");
120 if (p != NULL)
121 return g_strdup (p);
122
123 return g_win32_getlocale ();
124#else
125 return g_strdup (str: setlocale (LC_CTYPE, NULL));
126#endif
127}
128
129gboolean
130_gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
131 GValue *return_accu,
132 const GValue *handler_return,
133 gpointer dummy)
134{
135 gboolean continue_emission;
136 gboolean signal_handled;
137
138 signal_handled = g_value_get_boolean (value: handler_return);
139 g_value_set_boolean (value: return_accu, v_boolean: signal_handled);
140 continue_emission = !signal_handled;
141
142 return continue_emission;
143}
144
145gboolean
146_gtk_single_string_accumulator (GSignalInvocationHint *ihint,
147 GValue *return_accu,
148 const GValue *handler_return,
149 gpointer dummy)
150{
151 gboolean continue_emission;
152 const char *str;
153
154 str = g_value_get_string (value: handler_return);
155 g_value_set_string (value: return_accu, v_string: str);
156 continue_emission = str == NULL;
157
158 return continue_emission;
159}
160
161static gpointer
162register_resources (gpointer data)
163{
164 _gtk_register_resource ();
165 return NULL;
166}
167
168void
169_gtk_ensure_resources (void)
170{
171 static GOnce register_resources_once = G_ONCE_INIT;
172
173 g_once (&register_resources_once, register_resources, NULL);
174}
175
176/*
177 * gtk_get_portal_interface_version:
178 * @connection: a session `GDBusConnection`
179 * @interface_name: the interface name for the portal interface
180 * we're interested in.
181 *
182 * Returns: the version number of the portal, or 0 on error.
183 */
184guint
185gtk_get_portal_interface_version (GDBusConnection *connection,
186 const char *interface_name)
187{
188 GDBusProxy *proxy = NULL;
189 GError *error = NULL;
190 GVariant *ret = NULL;
191 char *owner = NULL;
192 guint version = 0;
193
194 proxy = g_dbus_proxy_new_sync (connection,
195 flags: 0,
196 NULL,
197 name: "org.freedesktop.portal.Desktop",
198 object_path: "/org/freedesktop/portal/desktop",
199 interface_name,
200 NULL,
201 error: &error);
202 if (!proxy)
203 {
204 if (!g_error_matches (error, G_IO_ERROR, code: G_IO_ERROR_CANCELLED))
205 g_warning ("Could not query portal version on interface '%s': %s",
206 interface_name, error->message);
207 goto out;
208 }
209
210 owner = g_dbus_proxy_get_name_owner (proxy);
211 if (owner == NULL)
212 {
213 g_debug ("%s not provided by any service", interface_name);
214 goto out;
215 }
216
217 ret = g_dbus_proxy_get_cached_property (proxy, property_name: "version");
218 if (ret)
219 version = g_variant_get_uint32 (value: ret);
220
221 g_debug ("Got version %u for portal interface '%s'",
222 version, interface_name);
223
224out:
225 g_clear_object (&proxy);
226 g_clear_error (err: &error);
227 g_clear_pointer (&ret, g_variant_unref);
228 g_clear_pointer (&owner, g_free);
229
230 return version;
231}
232
233static char *
234get_portal_path (GDBusConnection *connection,
235 const char *kind,
236 char **token)
237{
238 char *sender;
239 int i;
240 char *path;
241
242 *token = g_strdup_printf (format: "gtk%d", g_random_int_range (begin: 0, G_MAXINT));
243 /* +1 to skip the leading : */
244 sender = g_strdup (str: g_dbus_connection_get_unique_name (connection) + 1);
245 for (i = 0; sender[i]; i++)
246 if (sender[i] == '.')
247 sender[i] = '_';
248
249 path = g_strconcat (PORTAL_OBJECT_PATH, "/", kind, "/", sender, "/", *token, NULL);
250
251 g_free (mem: sender);
252
253 return path;
254}
255
256char *
257gtk_get_portal_request_path (GDBusConnection *connection,
258 char **token)
259{
260 return get_portal_path (connection, kind: "request", token);
261}
262
263char *
264gtk_get_portal_session_path (GDBusConnection *connection,
265 char **token)
266{
267 return get_portal_path (connection, kind: "session", token);
268}
269
270char *
271_gtk_elide_underscores (const char *original)
272{
273 char *q, *result;
274 const char *p, *end;
275 gsize len;
276 gboolean last_underscore;
277
278 if (!original)
279 return NULL;
280
281 len = strlen (s: original);
282 q = result = g_malloc (n_bytes: len + 1);
283 last_underscore = FALSE;
284
285 end = original + len;
286 for (p = original; p < end; p++)
287 {
288 if (!last_underscore && *p == '_')
289 last_underscore = TRUE;
290 else
291 {
292 last_underscore = FALSE;
293 if (original + 2 <= p && p + 1 <= end &&
294 p[-2] == '(' && p[-1] == '_' && p[0] != '_' && p[1] == ')')
295 {
296 q--;
297 *q = '\0';
298 p++;
299 }
300 else
301 *q++ = *p;
302 }
303 }
304
305 if (last_underscore)
306 *q++ = '_';
307
308 *q = '\0';
309
310 return result;
311}
312

source code of gtk/gtk/gtkprivate.c