Bug Summary

File:plugins/keybindings/csd_keybindings-manager.c
Warning:line 436, column 20
Out of bound memory access (access exceeds upper limit of memory block)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name csd_keybindings-manager.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/plugins/keybindings -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I ../../cafe-settings-daemon -I ../../plugins/common -D CAFE_SETTINGS_LOCALEDIR="/usr/share/locale" -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/dconf -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/plugins/keybindings -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-04-16-114257-65650-1 -x c csd_keybindings-manager.c
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
52typedef struct {
53 char *binding_str;
54 char *action;
55 char *settings_path;
56 Key key;
57 Key previous_key;
58} Binding;
59
60struct CsdKeybindingsManagerPrivate
61{
62 DConfClient *client;
63 GSList *binding_list;
64 GSList *screens;
65};
66
67static void csd_keybindings_manager_finalize (GObject *object);
68
69G_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 gsize
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 (&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 ((&static_g_define_type_id
), (gsize) (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
71static gpointer manager_object = NULL((void*)0);
72
73static GSList *
74get_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
83static gboolean
84parse_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
113static gint
114compare_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
123static gboolean
124bindings_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
192static void
193bindings_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
214static void
215bindings_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
238static gboolean
239same_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
252static gboolean
253same_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
274static gboolean
275key_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
293static void
294binding_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
318static void
319binding_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
362extern char **environ;
363
364static char *
365screen_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 **/
401static char **
402get_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) {
21
Assuming 'window' is non-null
22
Taking true branch
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)
;
23
Assuming '__inst' is non-null
24
Taking false branch
25
Assuming field 'g_class' is null
26
Assuming the condition is true
27
Taking true branch
28
Loop condition is false. Exiting loop
415
416 for (i = 0; environ [i]; i++) {
29
Loop condition is true. Entering loop body
31
Loop condition is false. Execution continues on line 422
417 if (!strncmp (environ [i], "DISPLAY", 7)) {
30
Taking true branch
418 display_index = i;
419 }
420 }
421
422 if (display_index == -1) {
32
Taking false branch
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++) {
33
Loop condition is true. Entering loop body
35
Loop condition is true. Entering loop body
37
Loop condition is false. Execution continues on line 436
429 if (i
33.1
'i' is equal to 'display_index'
35.1
'i' is not equal to 'display_index'
== display_index) {
34
Taking true branch
36
Taking false branch
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);
38
Out of bound memory access (access exceeds upper limit of memory block)
437
438 return retval;
439}
440
441static CdkFilterReturn
442keybindings_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) {
1
Assuming field 'type' is equal to KeyPress
2
Taking false branch
450 return CDK_FILTER_CONTINUE;
451 }
452
453 for (li = manager->priv->binding_list; li != NULL((void*)0); li = li->next) {
3
Assuming 'li' is not equal to NULL
4
Loop condition is true. Entering loop body
7
Assuming 'li' is not equal to NULL
8
Loop condition is true. Entering loop body
11
Assuming 'li' is not equal to NULL
12
Loop condition is true. Entering loop body
454 Binding *binding = (Binding *) li->data;
455
456 if (match_key (&binding->key, xevent)) {
5
Assuming the condition is false
6
Taking false branch
9
Assuming the condition is false
10
Taking false branch
13
Assuming the condition is true
14
Taking true branch
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)
;
15
Assuming field 'action' is not equal to null
16
Taking true branch
17
Loop condition is false. Exiting loop
463
464 if (!g_shell_parse_argv (binding->action,
18
Assuming the condition is false
19
Taking false branch
465 NULL((void*)0), &argv,
466 &error)) {
467 return CDK_FILTER_CONTINUE;
468 }
469
470 envp = get_exec_environment (xevent);
20
Calling 'get_exec_environment'
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
502static void
503bindings_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
518gboolean
519csd_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
564void
565csd_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
591static void
592csd_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
599static void
600csd_keybindings_manager_init (CsdKeybindingsManager *manager)
601{
602 manager->priv = csd_keybindings_manager_get_instance_private (manager);
603
604}
605
606static void
607csd_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
621CsdKeybindingsManager *
622csd_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}