Bug Summary

File:plugins/keybindings/csd_keybindings-manager.c
Warning:line 431, column 25
Access of the heap area at index 2, while it holds only 2 'char *' elements

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