|
1 /* GObject - GLib Type, Object, Parameter and Signal Library |
|
2 * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. |
|
3 * Portions copyright (c) 2006 Nokia Corporation. All rights reserved. |
|
4 * |
|
5 * This library is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU Lesser General Public |
|
7 * License as published by the Free Software Foundation; either |
|
8 * version 2 of the License, or (at your option) any later version. |
|
9 * |
|
10 * This library is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 * Lesser General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Lesser General |
|
16 * Public License along with this library; if not, write to the |
|
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
|
18 * Boston, MA 02111-1307, USA. |
|
19 */ |
|
20 |
|
21 /* |
|
22 * MT safe |
|
23 */ |
|
24 |
|
25 #include <string.h> |
|
26 |
|
27 #include "genums.h" |
|
28 |
|
29 #include "gvalue.h" |
|
30 #include "gvaluecollector.h" |
|
31 |
|
32 #include "gobjectalias.h" |
|
33 |
|
34 #ifdef __SYMBIAN32__ |
|
35 #include <gobject_wsd.h> |
|
36 #endif /* __SYMBIAN32__ */ |
|
37 |
|
38 |
|
39 /* --- prototypes --- */ |
|
40 static void g_enum_class_init (GEnumClass *class, |
|
41 gpointer class_data); |
|
42 static void g_flags_class_init (GFlagsClass *class, |
|
43 gpointer class_data); |
|
44 static void value_flags_enum_init (GValue *value); |
|
45 static void value_flags_enum_copy_value (const GValue *src_value, |
|
46 GValue *dest_value); |
|
47 static gchar* value_flags_enum_collect_value (GValue *value, |
|
48 guint n_collect_values, |
|
49 GTypeCValue *collect_values, |
|
50 guint collect_flags); |
|
51 static gchar* value_flags_enum_lcopy_value (const GValue *value, |
|
52 guint n_collect_values, |
|
53 GTypeCValue *collect_values, |
|
54 guint collect_flags); |
|
55 |
|
56 /* --- functions --- */ |
|
57 #if EMULATOR |
|
58 |
|
59 PLS(initialized ,g_enum_types_init,gboolean) |
|
60 PLS(info,g_enum_types_init,GTypeInfo) |
|
61 |
|
62 #define initialized (*FUNCTION_NAME(initialized ,g_enum_types_init)()) |
|
63 #define info (*FUNCTION_NAME(info ,g_enum_types_init)()) |
|
64 |
|
65 const GTypeValueTable temp_flags_enum_value_table = { |
|
66 value_flags_enum_init, /* value_init */ |
|
67 NULL, /* value_free */ |
|
68 value_flags_enum_copy_value, /* value_copy */ |
|
69 NULL, /* value_peek_pointer */ |
|
70 "i", /* collect_format */ |
|
71 value_flags_enum_collect_value, /* collect_value */ |
|
72 "p", /* lcopy_format */ |
|
73 value_flags_enum_lcopy_value, /* lcopy_value */ |
|
74 }; |
|
75 |
|
76 const GTypeInfo temp_info = { |
|
77 0, /* class_size */ |
|
78 NULL, /* base_init */ |
|
79 NULL, /* base_destroy */ |
|
80 NULL, /* class_init */ |
|
81 NULL, /* class_destroy */ |
|
82 NULL, /* class_data */ |
|
83 0, /* instance_size */ |
|
84 0, /* n_preallocs */ |
|
85 NULL, /* instance_init */ |
|
86 &temp_flags_enum_value_table, /* value_table */ |
|
87 }; |
|
88 |
|
89 #endif /* EMULATOR */ |
|
90 |
|
91 void |
|
92 g_enum_types_init (void) |
|
93 { |
|
94 static const GTypeValueTable flags_enum_value_table = { |
|
95 value_flags_enum_init, /* value_init */ |
|
96 NULL, /* value_free */ |
|
97 value_flags_enum_copy_value, /* value_copy */ |
|
98 NULL, /* value_peek_pointer */ |
|
99 "i", /* collect_format */ |
|
100 value_flags_enum_collect_value, /* collect_value */ |
|
101 "p", /* lcopy_format */ |
|
102 value_flags_enum_lcopy_value, /* lcopy_value */ |
|
103 }; |
|
104 |
|
105 #if !(EMULATOR) |
|
106 static gboolean initialized = FALSE; |
|
107 static GTypeInfo info = { |
|
108 0, /* class_size */ |
|
109 NULL, /* base_init */ |
|
110 NULL, /* base_destroy */ |
|
111 NULL, /* class_init */ |
|
112 NULL, /* class_destroy */ |
|
113 NULL, /* class_data */ |
|
114 0, /* instance_size */ |
|
115 0, /* n_preallocs */ |
|
116 NULL, /* instance_init */ |
|
117 &flags_enum_value_table, /* value_table */ |
|
118 }; |
|
119 #endif /*EMULATOR */ |
|
120 |
|
121 static const GTypeFundamentalInfo finfo = { |
|
122 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE, |
|
123 }; |
|
124 GType type; |
|
125 |
|
126 g_return_if_fail (initialized == FALSE); |
|
127 initialized = TRUE; |
|
128 |
|
129 /* G_TYPE_ENUM |
|
130 */ |
|
131 info.class_size = sizeof (GEnumClass); |
|
132 type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo, |
|
133 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); |
|
134 g_assert (type == G_TYPE_ENUM); |
|
135 |
|
136 /* G_TYPE_FLAGS |
|
137 */ |
|
138 info.class_size = sizeof (GFlagsClass); |
|
139 type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo, |
|
140 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); |
|
141 g_assert (type == G_TYPE_FLAGS); |
|
142 } |
|
143 |
|
144 #if EMULATOR |
|
145 #undef initialized |
|
146 #undef info |
|
147 #endif /* EMULATOR */ |
|
148 |
|
149 static void |
|
150 value_flags_enum_init (GValue *value) |
|
151 { |
|
152 value->data[0].v_long = 0; |
|
153 } |
|
154 |
|
155 static void |
|
156 value_flags_enum_copy_value (const GValue *src_value, |
|
157 GValue *dest_value) |
|
158 { |
|
159 dest_value->data[0].v_long = src_value->data[0].v_long; |
|
160 } |
|
161 |
|
162 static gchar* |
|
163 value_flags_enum_collect_value (GValue *value, |
|
164 guint n_collect_values, |
|
165 GTypeCValue *collect_values, |
|
166 guint collect_flags) |
|
167 { |
|
168 value->data[0].v_long = collect_values[0].v_int; |
|
169 |
|
170 return NULL; |
|
171 } |
|
172 |
|
173 static gchar* |
|
174 value_flags_enum_lcopy_value (const GValue *value, |
|
175 guint n_collect_values, |
|
176 GTypeCValue *collect_values, |
|
177 guint collect_flags) |
|
178 { |
|
179 gint *int_p = collect_values[0].v_pointer; |
|
180 |
|
181 if (!int_p) |
|
182 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); |
|
183 |
|
184 *int_p = value->data[0].v_long; |
|
185 |
|
186 return NULL; |
|
187 } |
|
188 |
|
189 EXPORT_C GType |
|
190 g_enum_register_static (const gchar *name, |
|
191 const GEnumValue *const_static_values) |
|
192 { |
|
193 GTypeInfo enum_type_info = { |
|
194 sizeof (GEnumClass), /* class_size */ |
|
195 NULL, /* base_init */ |
|
196 NULL, /* base_finalize */ |
|
197 (GClassInitFunc) g_enum_class_init, |
|
198 NULL, /* class_finalize */ |
|
199 NULL, /* class_data */ |
|
200 0, /* instance_size */ |
|
201 0, /* n_preallocs */ |
|
202 NULL, /* instance_init */ |
|
203 NULL, /* value_table */ |
|
204 }; |
|
205 GType type; |
|
206 |
|
207 g_return_val_if_fail (name != NULL, 0); |
|
208 g_return_val_if_fail (const_static_values != NULL, 0); |
|
209 |
|
210 enum_type_info.class_data = const_static_values; |
|
211 |
|
212 type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0); |
|
213 |
|
214 return type; |
|
215 } |
|
216 |
|
217 EXPORT_C GType |
|
218 g_flags_register_static (const gchar *name, |
|
219 const GFlagsValue *const_static_values) |
|
220 { |
|
221 GTypeInfo flags_type_info = { |
|
222 sizeof (GFlagsClass), /* class_size */ |
|
223 NULL, /* base_init */ |
|
224 NULL, /* base_finalize */ |
|
225 (GClassInitFunc) g_flags_class_init, |
|
226 NULL, /* class_finalize */ |
|
227 NULL, /* class_data */ |
|
228 0, /* instance_size */ |
|
229 0, /* n_preallocs */ |
|
230 NULL, /* instance_init */ |
|
231 NULL, /* value_table */ |
|
232 }; |
|
233 GType type; |
|
234 |
|
235 g_return_val_if_fail (name != NULL, 0); |
|
236 g_return_val_if_fail (const_static_values != NULL, 0); |
|
237 |
|
238 flags_type_info.class_data = const_static_values; |
|
239 |
|
240 type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0); |
|
241 |
|
242 return type; |
|
243 } |
|
244 |
|
245 EXPORT_C void |
|
246 g_enum_complete_type_info (GType g_enum_type, |
|
247 GTypeInfo *info, |
|
248 const GEnumValue *const_values) |
|
249 { |
|
250 g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type)); |
|
251 g_return_if_fail (info != NULL); |
|
252 g_return_if_fail (const_values != NULL); |
|
253 |
|
254 info->class_size = sizeof (GEnumClass); |
|
255 info->base_init = NULL; |
|
256 info->base_finalize = NULL; |
|
257 info->class_init = (GClassInitFunc) g_enum_class_init; |
|
258 info->class_finalize = NULL; |
|
259 info->class_data = const_values; |
|
260 } |
|
261 |
|
262 EXPORT_C void |
|
263 g_flags_complete_type_info (GType g_flags_type, |
|
264 GTypeInfo *info, |
|
265 const GFlagsValue *const_values) |
|
266 { |
|
267 g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type)); |
|
268 g_return_if_fail (info != NULL); |
|
269 g_return_if_fail (const_values != NULL); |
|
270 |
|
271 info->class_size = sizeof (GFlagsClass); |
|
272 info->base_init = NULL; |
|
273 info->base_finalize = NULL; |
|
274 info->class_init = (GClassInitFunc) g_flags_class_init; |
|
275 info->class_finalize = NULL; |
|
276 info->class_data = const_values; |
|
277 } |
|
278 |
|
279 static void |
|
280 g_enum_class_init (GEnumClass *class, |
|
281 gpointer class_data) |
|
282 { |
|
283 g_return_if_fail (G_IS_ENUM_CLASS (class)); |
|
284 |
|
285 class->minimum = 0; |
|
286 class->maximum = 0; |
|
287 class->n_values = 0; |
|
288 class->values = class_data; |
|
289 |
|
290 if (class->values) |
|
291 { |
|
292 GEnumValue *values; |
|
293 |
|
294 class->minimum = class->values->value; |
|
295 class->maximum = class->values->value; |
|
296 for (values = class->values; values->value_name; values++) |
|
297 { |
|
298 class->minimum = MIN (class->minimum, values->value); |
|
299 class->maximum = MAX (class->maximum, values->value); |
|
300 class->n_values++; |
|
301 } |
|
302 } |
|
303 } |
|
304 |
|
305 static void |
|
306 g_flags_class_init (GFlagsClass *class, |
|
307 gpointer class_data) |
|
308 { |
|
309 g_return_if_fail (G_IS_FLAGS_CLASS (class)); |
|
310 |
|
311 class->mask = 0; |
|
312 class->n_values = 0; |
|
313 class->values = class_data; |
|
314 |
|
315 if (class->values) |
|
316 { |
|
317 GFlagsValue *values; |
|
318 |
|
319 for (values = class->values; values->value_name; values++) |
|
320 { |
|
321 class->mask |= values->value; |
|
322 class->n_values++; |
|
323 } |
|
324 } |
|
325 } |
|
326 |
|
327 EXPORT_C GEnumValue* |
|
328 g_enum_get_value_by_name (GEnumClass *enum_class, |
|
329 const gchar *name) |
|
330 { |
|
331 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); |
|
332 g_return_val_if_fail (name != NULL, NULL); |
|
333 |
|
334 if (enum_class->n_values) |
|
335 { |
|
336 GEnumValue *enum_value; |
|
337 |
|
338 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) |
|
339 if (strcmp (name, enum_value->value_name) == 0) |
|
340 return enum_value; |
|
341 } |
|
342 |
|
343 return NULL; |
|
344 } |
|
345 |
|
346 EXPORT_C GFlagsValue* |
|
347 g_flags_get_value_by_name (GFlagsClass *flags_class, |
|
348 const gchar *name) |
|
349 { |
|
350 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); |
|
351 g_return_val_if_fail (name != NULL, NULL); |
|
352 |
|
353 if (flags_class->n_values) |
|
354 { |
|
355 GFlagsValue *flags_value; |
|
356 |
|
357 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) |
|
358 if (strcmp (name, flags_value->value_name) == 0) |
|
359 return flags_value; |
|
360 } |
|
361 |
|
362 return NULL; |
|
363 } |
|
364 |
|
365 EXPORT_C GEnumValue* |
|
366 g_enum_get_value_by_nick (GEnumClass *enum_class, |
|
367 const gchar *nick) |
|
368 { |
|
369 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); |
|
370 g_return_val_if_fail (nick != NULL, NULL); |
|
371 |
|
372 if (enum_class->n_values) |
|
373 { |
|
374 GEnumValue *enum_value; |
|
375 |
|
376 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) |
|
377 if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0) |
|
378 return enum_value; |
|
379 } |
|
380 |
|
381 return NULL; |
|
382 } |
|
383 |
|
384 EXPORT_C GFlagsValue* |
|
385 g_flags_get_value_by_nick (GFlagsClass *flags_class, |
|
386 const gchar *nick) |
|
387 { |
|
388 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); |
|
389 g_return_val_if_fail (nick != NULL, NULL); |
|
390 |
|
391 if (flags_class->n_values) |
|
392 { |
|
393 GFlagsValue *flags_value; |
|
394 |
|
395 for (flags_value = flags_class->values; flags_value->value_nick; flags_value++) |
|
396 if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0) |
|
397 return flags_value; |
|
398 } |
|
399 |
|
400 return NULL; |
|
401 } |
|
402 |
|
403 EXPORT_C GEnumValue* |
|
404 g_enum_get_value (GEnumClass *enum_class, |
|
405 gint value) |
|
406 { |
|
407 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); |
|
408 |
|
409 if (enum_class->n_values) |
|
410 { |
|
411 GEnumValue *enum_value; |
|
412 |
|
413 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) |
|
414 if (enum_value->value == value) |
|
415 return enum_value; |
|
416 } |
|
417 |
|
418 return NULL; |
|
419 } |
|
420 |
|
421 EXPORT_C GFlagsValue* |
|
422 g_flags_get_first_value (GFlagsClass *flags_class, |
|
423 guint value) |
|
424 { |
|
425 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); |
|
426 |
|
427 if (flags_class->n_values) |
|
428 { |
|
429 GFlagsValue *flags_value; |
|
430 |
|
431 if (value == 0) |
|
432 { |
|
433 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) |
|
434 if (flags_value->value == 0) |
|
435 return flags_value; |
|
436 } |
|
437 else |
|
438 { |
|
439 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) |
|
440 if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value) |
|
441 return flags_value; |
|
442 } |
|
443 } |
|
444 |
|
445 return NULL; |
|
446 } |
|
447 |
|
448 EXPORT_C void |
|
449 g_value_set_enum (GValue *value, |
|
450 gint v_enum) |
|
451 { |
|
452 g_return_if_fail (G_VALUE_HOLDS_ENUM (value)); |
|
453 |
|
454 value->data[0].v_long = v_enum; |
|
455 } |
|
456 |
|
457 EXPORT_C gint |
|
458 g_value_get_enum (const GValue *value) |
|
459 { |
|
460 g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0); |
|
461 |
|
462 return value->data[0].v_long; |
|
463 } |
|
464 |
|
465 EXPORT_C void |
|
466 g_value_set_flags (GValue *value, |
|
467 guint v_flags) |
|
468 { |
|
469 g_return_if_fail (G_VALUE_HOLDS_FLAGS (value)); |
|
470 |
|
471 value->data[0].v_ulong = v_flags; |
|
472 } |
|
473 |
|
474 EXPORT_C guint |
|
475 g_value_get_flags (const GValue *value) |
|
476 { |
|
477 g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0); |
|
478 |
|
479 return value->data[0].v_ulong; |
|
480 } |
|
481 |
|
482 #define __G_ENUMS_C__ |
|
483 #include "gobjectaliasdef.c" |