2005-01-03 [colin] 0.9.13cvs25.4
authorColin Leroy <colin@colino.net>
Mon, 3 Jan 2005 18:03:20 +0000 (18:03 +0000)
committerColin Leroy <colin@colino.net>
Mon, 3 Jan 2005 18:03:20 +0000 (18:03 +0000)
* src/common/utils.c
* src/common/utils.h
* src/gtk/prefswindow.c
Move auto pointer stuff to utils.c
Patch by Alfons again :)

ChangeLog-gtk2.claws
PATCHSETS
configure.ac
src/common/utils.c
src/common/utils.h
src/gtk/prefswindow.c

index 7f7bddffff44426db61d9434d75afe0c7364d4a9..d3f6c02e84f97237cf22b35faf6e7ddeb86b17f1 100644 (file)
@@ -1,3 +1,11 @@
+2005-01-03 [colin]     0.9.13cvs25.4
+
+       * src/common/utils.c
+       * src/common/utils.h
+       * src/gtk/prefswindow.c
+               Move auto pointer stuff to utils.c
+               Patch by Alfons again :)
+
 2005-01-03 [colin]     0.9.13cvs25.3
 
        * src/compose.c
index 7fe175a45a22989bfac345ec229738d0d2882a78..8de32c718abfd8a65cfcce3a0bee0066a5e3d899 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.56.2.30 -r 1.56.2.31 src/pop.c; cvs diff -u -r 1.17.2.12 -r 1.17.2.13 src/pop.h; ) > 0.9.13cvs25.1.patchset
 ( cvs diff -u -r 1.115.2.25 -r 1.115.2.26 src/main.c; cvs diff -u -r 1.100.2.9 -r 1.100.2.10 AUTHORS; ) > 0.9.13cvs25.2.patchset
 ( cvs diff -u -r 1.382.2.81 -r 1.382.2.82 src/compose.c; cvs diff -u -r 1.10.2.8 -r 1.10.2.9 src/prefs_gtk.c; cvs diff -u -r 1.12.2.4 -r 1.12.2.5 src/prefs_template.c; cvs diff -u -r 1.96.2.37 -r 1.96.2.38 src/textview.c; ) > 0.9.13cvs25.3.patchset
+( cvs diff -u -r 1.36.2.18 -r 1.36.2.19 src/common/utils.c; cvs diff -u -r 1.20.2.12 -r 1.20.2.13 src/common/utils.h; cvs diff -u -r 1.12.2.13 -r 1.12.2.14 src/gtk/prefswindow.c; ) > 0.9.13cvs25.4.patchset
index b5c2e1ece6d7a25ad737bc7ce2b8e26dcf8bdc4b..766f042c80e7a0e5a35937698ac4a8e3a9c08ac0 100644 (file)
@@ -13,7 +13,7 @@ INTERFACE_AGE=0
 BINARY_AGE=0
 EXTRA_VERSION=25
 EXTRA_RELEASE=
-EXTRA_GTK2_VERSION=.3
+EXTRA_GTK2_VERSION=.4
 
 if test \( $EXTRA_VERSION -eq 0 \) -o \( "x$EXTRA_RELEASE" != "x" \); then
     VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}${EXTRA_RELEASE}${EXTRA_GTK2_VERSION}
index 1bb4b7c01ed5a629c9f2346bc7bcc3626023ca03..b0f9e5516ef6c8857ccc2e7160e05b9e7b67dd0e 100644 (file)
@@ -3731,3 +3731,168 @@ void get_hex_str(gchar *out, guchar ch)
        INT_TO_HEX(hex, ch & 0x0f);
        *out++ = hex;
 }
