File: | plugins/keybindings/csd_keybindings-manager.c |
Warning: | line 432, column 36 Out of bound memory access (access exceeds upper limit of memory block) |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- | ||||||
2 | * | ||||||
3 | * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> | ||||||
4 | * | ||||||
5 | * This program is free software; you can redistribute it and/or modify | ||||||
6 | * it under the terms of the GNU General Public License as published by | ||||||
7 | * the Free Software Foundation; either version 2 of the License, or | ||||||
8 | * (at your option) any later version. | ||||||
9 | * | ||||||
10 | * This program 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 | ||||||
13 | * GNU General Public License for more details. | ||||||
14 | * | ||||||
15 | * You should have received a copy of the GNU General Public License | ||||||
16 | * along with this program; if not, write to the Free Software | ||||||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||||
18 | * | ||||||
19 | */ | ||||||
20 | |||||||
21 | #include "config.h" | ||||||
22 | |||||||
23 | #include <sys/types.h> | ||||||
24 | #include <sys/wait.h> | ||||||
25 | #include <stdlib.h> | ||||||
26 | #include <stdio.h> | ||||||
27 | #include <unistd.h> | ||||||
28 | #include <string.h> | ||||||
29 | #include <errno(*__errno_location ()).h> | ||||||
30 | |||||||
31 | #include <locale.h> | ||||||
32 | |||||||
33 | #include <glib.h> | ||||||
34 | #include <glib/gi18n.h> | ||||||
35 | #include <cdk/cdk.h> | ||||||
36 | #include <cdk/cdkx.h> | ||||||
37 | #include <ctk/ctk.h> | ||||||
38 | #include <X11/keysym.h> | ||||||
39 | #include <gio/gio.h> | ||||||
40 | #include <dconf.h> | ||||||
41 | |||||||
42 | #include "cafe-settings-profile.h" | ||||||
43 | #include "csd_keybindings-manager.h" | ||||||
44 | #include "dconf-util.h" | ||||||
45 | |||||||
46 | #include "csd_keygrab.h" | ||||||
47 | #include "eggaccelerators.h" | ||||||
48 | |||||||
49 | #define GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/" "/org/cafe/desktop/keybindings/" | ||||||
50 | #define CUSTOM_KEYBINDING_SCHEMA"org.cafe.control-center.keybinding" "org.cafe.control-center.keybinding" | ||||||
51 | |||||||
52 | typedef struct { | ||||||
53 | char *binding_str; | ||||||
54 | char *action; | ||||||
55 | char *settings_path; | ||||||
56 | Key key; | ||||||
57 | Key previous_key; | ||||||
58 | } Binding; | ||||||
59 | |||||||
60 | struct CsdKeybindingsManagerPrivate | ||||||
61 | { | ||||||
62 | DConfClient *client; | ||||||
63 | GSList *binding_list; | ||||||
64 | GSList *screens; | ||||||
65 | }; | ||||||
66 | |||||||
67 | static void csd_keybindings_manager_finalize (GObject *object); | ||||||
68 | |||||||
69 | G_DEFINE_TYPE_WITH_PRIVATE (CsdKeybindingsManager, csd_keybindings_manager, G_TYPE_OBJECT)static void csd_keybindings_manager_init (CsdKeybindingsManager *self); static void csd_keybindings_manager_class_init (CsdKeybindingsManagerClass *klass); static GType csd_keybindings_manager_get_type_once ( void); static gpointer csd_keybindings_manager_parent_class = ((void*)0); static gint CsdKeybindingsManager_private_offset ; static void csd_keybindings_manager_class_intern_init (gpointer klass) { csd_keybindings_manager_parent_class = g_type_class_peek_parent (klass); if (CsdKeybindingsManager_private_offset != 0) g_type_class_adjust_private_offset (klass, &CsdKeybindingsManager_private_offset); csd_keybindings_manager_class_init ((CsdKeybindingsManagerClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer csd_keybindings_manager_get_instance_private (CsdKeybindingsManager *self) { return (((gpointer) ((guint8 *) (self) + (glong) (CsdKeybindingsManager_private_offset)))) ; } GType csd_keybindings_manager_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) * ( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = csd_keybindings_manager_get_type_once (); (__extension__ ( { _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*( &static_g_define_type_id) = (g_define_type_id)) : (void) 0 ; g_once_init_leave_pointer ((&static_g_define_type_id), ( gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType csd_keybindings_manager_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CsdKeybindingsManager" ), sizeof (CsdKeybindingsManagerClass), (GClassInitFunc)(void (*)(void)) csd_keybindings_manager_class_intern_init, sizeof (CsdKeybindingsManager), (GInstanceInitFunc)(void (*)(void)) csd_keybindings_manager_init, (GTypeFlags) 0); { {{ CsdKeybindingsManager_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CsdKeybindingsManagerPrivate )); };} } return g_define_type_id; } | ||||||
70 | |||||||
71 | static gpointer manager_object = NULL((void*)0); | ||||||
72 | |||||||
73 | static GSList * | ||||||
74 | get_screens_list (void) | ||||||
75 | { | ||||||
76 | GSList *list = NULL((void*)0); | ||||||
77 | |||||||
78 | list = g_slist_append (list, cdk_screen_get_default ()); | ||||||
79 | |||||||
80 | return list; | ||||||
81 | } | ||||||
82 | |||||||
83 | static gboolean | ||||||
84 | parse_binding (Binding *binding) | ||||||
85 | { | ||||||
86 | gboolean success; | ||||||
87 | |||||||
88 | g_return_val_if_fail (binding != NULL, FALSE)do { if ((binding != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "binding != NULL" ); return ((0)); } } while (0); | ||||||
89 | |||||||
90 | binding->key.keysym = 0; | ||||||
91 | binding->key.state = 0; | ||||||
92 | g_free (binding->key.keycodes); | ||||||
93 | binding->key.keycodes = NULL((void*)0); | ||||||
94 | |||||||
95 | if (binding->binding_str == NULL((void*)0) || | ||||||
96 | binding->binding_str[0] == '\0' || | ||||||
97 | g_strcmp0 (binding->binding_str, "Disabled") == 0 || | ||||||
98 | g_strcmp0 (binding->binding_str, "disabled") == 0 ) { | ||||||
99 | return FALSE(0); | ||||||
100 | } | ||||||
101 | |||||||
102 | success = egg_accelerator_parse_virtual (binding->binding_str, | ||||||
103 | &binding->key.keysym, | ||||||
104 | &binding->key.keycodes, | ||||||
105 | &binding->key.state); | ||||||
106 | |||||||
107 | if (!success) | ||||||
108 | g_warning (_("Key binding (%s) is invalid")gettext ("Key binding (%s) is invalid"), binding->settings_path); | ||||||
109 | |||||||
110 | return success; | ||||||
111 | } | ||||||
112 | |||||||
113 | static gint | ||||||
114 | compare_bindings (gconstpointer a, | ||||||
115 | gconstpointer b) | ||||||
116 | { | ||||||
117 | Binding *key_a = (Binding *) a; | ||||||
118 | char *key_b = (char *) b; | ||||||
119 | |||||||
120 | return g_strcmp0 (key_b, key_a->settings_path); | ||||||
121 | } | ||||||
122 | |||||||
123 | static gboolean | ||||||
124 | bindings_get_entry (CsdKeybindingsManager *manager, | ||||||
125 | const char *settings_path) | ||||||
126 | { | ||||||
127 | GSettings *settings; | ||||||
128 | Binding *new_binding; | ||||||
129 | GSList *tmp_elem; | ||||||
130 | char *action = NULL((void*)0); | ||||||
131 | char *key = NULL((void*)0); | ||||||
132 | |||||||
133 | if (!settings_path) { | ||||||
134 | return FALSE(0); | ||||||
135 | } | ||||||
136 | |||||||
137 | /* Get entries for this binding */ | ||||||
138 | settings = g_settings_new_with_path (CUSTOM_KEYBINDING_SCHEMA"org.cafe.control-center.keybinding", settings_path); | ||||||
139 | action = g_settings_get_string (settings, "action"); | ||||||
140 | key = g_settings_get_string (settings, "binding"); | ||||||
141 | g_object_unref (settings); | ||||||
142 | |||||||
143 | if (!action || !key) { | ||||||
144 | g_warning (_("Key binding (%s) is incomplete")gettext ("Key binding (%s) is incomplete"), settings_path); | ||||||
145 | g_free (action); | ||||||
146 | g_free (key); | ||||||
147 | return FALSE(0); | ||||||
148 | } | ||||||
149 | |||||||
150 | g_debug ("keybindings: get entries from '%s' (action: '%s', key: '%s')", settings_path, action, key); | ||||||
151 | |||||||
152 | tmp_elem = g_slist_find_custom (manager->priv->binding_list, | ||||||
153 | settings_path, | ||||||
154 | compare_bindings); | ||||||
155 | |||||||
156 | if (!tmp_elem) { | ||||||
157 | new_binding = g_new0 (Binding, 1)((Binding *) g_malloc0_n ((1), sizeof (Binding))); | ||||||
158 | } else { | ||||||
159 | new_binding = (Binding *) tmp_elem->data; | ||||||
160 | g_free (new_binding->binding_str); | ||||||
161 | g_free (new_binding->action); | ||||||
162 | g_free (new_binding->settings_path); | ||||||
163 | |||||||
164 | new_binding->previous_key.keysym = new_binding->key.keysym; | ||||||
165 | new_binding->previous_key.state = new_binding->key.state; | ||||||
166 | new_binding->previous_key.keycodes = new_binding->key.keycodes; | ||||||
167 | new_binding->key.keycodes = NULL((void*)0); | ||||||
168 | } | ||||||
169 | |||||||
170 | new_binding->binding_str = key; | ||||||
171 | new_binding->action = action; | ||||||
172 | new_binding->settings_path = g_strdup (settings_path)g_strdup_inline (settings_path); | ||||||
173 | |||||||
174 | if (parse_binding (new_binding)) { | ||||||
175 | if (!tmp_elem) | ||||||
176 | manager->priv->binding_list = g_slist_prepend (manager->priv->binding_list, new_binding); | ||||||
177 | } else { | ||||||
178 | g_free (new_binding->binding_str); | ||||||
179 | g_free (new_binding->action); | ||||||
180 | g_free (new_binding->settings_path); | ||||||
181 | g_free (new_binding->previous_key.keycodes); | ||||||
182 | g_free (new_binding); | ||||||
183 | |||||||
184 | if (tmp_elem) | ||||||
185 | manager->priv->binding_list = g_slist_delete_link (manager->priv->binding_list, tmp_elem); | ||||||
186 | return FALSE(0); | ||||||
187 | } | ||||||
188 | |||||||
189 | return TRUE(!(0)); | ||||||
190 | } | ||||||
191 | |||||||
192 | static void | ||||||
193 | bindings_clear (CsdKeybindingsManager *manager) | ||||||
194 | { | ||||||
195 | CsdKeybindingsManagerPrivate *p = manager->priv; | ||||||
196 | GSList *l; | ||||||
197 | |||||||
198 | if (p->binding_list != NULL((void*)0)) | ||||||
199 | { | ||||||
200 | for (l = p->binding_list; l; l = l->next) { | ||||||
201 | Binding *b = l->data; | ||||||
202 | g_free (b->binding_str); | ||||||
203 | g_free (b->action); | ||||||
204 | g_free (b->settings_path); | ||||||
205 | g_free (b->previous_key.keycodes); | ||||||
206 | g_free (b->key.keycodes); | ||||||
207 | g_free (b); | ||||||
208 | } | ||||||
209 | g_slist_free (p->binding_list); | ||||||
210 | p->binding_list = NULL((void*)0); | ||||||
211 | } | ||||||
212 | } | ||||||
213 | |||||||
214 | static void | ||||||
215 | bindings_get_entries (CsdKeybindingsManager *manager) | ||||||
216 | { | ||||||
217 | gchar **custom_list = NULL((void*)0); | ||||||
218 | gint i; | ||||||
219 | |||||||
220 | bindings_clear (manager); | ||||||
221 | |||||||
222 | custom_list = dconf_util_list_subdirs (GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/", FALSE(0)); | ||||||
223 | |||||||
224 | if (custom_list != NULL((void*)0)) | ||||||
225 | { | ||||||
226 | for (i = 0; custom_list[i] != NULL((void*)0); i++) | ||||||
227 | { | ||||||
228 | gchar *settings_path; | ||||||
229 | settings_path = g_strdup_printf("%s%s", GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/", custom_list[i]); | ||||||
230 | bindings_get_entry (manager, settings_path); | ||||||
231 | g_free (settings_path); | ||||||
232 | } | ||||||
233 | g_strfreev (custom_list); | ||||||
234 | } | ||||||
235 | |||||||
236 | } | ||||||
237 | |||||||
238 | static gboolean | ||||||
239 | same_keycode (const Key *key, const Key *other) | ||||||
240 | { | ||||||
241 | if (key->keycodes != NULL((void*)0) && other->keycodes != NULL((void*)0)) { | ||||||
242 | guint *c; | ||||||
243 | |||||||
244 | for (c = key->keycodes; *c; ++c) { | ||||||
245 | if (key_uses_keycode (other, *c)) | ||||||
246 | return TRUE(!(0)); | ||||||
247 | } | ||||||
248 | } | ||||||
249 | return FALSE(0); | ||||||
250 | } | ||||||
251 | |||||||
252 | static gboolean | ||||||
253 | same_key (const Key *key, const Key *other) | ||||||
254 | { | ||||||
255 | if (key->state == other->state) { | ||||||
256 | if (key->keycodes != NULL((void*)0) && other->keycodes != NULL((void*)0)) { | ||||||
257 | guint *c1, *c2; | ||||||
258 | |||||||
259 | for (c1 = key->keycodes, c2 = other->keycodes; | ||||||
260 | *c1 || *c2; ++c1, ++c2) { | ||||||
261 | if (*c1 != *c2) | ||||||
262 | return FALSE(0); | ||||||
263 | } | ||||||
264 | } else if (key->keycodes != NULL((void*)0) || other->keycodes != NULL((void*)0)) | ||||||
265 | return FALSE(0); | ||||||
266 | |||||||
267 | |||||||
268 | return TRUE(!(0)); | ||||||
269 | } | ||||||
270 | |||||||
271 | return FALSE(0); | ||||||
272 | } | ||||||
273 | |||||||
274 | static gboolean | ||||||
275 | key_already_used (CsdKeybindingsManager *manager, | ||||||
276 | Binding *binding) | ||||||
277 | { | ||||||
278 | GSList *li; | ||||||
279 | |||||||
280 | for (li = manager->priv->binding_list; li != NULL((void*)0); li = li->next) { | ||||||
281 | Binding *tmp_binding = (Binding*) li->data; | ||||||
282 | |||||||
283 | if (tmp_binding != binding && | ||||||
284 | same_keycode (&tmp_binding->key, &binding->key) && | ||||||
285 | tmp_binding->key.state == binding->key.state) { | ||||||
286 | return TRUE(!(0)); | ||||||
287 | } | ||||||
288 | } | ||||||
289 | |||||||
290 | return FALSE(0); | ||||||
291 | } | ||||||
292 | |||||||
293 | static void | ||||||
294 | binding_unregister_keys (CsdKeybindingsManager *manager) | ||||||
295 | { | ||||||
296 | CdkDisplay *dpy; | ||||||
297 | GSList *li; | ||||||
298 | gboolean need_flush = FALSE(0); | ||||||
299 | |||||||
300 | dpy = cdk_display_get_default (); | ||||||
301 | cdk_x11_display_error_trap_push (dpy); | ||||||
302 | |||||||
303 | for (li = manager->priv->binding_list; li != NULL((void*)0); li = li->next) { | ||||||
304 | Binding *binding = (Binding *) li->data; | ||||||
305 | |||||||
306 | if (binding->key.keycodes) { | ||||||
307 | need_flush = TRUE(!(0)); | ||||||
308 | grab_key_unsafe (&binding->key, FALSE(0), manager->priv->screens); | ||||||
309 | } | ||||||
310 | } | ||||||
311 | |||||||
312 | if (need_flush) | ||||||
313 | cdk_display_flush (dpy); | ||||||
314 | |||||||
315 | cdk_x11_display_error_trap_pop_ignored (dpy); | ||||||
316 | } | ||||||
317 | |||||||
318 | static void | ||||||
319 | binding_register_keys (CsdKeybindingsManager *manager) | ||||||
320 | { | ||||||
321 | GSList *li; | ||||||
322 | CdkDisplay *dpy; | ||||||
323 | gboolean need_flush = FALSE(0); | ||||||
324 | |||||||
325 | dpy = cdk_display_get_default (); | ||||||
326 | cdk_x11_display_error_trap_push (dpy); | ||||||
327 | |||||||
328 | /* Now check for changes and grab new key if not already used */ | ||||||
329 | for (li = manager->priv->binding_list; li != NULL((void*)0); li = li->next) { | ||||||
330 | Binding *binding = (Binding *) li->data; | ||||||
331 | |||||||
332 | if (!same_key (&binding->previous_key, &binding->key)) { | ||||||
333 | /* Ungrab key if it changed and not clashing with previously set binding */ | ||||||
334 | if (!key_already_used (manager, binding)) { | ||||||
335 | gint i; | ||||||
336 | |||||||
337 | need_flush = TRUE(!(0)); | ||||||
338 | if (binding->previous_key.keycodes) { | ||||||
339 | grab_key_unsafe (&binding->previous_key, FALSE(0), manager->priv->screens); | ||||||
340 | } | ||||||
341 | grab_key_unsafe (&binding->key, TRUE(!(0)), manager->priv->screens); | ||||||
342 | |||||||
343 | binding->previous_key.keysym = binding->key.keysym; | ||||||
344 | binding->previous_key.state = binding->key.state; | ||||||
345 | g_free (binding->previous_key.keycodes); | ||||||
346 | for (i = 0; binding->key.keycodes[i]; ++i); | ||||||
347 | binding->previous_key.keycodes = g_new0 (guint, i)((guint *) g_malloc0_n ((i), sizeof (guint))); | ||||||
348 | for (i = 0; binding->key.keycodes[i]; ++i) | ||||||
349 | binding->previous_key.keycodes[i] = binding->key.keycodes[i]; | ||||||
350 | } else | ||||||
351 | g_warning ("Key binding (%s) is already in use", binding->binding_str); | ||||||
352 | } | ||||||
353 | } | ||||||
354 | |||||||
355 | if (need_flush) | ||||||
356 | cdk_display_flush (dpy); | ||||||
357 | if (cdk_x11_display_error_trap_pop (dpy)) | ||||||
358 | g_warning ("Grab failed for some keys, another application may already have access the them."); | ||||||
359 | |||||||
360 | } | ||||||
361 | |||||||
362 | extern char **environ; | ||||||
363 | |||||||
364 | static char * | ||||||
365 | screen_exec_display_string (CdkScreen *screen) | ||||||
366 | { | ||||||
367 | GString *str; | ||||||
368 | const char *old_display; | ||||||
369 | char *p; | ||||||
370 | |||||||
371 | g_return_val_if_fail (CDK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "CDK_IS_SCREEN (screen)"); return (((void*)0)) ; } } while (0); | ||||||
372 | |||||||
373 | old_display = cdk_display_get_name (cdk_screen_get_display (screen)); | ||||||
374 | |||||||
375 | str = g_string_new ("DISPLAY="); | ||||||
376 | g_string_append (str, old_display)(__builtin_constant_p (old_display) ? __extension__ ({ const char * const __val = (old_display); g_string_append_len_inline (str , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (str , old_display, (gssize) -1)); | ||||||
377 | |||||||
378 | p = strrchr (str->str, '.'); | ||||||
379 | if (p && p > strchr (str->str, ':')) { | ||||||
380 | g_string_truncate (str, p - str->str)g_string_truncate_inline (str, p - str->str); | ||||||
381 | } | ||||||
382 | |||||||
383 | g_string_append_printf (str, ".%d", cdk_x11_screen_get_screen_number (screen)); | ||||||
384 | |||||||
385 | return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str) , ((0))) : g_string_free_and_steal (str)) : (g_string_free) ( (str), ((0)))); | ||||||
386 | } | ||||||
387 | |||||||
388 | /** | ||||||
389 | * get_exec_environment: | ||||||
390 | * | ||||||
391 | * Description: Modifies the current program environment to | ||||||
392 | * ensure that $DISPLAY is set such that a launched application | ||||||
393 | * inheriting this environment would appear on screen. | ||||||
394 | * | ||||||
395 | * Returns: a newly-allocated %NULL-terminated array of strings or | ||||||
396 | * %NULL on error. Use g_strfreev() to free it. | ||||||
397 | * | ||||||
398 | * mainly ripped from egg_screen_exec_display_string in | ||||||
399 | * cafe-panel/egg-screen-exec.c | ||||||
400 | **/ | ||||||
401 | static char ** | ||||||
402 | get_exec_environment (XEvent *xevent) | ||||||
403 | { | ||||||
404 | char **retval = NULL((void*)0); | ||||||
405 | int i; | ||||||
406 | int display_index = -1; | ||||||
407 | CdkScreen *screen = NULL((void*)0); | ||||||
408 | CdkWindow *window = cdk_x11_window_lookup_for_display (cdk_display_get_default (), xevent->xkey.root); | ||||||
409 | |||||||
410 | if (window) { | ||||||
411 | screen = cdk_window_get_screen (window); | ||||||
412 | } | ||||||
413 | |||||||
414 | g_return_val_if_fail (CDK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "CDK_IS_SCREEN (screen)"); return (((void*)0)) ; } } while (0); | ||||||
415 | |||||||
416 | for (i = 0; environ [i]; i++) { | ||||||
417 | if (!strncmp (environ [i], "DISPLAY", 7)) { | ||||||
418 | display_index = i; | ||||||
419 | } | ||||||
420 | } | ||||||
421 | |||||||
422 | if (display_index == -1) { | ||||||
423 | display_index = i++; | ||||||
424 | } | ||||||
425 | |||||||
426 | retval = g_new (char *, i + 1)((char * *) g_malloc_n ((i + 1), sizeof (char *))); | ||||||
427 | |||||||
428 | for (i = 0; environ [i]; i++) { | ||||||
429 | if (i
| ||||||
430 | retval [i] = screen_exec_display_string (screen); | ||||||
431 | } else { | ||||||
432 | retval [i] = g_strdup (environ [i])g_strdup_inline (environ [i]); | ||||||
| |||||||
433 | } | ||||||
434 | } | ||||||
435 | |||||||
436 | retval [i] = NULL((void*)0); | ||||||
437 | |||||||
438 | return retval; | ||||||
439 | } | ||||||
440 | |||||||
441 | static CdkFilterReturn | ||||||
442 | keybindings_filter (CdkXEvent *cdk_xevent, | ||||||
443 | CdkEvent *event, | ||||||
444 | CsdKeybindingsManager *manager) | ||||||
445 | { | ||||||
446 | XEvent *xevent = (XEvent *) cdk_xevent; | ||||||
447 | GSList *li; | ||||||
448 | |||||||
449 | if (xevent->type != KeyPress2) { | ||||||
| |||||||
450 | return CDK_FILTER_CONTINUE; | ||||||
451 | } | ||||||
452 | |||||||
453 | for (li = manager->priv->binding_list; li != NULL((void*)0); li = li->next) { | ||||||
454 | Binding *binding = (Binding *) li->data; | ||||||
455 | |||||||
456 | if (match_key (&binding->key, xevent)) { | ||||||
457 | GError *error = NULL((void*)0); | ||||||
458 | gboolean retval; | ||||||
459 | gchar **argv = NULL((void*)0); | ||||||
460 | gchar **envp = NULL((void*)0); | ||||||
461 | |||||||
462 | g_return_val_if_fail (binding->action != NULL, CDK_FILTER_CONTINUE)do { if ((binding->action != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "binding->action != NULL" ); return (CDK_FILTER_CONTINUE); } } while (0); | ||||||
463 | |||||||
464 | if (!g_shell_parse_argv (binding->action, | ||||||
465 | NULL((void*)0), &argv, | ||||||
466 | &error)) { | ||||||
467 | return CDK_FILTER_CONTINUE; | ||||||
468 | } | ||||||
469 | |||||||
470 | envp = get_exec_environment (xevent); | ||||||
471 | |||||||
472 | retval = g_spawn_async (NULL((void*)0), | ||||||
473 | argv, | ||||||
474 | envp, | ||||||
475 | G_SPAWN_SEARCH_PATH, | ||||||
476 | NULL((void*)0), | ||||||
477 | NULL((void*)0), | ||||||
478 | NULL((void*)0), | ||||||
479 | &error); | ||||||
480 | g_strfreev (argv); | ||||||
481 | g_strfreev (envp); | ||||||
482 | |||||||
483 | if (!retval) { | ||||||
484 | CtkWidget *dialog = ctk_message_dialog_new (NULL((void*)0), 0, CTK_MESSAGE_WARNING, | ||||||
485 | CTK_BUTTONS_CLOSE, | ||||||
486 | _("Error while trying to run (%s)\n"\gettext ("Error while trying to run (%s)\n" "which is linked to the key (%s)" ) | ||||||
487 | "which is linked to the key (%s)")gettext ("Error while trying to run (%s)\n" "which is linked to the key (%s)" ), | ||||||
488 | binding->action, | ||||||
489 | binding->binding_str); | ||||||
490 | g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) ( ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags ) 0) | ||||||
491 | "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) ( ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags ) 0) | ||||||
492 | G_CALLBACK (ctk_widget_destroy),g_signal_connect_data ((dialog), ("response"), (((GCallback) ( ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags ) 0) | ||||||
493 | NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) ( ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags ) 0); | ||||||
494 | ctk_widget_show (dialog); | ||||||
495 | } | ||||||
496 | return CDK_FILTER_REMOVE; | ||||||
497 | } | ||||||
498 | } | ||||||
499 | return CDK_FILTER_CONTINUE; | ||||||
500 | } | ||||||
501 | |||||||
502 | static void | ||||||
503 | bindings_callback (DConfClient *client, | ||||||
504 | gchar *prefix, | ||||||
505 | GStrv changes, | ||||||
506 | gchar *tag, | ||||||
507 | CsdKeybindingsManager *manager) | ||||||
508 | { | ||||||
509 | g_debug ("keybindings: received 'changed' signal from dconf"); | ||||||
510 | |||||||
511 | binding_unregister_keys (manager); | ||||||
512 | |||||||
513 | bindings_get_entries (manager); | ||||||
514 | |||||||
515 | binding_register_keys (manager); | ||||||
516 | } | ||||||
517 | |||||||
518 | gboolean | ||||||
519 | csd_keybindings_manager_start (CsdKeybindingsManager *manager, | ||||||
520 | GError **error) | ||||||
521 | { | ||||||
522 | CdkDisplay *dpy; | ||||||
523 | CdkScreen *screen; | ||||||
524 | CdkWindow *window; | ||||||
525 | Display *xdpy; | ||||||
526 | Window xwindow; | ||||||
527 | XWindowAttributes atts; | ||||||
528 | |||||||
529 | g_debug ("Starting keybindings manager"); | ||||||
530 | cafe_settings_profile_start (NULL); | ||||||
531 | |||||||
532 | dpy = cdk_display_get_default (); | ||||||
533 | xdpy = CDK_DISPLAY_XDISPLAY (dpy)(cdk_x11_display_get_xdisplay (dpy)); | ||||||
534 | |||||||
535 | screen = cdk_display_get_default_screen (dpy); | ||||||
536 | window = cdk_screen_get_root_window (screen); | ||||||
537 | xwindow = CDK_WINDOW_XID (window)(cdk_x11_window_get_xid (window)); | ||||||
538 | |||||||
539 | cdk_window_add_filter (window, | ||||||
540 | (CdkFilterFunc) keybindings_filter, | ||||||
541 | manager); | ||||||
542 | |||||||
543 | cdk_x11_display_error_trap_push (dpy); | ||||||
544 | /* Add KeyPressMask to the currently reportable event masks */ | ||||||
545 | XGetWindowAttributes (xdpy, xwindow, &atts); | ||||||
546 | XSelectInput (xdpy, xwindow, atts.your_event_mask | KeyPressMask(1L<<0)); | ||||||
547 | cdk_x11_display_error_trap_pop_ignored (dpy); | ||||||
548 | |||||||
549 | manager->priv->screens = get_screens_list (); | ||||||
550 | |||||||
551 | manager->priv->binding_list = NULL((void*)0); | ||||||
552 | bindings_get_entries (manager); | ||||||
553 | binding_register_keys (manager); | ||||||
554 | |||||||
555 | manager->priv->client = dconf_client_new (); | ||||||
556 | dconf_client_watch_fast (manager->priv->client, GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/"); | ||||||
557 | g_signal_connect (manager->priv->client, "changed", G_CALLBACK (bindings_callback), manager)g_signal_connect_data ((manager->priv->client), ("changed" ), (((GCallback) (bindings_callback))), (manager), ((void*)0) , (GConnectFlags) 0); | ||||||
558 | |||||||
559 | cafe_settings_profile_end (NULL); | ||||||
560 | |||||||
561 | return TRUE(!(0)); | ||||||
562 | } | ||||||
563 | |||||||
564 | void | ||||||
565 | csd_keybindings_manager_stop (CsdKeybindingsManager *manager) | ||||||
566 | { | ||||||
567 | CsdKeybindingsManagerPrivate *p = manager->priv; | ||||||
568 | GSList *l; | ||||||
569 | |||||||
570 | g_debug ("Stopping keybindings manager"); | ||||||
571 | |||||||
572 | if (p->client != NULL((void*)0)) { | ||||||
573 | g_object_unref (p->client); | ||||||
574 | p->client = NULL((void*)0); | ||||||
575 | } | ||||||
576 | |||||||
577 | for (l = p->screens; l; l = l->next) { | ||||||
578 | CdkScreen *screen = l->data; | ||||||
579 | cdk_window_remove_filter (cdk_screen_get_root_window (screen), | ||||||
580 | (CdkFilterFunc) keybindings_filter, | ||||||
581 | manager); | ||||||
582 | } | ||||||
583 | |||||||
584 | binding_unregister_keys (manager); | ||||||
585 | bindings_clear (manager); | ||||||
586 | |||||||
587 | g_slist_free (p->screens); | ||||||
588 | p->screens = NULL((void*)0); | ||||||
589 | } | ||||||
590 | |||||||
591 | static void | ||||||
592 | csd_keybindings_manager_class_init (CsdKeybindingsManagerClass *klass) | ||||||
593 | { | ||||||
594 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | ||||||
595 | |||||||
596 | object_class->finalize = csd_keybindings_manager_finalize; | ||||||
597 | } | ||||||
598 | |||||||
599 | static void | ||||||
600 | csd_keybindings_manager_init (CsdKeybindingsManager *manager) | ||||||
601 | { | ||||||
602 | manager->priv = csd_keybindings_manager_get_instance_private (manager); | ||||||
603 | |||||||
604 | } | ||||||
605 | |||||||
606 | static void | ||||||
607 | csd_keybindings_manager_finalize (GObject *object) | ||||||
608 | { | ||||||
609 | CsdKeybindingsManager *keybindings_manager; | ||||||
610 | |||||||
611 | g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "object != NULL") ; return; } } while (0); | ||||||
612 | g_return_if_fail (CSD_IS_KEYBINDINGS_MANAGER (object))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((object)); GType __t = ((csd_keybindings_manager_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "CSD_IS_KEYBINDINGS_MANAGER (object)" ); return; } } while (0); | ||||||
613 | |||||||
614 | keybindings_manager = CSD_KEYBINDINGS_MANAGER (object)((((CsdKeybindingsManager*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((csd_keybindings_manager_get_type ())))))); | ||||||
615 | |||||||
616 | g_return_if_fail (keybindings_manager->priv != NULL)do { if ((keybindings_manager->priv != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__ )), "keybindings_manager->priv != NULL"); return; } } while (0); | ||||||
617 | |||||||
618 | G_OBJECT_CLASS (csd_keybindings_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((csd_keybindings_manager_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | ||||||
619 | } | ||||||
620 | |||||||
621 | CsdKeybindingsManager * | ||||||
622 | csd_keybindings_manager_new (void) | ||||||
623 | { | ||||||
624 | if (manager_object != NULL((void*)0)) { | ||||||
625 | g_object_ref (manager_object)((__typeof__ (manager_object)) (g_object_ref) (manager_object )); | ||||||
626 | } else { | ||||||
627 | manager_object = g_object_new (CSD_TYPE_KEYBINDINGS_MANAGER(csd_keybindings_manager_get_type ()), NULL((void*)0)); | ||||||
628 | g_object_add_weak_pointer (manager_object, | ||||||
629 | (gpointer *) &manager_object); | ||||||
630 | } | ||||||
631 | |||||||
632 | return CSD_KEYBINDINGS_MANAGER (manager_object)((((CsdKeybindingsManager*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((manager_object)), ((csd_keybindings_manager_get_type ())))))); | ||||||
633 | } |