diff --git a/docs/refcounting.txt b/docs/refcounting.txt deleted file mode 100644 index 806940096f..0000000000 --- a/docs/refcounting.txt +++ /dev/null @@ -1,315 +0,0 @@ -The Reference Counting Scheme of GDK an GTK+ -============================================ - -Each data structure that provides reference counting offers a bunch of -functions that follow these conventions: - - *_new: Create a new structure with a reference count of 1. - *_ref: Increase ref count by one. - *_unref: Decrease ref count by one. If the count drops to zero, - run appropriate finalization code and free the memory. - For data structures with a _destroy function, it will be - invoked at this point, if the data structure is not - already in a destroyed state. - -GtkObjects also provide the following functions: - - *_destroy: Render an object `unusable', but as long as there are - references to it, its allocated memory will not be freed. - *_sink: Clear a GtkObjects `floating' state and decrement the - reference count by 1. - -GdkWindow ---------- - -A GdkWindow has to be explicitly destroyed with gdk_window_destroy. -This will send out a request to destroy this window and all its -children, and will decrement the ref_count of the GdkWindow by one. -Thus, it releases the initial reference created by gdk_window_new. - -All GdkWindows are kept in a hash table to translate from their XId to -the actual structure and the pointer in the hash table is reflected in -the reference count. When a DestroyNotify event is received for a -particular GdkWindow, it is removed from the hash table and the -ref_count is updated accordingly. - -You can call gdk_window_destroy more than once on a particular -GdkWindow, it will only be destroyed when it hasn't been yet. The -ref_count is *always* decremented, tho. Be careful. - -Remark: When writing NO_WINDOW widgets, care should be taken about - proper referencing/unreferencing of the parent's GdkWindow - that is used by the widget. - -GdkPixmap ---------- - -There is no gdk_pixmap_destroy function. The Pixmap is destroyed when -the last reference to it vanishes. - -GdkPixmaps are kept in the same hash table as GdkWindows but the -pointer in the hash table is *not* reflected in the ref_count. - -This works only when Pixmaps never get XEvents. I'm not sure if this -is the case. - -GdkBitmap ---------- - -A GdkBitmap is only another name for a special use of GdkPixmap. - -GdkVisual ---------- - -There are no *_new or *_destroy functions and the *_ref and *_unref -functions are no-ops. GdkVisuals are static structures and thus do not -need reference counting. The ref counting functions are only there -for extra defensive programming. - -GdkColormap ------------ - -Nothing special. There is no gdk_colormap_destroy function. - -GdkFont / GdkFontSet --------------------- - -GdkFont and GdkFontSet are equivalent as far as ref counting is -concerned. Use gdk_font_ref and gdk_font_unref for both. - -There is no gdk_font_free or gdk_fontset_free function. - -GtkAcceleratorTable -------------------- - -There is no gtk_accelerator_table_destroy function. - -GtkTooltips ------------ - -There is no gtk_tooltips_destroy function. - -GtkStyle --------- - -There is no gtk_style_destroy function. - -GtkObject ---------- - -GtkObjects follow the usual ref_counting strategy, but with a twist. - -They are created with a ref_count of 1. GtkObjects are able to -run finalization code when the ref_count drops to zero but you cannot -register arbitrary signal handlers to run at finalization time. - -There is also the old gtk_object_destroy function and the "destroy" -signal but they are somewhat independent from finalization. Just as -stated at the top of this text, gtk_object_destroy merely renders an -object unusable. When the object is a container widget for example, -it unrealizes that widget, removes all children and disconnects all -signal handlers. The finalization code is different, it would for -example free associated memory for text strings and release the -attached style. - -This is the biggest change. Every widget must be revised to have a -proper "destroy" function, etc. Such a destroy function will only -be called once and is expected to leave the widget in a minimal but -consistent state. Widgets that have been "destroyed" but not yet -finalized are flagged with GTK_DESTROY. The "finalization" function -is new and should perform last-minute cleanup actions, in contrast -to the destroy function it will not be emitted as signal though. -It can assume that the "destroy" function has been called as the -last function on this widget. - -Essentially, the old "destroy" function has been split into a -"finalize" plus a "destroy" function. - -It is not possible to create GtkObjects with a ref_count of 0 -because the first ref/unref pair will destroy it unintentionally. - -To be mostly backward compatible with existing practice, a GtkObject -leads a more complicated life than the other reference counted structures. - -When a GtkObject is created, it starts out in a special state called -"floating" (this is the twist). This means that it is alive and has a -reference to it, but the `owner' of this reference is not known. -There are certain `potential owners' that will adopt a floating -GtkObject. For GtkWidgets the most common adopters are the parent -widget. - -When you want to adopt a possibly floating GtkObject, you call -gtk_object_sink on it. This clears the floating state of the -GtkObject and decrements the ref_count by one, if it has been floating -previously. Once the floating state has been cleared, it will never -be set again. - -All widgets that are part of the display are linked into a -parent/child tree. The link from the parent to a child is reflected -in the ref_count of the child, but the link from the child to the -parent is not reflected in the ref_count of the parent. - -Like a GtkObject, a GtkWidget is created with a ref_count of 1 and -initially flagged as `floating'. As soon as it is added as a child to -a parent, the `floating' flag is cleared and never will be set again. -Not even when it is later unparented. The act of clearing the -`floating' flag also decrements the ref_count of the widget by one. - -When the widget is unparented, its underlying GdkWindow is destroyed -(when it has one), it loses its reference from the parent and -naturally the ref_count is decremented. - -It is considered a bug if a widget still has a GdkWindow when it is -being freed. - -Toplevel widgets, which don't have a `natural' parent, are adopted by -special registering functions. Because the of the reference count that -is set by the registering functions, toplevel widgets will have to be -explicitly destroyed, with the exception of GtkMenus. GtkMenus are a -special case of toplevel widgets in that they will be `attached' to and -`detached' from other widgets. The act of attaching a GtkMenu to a -widget will be reflected in its reference count. The act of detaching -a GtkMenu will revert that. Therefore GtkMenus naturally get destroyed -and finalized once they are detached from their reference holder. - -So, the typical career of a GtkWindow a GtMenu attached to a -GtkOptionMenu looks like this: - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - /* window is created with ref_count == 1. It is not flagged as - * `floating' because it has already been registered as a toplevel - * widget. - */ - - option_menu = gtk_option_menu_new (); - /* option_menu->ref_count == 1 and it is flagged as `floating'. - */ - - gtk_container_add (window, option_menu); - /* option_menu->ref_count still == 1, but it is no longer `floating'. - */ - - menu = gtk_menu_new (); - /* menu->ref_count == 1 and it is flagged as `floating'. - */ - - menu_item = gtk_menu_item_new_with_label ("Choose Me"); - /* menu_item->ref_count == 1 and it is flagged as `floating'. - */ - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - /* menu_item->ref_count still == 1, but it is no longer `floating'. - */ - - gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); - /* menu->ref_count still == 1, but it is no longer `floating'. - */ - - gtk_widget_show (menu_item); - gtk_widget_show (option_menu); - gtk_widget_show (window); - - /* The widgets get their GdkWindows, nothing significant happens to - * the ref_counts. - */ - -Then, when the user wants to get rid of the window: - - gtk_widget_destroy (window); - - /* The GdkWindow of `window' and all its child GdkWindows are - * destroyed. - * - * window is unregistered from the toplevel list and its ref_count - * drops to zero. The destroy code of `window' destroys `option_menu'. - * - * The destroy code of `option_menu' causes the `menu' to be detached - * from it and its reference count drops to zero. - * - * The destroy code of `menu' destroys `menu_item'. - * - * The destruction of `menu_item' removes it from its parent, the - * menu_item->ref_count drops to zero and `menu_item' is finalized (freed). - * - * Now `menu', `option_menu' and `window' will be destroyed and finalized, - * in this order, since the reference count of each is zero. - */ - - -Taking care of proper referencing ---------------------------------- - -There are some cases where referencing of widgets from outside the toolkit -(on the application side) is needed. -Once the application performs an operation on a widget that will cause -its reference count to drop, if it wants to take further actions on the -widget, it needs to hold a reference to it. - -Example code sequences that require reference wraps: - - /* gtk_container_remove() will unparent the child and therefore - * cause its reference count to be decremented by one. - */ - g_object_ref (widget); - gtk_container_remove (container, widget); - /* without the reference count, the widget would have been destroyed here. - */ - gtk_container_add (container, widget); - g_object_unref (widget); - - - /* all items in item_list need to be referenced - * before gtk_list_remove_items() is invoked. - * this is somewhat tricky as gtk_list_append_items/gtk_list_prepend_items/ - * gtk_list_insert_items will take over the lists nodes. - * we therefore have an extra GSList `*slist' for later unreferencing. - */ - slist = NULL; - for (list = item_list; list; list = list->next) - { - g_object_ref (GTK_WIDGET (list->data)); - slist = g_slist_prepend (slist, list->data); - } - gtk_list_remove_items (list, item_list); - gtk_list_append_items (other_list, item_list); - /* gtk_list_prepend_items (other_list, item_list); */ - /* gtk_list_insert_items (other_list, item_list, 3); */ - while (slist) - { - GSList *tmp; - - tmp = slist; - slist = slist->next; - g_object_unref (GTK_WIDGET (tmp->data)); - g_slist_free_1 (tmp); - } - - /* Alternatively to the removal above you could just use - * gtk_list_remove_items_no_unref() which will add the additional - * reference count to the widget. - */ - gtk_list_remove_items_no_unref (list, item_list); - gtk_list_prepend_items (other_list, item_list); - - -Now a (hopefully) complete list of functions that require -wrappers similar to the examples above: - -void gtk_container_remove (GtkContainer *container, - GtkWidget *widget); -void gtk_list_remove_items (GtkList *list, - GList *items); -void gtk_tree_remove_items (GtkTree *tree, - GList *items); -void gtk_tree_item_remove_subtree (GtkTreeItem *tree_item); -void gtk_menu_item_remove_submenu (GtkMenuItem *menu_item); -void gtk_option_menu_remove_menu (GtkOptionMenu *option_menu); - - - -Initial proposal: - - Marius Vollmer - -Some modifications/additions, "Taking care of proper referencing" and -reference counting solution for GtkMenus: - - Tim Janik