+
+#undef REF_DEBUG
+#ifndef REF_DEBUG
+#define G_PRINT_REF 1 == 1 ? (void) 0 : (void)
+#else
+#define G_PRINT_REF g_print
+#endif
+
+/*!
+ *\brief       Register ref counted pointer. It is based on GBoxed, so should
+ *             work with anything that uses the GType system. The semantics
+ *             are similar to a C++ auto pointer, with the exception that
+ *             C doesn't have automatic closure (calling destructors) when 
+ *             exiting a block scope.
+ *             Use the \ref G_TYPE_AUTO_POINTER macro instead of calling this
+ *             function directly.
+ *
+ *\return      GType A GType type.
+ */
+GType g_auto_pointer_register(void)
+{
+       static GType auto_pointer_type;
+       if (!auto_pointer_type)
+               auto_pointer_type =
+                       g_boxed_type_register_static
+                               ("G_TYPE_AUTO_POINTER",
+                                (GBoxedCopyFunc) g_auto_pointer_copy,
+                                (GBoxedFreeFunc) g_auto_pointer_free);
+       return auto_pointer_type;                                                    
+}
+
+/*!
+ *\brief       Structure with g_new() allocated pointer guarded by the
+ *             auto pointer
+ */
+typedef struct AutoPointerRef {
+       void          (*free) (gpointer);
+       gpointer        pointer;
+       glong           cnt;
+} AutoPointerRef;
+
+/*!
+ *\brief       The auto pointer opaque structure that references the
+ *             pointer guard block.
+ */
+typedef struct AutoPointer {
+       AutoPointerRef *ref;
+       gpointer        ptr; /*!< access to protected pointer */
+} AutoPointer;
+
+/*!
+ *\brief       Creates an auto pointer for a g_new()ed pointer. Example:
+ *
+ *\code        
+ *
+ *             ... tell gtk_list_store it should use a G_TYPE_AUTO_POINTER
+ *             ... when assigning, copying and freeing storage elements
+ *
+ *             gtk_list_store_new(N_S_COLUMNS, 
+ *                                G_TYPE_AUTO_POINTER,
+ *                                -1);
+ *
+ *
+ *             Template *precious_data = g_new0(Template, 1);
+ *             g_pointer protect = g_auto_pointer_new(precious_data);
+ *
+ *             gtk_list_store_set(container, &iter,
+ *                                S_DATA, protect,
+ *                                -1);
+ *
+ *             ... the gtk_list_store has copied the pointer and 
+ *             ... incremented its reference count, we should free
+ *             ... the auto pointer (in C++ a destructor would do
+ *             ... this for us when leaving block scope)
+ * 
+ *             g_auto_pointer_free(protect);
+ *
+ *             ... gtk_list_store_set() now manages the data. When
+ *             ... *explicitly* requesting a pointer from the list 
+ *             ... store, don't forget you get a copy that should be 
+ *             ... freed with g_auto_pointer_free() eventually.
+ *
+ *\endcode
+ *
+ *\param       pointer Pointer to be guarded.
+ *
+ *\return      GAuto * Pointer that should be used in containers with
+ *             GType support.
+ */
+GAuto *g_auto_pointer_new(gpointer p)
+{
+       AutoPointerRef *ref = g_new0(AutoPointerRef, 1);
+       AutoPointer    *ptr = g_new0(AutoPointer, 1);
+
+       ref->pointer = p;
+       ref->free = g_free;
+       ref->cnt = 1;
+
+       ptr->ref = ref;
+       ptr->ptr = p;
+
+       G_PRINT_REF ("XXXX ALLOC(%lx)\n", p);
+
+       return ptr;
+}
+
+/*!
+ *\brief       Allocate an autopointer using the passed \a free function to
+ *             free the guarded pointer
+ */
+GAuto *g_auto_pointer_new_with_free(gpointer p, GFreeFunc free_)
+{      
+       AutoPointer *aptr = g_auto_pointer_new(p);
+
+       aptr->ref->free = free_;
+       return aptr; 
+}
+
+gpointer g_auto_pointer_get_ptr(GAuto *auto_ptr)
+{
+       return ((AutoPointer *) auto_ptr)->ptr; 
+}
+
+/*!
+ *\brief       Copies an auto pointer by. It's mostly not necessary
+ *             to call this function directly, unless you copy/assign
+ *             the guarded pointer.
+ *
+ *\param       auto_ptr Auto pointer returned by previous call to 
+ *             g_auto_pointer_new_XXX()
+ *
+ *\return      gpointer An auto pointer
+ */
+GAuto *g_auto_pointer_copy(GAuto *auto_ptr)
+{
+       AutoPointer     *ptr = auto_ptr;
+       AutoPointerRef  *ref = ptr->ref;
+       AutoPointer     *newp = g_new0(AutoPointer, 1);
+
+       newp->ref = ref;
+       newp->ptr = ref->pointer;
+       ++(ref->cnt);
+       
+       G_PRINT_REF ("XXXX COPY(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
+
+       return newp;
+}
+
+/*!
+ *\brief       Free an auto pointer
+ */
+void g_auto_pointer_free(GAuto *auto_ptr)
+{
+       AutoPointer     *ptr = auto_ptr;
+       AutoPointerRef  *ref = ptr->ref;
+
+       if (--(ref->cnt) == 0) {
+               G_PRINT_REF ("XXXX FREE(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
+               ref->free(ref->pointer);
+               g_free(ref);
+       } else
+               G_PRINT_REF ("XXXX DEREF(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
+       g_free(ptr);            
+}
+
index c854ab45e897adfe42662c6af61c2d57406b2e90..faeb7114a5a28435d20211c4c81694f0068100ea 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include <glib.h>
+#include <glib-object.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -477,6 +478,18 @@ GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data);
 gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
 void get_hex_str(gchar *out, guchar ch);
 
+/* auto pointer for containers that support GType system */
+
+#define G_TYPE_AUTO_POINTER    g_auto_pointer_register()
+typedef struct AutoPointer     GAuto;
+GType g_auto_pointer_register          (void);
+GAuto *g_auto_pointer_new              (gpointer pointer);
+GAuto *g_auto_pointer_new_with_free    (gpointer p, 
+                                        GFreeFunc free);
+gpointer g_auto_pointer_get_ptr                (GAuto *auto_ptr);
+GAuto *g_auto_pointer_copy             (GAuto *auto_ptr);
+void g_auto_pointer_free               (GAuto *auto_ptr);
+
 #ifdef __cplusplus
 }
 #endif
index 5149036c62d3beba1a35705ea39ce77fcd2fd51b..b52e44ecb297d2ebe307a04f8a0af9a3869159c1 100644 (file)
@@ -72,21 +72,6 @@ struct _PrefsTreeNode
        gfloat     treeweight; /* GTK2: not used */
 };
 
-static GType G_TYPE_AUTO_POINTER;
-
-typedef struct AutoPointerRef {
-       gpointer        pointer;
-       glong           cnt;
-} AutoPointerRef;
-
-typedef struct AutoPointer {
-       AutoPointerRef *ref;
-} AutoPointer;
-
-static gpointer g_auto_pointer_new                     (gpointer pointer);
-static gpointer g_auto_pointer_copy                    (gpointer p);
-static void g_auto_pointer_free                                (gpointer p);
-
 static GtkTreeStore *prefswindow_create_data_store     (void);
 static GtkWidget *prefswindow_tree_view_create         (PrefsWindow* prefswindow);
 static void prefs_filtering_create_tree_view_columns   (GtkWidget *tree_view);
@@ -272,7 +257,7 @@ static void prefswindow_build_tree(GtkWidget *tree_view, GSList *prefs_pages)
                                                   PREFS_PAGE_DATA, &prefs_node,
                                                   -1);
                        } else {
-                               gpointer autoptr; 
+                               GAuto *autoptr; 
                        
                                /* create a new top level */
                                gtk_tree_store_append(store, &child, i == 0 ? NULL : &node);
@@ -425,59 +410,8 @@ void prefswindow_open(const gchar *title, GSList *prefs_pages, gpointer data)
        prefswindow_open_full(title, prefs_pages, data, NULL);
 }
 
