]> Pileus Git - ~andy/gtk/blob - gtk/gtktreedatalist.c
Adapt to GtkTreeSelection changes
[~andy/gtk] / gtk / gtktreedatalist.c
1 /* gtktreedatalist.c
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 #include "gobject/gvaluetypes.h"
23
24 /* node allocation
25  */
26 struct _GAllocator /* from gmem.c */
27 {
28   gchar           *name;
29   guint16          n_preallocs;
30   guint            is_unused : 1;
31   guint            type : 4;
32   GAllocator      *last;
33   GMemChunk       *mem_chunk;
34   GtkTreeDataList *free_nodes;
35 };
36
37
38 G_LOCK_DEFINE_STATIC (current_allocator);
39 static GAllocator *current_allocator = NULL;
40
41 /* HOLDS: current_allocator_lock */
42 static void
43 gtk_tree_data_list_validate_allocator (GAllocator *allocator)
44 {
45   g_return_if_fail (allocator != NULL);
46   g_return_if_fail (allocator->is_unused == TRUE);
47
48   if (allocator->type != G_ALLOCATOR_NODE)
49     {
50       allocator->type = G_ALLOCATOR_NODE;
51       if (allocator->mem_chunk)
52         {
53           g_mem_chunk_destroy (allocator->mem_chunk);
54           allocator->mem_chunk = NULL;
55         }
56     }
57
58   if (!allocator->mem_chunk)
59     {
60       allocator->mem_chunk = g_mem_chunk_new (allocator->name,
61                                               sizeof (GtkTreeDataList),
62                                               sizeof (GtkTreeDataList) * allocator->n_preallocs,
63                                               G_ALLOC_ONLY);
64       allocator->free_nodes = NULL;
65     }
66
67   allocator->is_unused = FALSE;
68 }
69
70 void
71 _gtk_tree_data_list_push_allocator (GAllocator *allocator)
72 {
73   G_LOCK (current_allocator);
74   gtk_tree_data_list_validate_allocator ( allocator );
75   allocator->last = current_allocator;
76   current_allocator = allocator;
77   G_UNLOCK (current_allocator);
78 }
79
80 void
81 _gtk_tree_data_list_pop_allocator (void)
82 {
83   G_LOCK (current_allocator);
84   if (current_allocator)
85     {
86       GAllocator *allocator;
87
88       allocator = current_allocator;
89       current_allocator = allocator->last;
90       allocator->last = NULL;
91       allocator->is_unused = TRUE;
92     }
93   G_UNLOCK (current_allocator);
94 }
95
96 GtkTreeDataList *
97 _gtk_tree_data_list_alloc (void)
98 {
99   GtkTreeDataList *list;
100
101   G_LOCK (current_allocator);
102   if (!current_allocator)
103     {
104        GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator",
105                                                 128);
106        gtk_tree_data_list_validate_allocator (allocator);
107        allocator->last = NULL;
108        current_allocator = allocator;
109     }
110   if (!current_allocator->free_nodes)
111     list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
112   else
113     {
114       list = current_allocator->free_nodes;
115       current_allocator->free_nodes = list->next;
116     }
117   G_UNLOCK (current_allocator);
118
119   return list;
120 }
121
122 void
123 _gtk_tree_data_list_free (GtkTreeDataList *list,
124                           GType           *column_headers)
125 {
126   GtkTreeDataList *tmp;
127   gint i = 0;
128
129   for (tmp = list; tmp; tmp = tmp->next)
130     {
131       switch (column_headers [i])
132         {
133         case G_TYPE_STRING:
134           g_free ((gchar *) tmp->data.v_pointer);
135           break;
136         case G_TYPE_OBJECT:
137           g_object_unref (G_OBJECT (tmp->data.v_pointer));
138           break;
139         default:
140           break;
141         }
142       i++;
143     }
144
145   G_LOCK (current_allocator);
146   list->next = current_allocator->free_nodes;
147   current_allocator->free_nodes = list;
148   G_UNLOCK (current_allocator);
149 }
150
151 void
152 _gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
153                                    GType            type,
154                                    GValue          *value)
155 {
156   g_value_init (value, type);
157
158   switch (type)
159     {
160     case G_TYPE_BOOLEAN:
161       g_value_set_boolean (value, (gboolean) list->data.v_int);
162       break;
163     case G_TYPE_CHAR:
164       g_value_set_char (value, list->data.v_char);
165       break;
166     case G_TYPE_UCHAR:
167       g_value_set_uchar (value, list->data.v_uchar);
168       break;
169     case G_TYPE_INT:
170       g_value_set_int (value, list->data.v_int);
171       break;
172     case G_TYPE_UINT:
173       g_value_set_uint (value, list->data.v_uint);
174       break;
175     case G_TYPE_POINTER:
176       g_value_set_pointer (value, (gpointer) list->data.v_pointer);
177       break;
178     case G_TYPE_FLOAT:
179       g_value_set_float (value, list->data.v_float);
180       break;
181     case G_TYPE_STRING:
182       g_value_set_string (value, (gchar *) list->data.v_pointer);
183       break;
184     case G_TYPE_OBJECT:
185       g_value_set_object (value, (GObject *) list->data.v_pointer);
186       break;
187     default:
188       g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
189       return;
190     }
191 }
192
193 void
194 _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
195                                    GValue          *value)
196 {
197   switch (value->g_type)
198     {
199     case G_TYPE_BOOLEAN:
200       list->data.v_int = g_value_get_boolean (value);
201       break;
202     case G_TYPE_CHAR:
203       list->data.v_char = g_value_get_char (value);
204       break;
205     case G_TYPE_UCHAR:
206       list->data.v_uchar = g_value_get_uchar (value);
207       break;
208     case G_TYPE_INT:
209       list->data.v_int = g_value_get_int (value);
210       break;
211     case G_TYPE_UINT:
212       list->data.v_uint = g_value_get_uint (value);
213       break;
214     case G_TYPE_POINTER:
215       list->data.v_pointer = g_value_get_pointer (value);
216       break;
217     case G_TYPE_FLOAT:
218       list->data.v_float = g_value_get_float (value);
219       break;
220     case G_TYPE_STRING:
221       list->data.v_pointer = g_value_dup_string (value);
222       break;
223     case G_TYPE_OBJECT:
224       list->data.v_pointer = g_value_dup_object (value);
225       break;
226     default:
227       g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
228       return;
229     }
230 }
231
232