]> Pileus Git - ~andy/gtk/blob - gtk/gtktreedatalist.c
Checked in initial draft of the new tree widget.
[~andy/gtk] / gtk / gtktreedatalist.c
1 /* gtktreedatalist.h
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
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 #include "gtktreedatalist.h"
21 #include "gobject/gvalue.h"
22
23 /* node allocation
24  */
25 struct _GAllocator /* from gmem.c */
26 {
27   gchar           *name;
28   guint16          n_preallocs;
29   guint            is_unused : 1;
30   guint            type : 4;
31   GAllocator      *last;
32   GMemChunk       *mem_chunk;
33   GtkTreeDataList *free_nodes;
34 };
35
36
37 G_LOCK_DEFINE_STATIC (current_allocator);
38 static GAllocator *current_allocator = NULL;
39
40 /* HOLDS: current_allocator_lock */
41 static void
42 gtk_tree_data_list_validate_allocator (GAllocator *allocator)
43 {
44   g_return_if_fail (allocator != NULL);
45   g_return_if_fail (allocator->is_unused == TRUE);
46
47   if (allocator->type != G_ALLOCATOR_NODE)
48     {
49       allocator->type = G_ALLOCATOR_NODE;
50       if (allocator->mem_chunk)
51         {
52           g_mem_chunk_destroy (allocator->mem_chunk);
53           allocator->mem_chunk = NULL;
54         }
55     }
56
57   if (!allocator->mem_chunk)
58     {
59       allocator->mem_chunk = g_mem_chunk_new (allocator->name,
60                                               sizeof (GtkTreeDataList),
61                                               sizeof (GtkTreeDataList) * allocator->n_preallocs,
62                                               G_ALLOC_ONLY);
63       allocator->free_nodes = NULL;
64     }
65
66   allocator->is_unused = FALSE;
67 }
68
69 void
70 gtk_tree_data_list_push_allocator (GAllocator *allocator)
71 {
72   G_LOCK (current_allocator);
73   gtk_tree_data_list_validate_allocator ( allocator );
74   allocator->last = current_allocator;
75   current_allocator = allocator;
76   G_UNLOCK (current_allocator);
77 }
78
79 void
80 gtk_tree_data_list_pop_allocator (void)
81 {
82   G_LOCK (current_allocator);
83   if (current_allocator)
84     {
85       GAllocator *allocator;
86
87       allocator = current_allocator;
88       current_allocator = allocator->last;
89       allocator->last = NULL;
90       allocator->is_unused = TRUE;
91     }
92   G_UNLOCK (current_allocator);
93 }
94
95 GtkTreeDataList *
96 gtk_tree_data_list_alloc (void)
97 {
98   GtkTreeDataList *list;
99
100   G_LOCK (current_allocator);
101   if (!current_allocator)
102     {
103        GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator",
104                                                 128);
105        gtk_tree_data_list_validate_allocator (allocator);
106        allocator->last = NULL;
107        current_allocator = allocator;
108     }
109   if (!current_allocator->free_nodes)
110     list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
111   else
112     {
113       list = current_allocator->free_nodes;
114       current_allocator->free_nodes = list->next;
115     }
116   G_UNLOCK (current_allocator);
117
118   return list;
119 }
120
121 void
122 gtk_tree_data_list_free (GtkTreeDataList *list)
123 {
124   G_LOCK (current_allocator);
125   list->next = current_allocator->free_nodes;
126   current_allocator->free_nodes = list;
127   G_UNLOCK (current_allocator);
128 }
129
130 void
131 gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
132                                   GType            type,
133                                   GValue          *value)
134 {
135   g_value_init (value, type);
136
137   switch (type)
138     {
139     case G_TYPE_STRING:
140       g_value_set_string (value, (gchar *) list->data.v_pointer);
141       break;
142     }
143 }
144
145 void
146 gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
147                                   GValue          *value)
148 {
149   switch (value->g_type)
150     {
151     case G_TYPE_STRING:
152       list->data.v_pointer = g_value_dup_string (value);
153       break;
154     default:
155       g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
156       return;
157     }
158 }
159