-/* NOTE: auto pointer could be made more generic, but this works
- * fine for now. */
-
-static gpointer g_auto_pointer_new(gpointer p)
-{      
-       AutoPointerRef *ref = g_new0(AutoPointerRef, 1);
-       AutoPointer    *ptr = g_new0(AutoPointer, 1);
-
-       ref->pointer = p;
-       ref->cnt = 1;
-
-       ptr->ref = ref;
-
-       return ptr;
-}
-
-static gpointer g_auto_pointer_copy(gpointer p)
-{
-       AutoPointer     *ptr = p;
-       AutoPointerRef  *ref = ptr->ref;
-       AutoPointer     *newp = g_new0(AutoPointer, 1);
-       newp->ref = ref;
-
-       ++(ref->cnt);
-       return newp;
-}
-
-static void g_auto_pointer_free(gpointer p)
-{
-       AutoPointer     *ptr = p;
-       AutoPointerRef  *ref = ptr->ref;
-
-       if (--(ref->cnt) == 0) {
-               g_free(ref->pointer);
-               g_free(ref);
-       }
-       g_free(ptr);            
-}
-
-static void prefswindow_static_init(void)
-{
-       if (!G_TYPE_AUTO_POINTER)
-               G_TYPE_AUTO_POINTER = 
-                       g_boxed_type_register_static("G_TYPE_AUTO_POINTER",
-                                                    g_auto_pointer_copy,
-                                                    g_auto_pointer_free);
-}
-
 static GtkTreeStore *prefswindow_create_data_store(void)
 {
-       /* should always be called before using auto pointer type */
-       prefswindow_static_init();
-       
        return gtk_tree_store_new(N_PREFS_PAGE_COLUMNS,
                                  G_TYPE_STRING,
                                  G_TYPE_POINTER,