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 :)
This commit is contained in:
parent
3d0e2ea4b3
commit
bc4055664b
6 changed files with 189 additions and 68 deletions
|
@ -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
|
||||
|
|
|
@ -303,3 +303,4 @@
|
|||
( 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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue