[14481] | 1 | /* GTK - The GIMP Toolkit |
---|
| 2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
---|
| 3 | * |
---|
| 4 | * This library is free software; you can redistribute it and/or |
---|
| 5 | * modify it under the terms of the GNU Library General Public |
---|
| 6 | * License as published by the Free Software Foundation; either |
---|
| 7 | * version 2 of the License, or (at your option) any later version. |
---|
| 8 | * |
---|
| 9 | * This library is distributed in the hope that it will be useful, |
---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 12 | * Library General Public License for more details. |
---|
| 13 | * |
---|
| 14 | * You should have received a copy of the GNU Library General Public |
---|
| 15 | * License along with this library; if not, write to the |
---|
| 16 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
| 17 | * Boston, MA 02111-1307, USA. |
---|
| 18 | */ |
---|
| 19 | |
---|
| 20 | /* |
---|
| 21 | * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS |
---|
| 22 | * file for a list of people on the GTK+ Team. See the ChangeLog |
---|
| 23 | * files for a list of changes. These files are distributed with |
---|
| 24 | * GTK+ at ftp://ftp.gtk.org/pub/gtk/. |
---|
| 25 | */ |
---|
| 26 | |
---|
| 27 | #include <stdarg.h> |
---|
| 28 | #include <string.h> |
---|
| 29 | #include "gtkobject.h" |
---|
| 30 | #include "gtkargcollector.c" |
---|
| 31 | |
---|
| 32 | |
---|
| 33 | #define MAX_ARG_LENGTH (256) |
---|
| 34 | |
---|
| 35 | |
---|
| 36 | /* --- typedefs --- */ |
---|
| 37 | typedef struct _GtkArgQueryData GtkArgQueryData; |
---|
| 38 | |
---|
| 39 | |
---|
| 40 | /* --- structures --- */ |
---|
| 41 | struct _GtkArgQueryData |
---|
| 42 | { |
---|
| 43 | GList *arg_list; |
---|
| 44 | GtkType class_type; |
---|
| 45 | }; |
---|
| 46 | |
---|
| 47 | |
---|
| 48 | |
---|
| 49 | /* --- functions --- */ |
---|
| 50 | GtkArgInfo* |
---|
| 51 | gtk_arg_type_new_static (GtkType base_class_type, |
---|
| 52 | const gchar *arg_name, |
---|
| 53 | guint class_n_args_offset, |
---|
| 54 | GHashTable *arg_info_hash_table, |
---|
| 55 | GtkType arg_type, |
---|
| 56 | guint arg_flags, |
---|
| 57 | guint arg_id) |
---|
| 58 | { |
---|
| 59 | GtkArgInfo *info; |
---|
| 60 | gchar class_part[MAX_ARG_LENGTH]; |
---|
| 61 | gchar *arg_part; |
---|
| 62 | GtkType class_type; |
---|
| 63 | guint class_offset; |
---|
| 64 | guint *n_args_p; |
---|
| 65 | gchar *p; |
---|
| 66 | |
---|
| 67 | g_return_val_if_fail (arg_name != NULL, NULL); |
---|
| 68 | g_return_val_if_fail (GTK_FUNDAMENTAL_TYPE (base_class_type) == GTK_TYPE_OBJECT, NULL); |
---|
| 69 | g_return_val_if_fail (class_n_args_offset != 0, NULL); |
---|
| 70 | g_return_val_if_fail (arg_info_hash_table != NULL, NULL); |
---|
| 71 | g_return_val_if_fail (arg_type > GTK_TYPE_NONE, NULL); |
---|
| 72 | g_return_val_if_fail (arg_id > 0, NULL); |
---|
| 73 | g_return_val_if_fail ((arg_flags & GTK_ARG_READWRITE) != 0, NULL); |
---|
| 74 | /* g_return_val_if_fail ((arg_flags & GTK_ARG_CHILD_ARG) == 0, NULL); */ |
---|
| 75 | |
---|
| 76 | arg_flags &= GTK_ARG_MASK; |
---|
| 77 | |
---|
| 78 | arg_part = strchr (arg_name, ':'); |
---|
| 79 | if (!arg_part || (arg_part[0] != ':') || (arg_part[1] != ':')) |
---|
| 80 | { |
---|
| 81 | g_warning ("gtk_arg_type_new(): invalid arg name: \"%s\"\n", arg_name); |
---|
| 82 | return NULL; |
---|
| 83 | } |
---|
| 84 | |
---|
| 85 | class_offset = (guint) (arg_part - arg_name); |
---|
| 86 | strncpy (class_part, arg_name, class_offset); |
---|
| 87 | class_part[class_offset] = 0; |
---|
| 88 | |
---|
| 89 | class_type = gtk_type_from_name (class_part); |
---|
| 90 | if (!gtk_type_is_a (class_type, base_class_type)) |
---|
| 91 | { |
---|
| 92 | g_warning ("gtk_arg_type_new(): argument class in \"%s\" is not in the `%s' ancestry", |
---|
| 93 | arg_name, |
---|
| 94 | gtk_type_name (base_class_type)); |
---|
| 95 | return NULL; |
---|
| 96 | } |
---|
| 97 | |
---|
| 98 | p = gtk_type_class (class_type); |
---|
| 99 | p += class_n_args_offset; |
---|
| 100 | n_args_p = (guint*) p; |
---|
| 101 | *n_args_p += 1; |
---|
| 102 | |
---|
| 103 | info = g_new (GtkArgInfo, 1); |
---|
| 104 | info->class_type = class_type; |
---|
| 105 | info->full_name = (gchar*) arg_name; /* _static */ |
---|
| 106 | info->name = info->full_name + class_offset + 2; |
---|
| 107 | info->type = arg_type; |
---|
| 108 | info->arg_flags = arg_flags; |
---|
| 109 | info->arg_id = arg_id; |
---|
| 110 | info->seq_id = *n_args_p; |
---|
| 111 | |
---|
| 112 | g_hash_table_insert (arg_info_hash_table, info, info); |
---|
| 113 | |
---|
| 114 | return info; |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | gchar* |
---|
| 118 | gtk_arg_name_strip_type (const gchar *arg_name) |
---|
| 119 | { |
---|
| 120 | gchar buffer[MAX_ARG_LENGTH]; |
---|
| 121 | gchar *p; |
---|
| 122 | |
---|
| 123 | /* security audit |
---|
| 124 | */ |
---|
| 125 | if (!arg_name || strlen (arg_name) > MAX_ARG_LENGTH - 8) |
---|
| 126 | return NULL; |
---|
| 127 | |
---|
| 128 | p = strchr (arg_name, ':'); |
---|
| 129 | if (p) |
---|
| 130 | { |
---|
| 131 | guint len; |
---|
| 132 | |
---|
| 133 | if ((p[0] != ':') || (p[1] != ':') || (p[2] == 0)) |
---|
| 134 | return NULL; |
---|
| 135 | len = (guint) (p - arg_name); |
---|
| 136 | strncpy (buffer, arg_name, len); |
---|
| 137 | buffer[len] = 0; |
---|
| 138 | |
---|
| 139 | if (gtk_type_from_name (buffer) != GTK_TYPE_INVALID) |
---|
| 140 | return p + 2; |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | return (gchar*) arg_name; |
---|
| 144 | } |
---|
| 145 | |
---|
| 146 | gchar* |
---|
| 147 | gtk_arg_get_info (GtkType object_type, |
---|
| 148 | GHashTable *arg_info_hash_table, |
---|
| 149 | const gchar *arg_name, |
---|
| 150 | GtkArgInfo **info_p) |
---|
| 151 | { |
---|
| 152 | GtkType otype; |
---|
| 153 | gchar buffer[MAX_ARG_LENGTH]; |
---|
| 154 | guint len; |
---|
| 155 | gchar *p; |
---|
| 156 | |
---|
| 157 | *info_p = NULL; |
---|
| 158 | |
---|
| 159 | /* security audit |
---|
| 160 | */ |
---|
| 161 | if (!arg_name || strlen (arg_name) > MAX_ARG_LENGTH - 8) |
---|
| 162 | return g_strdup ("argument name exceeds maximum size."); |
---|
| 163 | |
---|
| 164 | /* split off the object-type part |
---|
| 165 | */ |
---|
| 166 | p = strchr (arg_name, ':'); |
---|
| 167 | if (p) |
---|
| 168 | { |
---|
| 169 | if ((p[0] != ':') || (p[1] != ':')) |
---|
| 170 | return g_strconcat ("invalid argument syntax: \"", |
---|
| 171 | arg_name, |
---|
| 172 | "\"", |
---|
| 173 | NULL); |
---|
| 174 | len = (guint) (p - arg_name); |
---|
| 175 | strncpy (buffer, arg_name, len); |
---|
| 176 | buffer[len] = 0; |
---|
| 177 | |
---|
| 178 | otype = gtk_type_from_name (buffer); |
---|
| 179 | if (otype != GTK_TYPE_INVALID) |
---|
| 180 | arg_name = p + 2; |
---|
| 181 | } |
---|
| 182 | else |
---|
| 183 | otype = GTK_TYPE_INVALID; |
---|
| 184 | |
---|
| 185 | /* split off the argument name |
---|
| 186 | */ |
---|
| 187 | p = strchr (arg_name, ':'); |
---|
| 188 | if (p) |
---|
| 189 | { |
---|
| 190 | if ((p[0] != ':') || (p[1] != ':')) |
---|
| 191 | return g_strconcat ("invalid argument syntax: \"", |
---|
| 192 | arg_name, |
---|
| 193 | "\"", |
---|
| 194 | NULL); |
---|
| 195 | len = (guint) (p - arg_name); |
---|
| 196 | strncpy (buffer, arg_name, len); |
---|
| 197 | buffer[len] = 0; |
---|
| 198 | arg_name = buffer; |
---|
| 199 | } |
---|
| 200 | |
---|
| 201 | /* lookup the argument |
---|
| 202 | */ |
---|
| 203 | if (otype != GTK_TYPE_INVALID) |
---|
| 204 | { |
---|
| 205 | GtkArgInfo info; |
---|
| 206 | |
---|
| 207 | info.class_type = otype; |
---|
| 208 | info.name = (gchar*) arg_name; |
---|
| 209 | |
---|
| 210 | *info_p = g_hash_table_lookup (arg_info_hash_table, &info); |
---|
| 211 | if (*info_p && !gtk_type_is_a (object_type, (*info_p)->class_type)) |
---|
| 212 | *info_p = NULL; |
---|
| 213 | } |
---|
| 214 | else |
---|
| 215 | { |
---|
| 216 | otype = object_type; |
---|
| 217 | while (!*info_p && GTK_FUNDAMENTAL_TYPE (otype) == GTK_TYPE_OBJECT) |
---|
| 218 | { |
---|
| 219 | GtkArgInfo info; |
---|
| 220 | |
---|
| 221 | info.class_type = otype; |
---|
| 222 | info.name = (gchar*) arg_name; |
---|
| 223 | |
---|
| 224 | *info_p = g_hash_table_lookup (arg_info_hash_table, &info); |
---|
| 225 | |
---|
| 226 | otype = gtk_type_parent (otype); |
---|
| 227 | } |
---|
| 228 | } |
---|
| 229 | |
---|
| 230 | if (!*info_p) |
---|
| 231 | return g_strconcat ("could not find argument \"", |
---|
| 232 | arg_name, |
---|
| 233 | "\" in the `", |
---|
| 234 | gtk_type_name (object_type), |
---|
| 235 | "' class ancestry", |
---|
| 236 | NULL); |
---|
| 237 | |
---|
| 238 | return NULL; |
---|
| 239 | } |
---|
| 240 | |
---|
| 241 | gchar* |
---|
| 242 | gtk_args_collect (GtkType object_type, |
---|
| 243 | GHashTable *arg_info_hash_table, |
---|
| 244 | GSList **arg_list_p, |
---|
| 245 | GSList **info_list_p, |
---|
| 246 | const gchar *first_arg_name, |
---|
| 247 | va_list var_args) |
---|
| 248 | { |
---|
| 249 | GSList *arg_list; |
---|
| 250 | GSList *info_list; |
---|
| 251 | const gchar *arg_name; |
---|
| 252 | |
---|
| 253 | g_return_val_if_fail (arg_list_p != NULL, NULL); |
---|
| 254 | *arg_list_p = NULL; |
---|
| 255 | g_return_val_if_fail (info_list_p != NULL, NULL); |
---|
| 256 | *info_list_p = 0; |
---|
| 257 | g_return_val_if_fail (arg_info_hash_table != NULL, NULL); |
---|
| 258 | |
---|
| 259 | arg_list = NULL; |
---|
| 260 | info_list = NULL; |
---|
| 261 | arg_name = first_arg_name; |
---|
| 262 | while (arg_name) |
---|
| 263 | { |
---|
| 264 | GtkArgInfo *info = NULL; |
---|
| 265 | gchar *error; |
---|
| 266 | |
---|
| 267 | error = gtk_arg_get_info (object_type, arg_info_hash_table, arg_name, &info); |
---|
| 268 | if (!error) |
---|
| 269 | { |
---|
| 270 | GtkArg *arg; |
---|
| 271 | |
---|
| 272 | info_list = g_slist_prepend (info_list, info); |
---|
| 273 | |
---|
| 274 | arg = gtk_arg_new (info->type); |
---|
| 275 | arg->name = (gchar*) arg_name; |
---|
| 276 | GTK_ARG_COLLECT_VALUE (arg, var_args, error); |
---|
| 277 | arg_list = g_slist_prepend (arg_list, arg); |
---|
| 278 | } |
---|
| 279 | if (error) |
---|
| 280 | { |
---|
| 281 | gtk_args_collect_cleanup (arg_list, info_list); |
---|
| 282 | |
---|
| 283 | return error; |
---|
| 284 | } |
---|
| 285 | |
---|
| 286 | arg_name = va_arg (var_args, gchar*); |
---|
| 287 | } |
---|
| 288 | |
---|
| 289 | *arg_list_p = g_slist_reverse (arg_list); |
---|
| 290 | *info_list_p = g_slist_reverse (info_list); |
---|
| 291 | |
---|
| 292 | return NULL; |
---|
| 293 | } |
---|
| 294 | |
---|
| 295 | void |
---|
| 296 | gtk_args_collect_cleanup (GSList *arg_list, |
---|
| 297 | GSList *info_list) |
---|
| 298 | { |
---|
| 299 | GSList *slist; |
---|
| 300 | |
---|
| 301 | g_slist_free (info_list); |
---|
| 302 | |
---|
| 303 | for (slist = arg_list; slist; slist = slist->next) |
---|
| 304 | gtk_arg_free (slist->data, FALSE); |
---|
| 305 | g_slist_free (arg_list); |
---|
| 306 | } |
---|
| 307 | |
---|
| 308 | static void |
---|
| 309 | gtk_args_query_foreach (gpointer key, |
---|
| 310 | gpointer value, |
---|
| 311 | gpointer user_data) |
---|
| 312 | { |
---|
| 313 | register GtkArgInfo *info; |
---|
| 314 | register GtkArgQueryData *data; |
---|
| 315 | |
---|
| 316 | g_assert (key == value); /* paranoid */ |
---|
| 317 | |
---|
| 318 | info = value; |
---|
| 319 | data = user_data; |
---|
| 320 | |
---|
| 321 | if (info->class_type == data->class_type) |
---|
| 322 | data->arg_list = g_list_prepend (data->arg_list, info); |
---|
| 323 | } |
---|
| 324 | |
---|
| 325 | GtkArg* |
---|
| 326 | gtk_args_query (GtkType class_type, |
---|
| 327 | GHashTable *arg_info_hash_table, |
---|
| 328 | guint32 **arg_flags, |
---|
| 329 | guint *n_args_p) |
---|
| 330 | { |
---|
| 331 | GtkArg *args; |
---|
| 332 | GtkArgQueryData query_data; |
---|
| 333 | |
---|
| 334 | if (arg_flags) |
---|
| 335 | *arg_flags = NULL; |
---|
| 336 | g_return_val_if_fail (n_args_p != NULL, NULL); |
---|
| 337 | *n_args_p = 0; |
---|
| 338 | g_return_val_if_fail (arg_info_hash_table != NULL, NULL); |
---|
| 339 | |
---|
| 340 | /* make sure the types class has been initialized, because |
---|
| 341 | * the argument setup happens in the gtk_*_class_init() functions. |
---|
| 342 | */ |
---|
| 343 | gtk_type_class (class_type); |
---|
| 344 | |
---|
| 345 | query_data.arg_list = NULL; |
---|
| 346 | query_data.class_type = class_type; |
---|
| 347 | g_hash_table_foreach (arg_info_hash_table, gtk_args_query_foreach, &query_data); |
---|
| 348 | |
---|
| 349 | if (query_data.arg_list) |
---|
| 350 | { |
---|
| 351 | register GList *list; |
---|
| 352 | register guint len; |
---|
| 353 | |
---|
| 354 | list = query_data.arg_list; |
---|
| 355 | len = 1; |
---|
| 356 | while (list->next) |
---|
| 357 | { |
---|
| 358 | len++; |
---|
| 359 | list = list->next; |
---|
| 360 | } |
---|
| 361 | |
---|
| 362 | args = g_new0 (GtkArg, len); |
---|
| 363 | *n_args_p = len; |
---|
| 364 | if (arg_flags) |
---|
| 365 | *arg_flags = g_new (guint32, len); |
---|
| 366 | |
---|
| 367 | do |
---|
| 368 | { |
---|
| 369 | GtkArgInfo *info; |
---|
| 370 | |
---|
| 371 | info = list->data; |
---|
| 372 | list = list->prev; |
---|
| 373 | |
---|
| 374 | g_assert (info->seq_id > 0 && info->seq_id <= len); /* paranoid */ |
---|
| 375 | |
---|
| 376 | args[info->seq_id - 1].type = info->type; |
---|
| 377 | args[info->seq_id - 1].name = info->full_name; |
---|
| 378 | if (arg_flags) |
---|
| 379 | (*arg_flags)[info->seq_id - 1] = info->arg_flags; |
---|
| 380 | } |
---|
| 381 | while (list); |
---|
| 382 | |
---|
| 383 | g_list_free (query_data.arg_list); |
---|
| 384 | } |
---|
| 385 | else |
---|
| 386 | args = NULL; |
---|
| 387 | |
---|
| 388 | return args; |
---|
| 389 | } |
---|
| 390 | |
---|
| 391 | GtkArg* |
---|
| 392 | gtk_arg_new (GtkType arg_type) |
---|
| 393 | { |
---|
| 394 | GtkArg *arg; |
---|
| 395 | |
---|
| 396 | arg = g_new0 (GtkArg, 1); |
---|
| 397 | arg->type = arg_type; |
---|
| 398 | arg->name = NULL; |
---|
| 399 | |
---|
| 400 | return arg; |
---|
| 401 | } |
---|
| 402 | |
---|
| 403 | GtkArg* |
---|
| 404 | gtk_arg_copy (GtkArg *src_arg, |
---|
| 405 | GtkArg *dest_arg) |
---|
| 406 | { |
---|
| 407 | g_return_val_if_fail (src_arg != NULL, NULL); |
---|
| 408 | |
---|
| 409 | if (!dest_arg) |
---|
| 410 | { |
---|
| 411 | dest_arg = g_new0 (GtkArg, 1); |
---|
| 412 | dest_arg->name = src_arg->name; |
---|
| 413 | } |
---|
| 414 | |
---|
| 415 | dest_arg->type = src_arg->type; |
---|
| 416 | dest_arg->d = src_arg->d; |
---|
| 417 | |
---|
| 418 | if (GTK_FUNDAMENTAL_TYPE (src_arg->type) == GTK_TYPE_STRING) |
---|
| 419 | GTK_VALUE_STRING (*dest_arg) = g_strdup (GTK_VALUE_STRING (*src_arg)); |
---|
| 420 | |
---|
| 421 | return dest_arg; |
---|
| 422 | } |
---|
| 423 | |
---|
| 424 | void |
---|
| 425 | gtk_arg_free (GtkArg *arg, |
---|
| 426 | gboolean free_contents) |
---|
| 427 | { |
---|
| 428 | g_return_if_fail (arg != NULL); |
---|
| 429 | |
---|
| 430 | if (free_contents) |
---|
| 431 | gtk_arg_reset (arg); |
---|
| 432 | g_free (arg); |
---|
| 433 | } |
---|
| 434 | |
---|
| 435 | void |
---|
| 436 | gtk_arg_reset (GtkArg *arg) |
---|
| 437 | { |
---|
| 438 | GtkType fundamental_type; |
---|
| 439 | |
---|
| 440 | g_return_if_fail (arg != NULL); |
---|
| 441 | |
---|
| 442 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); |
---|
| 443 | if (fundamental_type > GTK_TYPE_FUNDAMENTAL_LAST) |
---|
| 444 | { |
---|
| 445 | fundamental_type = gtk_type_get_varargs_type (fundamental_type); |
---|
| 446 | if (!fundamental_type) |
---|
| 447 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); |
---|
| 448 | } |
---|
| 449 | |
---|
| 450 | if (fundamental_type == GTK_TYPE_STRING) |
---|
| 451 | { |
---|
| 452 | g_free (GTK_VALUE_STRING (*arg)); |
---|
| 453 | arg->type = GTK_TYPE_INVALID; |
---|
| 454 | } |
---|
| 455 | else if (arg->type != GTK_TYPE_INVALID) |
---|
| 456 | arg->type = GTK_TYPE_INVALID; |
---|
| 457 | } |
---|
| 458 | |
---|
| 459 | gint |
---|
| 460 | gtk_arg_info_equal (gconstpointer arg_info_1, |
---|
| 461 | gconstpointer arg_info_2) |
---|
| 462 | { |
---|
| 463 | register const GtkArgInfo *info1 = arg_info_1; |
---|
| 464 | register const GtkArgInfo *info2 = arg_info_2; |
---|
| 465 | |
---|
| 466 | return ((info1->class_type == info2->class_type) && |
---|
| 467 | strcmp (info1->name, info2->name) == 0); |
---|
| 468 | } |
---|
| 469 | |
---|
| 470 | guint |
---|
| 471 | gtk_arg_info_hash (gconstpointer arg_info) |
---|
| 472 | { |
---|
| 473 | register const GtkArgInfo *info = arg_info; |
---|
| 474 | register const gchar *p; |
---|
| 475 | register guint h = info->class_type >> 8; |
---|
| 476 | |
---|
| 477 | for (p = info->name; *p; p++) |
---|
| 478 | { |
---|
| 479 | register guint g; |
---|
| 480 | |
---|
| 481 | h = (h << 4) + *p; |
---|
| 482 | g = h & 0xf0000000; |
---|
| 483 | if (g) |
---|
| 484 | { |
---|
| 485 | h = h ^ (g >> 24); |
---|
| 486 | h = h ^ g; |
---|
| 487 | } |
---|
| 488 | } |
---|
| 489 | |
---|
| 490 | return h; |
---|
| 491 | } |
---|
| 492 | |
---|
| 493 | gboolean |
---|
| 494 | gtk_arg_values_equal (const GtkArg *arg1, |
---|
| 495 | const GtkArg *arg2) |
---|
| 496 | { |
---|
| 497 | GtkType fundamental_type; |
---|
| 498 | gboolean equal; |
---|
| 499 | |
---|
| 500 | g_return_val_if_fail (arg1 != NULL, FALSE); |
---|
| 501 | g_return_val_if_fail (arg2 != NULL, FALSE); |
---|
| 502 | g_return_val_if_fail (GTK_FUNDAMENTAL_TYPE (arg1->type) == |
---|
| 503 | GTK_FUNDAMENTAL_TYPE (arg2->type), FALSE); |
---|
| 504 | |
---|
| 505 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg1->type); |
---|
| 506 | if (fundamental_type > GTK_TYPE_FUNDAMENTAL_LAST) |
---|
| 507 | { |
---|
| 508 | fundamental_type = gtk_type_get_varargs_type (fundamental_type); |
---|
| 509 | if (!fundamental_type) |
---|
| 510 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg1->type); |
---|
| 511 | } |
---|
| 512 | |
---|
| 513 | switch (fundamental_type) |
---|
| 514 | { |
---|
| 515 | case GTK_TYPE_INVALID: |
---|
| 516 | equal = TRUE; |
---|
| 517 | break; |
---|
| 518 | case GTK_TYPE_CHAR: |
---|
| 519 | equal = GTK_VALUE_CHAR (*arg1) == GTK_VALUE_CHAR (*arg2); |
---|
| 520 | break; |
---|
| 521 | case GTK_TYPE_BOOL: |
---|
| 522 | equal = (GTK_VALUE_BOOL (*arg1) != FALSE) == (GTK_VALUE_BOOL (*arg2) != FALSE); |
---|
| 523 | break; |
---|
| 524 | case GTK_TYPE_INT: |
---|
| 525 | equal = GTK_VALUE_INT (*arg1) == GTK_VALUE_INT (*arg2); |
---|
| 526 | break; |
---|
| 527 | case GTK_TYPE_UINT: |
---|
| 528 | equal = GTK_VALUE_UINT (*arg1) == GTK_VALUE_UINT (*arg2); |
---|
| 529 | break; |
---|
| 530 | case GTK_TYPE_LONG: |
---|
| 531 | equal = GTK_VALUE_LONG (*arg1) == GTK_VALUE_LONG (*arg2); |
---|
| 532 | break; |
---|
| 533 | case GTK_TYPE_ULONG: |
---|
| 534 | equal = GTK_VALUE_ULONG (*arg1) == GTK_VALUE_ULONG (*arg2); |
---|
| 535 | break; |
---|
| 536 | case GTK_TYPE_FLOAT: |
---|
| 537 | equal = GTK_VALUE_FLOAT (*arg1) == GTK_VALUE_FLOAT (*arg2); |
---|
| 538 | break; |
---|
| 539 | case GTK_TYPE_DOUBLE: |
---|
| 540 | equal = GTK_VALUE_DOUBLE (*arg1) == GTK_VALUE_DOUBLE (*arg2); |
---|
| 541 | break; |
---|
| 542 | case GTK_TYPE_STRING: |
---|
| 543 | if (!GTK_VALUE_STRING (*arg1) || |
---|
| 544 | !GTK_VALUE_STRING (*arg2)) |
---|
| 545 | equal = GTK_VALUE_STRING (*arg1) == GTK_VALUE_STRING (*arg2); |
---|
| 546 | else |
---|
| 547 | equal = g_str_equal (GTK_VALUE_STRING (*arg1), GTK_VALUE_STRING (*arg2)); |
---|
| 548 | break; |
---|
| 549 | case GTK_TYPE_ENUM: |
---|
| 550 | equal = GTK_VALUE_ENUM (*arg1) == GTK_VALUE_ENUM (*arg2); |
---|
| 551 | break; |
---|
| 552 | case GTK_TYPE_FLAGS: |
---|
| 553 | equal = GTK_VALUE_FLAGS (*arg1) == GTK_VALUE_FLAGS (*arg2); |
---|
| 554 | break; |
---|
| 555 | case GTK_TYPE_BOXED: |
---|
| 556 | equal = GTK_VALUE_BOXED (*arg1) == GTK_VALUE_BOXED (*arg2); |
---|
| 557 | break; |
---|
| 558 | case GTK_TYPE_FOREIGN: |
---|
| 559 | equal = (GTK_VALUE_FOREIGN (*arg1).data == GTK_VALUE_FOREIGN (*arg2).data && |
---|
| 560 | GTK_VALUE_FOREIGN (*arg1).notify == GTK_VALUE_FOREIGN (*arg2).notify); |
---|
| 561 | break; |
---|
| 562 | case GTK_TYPE_CALLBACK: |
---|
| 563 | equal = (GTK_VALUE_CALLBACK (*arg1).marshal == GTK_VALUE_CALLBACK (*arg2).marshal && |
---|
| 564 | GTK_VALUE_CALLBACK (*arg1).data == GTK_VALUE_CALLBACK (*arg2).data && |
---|
| 565 | GTK_VALUE_CALLBACK (*arg1).notify == GTK_VALUE_CALLBACK (*arg2).notify); |
---|
| 566 | break; |
---|
| 567 | case GTK_TYPE_ARGS: |
---|
| 568 | equal = (GTK_VALUE_ARGS (*arg1).n_args == GTK_VALUE_ARGS (*arg2).n_args && |
---|
| 569 | GTK_VALUE_ARGS (*arg1).args == GTK_VALUE_ARGS (*arg2).args); |
---|
| 570 | break; |
---|
| 571 | case GTK_TYPE_OBJECT: |
---|
| 572 | equal = GTK_VALUE_OBJECT (*arg1) == GTK_VALUE_OBJECT (*arg2); |
---|
| 573 | break; |
---|
| 574 | case GTK_TYPE_POINTER: |
---|
| 575 | equal = GTK_VALUE_POINTER (*arg1) == GTK_VALUE_POINTER (*arg2); |
---|
| 576 | break; |
---|
| 577 | case GTK_TYPE_SIGNAL: |
---|
| 578 | equal = (GTK_VALUE_SIGNAL (*arg1).f == GTK_VALUE_SIGNAL (*arg2).f && |
---|
| 579 | GTK_VALUE_SIGNAL (*arg1).d == GTK_VALUE_SIGNAL (*arg2).d); |
---|
| 580 | break; |
---|
| 581 | case GTK_TYPE_C_CALLBACK: |
---|
| 582 | equal = (GTK_VALUE_C_CALLBACK (*arg1).func == GTK_VALUE_C_CALLBACK (*arg2).func && |
---|
| 583 | GTK_VALUE_C_CALLBACK (*arg1).func_data == GTK_VALUE_C_CALLBACK (*arg2).func_data); |
---|
| 584 | break; |
---|
| 585 | default: |
---|
| 586 | g_warning ("gtk_arg_values_equal() used with unknown type `%s'", gtk_type_name (arg1->type)); |
---|
| 587 | equal = FALSE; |
---|
| 588 | break; |
---|
| 589 | } |
---|
| 590 | |
---|
| 591 | return equal; |
---|
| 592 | } |
---|
| 593 | |
---|
| 594 | void |
---|
| 595 | gtk_arg_to_valueloc (GtkArg *arg, |
---|
| 596 | gpointer value_pointer) |
---|
| 597 | { |
---|
| 598 | GtkType fundamental_type; |
---|
| 599 | |
---|
| 600 | g_return_if_fail (arg != NULL); |
---|
| 601 | g_return_if_fail (value_pointer != NULL); |
---|
| 602 | |
---|
| 603 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); |
---|
| 604 | if (fundamental_type > GTK_TYPE_FUNDAMENTAL_LAST) |
---|
| 605 | { |
---|
| 606 | fundamental_type = gtk_type_get_varargs_type (fundamental_type); |
---|
| 607 | if (!fundamental_type) |
---|
| 608 | fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); |
---|
| 609 | } |
---|
| 610 | |
---|
| 611 | switch (fundamental_type) |
---|
| 612 | { |
---|
| 613 | gchar *p_char; |
---|
| 614 | guchar *p_uchar; |
---|
| 615 | gboolean *p_boolean; |
---|
| 616 | gint *p_int; |
---|
| 617 | guint *p_uint; |
---|
| 618 | glong *p_long; |
---|
| 619 | gulong *p_ulong; |
---|
| 620 | gfloat *p_float; |
---|
| 621 | gdouble *p_double; |
---|
| 622 | gpointer *p_pointer; |
---|
| 623 | case GTK_TYPE_CHAR: |
---|
| 624 | p_char = value_pointer; |
---|
| 625 | *p_char = GTK_VALUE_CHAR (*arg); |
---|
| 626 | break; |
---|
| 627 | case GTK_TYPE_UCHAR: |
---|
| 628 | p_uchar = value_pointer; |
---|
| 629 | *p_uchar = GTK_VALUE_UCHAR (*arg); |
---|
| 630 | break; |
---|
| 631 | case GTK_TYPE_BOOL: |
---|
| 632 | p_boolean = value_pointer; |
---|
| 633 | *p_boolean = GTK_VALUE_BOOL (*arg); |
---|
| 634 | break; |
---|
| 635 | case GTK_TYPE_INT: |
---|
| 636 | case GTK_TYPE_ENUM: |
---|
| 637 | p_int = value_pointer; |
---|
| 638 | *p_int = GTK_VALUE_INT (*arg); |
---|
| 639 | break; |
---|
| 640 | case GTK_TYPE_UINT: |
---|
| 641 | case GTK_TYPE_FLAGS: |
---|
| 642 | p_uint = value_pointer; |
---|
| 643 | *p_uint = GTK_VALUE_UINT (*arg); |
---|
| 644 | break; |
---|
| 645 | case GTK_TYPE_LONG: |
---|
| 646 | p_long = value_pointer; |
---|
| 647 | *p_long = GTK_VALUE_LONG (*arg); |
---|
| 648 | break; |
---|
| 649 | case GTK_TYPE_ULONG: |
---|
| 650 | p_ulong = value_pointer; |
---|
| 651 | *p_ulong = GTK_VALUE_ULONG (*arg); |
---|
| 652 | break; |
---|
| 653 | case GTK_TYPE_FLOAT: |
---|
| 654 | p_float = value_pointer; |
---|
| 655 | *p_float = GTK_VALUE_FLOAT (*arg); |
---|
| 656 | break; |
---|
| 657 | case GTK_TYPE_DOUBLE: |
---|
| 658 | p_double = value_pointer; |
---|
| 659 | *p_double = GTK_VALUE_DOUBLE (*arg); |
---|
| 660 | break; |
---|
| 661 | case GTK_TYPE_STRING: |
---|
| 662 | case GTK_TYPE_POINTER: |
---|
| 663 | case GTK_TYPE_BOXED: |
---|
| 664 | case GTK_TYPE_OBJECT: |
---|
| 665 | p_pointer = value_pointer; |
---|
| 666 | *p_pointer = GTK_VALUE_POINTER (*arg); |
---|
| 667 | break; |
---|
| 668 | case GTK_TYPE_SIGNAL: |
---|
| 669 | case GTK_TYPE_ARGS: |
---|
| 670 | case GTK_TYPE_FOREIGN: |
---|
| 671 | case GTK_TYPE_CALLBACK: |
---|
| 672 | case GTK_TYPE_C_CALLBACK: |
---|
| 673 | case GTK_TYPE_NONE: |
---|
| 674 | case GTK_TYPE_INVALID: |
---|
| 675 | /* it doesn't make much sense to retrive these values, |
---|
| 676 | * they either are always read-only args, or require |
---|
| 677 | * multiple pointers. |
---|
| 678 | */ |
---|
| 679 | g_warning ("gtk_arg_fill_retloc(): unsupported argument type `%s'", |
---|
| 680 | gtk_type_name (arg->type)); |
---|
| 681 | break; |
---|
| 682 | } |
---|
| 683 | } |
---|