]> Pileus Git - ~andy/gtk/blob - gtk/gtkprivate.c
df4579024a66eb2d90ccaf2543c419d507477aa7
[~andy/gtk] / gtk / gtkprivate.c
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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25  */
26
27 #include "config.h"
28
29 #include <locale.h>
30 #include <stdlib.h>
31
32 #include "gdk/gdk.h"
33
34 #include "gtkprivate.h"
35
36
37 #if !defined G_OS_WIN32 && !(defined GDK_WINDOWING_QUARTZ && defined QUARTZ_RELOCATION)
38
39 const gchar *
40 _gtk_get_datadir (void)
41 {
42   return GTK_DATADIR;
43 }
44
45 const gchar *
46 _gtk_get_libdir (void)
47 {
48   return GTK_LIBDIR;
49 }
50
51 const gchar *
52 _gtk_get_sysconfdir (void)
53 {
54   return GTK_SYSCONFDIR;
55 }
56
57 const gchar *
58 _gtk_get_localedir (void)
59 {
60   return GTK_LOCALEDIR;
61 }
62
63 const gchar *
64 _gtk_get_data_prefix (void)
65 {
66   return GTK_DATA_PREFIX;
67 }
68
69 #endif
70
71 /* _gtk_get_lc_ctype:
72  *
73  * Return the Unix-style locale string for the language currently in
74  * effect. On Unix systems, this is the return value from
75  * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can
76  * affect this through the environment variables LC_ALL, LC_CTYPE or
77  * LANG (checked in that order). The locale strings typically is in
78  * the form lang_COUNTRY, where lang is an ISO-639 language code, and
79  * COUNTRY is an ISO-3166 country code. For instance, sv_FI for
80  * Swedish as written in Finland or pt_BR for Portuguese as written in
81  * Brazil.
82  *
83  * On Windows, the C library doesn't use any such environment
84  * variables, and setting them won't affect the behaviour of functions
85  * like ctime(). The user sets the locale through the Regional Options
86  * in the Control Panel. The C library (in the setlocale() function)
87  * does not use country and language codes, but country and language
88  * names spelled out in English.
89  * However, this function does check the above environment
90  * variables, and does return a Unix-style locale string based on
91  * either said environment variables or the thread's current locale.
92  *
93  * Return value: a dynamically allocated string, free with g_free().
94  */
95
96 gchar *
97 _gtk_get_lc_ctype (void)
98 {
99 #ifdef G_OS_WIN32
100   /* Somebody might try to set the locale for this process using the
101    * LANG or LC_ environment variables. The Microsoft C library
102    * doesn't know anything about them. You set the locale in the
103    * Control Panel. Setting these env vars won't have any affect on
104    * locale-dependent C library functions like ctime(). But just for
105    * kicks, do obey LC_ALL, LC_CTYPE and LANG in GTK. (This also makes
106    * it easier to test GTK and Pango in various default languages, you
107    * don't have to clickety-click in the Control Panel, you can simply
108    * start the program with LC_ALL=something on the command line.)
109    */
110   gchar *p;
111
112   p = getenv ("LC_ALL");
113   if (p != NULL)
114     return g_strdup (p);
115
116   p = getenv ("LC_CTYPE");
117   if (p != NULL)
118     return g_strdup (p);
119
120   p = getenv ("LANG");
121   if (p != NULL)
122     return g_strdup (p);
123
124   return g_win32_getlocale ();
125 #else
126   return g_strdup (setlocale (LC_CTYPE, NULL));
127 #endif
128 }
129
130 gboolean
131 _gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
132                                   GValue                *return_accu,
133                                   const GValue          *handler_return,
134                                   gpointer               dummy)
135 {
136   gboolean continue_emission;
137   gboolean signal_handled;
138
139   signal_handled = g_value_get_boolean (handler_return);
140   g_value_set_boolean (return_accu, signal_handled);
141   continue_emission = !signal_handled;
142
143   return continue_emission;
144 }
145
146 gboolean
147 _gtk_single_string_accumulator (GSignalInvocationHint *ihint,
148                                 GValue                *return_accu,
149                                 const GValue          *handler_return,
150                                 gpointer               dummy)
151 {
152   gboolean continue_emission;
153   const gchar *str;
154
155   str = g_value_get_string (handler_return);
156   g_value_set_string (return_accu, str);
157   continue_emission = str == NULL;
158
159   return continue_emission;
160 }
161
162 GdkModifierType
163 _gtk_replace_virtual_modifiers (GdkKeymap       *keymap,
164                                 GdkModifierType  modifiers)
165 {
166   GdkModifierType result = 0;
167   gint            i;
168
169   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), 0);
170
171   for (i = 0; i < 8; i++) /* SHIFT...MOD5 */
172     {
173       GdkModifierType real = 1 << i;
174
175       if (modifiers & real)
176         {
177           GdkModifierType virtual = real;
178
179           gdk_keymap_add_virtual_modifiers (keymap, &virtual);
180
181           if (virtual == real)
182             result |= virtual;
183           else
184             result |= virtual & ~real;
185         }
186     }
187
188   return result;
189 }
190
191 GdkModifierType
192 _gtk_get_primary_accel_mod (void)
193 {
194   static GdkModifierType primary = 0;
195
196   if (! primary)
197     {
198       GdkDisplay *display = gdk_display_get_default ();
199
200       primary = gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display),
201                                               GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);
202       primary = _gtk_replace_virtual_modifiers (gdk_keymap_get_for_display (display),
203                                                 primary);
204     }
205
206   return primary;
207 }
208
209 gboolean
210 _gtk_translate_keyboard_accel_state (GdkKeymap       *keymap,
211                                      guint            hardware_keycode,
212                                      GdkModifierType  state,
213                                      GdkModifierType  accel_mask,
214                                      gint             group,
215                                      guint           *keyval,
216                                      gint            *effective_group,
217                                      gint            *level,
218                                      GdkModifierType *consumed_modifiers)
219 {
220   GdkModifierType shift_group_mask;
221   gboolean group_mask_disabled = FALSE;
222   gboolean retval;
223
224   /* if the group-toggling modifier is part of the accel mod mask, and
225    * it is active, disable it for matching
226    */
227   shift_group_mask = gdk_keymap_get_modifier_mask (keymap,
228                                                    GDK_MODIFIER_INTENT_SHIFT_GROUP);
229   if (accel_mask & state & shift_group_mask)
230     {
231       state &= ~shift_group_mask;
232       group = 0;
233       group_mask_disabled = TRUE;
234     }
235
236   retval = gdk_keymap_translate_keyboard_state (keymap,
237                                                 hardware_keycode, state, group,
238                                                 keyval,
239                                                 effective_group, level,
240                                                 consumed_modifiers);
241
242   /* add back the group mask, we want to match against the modifier,
243    * but not against the keyval from its group
244    */
245   if (group_mask_disabled)
246     {
247       if (effective_group)
248         *effective_group = 1;
249
250       if (consumed_modifiers)
251         *consumed_modifiers &= ~shift_group_mask;
252     }
253
254   return retval;
255 }