| File: | ctk/ctkapplicationaccels.c |
| Warning: | line 98, column 3 Null pointer passed to 2nd parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * Copyright © 2013 Canonical Limited | |||
| 3 | * Copyright © 2016 Sébastien Wilmet | |||
| 4 | * | |||
| 5 | * This library is free software; you can redistribute it and/or | |||
| 6 | * modify it under the terms of the GNU Lesser General Public | |||
| 7 | * License as published by the Free Software Foundation; either | |||
| 8 | * version 2 of the licence, or (at your option) any later version. | |||
| 9 | * | |||
| 10 | * This library 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 GNU | |||
| 13 | * Lesser General Public License for more details. | |||
| 14 | * | |||
| 15 | * You should have received a copy of the GNU Lesser General Public | |||
| 16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
| 17 | * | |||
| 18 | * Authors: Ryan Lortie <desrt@desrt.ca> | |||
| 19 | * Sébastien Wilmet <swilmet@gnome.org> | |||
| 20 | */ | |||
| 21 | ||||
| 22 | #include "config.h" | |||
| 23 | #include "ctkapplicationaccelsprivate.h" | |||
| 24 | #include <string.h> | |||
| 25 | #include "ctkactionmuxer.h" | |||
| 26 | ||||
| 27 | typedef struct | |||
| 28 | { | |||
| 29 | guint key; | |||
| 30 | CdkModifierType modifier; | |||
| 31 | } AccelKey; | |||
| 32 | ||||
| 33 | struct _CtkApplicationAccels | |||
| 34 | { | |||
| 35 | GObject parent; | |||
| 36 | ||||
| 37 | GHashTable *action_to_accels; | |||
| 38 | GHashTable *accel_to_actions; | |||
| 39 | }; | |||
| 40 | ||||
| 41 | G_DEFINE_TYPE (CtkApplicationAccels, ctk_application_accels, G_TYPE_OBJECT)static void ctk_application_accels_init (CtkApplicationAccels *self); static void ctk_application_accels_class_init (CtkApplicationAccelsClass *klass); static GType ctk_application_accels_get_type_once ( void); static gpointer ctk_application_accels_parent_class = ( (void*)0); static gint CtkApplicationAccels_private_offset; static void ctk_application_accels_class_intern_init (gpointer klass ) { ctk_application_accels_parent_class = g_type_class_peek_parent (klass); if (CtkApplicationAccels_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkApplicationAccels_private_offset); ctk_application_accels_class_init ((CtkApplicationAccelsClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_application_accels_get_instance_private (CtkApplicationAccels *self) { return (((gpointer) ((guint8* ) (self) + (glong) (CtkApplicationAccels_private_offset)))); } GType ctk_application_accels_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 = ctk_application_accels_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 ctk_application_accels_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkApplicationAccels" ), sizeof (CtkApplicationAccelsClass), (GClassInitFunc)(void ( *)(void)) ctk_application_accels_class_intern_init, sizeof (CtkApplicationAccels ), (GInstanceInitFunc)(void (*)(void)) ctk_application_accels_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
| 42 | ||||
| 43 | static AccelKey * | |||
| 44 | accel_key_copy (const AccelKey *source) | |||
| 45 | { | |||
| 46 | AccelKey *dest; | |||
| 47 | ||||
| 48 | dest = g_slice_new (AccelKey)((AccelKey*) g_slice_alloc (sizeof (AccelKey))); | |||
| 49 | dest->key = source->key; | |||
| 50 | dest->modifier = source->modifier; | |||
| 51 | ||||
| 52 | return dest; | |||
| 53 | } | |||
| 54 | ||||
| 55 | static void | |||
| 56 | accel_key_free (gpointer data) | |||
| 57 | { | |||
| 58 | AccelKey *key = data; | |||
| 59 | ||||
| 60 | g_slice_free (AccelKey, key)do { if (1) g_slice_free1 (sizeof (AccelKey), (key)); else (void ) ((AccelKey*) 0 == (key)); } while (0); | |||
| 61 | } | |||
| 62 | ||||
| 63 | static guint | |||
| 64 | accel_key_hash (gconstpointer data) | |||
| 65 | { | |||
| 66 | const AccelKey *key = data; | |||
| 67 | ||||
| 68 | return key->key + (key->modifier << 16); | |||
| 69 | } | |||
| 70 | ||||
| 71 | static gboolean | |||
| 72 | accel_key_equal (gconstpointer a, | |||
| 73 | gconstpointer b) | |||
| 74 | { | |||
| 75 | const AccelKey *ak = a; | |||
| 76 | const AccelKey *bk = b; | |||
| 77 | ||||
| 78 | return ak->key == bk->key && ak->modifier == bk->modifier; | |||
| 79 | } | |||
| 80 | ||||
| 81 | static void | |||
| 82 | add_entry (CtkApplicationAccels *accels, | |||
| 83 | AccelKey *key, | |||
| 84 | const gchar *action_and_target) | |||
| 85 | { | |||
| 86 | const gchar **old; | |||
| 87 | const gchar **new; | |||
| 88 | gint n; | |||
| 89 | ||||
| 90 | old = g_hash_table_lookup (accels->accel_to_actions, key); | |||
| 91 | if (old != NULL((void*)0)) | |||
| 92 | for (n = 0; old[n]; n++) /* find the length */ | |||
| 93 | ; | |||
| 94 | else | |||
| 95 | n = 0; | |||
| 96 | ||||
| 97 | new = g_new (const gchar *, n + 1 + 1)((const gchar * *) g_malloc_n ((n + 1 + 1), sizeof (const gchar *))); | |||
| 98 | memcpy (new, old, n * sizeof (const gchar *)); | |||
| ||||
| 99 | new[n] = action_and_target; | |||
| 100 | new[n + 1] = NULL((void*)0); | |||
| 101 | ||||
| 102 | g_hash_table_insert (accels->accel_to_actions, accel_key_copy (key), new); | |||
| 103 | } | |||
| 104 | ||||
| 105 | static void | |||
| 106 | remove_entry (CtkApplicationAccels *accels, | |||
| 107 | AccelKey *key, | |||
| 108 | const gchar *action_and_target) | |||
| 109 | { | |||
| 110 | const gchar **old; | |||
| 111 | const gchar **new; | |||
| 112 | gint n, i; | |||
| 113 | ||||
| 114 | /* if we can't find the entry then something has gone very wrong... */ | |||
| 115 | old = g_hash_table_lookup (accels->accel_to_actions, key); | |||
| 116 | g_assert (old != NULL)do { if (old != ((void*)0)) ; else g_assertion_message_expr ( "Ctk", "ctkapplicationaccels.c", 116, ((const char*) (__func__ )), "old != NULL"); } while (0); | |||
| 117 | ||||
| 118 | for (n = 0; old[n]; n++) /* find the length */ | |||
| 119 | ; | |||
| 120 | g_assert_cmpint (n, >, 0)do { gint64 __n1 = (n), __n2 = (0); if (__n1 > __n2) ; else g_assertion_message_cmpint ("Ctk", "ctkapplicationaccels.c", 120, ((const char*) (__func__)), "n" " " ">" " " "0", (guint64 )__n1, ">", (guint64)__n2, 'i'); } while (0); | |||
| 121 | ||||
| 122 | if (n == 1) | |||
| 123 | { | |||
| 124 | /* The simple case of removing the last action for an accel. */ | |||
| 125 | g_assert_cmpstr (old[0], ==, action_and_target)do { const char *__s1 = (old[0]), *__s2 = (action_and_target) ; if (g_strcmp0 (__s1, __s2) == 0) ; else g_assertion_message_cmpstr ("Ctk", "ctkapplicationaccels.c", 125, ((const char*) (__func__ )), "old[0]" " " "==" " " "action_and_target", __s1, "==", __s2 ); } while (0); | |||
| 126 | g_hash_table_remove (accels->accel_to_actions, key); | |||
| 127 | return; | |||
| 128 | } | |||
| 129 | ||||
| 130 | for (i = 0; i < n; i++) | |||
| 131 | if (g_str_equal (old[i], action_and_target)(strcmp ((const char *) (old[i]), (const char *) (action_and_target )) == 0)) | |||
| 132 | break; | |||
| 133 | ||||
| 134 | /* We must have found it... */ | |||
| 135 | g_assert_cmpint (i, <, n)do { gint64 __n1 = (i), __n2 = (n); if (__n1 < __n2) ; else g_assertion_message_cmpint ("Ctk", "ctkapplicationaccels.c", 135, ((const char*) (__func__)), "i" " " "<" " " "n", (guint64 )__n1, "<", (guint64)__n2, 'i'); } while (0); | |||
| 136 | ||||
| 137 | new = g_new (const gchar *, n - 1 + 1)((const gchar * *) g_malloc_n ((n - 1 + 1), sizeof (const gchar *))); | |||
| 138 | memcpy (new, old, i * sizeof (const gchar *)); | |||
| 139 | memcpy (new + i, old + i + 1, (n - (i + 1)) * sizeof (const gchar *)); | |||
| 140 | new[n - 1] = NULL((void*)0); | |||
| 141 | ||||
| 142 | g_hash_table_insert (accels->accel_to_actions, accel_key_copy (key), new); | |||
| 143 | } | |||
| 144 | ||||
| 145 | static void | |||
| 146 | ctk_application_accels_finalize (GObject *object) | |||
| 147 | { | |||
| 148 | CtkApplicationAccels *accels = CTK_APPLICATION_ACCELS (object); | |||
| 149 | ||||
| 150 | g_hash_table_unref (accels->accel_to_actions); | |||
| 151 | g_hash_table_unref (accels->action_to_accels); | |||
| 152 | ||||
| 153 | G_OBJECT_CLASS (ctk_application_accels_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_application_accels_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
| 154 | } | |||
| 155 | ||||
| 156 | static void | |||
| 157 | ctk_application_accels_class_init (CtkApplicationAccelsClass *klass) | |||
| 158 | { | |||
| 159 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
| 160 | ||||
| 161 | object_class->finalize = ctk_application_accels_finalize; | |||
| 162 | } | |||
| 163 | ||||
| 164 | static void | |||
| 165 | ctk_application_accels_init (CtkApplicationAccels *accels) | |||
| 166 | { | |||
| 167 | accels->accel_to_actions = g_hash_table_new_full (accel_key_hash, accel_key_equal, | |||
| 168 | accel_key_free, g_free); | |||
| 169 | accels->action_to_accels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); | |||
| 170 | } | |||
| 171 | ||||
| 172 | CtkApplicationAccels * | |||
| 173 | ctk_application_accels_new (void) | |||
| 174 | { | |||
| 175 | return g_object_new (CTK_TYPE_APPLICATION_ACCELS(ctk_application_accels_get_type ()), NULL((void*)0)); | |||
| 176 | } | |||
| 177 | ||||
| 178 | void | |||
| 179 | ctk_application_accels_set_accels_for_action (CtkApplicationAccels *accels, | |||
| 180 | const gchar *detailed_action_name, | |||
| 181 | const gchar * const *accelerators) | |||
| 182 | { | |||
| 183 | gchar *action_and_target; | |||
| 184 | AccelKey *keys, *old_keys; | |||
| 185 | gint i, n; | |||
| 186 | ||||
| 187 | action_and_target = ctk_normalise_detailed_action_name (detailed_action_name); | |||
| 188 | ||||
| 189 | n = accelerators ? g_strv_length ((gchar **) accelerators) : 0; | |||
| ||||
| 190 | ||||
| 191 | if (n > 0) | |||
| 192 | { | |||
| 193 | keys = g_new0 (AccelKey, n + 1)((AccelKey *) g_malloc0_n ((n + 1), sizeof (AccelKey))); | |||
| 194 | ||||
| 195 | for (i = 0; i
| |||
| 196 | { | |||
| 197 | ctk_accelerator_parse (accelerators[i], &keys[i].key, &keys[i].modifier); | |||
| 198 | ||||
| 199 | if (keys[i].key == 0) | |||
| 200 | { | |||
| 201 | g_warning ("Unable to parse accelerator '%s': ignored request to install %d accelerators", | |||
| 202 | accelerators[i], n); | |||
| 203 | g_free (action_and_target); | |||
| 204 | g_free (keys); | |||
| 205 | return; | |||
| 206 | } | |||
| 207 | } | |||
| 208 | } | |||
| 209 | else | |||
| 210 | keys = NULL((void*)0); | |||
| 211 | ||||
| 212 | old_keys = g_hash_table_lookup (accels->action_to_accels, action_and_target); | |||
| 213 | if (old_keys) | |||
| 214 | { | |||
| 215 | /* We need to remove accel entries from existing keys */ | |||
| 216 | for (i = 0; old_keys[i].key; i++) | |||
| 217 | remove_entry (accels, &old_keys[i], action_and_target); | |||
| 218 | } | |||
| 219 | ||||
| 220 | if (keys
| |||
| 221 | { | |||
| 222 | g_hash_table_replace (accels->action_to_accels, action_and_target, keys); | |||
| 223 | ||||
| 224 | for (i = 0; i < n; i++) | |||
| 225 | add_entry (accels, &keys[i], action_and_target); | |||
| 226 | } | |||
| 227 | else | |||
| 228 | { | |||
| 229 | g_hash_table_remove (accels->action_to_accels, action_and_target); | |||
| 230 | g_free (action_and_target); | |||
| 231 | } | |||
| 232 | } | |||
| 233 | ||||
| 234 | gchar ** | |||
| 235 | ctk_application_accels_get_accels_for_action (CtkApplicationAccels *accels, | |||
| 236 | const gchar *detailed_action_name) | |||
| 237 | { | |||
| 238 | gchar *action_and_target; | |||
| 239 | AccelKey *keys; | |||
| 240 | gchar **result; | |||
| 241 | gint n, i = 0; | |||
| 242 | ||||
| 243 | action_and_target = ctk_normalise_detailed_action_name (detailed_action_name); | |||
| 244 | ||||
| 245 | keys = g_hash_table_lookup (accels->action_to_accels, action_and_target); | |||
| 246 | if (!keys) | |||
| 247 | { | |||
| 248 | g_free (action_and_target); | |||
| 249 | return g_new0 (gchar *, 0 + 1)((gchar * *) g_malloc0_n ((0 + 1), sizeof (gchar *))); | |||
| 250 | } | |||
| 251 | ||||
| 252 | for (n = 0; keys[n].key; n++) | |||
| 253 | ; | |||
| 254 | ||||
| 255 | result = g_new0 (gchar *, n + 1)((gchar * *) g_malloc0_n ((n + 1), sizeof (gchar *))); | |||
| 256 | ||||
| 257 | for (i = 0; i < n; i++) | |||
| 258 | result[i] = ctk_accelerator_name (keys[i].key, keys[i].modifier); | |||
| 259 | ||||
| 260 | g_free (action_and_target); | |||
| 261 | return result; | |||
| 262 | } | |||
| 263 | ||||
| 264 | gchar ** | |||
| 265 | ctk_application_accels_get_actions_for_accel (CtkApplicationAccels *accels, | |||
| 266 | const gchar *accel) | |||
| 267 | { | |||
| 268 | const gchar * const *actions_and_targets; | |||
| 269 | gchar **detailed_actions; | |||
| 270 | AccelKey accel_key; | |||
| 271 | guint i, n; | |||
| 272 | ||||
| 273 | ctk_accelerator_parse (accel, &accel_key.key, &accel_key.modifier); | |||
| 274 | ||||
| 275 | if (accel_key.key == 0) | |||
| 276 | { | |||
| 277 | g_critical ("invalid accelerator string '%s'", accel); | |||
| 278 | g_return_val_if_fail (accel_key.key != 0, NULL)do { if ((accel_key.key != 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "accel_key.key != 0"); return (((void*)0)); } } while (0); | |||
| 279 | } | |||
| 280 | ||||
| 281 | actions_and_targets = g_hash_table_lookup (accels->accel_to_actions, &accel_key); | |||
| 282 | n = actions_and_targets ? g_strv_length ((gchar **) actions_and_targets) : 0; | |||
| 283 | ||||
| 284 | detailed_actions = g_new0 (gchar *, n + 1)((gchar * *) g_malloc0_n ((n + 1), sizeof (gchar *))); | |||
| 285 | ||||
| 286 | for (i = 0; i < n; i++) | |||
| 287 | { | |||
| 288 | const gchar *action_and_target = actions_and_targets[i]; | |||
| 289 | const gchar *sep; | |||
| 290 | GVariant *target; | |||
| 291 | ||||
| 292 | sep = strrchr (action_and_target, '|'); | |||
| 293 | target = g_variant_parse (NULL((void*)0), action_and_target, sep, NULL((void*)0), NULL((void*)0)); | |||
| 294 | detailed_actions[i] = g_action_print_detailed_name (sep + 1, target); | |||
| 295 | if (target) | |||
| 296 | g_variant_unref (target); | |||
| 297 | } | |||
| 298 | ||||
| 299 | detailed_actions[n] = NULL((void*)0); | |||
| 300 | ||||
| 301 | return detailed_actions; | |||
| 302 | } | |||
| 303 | ||||
| 304 | gchar ** | |||
| 305 | ctk_application_accels_list_action_descriptions (CtkApplicationAccels *accels) | |||
| 306 | { | |||
| 307 | GHashTableIter iter; | |||
| 308 | gchar **result; | |||
| 309 | gint n, i = 0; | |||
| 310 | gpointer key; | |||
| 311 | ||||
| 312 | n = g_hash_table_size (accels->action_to_accels); | |||
| 313 | result = g_new (gchar *, n + 1)((gchar * *) g_malloc_n ((n + 1), sizeof (gchar *))); | |||
| 314 | ||||
| 315 | g_hash_table_iter_init (&iter, accels->action_to_accels); | |||
| 316 | while (g_hash_table_iter_next (&iter, &key, NULL((void*)0))) | |||
| 317 | { | |||
| 318 | const gchar *action_and_target = key; | |||
| 319 | const gchar *sep; | |||
| 320 | GVariant *target; | |||
| 321 | ||||
| 322 | sep = strrchr (action_and_target, '|'); | |||
| 323 | target = g_variant_parse (NULL((void*)0), action_and_target, sep, NULL((void*)0), NULL((void*)0)); | |||
| 324 | result[i++] = g_action_print_detailed_name (sep + 1, target); | |||
| 325 | if (target) | |||
| 326 | g_variant_unref (target); | |||
| 327 | } | |||
| 328 | g_assert_cmpint (i, ==, n)do { gint64 __n1 = (i), __n2 = (n); if (__n1 == __n2) ; else g_assertion_message_cmpint ("Ctk", "ctkapplicationaccels.c", 328, ((const char*) (__func__ )), "i" " " "==" " " "n", (guint64)__n1, "==", (guint64)__n2, 'i'); } while (0); | |||
| 329 | result[i] = NULL((void*)0); | |||
| 330 | ||||
| 331 | return result; | |||
| 332 | } | |||
| 333 | ||||
| 334 | void | |||
| 335 | ctk_application_accels_foreach_key (CtkApplicationAccels *accels, | |||
| 336 | CtkWindow *window, | |||
| 337 | CtkWindowKeysForeachFunc callback, | |||
| 338 | gpointer user_data) | |||
| 339 | { | |||
| 340 | GHashTableIter iter; | |||
| 341 | gpointer key; | |||
| 342 | ||||
| 343 | g_hash_table_iter_init (&iter, accels->accel_to_actions); | |||
| 344 | while (g_hash_table_iter_next (&iter, &key, NULL((void*)0))) | |||
| 345 | { | |||
| 346 | AccelKey *accel_key = key; | |||
| 347 | ||||
| 348 | (* callback) (window, accel_key->key, accel_key->modifier, FALSE(0), user_data); | |||
| 349 | } | |||
| 350 | } | |||
| 351 | ||||
| 352 | gboolean | |||
| 353 | ctk_application_accels_activate (CtkApplicationAccels *accels, | |||
| 354 | GActionGroup *action_group, | |||
| 355 | guint key, | |||
| 356 | CdkModifierType modifier) | |||
| 357 | { | |||
| 358 | AccelKey accel_key = { key, modifier }; | |||
| 359 | const gchar **actions; | |||
| 360 | gint i; | |||
| 361 | ||||
| 362 | actions = g_hash_table_lookup (accels->accel_to_actions, &accel_key); | |||
| 363 | ||||
| 364 | if (actions == NULL((void*)0)) | |||
| 365 | return FALSE(0); | |||
| 366 | ||||
| 367 | /* We may have more than one action on a given accel. This could be | |||
| 368 | * the case if we have different types of windows with different | |||
| 369 | * actions in each. | |||
| 370 | * | |||
| 371 | * Find the first one that will successfully activate and use it. | |||
| 372 | */ | |||
| 373 | for (i = 0; actions[i]; i++) | |||
| 374 | { | |||
| 375 | const GVariantType *parameter_type; | |||
| 376 | const gchar *action_name; | |||
| 377 | const gchar *sep; | |||
| 378 | gboolean enabled; | |||
| 379 | GVariant *target; | |||
| 380 | ||||
| 381 | sep = strrchr (actions[i], '|'); | |||
| 382 | action_name = sep + 1; | |||
| 383 | ||||
| 384 | if (!g_action_group_query_action (action_group, action_name, &enabled, ¶meter_type, NULL((void*)0), NULL((void*)0), NULL((void*)0))) | |||
| 385 | continue; | |||
| 386 | ||||
| 387 | if (!enabled) | |||
| 388 | continue; | |||
| 389 | ||||
| 390 | /* We found an action with the correct name and it's enabled. | |||
| 391 | * This is the action that we are going to try to invoke. | |||
| 392 | * | |||
| 393 | * There is still the possibility that the target value doesn't | |||
| 394 | * match the expected parameter type. In that case, we will print | |||
| 395 | * a warning. | |||
| 396 | * | |||
| 397 | * Note: we want to hold a ref on the target while we're invoking | |||
| 398 | * the action to prevent trouble if someone uninstalls the accel | |||
| 399 | * from the handler. That's not a problem since we're parsing it. | |||
| 400 | */ | |||
| 401 | if (actions[i] != sep) /* if it has a target... */ | |||
| 402 | { | |||
| 403 | GError *error = NULL((void*)0); | |||
| 404 | ||||
| 405 | if (parameter_type == NULL((void*)0)) | |||
| 406 | { | |||
| 407 | gchar *accel_str = ctk_accelerator_name (key, modifier); | |||
| 408 | g_warning ("Accelerator '%s' tries to invoke action '%s' with target, but action has no parameter", | |||
| 409 | accel_str, action_name); | |||
| 410 | g_free (accel_str); | |||
| 411 | return TRUE(!(0)); | |||
| 412 | } | |||
| 413 | ||||
| 414 | target = g_variant_parse (NULL((void*)0), actions[i], sep, NULL((void*)0), &error); | |||
| 415 | g_assert_no_error (error)do { if (error) g_assertion_message_error ("Ctk", "ctkapplicationaccels.c" , 415, ((const char*) (__func__)), "error", error, 0, 0); } while (0); | |||
| 416 | g_assert (target)do { if (target) ; else g_assertion_message_expr ("Ctk", "ctkapplicationaccels.c" , 416, ((const char*) (__func__)), "target"); } while (0); | |||
| 417 | ||||
| 418 | if (!g_variant_is_of_type (target, parameter_type)) | |||
| 419 | { | |||
| 420 | gchar *accel_str = ctk_accelerator_name (key, modifier); | |||
| 421 | gchar *typestr = g_variant_type_dup_string (parameter_type); | |||
| 422 | gchar *targetstr = g_variant_print (target, TRUE(!(0))); | |||
| 423 | g_warning ("Accelerator '%s' tries to invoke action '%s' with target '%s'," | |||
| 424 | " but action expects parameter with type '%s'", accel_str, action_name, targetstr, typestr); | |||
| 425 | g_variant_unref (target); | |||
| 426 | g_free (targetstr); | |||
| 427 | g_free (accel_str); | |||
| 428 | g_free (typestr); | |||
| 429 | return TRUE(!(0)); | |||
| 430 | } | |||
| 431 | } | |||
| 432 | else | |||
| 433 | { | |||
| 434 | if (parameter_type != NULL((void*)0)) | |||
| 435 | { | |||
| 436 | gchar *accel_str = ctk_accelerator_name (key, modifier); | |||
| 437 | gchar *typestr = g_variant_type_dup_string (parameter_type); | |||
| 438 | g_warning ("Accelerator '%s' tries to invoke action '%s' without target," | |||
| 439 | " but action expects parameter with type '%s'", accel_str, action_name, typestr); | |||
| 440 | g_free (accel_str); | |||
| 441 | g_free (typestr); | |||
| 442 | return TRUE(!(0)); | |||
| 443 | } | |||
| 444 | ||||
| 445 | target = NULL((void*)0); | |||
| 446 | } | |||
| 447 | ||||
| 448 | g_action_group_activate_action (action_group, action_name, target); | |||
| 449 | ||||
| 450 | if (target) | |||
| 451 | g_variant_unref (target); | |||
| 452 | ||||
| 453 | return TRUE(!(0)); | |||
| 454 | } | |||
| 455 | ||||
| 456 | return FALSE(0); | |||
| 457 | } |