gobject.c revision 6bbcc10e8d7951aebfd8a4d5635906b101cd3c12
1/* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General 15 * Public 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#include <string.h> 21 22#include "gobject.h" 23#include "gvaluecollector.h" 24 25 26#define DEBUG_OBJECTS 27 28 29/* --- macros --- */ 30#define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_param_id))) 31 32 33/* --- prototypes --- */ 34static void g_object_base_class_init (GObjectClass *class); 35static void g_object_base_class_finalize (GObjectClass *class); 36static void g_object_do_class_init (GObjectClass *class); 37static void g_object_do_init (GObject *object); 38static void g_object_do_queue_param_changed (GObject *object, 39 GParamSpec *pspec); 40static void g_object_do_dispatch_param_changed (GObject *object, 41 GParamSpec *pspec); 42static void g_object_last_unref (GObject *object); 43static void g_object_do_shutdown (GObject *object); 44static void g_object_do_finalize (GObject *object); 45static void g_value_object_init (GValue *value); 46static void g_value_object_free_value (GValue *value); 47static void g_value_object_copy_value (const GValue *src_value, 48 GValue *dest_value); 49static gchar* g_value_object_collect_value (GValue *value, 50 guint nth_value, 51 GType *collect_type, 52 GTypeCValue *collect_value); 53static gchar* g_value_object_lcopy_value (const GValue *value, 54 guint nth_value, 55 GType *collect_type, 56 GTypeCValue *collect_value); 57 58 59/* --- variables --- */ 60static GQuark quark_param_id = 0; 61static GQuark quark_param_changed_queue = 0; 62static GHashTable *param_spec_hash_table = NULL; 63 64 65/* --- functions --- */ 66#ifdef DEBUG_OBJECTS 67static guint debug_objects_count = 0; 68static GHashTable *debug_objects_ht = NULL; 69static void 70debug_objects_foreach (gpointer key, 71 gpointer value, 72 gpointer user_data) 73{ 74 GObject *object = value; 75 76 g_message ("[%p] stale %s\tref_count=%u", 77 object, 78 G_OBJECT_TYPE_NAME (object), 79 object->ref_count); 80} 81static void 82debug_objects_atexit (void) 83{ 84 if (debug_objects_ht) 85 { 86 g_message ("stale GObjects: %u", debug_objects_count); 87 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL); 88 } 89} 90#endif DEBUG_OBJECTS 91 92void 93g_object_type_init (void) /* sync with gtype.c */ 94{ 95 static gboolean initialized = FALSE; 96 static const GTypeFundamentalInfo finfo = { 97 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE, 98 }; 99 static GTypeInfo info = { 100 sizeof (GObjectClass), 101 (GBaseInitFunc) g_object_base_class_init, 102 (GBaseFinalizeFunc) g_object_base_class_finalize, 103 (GClassInitFunc) g_object_do_class_init, 104 NULL /* class_destroy */, 105 NULL /* class_data */, 106 sizeof (GObject), 107 0 /* n_preallocs */, 108 (GInstanceInitFunc) g_object_do_init, 109 NULL, /* value_table */ 110 }; 111 static const GTypeValueTable value_table = { 112 g_value_object_init, /* value_init */ 113 g_value_object_free_value, /* value_free */ 114 g_value_object_copy_value, /* value_copy */ 115 G_VALUE_COLLECT_POINTER, /* collect_type */ 116 g_value_object_collect_value, /* collect_value */ 117 G_VALUE_COLLECT_POINTER, /* lcopy_type */ 118 g_value_object_lcopy_value, /* lcopy_value */ 119 }; 120 GType type; 121 122 g_return_if_fail (initialized == FALSE); 123 initialized = TRUE; 124 125 /* G_TYPE_OBJECT 126 */ 127 info.value_table = &value_table; 128 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo); 129 g_assert (type == G_TYPE_OBJECT); 130 131#ifdef DEBUG_OBJECTS 132 g_atexit (debug_objects_atexit); 133#endif DEBUG_OBJECTS 134} 135 136static void 137g_object_base_class_init (GObjectClass *class) 138{ 139 /* reset instance specific fields and methods that don't get inherited */ 140 class->n_param_specs = 0; 141 class->param_specs = NULL; 142 class->get_param = NULL; 143 class->set_param = NULL; 144} 145 146static void 147g_object_base_class_finalize (GObjectClass *class) 148{ 149 guint i; 150 151 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class)); 152 153 for (i = 0; i < class->n_param_specs; i++) 154 { 155 GParamSpec *pspec = class->param_specs[i]; 156 157 g_param_spec_hash_table_remove (param_spec_hash_table, pspec); 158 g_param_spec_set_qdata (pspec, quark_param_id, NULL); 159 g_param_spec_unref (pspec); 160 } 161 class->n_param_specs = 0; 162 g_free (class->param_specs); 163 class->param_specs = NULL; 164} 165 166static void 167g_object_do_class_init (GObjectClass *class) 168{ 169 quark_param_id = g_quark_from_static_string ("glib-object-param-id"); 170 quark_param_changed_queue = g_quark_from_static_string ("glib-object-param-changed-queue"); 171 param_spec_hash_table = g_param_spec_hash_table_new (); 172 173 class->queue_param_changed = g_object_do_queue_param_changed; 174 class->dispatch_param_changed = g_object_do_dispatch_param_changed; 175 class->shutdown = g_object_do_shutdown; 176 class->finalize = g_object_do_finalize; 177} 178 179void 180g_object_class_install_param (GObjectClass *class, 181 guint param_id, 182 GParamSpec *pspec /* 1 ref_count taken over */) 183{ 184 guint i; 185 186 g_return_if_fail (G_IS_OBJECT_CLASS (class)); 187 g_return_if_fail (G_IS_PARAM_SPEC (pspec)); 188 if (pspec->flags & G_PARAM_WRITABLE) 189 g_return_if_fail (class->set_param != NULL); 190 if (pspec->flags & G_PARAM_READABLE) 191 g_return_if_fail (class->get_param != NULL); 192 g_return_if_fail (param_id > 0); 193 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */ 194 195 /* expensive paranoia checks ;( */ 196 for (i = 0; i < class->n_param_specs; i++) 197 if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id) 198 { 199 g_warning (G_STRLOC ": class `%s' already contains a parameter `%s' with id %u, " 200 "cannot install parameter `%s'", 201 G_OBJECT_CLASS_NAME (class), 202 class->param_specs[i]->name, 203 param_id, 204 pspec->name); 205 return; 206 } 207 if (g_object_class_find_param_spec (class, pspec->name)) 208 { 209 g_warning (G_STRLOC ": class `%s' already contains a parameter named `%s'", 210 G_OBJECT_CLASS_NAME (class), 211 pspec->name); 212 return; 213 } 214 215 g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id)); 216 g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class)); 217 i = class->n_param_specs++; 218 class->param_specs = g_renew (GParamSpec*, class->param_specs, class->n_param_specs); 219 class->param_specs[i] = pspec; 220} 221 222GParamSpec* 223g_object_class_find_param_spec (GObjectClass *class, 224 const gchar *param_name) 225{ 226 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL); 227 g_return_val_if_fail (param_name != NULL, NULL); 228 229 return g_param_spec_hash_table_lookup (param_spec_hash_table, 230 param_name, 231 G_OBJECT_CLASS_TYPE (class), 232 TRUE, NULL); 233} 234 235static void 236g_object_do_init (GObject *object) 237{ 238 object->ref_count = 1; 239 object->qdata = NULL; 240 241#ifdef DEBUG_OBJECTS 242 if (!debug_objects_ht) 243 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL); 244 debug_objects_count++; 245 g_hash_table_insert (debug_objects_ht, object, object); 246#endif DEBUG_OBJECTS 247} 248 249static void 250g_object_last_unref (GObject *object) 251{ 252 g_return_if_fail (object->ref_count > 0); 253 254 if (object->ref_count == 1) /* may have been re-referenced meanwhile */ 255 G_OBJECT_GET_CLASS (object)->shutdown (object); 256 257 object->ref_count -= 1; 258 259 if (object->ref_count == 0) /* may have been re-referenced meanwhile */ 260 G_OBJECT_GET_CLASS (object)->finalize (object); 261} 262 263static void 264g_object_do_shutdown (GObject *object) 265{ 266 /* this function needs to be always present for unconditional 267 * chaining, we also might add some code here later. 268 * beware though, subclasses may invoke shutdown() arbitrarily. 269 */ 270} 271 272static void 273g_object_do_finalize (GObject *object) 274{ 275 g_datalist_clear (&object->qdata); 276 277#ifdef DEBUG_OBJECTS 278 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object); 279 280 g_hash_table_remove (debug_objects_ht, object); 281 debug_objects_count--; 282#endif DEBUG_OBJECTS 283 284 g_type_free_instance ((GTypeInstance*) object); 285} 286 287gpointer 288g_object_new (GType object_type, 289 const gchar *first_param_name, 290 ...) 291{ 292 GObject *object; 293 va_list var_args; 294 295 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); 296 297 va_start (var_args, first_param_name); 298 object = g_object_new_valist (object_type, first_param_name, var_args); 299 va_end (var_args); 300 301 return object; 302} 303 304gpointer 305g_object_new_valist (GType object_type, 306 const gchar *first_param_name, 307 va_list var_args) 308{ 309 GObject *object; 310 311 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); 312 313 object = (GObject*) g_type_create_instance (object_type); 314 if (first_param_name) 315 g_object_set_valist (object, first_param_name, var_args); 316 317 return object; 318} 319 320static void 321g_object_do_dispatch_param_changed (GObject *object, 322 GParamSpec *pspec) 323{ 324 g_message ("NOTIFICATION: parameter `%s' changed on object `%s'", 325 pspec->name, 326 G_OBJECT_TYPE_NAME (object)); 327} 328 329static gboolean 330notify_param_changed_handler (gpointer data) 331{ 332 GObject *object; 333 GObjectClass *class; 334 GSList *slist; 335 336 /* FIXME: need GDK_THREADS lock */ 337 338 object = G_OBJECT (data); 339 class = G_OBJECT_GET_CLASS (object); 340 slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue); 341 342 /* a reference count is still being held */ 343 344 for (; slist; slist = slist->next) 345 if (slist->data) 346 { 347 GParamSpec *pspec = slist->data; 348 349 slist->data = NULL; 350 class->dispatch_param_changed (object, pspec); 351 } 352 353 g_datalist_id_set_data (&object->qdata, quark_param_changed_queue, NULL); 354 355 return FALSE; 356} 357 358static void 359g_object_do_queue_param_changed (GObject *object, 360 GParamSpec *pspec) 361{ 362 GSList *slist, *last = NULL; 363 364 /* if this is a recursive call on this object (i.e. pspecs are queued 365 * for notification, while param_changed notification is currently in 366 * progress), we simply add them to the queue that is currently being 367 * dispatched. otherwise, we later dispatch parameter changed notification 368 * asyncronously from an idle handler untill the queue is completely empty. 369 */ 370 371 slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue); 372 for (; slist; last = slist, slist = last->next) 373 if (slist->data == pspec) 374 return; 375 376 if (!last) 377 { 378 g_object_ref (object); 379 g_idle_add_full (G_NOTIFY_PRIORITY, 380 notify_param_changed_handler, 381 object, 382 (GDestroyNotify) g_object_unref); 383 g_object_set_qdata_full (object, 384 quark_param_changed_queue, 385 g_slist_prepend (NULL, pspec), 386 (GDestroyNotify) g_slist_free); 387 } 388 else 389 last->next = g_slist_prepend (NULL, pspec); 390} 391 392static inline void 393object_get_param (GObject *object, 394 GValue *value, 395 GParamSpec *pspec, 396 const gchar *trailer) 397{ 398 GObjectClass *class; 399 400 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */ 401 402 class = g_type_class_peek (pspec->owner_type); 403 404 class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer); 405} 406 407static inline void 408object_set_param (GObject *object, 409 GValue *value, 410 GParamSpec *pspec, 411 const gchar *trailer) 412{ 413 GObjectClass *class; 414 415 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */ 416 417 class = g_type_class_peek (pspec->owner_type); 418 419 class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer); 420 421 class->queue_param_changed (object, pspec); 422} 423 424void 425g_object_set_valist (GObject *object, 426 const gchar *first_param_name, 427 va_list var_args) 428{ 429 const gchar *name; 430 431 g_return_if_fail (G_IS_OBJECT (object)); 432 433 g_object_ref (object); 434 435 name = first_param_name; 436 437 while (name) 438 { 439 const gchar *trailer = NULL; 440 GValue value = { 0, }; 441 GParamSpec *pspec; 442 gchar *error = NULL; 443 444 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, 445 name, 446 G_OBJECT_TYPE (object), 447 TRUE, 448 &trailer); 449 if (!pspec) 450 { 451 g_warning ("%s: object class `%s' has no parameter named `%s'", 452 G_STRLOC, 453 G_OBJECT_TYPE_NAME (object), 454 name); 455 break; 456 } 457 if (!(pspec->flags & G_PARAM_WRITABLE)) 458 { 459 g_warning ("%s: parameter `%s' of object class `%s' is not writable", 460 G_STRLOC, 461 pspec->name, 462 G_OBJECT_TYPE_NAME (object)); 463 break; 464 } 465 466 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); 467 468 G_VALUE_COLLECT (&value, var_args, &error); 469 if (error) 470 { 471 g_warning ("%s: %s", G_STRLOC, error); 472 g_free (error); 473 474 /* we purposely leak the value here, it might not be 475 * in a sane state if an error condition occoured 476 */ 477 break; 478 } 479 480 object_set_param (object, &value, pspec, trailer); 481 482 g_value_unset (&value); 483 484 name = va_arg (var_args, gchar*); 485 } 486 487 g_object_unref (object); 488} 489 490void 491g_object_get_valist (GObject *object, 492 const gchar *first_param_name, 493 va_list var_args) 494{ 495 const gchar *name; 496 497 g_return_if_fail (G_IS_OBJECT (object)); 498 499 g_object_ref (object); 500 501 name = first_param_name; 502 503 while (name) 504 { 505 const gchar *trailer = NULL; 506 GValue value = { 0, }; 507 GParamSpec *pspec; 508 gchar *error = NULL; 509 510 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, 511 name, 512 G_OBJECT_TYPE (object), 513 TRUE, 514 &trailer); 515 if (!pspec) 516 { 517 g_warning ("%s: object class `%s' has no parameter named `%s'", 518 G_STRLOC, 519 G_OBJECT_TYPE_NAME (object), 520 name); 521 break; 522 } 523 if (!(pspec->flags & G_PARAM_READABLE)) 524 { 525 g_warning ("%s: parameter `%s' of object class `%s' is not readable", 526 G_STRLOC, 527 pspec->name, 528 G_OBJECT_TYPE_NAME (object)); 529 break; 530 } 531 532 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); 533 534 object_get_param (object, &value, pspec, trailer); 535 536 G_VALUE_LCOPY (&value, var_args, &error); 537 if (error) 538 { 539 g_warning ("%s: %s", G_STRLOC, error); 540 g_free (error); 541 542 /* we purposely leak the value here, it might not be 543 * in a sane state if an error condition occoured 544 */ 545 break; 546 } 547 548 g_value_unset (&value); 549 550 name = va_arg (var_args, gchar*); 551 } 552 553 g_object_unref (object); 554} 555 556void 557g_object_set (GObject *object, 558 const gchar *first_param_name, 559 ...) 560{ 561 va_list var_args; 562 563 g_return_if_fail (G_IS_OBJECT (object)); 564 565 va_start (var_args, first_param_name); 566 g_object_set_valist (object, first_param_name, var_args); 567 va_end (var_args); 568} 569 570void 571g_object_get (GObject *object, 572 const gchar *first_param_name, 573 ...) 574{ 575 va_list var_args; 576 577 g_return_if_fail (G_IS_OBJECT (object)); 578 579 va_start (var_args, first_param_name); 580 g_object_get_valist (object, first_param_name, var_args); 581 va_end (var_args); 582} 583 584void 585g_object_set_param (GObject *object, 586 const gchar *param_name, 587 const GValue *value) 588{ 589 GParamSpec *pspec; 590 const gchar *trailer; 591 592 g_return_if_fail (G_IS_OBJECT (object)); 593 g_return_if_fail (param_name != NULL); 594 g_return_if_fail (G_IS_VALUE (value)); 595 596 g_object_ref (object); 597 598 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, 599 param_name, 600 G_OBJECT_TYPE (object), 601 TRUE, 602 &trailer); 603 if (!pspec) 604 g_warning ("%s: object class `%s' has no parameter named `%s'", 605 G_STRLOC, 606 G_OBJECT_TYPE_NAME (object), 607 param_name); 608 else 609 { 610 GValue tmp_value = { 0, }; 611 612 /* provide a copy to work from and convert if necessary */ 613 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); 614 615 if (!g_value_convert (value, &tmp_value) || 616 g_param_value_validate (pspec, &tmp_value)) 617 g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'", 618 G_STRLOC, 619 G_VALUE_TYPE_NAME (value), 620 pspec->name, 621 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); 622 else 623 object_set_param (object, &tmp_value, pspec, trailer); 624 625 g_value_unset (&tmp_value); 626 } 627 628 g_object_unref (object); 629} 630 631void 632g_object_get_param (GObject *object, 633 const gchar *param_name, 634 GValue *value) 635{ 636 GParamSpec *pspec; 637 const gchar *trailer; 638 639 g_return_if_fail (G_IS_OBJECT (object)); 640 g_return_if_fail (param_name != NULL); 641 g_return_if_fail (G_IS_VALUE (value)); 642 643 g_object_ref (object); 644 645 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, 646 param_name, 647 G_OBJECT_TYPE (object), 648 TRUE, 649 &trailer); 650 if (!pspec) 651 g_warning ("%s: object class `%s' has no parameter named `%s'", 652 G_STRLOC, 653 G_OBJECT_TYPE_NAME (object), 654 param_name); 655 else 656 { 657 GValue tmp_value = { 0, }; 658 659 /* provide a copy to work from and later convert if necessary, so 660 * _get_param() implementations need *not* care about freeing values 661 * that might be already set in the parameter to get. 662 * (though, at this point, GValue should exclusively be modified 663 * through the accessor functions anyways) 664 */ 665 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); 666 667 if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) 668 g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'", 669 G_STRLOC, 670 pspec->name, 671 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), 672 G_VALUE_TYPE_NAME (value)); 673 else 674 { 675 object_get_param (object, &tmp_value, pspec, trailer); 676 g_value_convert (&tmp_value, value); 677 /* g_value_validate (value, pspec); */ 678 } 679 680 g_value_unset (&tmp_value); 681 } 682 683 g_object_unref (object); 684} 685 686void 687g_object_queue_param_changed (GObject *object, 688 const gchar *param_name) 689{ 690 GParamSpec *pspec; 691 692 g_return_if_fail (G_IS_OBJECT (object)); 693 g_return_if_fail (param_name != NULL); 694 695 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, 696 param_name, 697 G_OBJECT_TYPE (object), 698 TRUE, NULL); 699 if (!pspec) 700 g_warning ("%s: object class `%s' has no parameter named `%s'", 701 G_STRLOC, 702 G_OBJECT_TYPE_NAME (object), 703 param_name); 704 else 705 G_OBJECT_GET_CLASS (object)->queue_param_changed (object, pspec); 706} 707 708GObject* 709g_object_ref (GObject *object) 710{ 711 g_return_val_if_fail (G_IS_OBJECT (object), NULL); 712 g_return_val_if_fail (object->ref_count > 0, NULL); 713 714 object->ref_count += 1; 715 716 return object; 717} 718 719void 720g_object_unref (GObject *object) 721{ 722 g_return_if_fail (G_IS_OBJECT (object)); 723 g_return_if_fail (object->ref_count > 0); 724 725 if (object->ref_count > 1) 726 object->ref_count -= 1; 727 else 728 g_object_last_unref (object); 729} 730 731gpointer 732g_object_get_qdata (GObject *object, 733 GQuark quark) 734{ 735 g_return_val_if_fail (G_IS_OBJECT (object), NULL); 736 737 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL; 738} 739 740void 741g_object_set_qdata (GObject *object, 742 GQuark quark, 743 gpointer data) 744{ 745 g_return_if_fail (G_IS_OBJECT (object)); 746 g_return_if_fail (quark > 0); 747 748 g_datalist_id_set_data (&object->qdata, quark, data); 749} 750 751void 752g_object_set_qdata_full (GObject *object, 753 GQuark quark, 754 gpointer data, 755 GDestroyNotify destroy) 756{ 757 g_return_if_fail (G_IS_OBJECT (object)); 758 g_return_if_fail (quark > 0); 759 760 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL); 761} 762 763gpointer 764g_object_steal_qdata (GObject *object, 765 GQuark quark) 766{ 767 g_return_val_if_fail (G_IS_OBJECT (object), NULL); 768 g_return_val_if_fail (quark > 0, NULL); 769 770 return g_datalist_id_remove_no_notify (&object->qdata, quark); 771} 772 773static void 774g_value_object_init (GValue *value) 775{ 776 value->data[0].v_pointer = NULL; 777} 778 779static void 780g_value_object_free_value (GValue *value) 781{ 782 if (value->data[0].v_pointer) 783 g_object_unref (value->data[0].v_pointer); 784} 785 786static void 787g_value_object_copy_value (const GValue *src_value, 788 GValue *dest_value) 789{ 790 if (src_value->data[0].v_pointer) 791 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer); 792 else 793 dest_value->data[0].v_pointer = NULL; 794} 795 796static gchar* 797g_value_object_collect_value (GValue *value, 798 guint nth_value, 799 GType *collect_type, 800 GTypeCValue *collect_value) 801{ 802 if (collect_value->v_pointer) 803 { 804 GObject *object = collect_value->v_pointer; 805 806 if (object->g_type_instance.g_class == NULL) 807 return g_strconcat ("invalid unclassed object pointer for value type `", 808 G_VALUE_TYPE_NAME (value), 809 "'", 810 NULL); 811 else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value))) 812 return g_strconcat ("invalid object type `", 813 G_OBJECT_TYPE_NAME (object), 814 "' for value type `", 815 G_VALUE_TYPE_NAME (value), 816 "'", 817 NULL); 818 value->data[0].v_pointer = g_object_ref (object); 819 } 820 else 821 value->data[0].v_pointer = NULL; 822 823 *collect_type = 0; 824 return NULL; 825} 826 827static gchar* 828g_value_object_lcopy_value (const GValue *value, 829 guint nth_value, 830 GType *collect_type, 831 GTypeCValue *collect_value) 832{ 833 GObject **object_p = collect_value->v_pointer; 834 835 if (!object_p) 836 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); 837 838 *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; 839 840 *collect_type = 0; 841 return NULL; 842} 843 844void 845g_value_set_object (GValue *value, 846 GObject *v_object) 847{ 848 g_return_if_fail (G_IS_VALUE_OBJECT (value)); 849 if (v_object) 850 g_return_if_fail (G_IS_OBJECT (v_object)); 851 852 if (value->data[0].v_pointer) 853 g_object_unref (value->data[0].v_pointer); 854 value->data[0].v_pointer = v_object; 855 if (value->data[0].v_pointer) 856 g_object_ref (value->data[0].v_pointer); 857} 858 859GObject* 860g_value_get_object (GValue *value) 861{ 862 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); 863 864 return value->data[0].v_pointer; 865} 866 867GObject* 868g_value_dup_object (GValue *value) 869{ 870 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); 871 872 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; 873} 874