glib2 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/ChangeLog +3023 -0
  2. data/README +28 -0
  3. data/Rakefile +87 -0
  4. data/extconf.rb +61 -0
  5. data/sample/bookmarkfile.rb +66 -0
  6. data/sample/completion.rb +45 -0
  7. data/sample/idle.rb +41 -0
  8. data/sample/iochannel.rb +44 -0
  9. data/sample/keyfile.rb +62 -0
  10. data/sample/shell.rb +36 -0
  11. data/sample/spawn.rb +25 -0
  12. data/sample/timeout.rb +28 -0
  13. data/sample/timeout2.rb +35 -0
  14. data/sample/timer.rb +40 -0
  15. data/sample/type-register.rb +103 -0
  16. data/sample/type-register2.rb +104 -0
  17. data/sample/utils.rb +54 -0
  18. data/src/glib-enum-types.c +1032 -0
  19. data/src/glib-enum-types.h +140 -0
  20. data/src/lib/glib-mkenums.rb +199 -0
  21. data/src/lib/glib2.rb +220 -0
  22. data/src/lib/mkmf-gnome2.rb +390 -0
  23. data/src/lib/pkg-config.rb +137 -0
  24. data/src/rbgcompat.h +30 -0
  25. data/src/rbglib.c +320 -0
  26. data/src/rbglib.h +96 -0
  27. data/src/rbglib_bookmarkfile.c +595 -0
  28. data/src/rbglib_completion.c +192 -0
  29. data/src/rbglib_convert.c +195 -0
  30. data/src/rbglib_error.c +95 -0
  31. data/src/rbglib_fileutils.c +83 -0
  32. data/src/rbglib_i18n.c +44 -0
  33. data/src/rbglib_int64.c +157 -0
  34. data/src/rbglib_iochannel.c +883 -0
  35. data/src/rbglib_keyfile.c +846 -0
  36. data/src/rbglib_maincontext.c +917 -0
  37. data/src/rbglib_mainloop.c +87 -0
  38. data/src/rbglib_messages.c +150 -0
  39. data/src/rbglib_pollfd.c +111 -0
  40. data/src/rbglib_shell.c +68 -0
  41. data/src/rbglib_source.c +190 -0
  42. data/src/rbglib_spawn.c +345 -0
  43. data/src/rbglib_threads.c +51 -0
  44. data/src/rbglib_timer.c +127 -0
  45. data/src/rbglib_unicode.c +611 -0
  46. data/src/rbglib_utils.c +386 -0
  47. data/src/rbglib_win32.c +136 -0
  48. data/src/rbgobj_boxed.c +251 -0
  49. data/src/rbgobj_closure.c +337 -0
  50. data/src/rbgobj_convert.c +167 -0
  51. data/src/rbgobj_enums.c +961 -0
  52. data/src/rbgobj_fundamental.c +30 -0
  53. data/src/rbgobj_object.c +892 -0
  54. data/src/rbgobj_param.c +390 -0
  55. data/src/rbgobj_paramspecs.c +305 -0
  56. data/src/rbgobj_signal.c +963 -0
  57. data/src/rbgobj_strv.c +61 -0
  58. data/src/rbgobj_type.c +851 -0
  59. data/src/rbgobj_typeinstance.c +121 -0
  60. data/src/rbgobj_typeinterface.c +148 -0
  61. data/src/rbgobj_typemodule.c +66 -0
  62. data/src/rbgobj_typeplugin.c +49 -0
  63. data/src/rbgobj_value.c +313 -0
  64. data/src/rbgobj_valuearray.c +59 -0
  65. data/src/rbgobj_valuetypes.c +298 -0
  66. data/src/rbgobject.c +406 -0
  67. data/src/rbgobject.h +265 -0
  68. data/src/rbgprivate.h +88 -0
  69. data/src/rbgutil.c +222 -0
  70. data/src/rbgutil.h +82 -0
  71. data/src/rbgutil_callback.c +231 -0
  72. data/test/glib-test-init.rb +6 -0
  73. data/test/glib-test-utils.rb +12 -0
  74. data/test/run-test.rb +25 -0
  75. data/test/test_enum.rb +99 -0
  76. data/test/test_file_utils.rb +15 -0
  77. data/test/test_glib2.rb +120 -0
  78. data/test/test_iochannel.rb +275 -0
  79. data/test/test_key_file.rb +38 -0
  80. data/test/test_mkenums.rb +25 -0
  81. data/test/test_signal.rb +20 -0
  82. data/test/test_timeout.rb +28 -0
  83. data/test/test_unicode.rb +369 -0
  84. data/test/test_utils.rb +37 -0
  85. data/test/test_win32.rb +13 -0
  86. metadata +165 -0
data/src/rbgobj_strv.c ADDED
@@ -0,0 +1,61 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_gstrv.c -
5
+
6
+ $Author: sakai $
7
+ $Date: 2007/07/07 08:46:50 $
8
+
9
+ Copyright (C) 2005 Masao Mutoh
10
+ **********************************************************************/
11
+
12
+ #include "rbgprivate.h"
13
+
14
+ #if GLIB_CHECK_VERSION(2,6,0)
15
+
16
+ static VALUE
17
+ strv_to_ruby(const GValue* from)
18
+ {
19
+ VALUE ary;
20
+ const gchar** boxed = (const gchar**)g_value_get_boxed(from);
21
+ if (!boxed)
22
+ return Qnil;
23
+
24
+ ary = rb_ary_new();
25
+ while (*boxed){
26
+ rb_ary_push(ary, CSTR2RVAL(*boxed));
27
+ boxed++;
28
+ }
29
+ return ary;
30
+ }
31
+
32
+ static void
33
+ strv_from_ruby(VALUE from, GValue* to)
34
+ {
35
+ int i;
36
+ gchar** gstrv;
37
+
38
+ if (NIL_P(from)) {
39
+ g_value_set_boxed(to, NULL);
40
+ return;
41
+ }
42
+
43
+ Check_Type(from, T_ARRAY);
44
+ gstrv = g_new(gchar*, RARRAY_LEN(from) + 1);
45
+
46
+ for (i = 0; i < RARRAY_LEN(from); i++) {
47
+ VALUE v = RARRAY_PTR(from)[i];
48
+ gstrv[i] = g_strdup(StringValuePtr(v));
49
+ }
50
+ gstrv[RARRAY_LEN(from)] = NULL;
51
+
52
+ g_value_set_boxed(to, gstrv);
53
+ }
54
+
55
+ void Init_gobject_gstrv()
56
+ {
57
+ /* GStrv is treated as Array */
58
+ rbgobj_register_g2r_func(G_TYPE_STRV, strv_to_ruby);
59
+ rbgobj_register_r2g_func(G_TYPE_STRV, strv_from_ruby);
60
+ }
61
+ #endif
data/src/rbgobj_type.c ADDED
@@ -0,0 +1,851 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_type.c -
5
+
6
+ $Author: sakai $
7
+ $Date: 2007/07/16 03:35:53 $
8
+ created at: Sun Jun 9 20:31:47 JST 2002
9
+
10
+ Copyright (C) 2002-2009 Ruby-GNOME2 Project Team
11
+ Copyright (C) 2002,2003 Masahiro Sakai
12
+
13
+ **********************************************************************/
14
+
15
+ #include "rbgprivate.h"
16
+
17
+ /**********************************************************************/
18
+ /* Type Mapping */
19
+
20
+ #ifdef RBGOBJ_USE_DLPTR
21
+ #include "dl.h"
22
+ #endif
23
+
24
+ static VALUE rb_cMutex;
25
+ static VALUE lookup_class_mutex;
26
+
27
+ static ID id_new;
28
+ static ID id_superclass;
29
+ static ID id_lock;
30
+ static ID id_unlock;
31
+ static GHashTable *gtype_to_cinfo;
32
+ static VALUE klass_to_cinfo;
33
+
34
+ static GHashTable* dynamic_gtype_list;
35
+ typedef struct {
36
+ const gchar* name;
37
+ VALUE module;
38
+ void (*mark)(gpointer);
39
+ void (*free)(gpointer);
40
+ int flags; /* RGObjClassFlag */
41
+ } RGObjClassInfoDynamic;
42
+
43
+ typedef struct {
44
+ VALUE parent;
45
+ GType gtype;
46
+ gboolean create_class;
47
+ } RGObjClassByGtypeData;
48
+
49
+ static void
50
+ cinfo_mark(RGObjClassInfo* cinfo)
51
+ {
52
+ rb_gc_mark(cinfo->klass);
53
+ }
54
+
55
+
56
+ const RGObjClassInfo *
57
+ rbgobj_lookup_class(klass)
58
+ VALUE klass;
59
+ {
60
+ VALUE data = rb_hash_aref(klass_to_cinfo, klass);
61
+ if (!NIL_P(data)){
62
+ RGObjClassInfo* cinfo;
63
+ Data_Get_Struct(data, RGObjClassInfo, cinfo);
64
+ return cinfo;
65
+ }
66
+
67
+ if (TYPE(klass) == T_CLASS) {
68
+ VALUE super;
69
+ if (FL_TEST(klass, FL_SINGLETON)) {
70
+ super = rb_class_real(klass);
71
+ } else {
72
+ super = rb_funcall(klass, id_superclass, 0);
73
+ }
74
+ return rbgobj_lookup_class(super);
75
+ }
76
+
77
+ rb_raise(rb_eRuntimeError, "can't get gobject class information");
78
+ }
79
+
80
+ static const RGObjClassInfo *rbgobj_lookup_class_by_gtype_without_lock(GType gtype,
81
+ VALUE parent,
82
+ gboolean create_class);
83
+
84
+ static VALUE
85
+ get_superclass(GType gtype)
86
+ {
87
+ VALUE super_class;
88
+
89
+ if (rbgobj_convert_get_superclass(gtype, &super_class))
90
+ return super_class;
91
+
92
+ switch (gtype) {
93
+ case G_TYPE_PARAM:
94
+ case G_TYPE_OBJECT:
95
+ return cInstantiatable;
96
+ case G_TYPE_BOXED:
97
+ return rb_cObject;
98
+ case G_TYPE_POINTER:
99
+ #ifdef RBGOBJ_USE_DLPTR
100
+ return rb_cDLPtrData;
101
+ #else
102
+ return rb_cData;
103
+ #endif
104
+ case G_TYPE_ENUM:
105
+ case G_TYPE_FLAGS:
106
+ return rb_cObject;
107
+ default:
108
+ {
109
+ const RGObjClassInfo *cinfo_super;
110
+ GType parent_type;
111
+
112
+ parent_type = g_type_parent(gtype);
113
+ cinfo_super = rbgobj_lookup_class_by_gtype_without_lock(parent_type,
114
+ Qnil,
115
+ TRUE);
116
+ return cinfo_super->klass;
117
+ }
118
+ }
119
+ }
120
+
121
+ static const RGObjClassInfo *
122
+ rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent,
123
+ gboolean create_class)
124
+ {
125
+ GType fundamental_type;
126
+ RGObjClassInfo* cinfo;
127
+ RGObjClassInfoDynamic* cinfod;
128
+ void* gclass = NULL;
129
+ VALUE c;
130
+
131
+ if (gtype == G_TYPE_INVALID)
132
+ return NULL;
133
+
134
+ cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype));
135
+ if (cinfo)
136
+ return cinfo;
137
+
138
+ if (!create_class)
139
+ return NULL;
140
+
141
+ c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
142
+ cinfo->gtype = gtype;
143
+ cinfo->mark = NULL;
144
+ cinfo->free = NULL;
145
+ cinfo->flags = 0;
146
+
147
+ fundamental_type = G_TYPE_FUNDAMENTAL(gtype);
148
+ switch (fundamental_type){
149
+ case G_TYPE_POINTER:
150
+ case G_TYPE_BOXED:
151
+ case G_TYPE_PARAM:
152
+ case G_TYPE_OBJECT:
153
+ case G_TYPE_ENUM:
154
+ case G_TYPE_FLAGS:
155
+ if (NIL_P(parent)) parent = get_superclass(gtype);
156
+ cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
157
+ break;
158
+
159
+ case G_TYPE_INTERFACE:
160
+ cinfo->klass = rb_module_new();
161
+ break;
162
+
163
+ default:
164
+ if (NIL_P(parent)) parent = get_superclass(gtype);
165
+ if (NIL_P(parent)) {
166
+ fprintf(stderr,
167
+ "%s: %s's fundamental type %s isn't supported\n",
168
+ "rbgobj_lookup_class_by_gtype",
169
+ g_type_name(gtype),
170
+ g_type_name(fundamental_type));
171
+ return NULL;
172
+ }
173
+ cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
174
+ }
175
+
176
+ cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list,
177
+ g_type_name(gtype));
178
+ if (cinfod){
179
+ cinfo->mark = cinfod->mark;
180
+ cinfo->free = cinfod->free;
181
+ rb_define_const(cinfod->module, cinfod->name, cinfo->klass);
182
+ }
183
+
184
+ rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
185
+ g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
186
+
187
+ if (G_TYPE_IS_CLASSED(gtype))
188
+ gclass = g_type_class_ref(gtype);
189
+
190
+ if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype))
191
+ rbgobj_define_action_methods(cinfo->klass);
192
+
193
+ if (G_TYPE_IS_INSTANTIATABLE(gtype)){
194
+ GType* interfaces = NULL;
195
+ guint n_interfaces = 0;
196
+ int i;
197
+
198
+ interfaces = g_type_interfaces(gtype, &n_interfaces);
199
+ for (i = 0; i < n_interfaces; i++){
200
+ const RGObjClassInfo *iface_cinfo;
201
+ iface_cinfo =
202
+ rbgobj_lookup_class_by_gtype_without_lock(interfaces[i],
203
+ Qnil,
204
+ TRUE);
205
+ rb_include_module(cinfo->klass, iface_cinfo->klass);
206
+ }
207
+ g_free(interfaces);
208
+ }
209
+
210
+ if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) {
211
+ switch (fundamental_type) {
212
+ case G_TYPE_OBJECT:
213
+ rbgobj_init_object_class(cinfo->klass);
214
+ break;
215
+ case G_TYPE_ENUM:
216
+ rbgobj_init_enum_class(cinfo->klass);
217
+ break;
218
+ case G_TYPE_FLAGS:
219
+ rbgobj_init_flags_class(cinfo->klass);
220
+ break;
221
+ case G_TYPE_INTERFACE:
222
+ rbgobj_init_interface(cinfo->klass);
223
+ break;
224
+ default:
225
+ rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass);
226
+ break;
227
+ }
228
+ }
229
+
230
+ if (gclass)
231
+ g_type_class_unref(gclass);
232
+
233
+ return cinfo;
234
+ }
235
+
236
+ static VALUE
237
+ rbgobj_lookup_class_by_gtype_body(VALUE data)
238
+ {
239
+ RGObjClassByGtypeData *cdata = (RGObjClassByGtypeData *)data;
240
+ const RGObjClassInfo *cinfo;
241
+
242
+ cinfo = rbgobj_lookup_class_by_gtype_without_lock(cdata->gtype,
243
+ cdata->parent,
244
+ cdata->create_class);
245
+ return (VALUE)cinfo;
246
+ }
247
+
248
+ static VALUE
249
+ rbgobj_lookup_class_by_gtype_ensure(VALUE data)
250
+ {
251
+ rb_funcall(lookup_class_mutex, id_unlock, 0);
252
+ return Qundef;
253
+ }
254
+
255
+ const RGObjClassInfo *
256
+ rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent)
257
+ {
258
+ return rbgobj_lookup_class_by_gtype_full(gtype, parent, TRUE);
259
+ }
260
+
261
+ const RGObjClassInfo *
262
+ rbgobj_lookup_class_by_gtype_full(GType gtype, VALUE parent,
263
+ gboolean create_class)
264
+ {
265
+ RGObjClassByGtypeData data;
266
+
267
+ data.gtype = gtype;
268
+ data.parent = parent;
269
+ data.create_class = create_class;
270
+
271
+ if (create_class) {
272
+ rb_funcall(lookup_class_mutex, id_lock, 0);
273
+ return (RGObjClassInfo *)rb_ensure(rbgobj_lookup_class_by_gtype_body,
274
+ (VALUE)&data,
275
+ rbgobj_lookup_class_by_gtype_ensure,
276
+ (VALUE)&data);
277
+ } else {
278
+ return rbgobj_lookup_class_by_gtype_without_lock(gtype, parent,
279
+ create_class);
280
+ }
281
+ }
282
+
283
+ VALUE
284
+ rbgobj_gtype_to_ruby_class(GType gtype)
285
+ {
286
+ const RGObjClassInfo *cinfo;
287
+
288
+ cinfo = GTYPE2CINFO(gtype);
289
+ return cinfo ? cinfo->klass : Qnil;
290
+ }
291
+
292
+ VALUE
293
+ rbgobj_define_class(gtype, name, module, mark, free, parent)
294
+ GType gtype;
295
+ const gchar* name;
296
+ VALUE module;
297
+ void* mark;
298
+ void* free;
299
+ VALUE parent;
300
+ {
301
+ RGObjClassInfo* cinfo;
302
+ if (gtype == 0)
303
+ rb_bug("rbgobj_define_class: Invalid gtype [%s]\n", name);
304
+
305
+ cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(gtype, parent);
306
+ cinfo->mark = mark;
307
+ cinfo->free = free;
308
+ rb_define_const(module, name, cinfo->klass);
309
+ return cinfo->klass;
310
+ }
311
+
312
+ VALUE
313
+ rbgobj_define_class_dynamic(gtype_name, name, module, mark, free)
314
+ const gchar* gtype_name;
315
+ const gchar* name;
316
+ VALUE module;
317
+ void* mark;
318
+ void* free;
319
+ {
320
+ RGObjClassInfoDynamic* cinfo;
321
+ cinfo = (RGObjClassInfoDynamic*)g_new(RGObjClassInfoDynamic, 1);
322
+ cinfo->name = name;
323
+ cinfo->module = module;
324
+ cinfo->mark = mark;
325
+ cinfo->free = free;
326
+ g_hash_table_insert(dynamic_gtype_list, (void*)gtype_name, (void*)cinfo);
327
+ return Qnil;
328
+ }
329
+
330
+ void
331
+ rbgobj_register_class(VALUE klass,
332
+ GType gtype,
333
+ gboolean klass2gtype,
334
+ gboolean gtype2klass)
335
+ {
336
+ RGObjClassInfo* cinfo = NULL;
337
+ VALUE c = Qnil;
338
+
339
+ if (klass2gtype)
340
+ c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
341
+ if (gtype2klass && !cinfo)
342
+ cinfo = g_new(RGObjClassInfo, 1);
343
+
344
+ if (cinfo) {
345
+ cinfo->klass = klass;
346
+ cinfo->gtype = gtype;
347
+ cinfo->mark = NULL;
348
+ cinfo->free = NULL;
349
+ cinfo->flags = 0;
350
+ }
351
+
352
+ if (klass2gtype)
353
+ rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
354
+
355
+ if (gtype2klass)
356
+ g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
357
+ }
358
+
359
+ #define _register_fundamental_klass_to_gtype(klass, gtype) \
360
+ rbgobj_register_class(klass, gtype, TRUE, FALSE)
361
+
362
+ #define _register_fundamental_gtype_to_klass(gtype,klass) \
363
+ rbgobj_register_class(klass, gtype, FALSE, TRUE)
364
+
365
+ static void
366
+ Init_typemap()
367
+ {
368
+ id_new = rb_intern("new");
369
+ id_superclass = rb_intern("superclass");
370
+
371
+ gtype_to_cinfo = g_hash_table_new(g_direct_hash, g_direct_equal);
372
+ rb_global_variable(&klass_to_cinfo);
373
+ klass_to_cinfo = rb_hash_new();
374
+
375
+ _register_fundamental_klass_to_gtype(rb_cFixnum, G_TYPE_LONG);
376
+ _register_fundamental_klass_to_gtype(rb_cFloat, G_TYPE_DOUBLE);
377
+ _register_fundamental_klass_to_gtype(rb_cInteger, G_TYPE_LONG);
378
+ _register_fundamental_klass_to_gtype(rb_cString, G_TYPE_STRING);
379
+ _register_fundamental_klass_to_gtype(rb_cSymbol, G_TYPE_STRING);
380
+ _register_fundamental_klass_to_gtype(Qnil, G_TYPE_NONE);
381
+ _register_fundamental_klass_to_gtype(rb_cNilClass, G_TYPE_NONE);
382
+ _register_fundamental_klass_to_gtype(rb_cTrueClass, G_TYPE_BOOLEAN);
383
+ _register_fundamental_klass_to_gtype(rb_cFalseClass, G_TYPE_BOOLEAN);
384
+ _register_fundamental_klass_to_gtype(Qtrue, G_TYPE_BOOLEAN);
385
+ _register_fundamental_klass_to_gtype(Qfalse, G_TYPE_BOOLEAN);
386
+ _register_fundamental_klass_to_gtype(rb_cObject, RBGOBJ_TYPE_RUBY_VALUE);
387
+
388
+ _register_fundamental_gtype_to_klass(G_TYPE_UINT, rb_cInteger);
389
+ _register_fundamental_gtype_to_klass(G_TYPE_FLOAT, rb_cFloat);
390
+ _register_fundamental_gtype_to_klass(G_TYPE_DOUBLE, rb_cFloat);
391
+ _register_fundamental_gtype_to_klass(G_TYPE_INT64, rb_cInteger);
392
+ _register_fundamental_gtype_to_klass(G_TYPE_UINT64, rb_cInteger);
393
+ _register_fundamental_gtype_to_klass(G_TYPE_INT, rb_cInteger);
394
+ _register_fundamental_gtype_to_klass(G_TYPE_LONG, rb_cInteger);
395
+ _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cFixnum);
396
+ _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cFixnum);
397
+ _register_fundamental_gtype_to_klass(G_TYPE_STRING, rb_cString);
398
+ _register_fundamental_gtype_to_klass(G_TYPE_ULONG, rb_cInteger);
399
+ _register_fundamental_gtype_to_klass(G_TYPE_NONE, rb_cNilClass);
400
+ _register_fundamental_gtype_to_klass(G_TYPE_BOOLEAN, rb_cTrueClass);
401
+ }
402
+
403
+ /**********************************************************************/
404
+ /* GLib::Type */
405
+
406
+ VALUE rbgobj_cType;
407
+ static ID id_gtype;
408
+
409
+ VALUE
410
+ rbgobj_gtype_new(gtype)
411
+ GType gtype;
412
+ {
413
+ VALUE result = rb_obj_alloc(rbgobj_cType);
414
+ VALUE arg = UINT2NUM(gtype);
415
+ rb_obj_call_init(result, 1, &arg);
416
+ return result;
417
+ }
418
+
419
+ GType
420
+ rbgobj_gtype_get(self)
421
+ VALUE self;
422
+ {
423
+ if (RVAL2CBOOL(rb_obj_is_kind_of(self, rbgobj_cType))) {
424
+ return NUM2ULONG(rb_ivar_get(self, id_gtype));
425
+ } else {
426
+ return CLASS2GTYPE(self);
427
+ }
428
+ rb_raise(rb_eTypeError, "Not a GLib::Type");
429
+ }
430
+
431
+ static VALUE
432
+ type_initialize(self, type)
433
+ VALUE self, type;
434
+ {
435
+ GType gtype;
436
+
437
+ if (RVAL2CBOOL(rb_obj_is_kind_of(type, rb_cInteger))) {
438
+ gtype = NUM2UINT(type);
439
+ // XXX
440
+ if (!g_type_name(gtype))
441
+ gtype = G_TYPE_INVALID;
442
+ } else {
443
+ gtype = g_type_from_name(StringValuePtr(type));
444
+ }
445
+
446
+ if (G_TYPE_INVALID == gtype)
447
+ rb_raise(rb_eArgError, "invalid type");
448
+
449
+ rb_ivar_set(self, id_gtype, UINT2NUM(gtype));
450
+
451
+ return Qnil;
452
+ }
453
+
454
+ static VALUE
455
+ type_inspect(self)
456
+ VALUE self;
457
+ {
458
+ GType gtype = rbgobj_gtype_get(self);
459
+ gchar* str;
460
+ VALUE result;
461
+
462
+ str = g_strdup_printf("GLib::Type[\"%s\"]", g_type_name(gtype));
463
+ result = rb_str_new2(str);
464
+ g_free(str);
465
+
466
+ return result;
467
+ }
468
+
469
+ static VALUE
470
+ type_compare(self, other)
471
+ VALUE self, other;
472
+ {
473
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
474
+ return Qnil;
475
+ else {
476
+ GType a = rbgobj_gtype_get(self);
477
+ GType b = rbgobj_gtype_get(other);
478
+
479
+ if (a==b)
480
+ return INT2FIX(0);
481
+ else if (g_type_is_a(a,b))
482
+ return INT2FIX(-1);
483
+ else if (g_type_is_a(b,a))
484
+ return INT2FIX(1);
485
+ else
486
+ return Qnil;
487
+ }
488
+ }
489
+
490
+ static VALUE
491
+ type_eq(self, other)
492
+ VALUE self, other;
493
+ {
494
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
495
+ return Qnil;
496
+ else {
497
+ GType a = rbgobj_gtype_get(self);
498
+ GType b = rbgobj_gtype_get(other);
499
+ return CBOOL2RVAL(a == b);
500
+ }
501
+ }
502
+
503
+ static VALUE
504
+ type_lt_eq(self, other)
505
+ VALUE self, other;
506
+ {
507
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
508
+ return Qnil;
509
+ else {
510
+ GType a = rbgobj_gtype_get(self);
511
+ GType b = rbgobj_gtype_get(other);
512
+ return CBOOL2RVAL(g_type_is_a(a, b));
513
+ }
514
+ }
515
+
516
+ static VALUE
517
+ type_gt_eq(self, other)
518
+ VALUE self, other;
519
+ {
520
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
521
+ return Qnil;
522
+ else {
523
+ GType a = rbgobj_gtype_get(self);
524
+ GType b = rbgobj_gtype_get(other);
525
+ return CBOOL2RVAL(g_type_is_a(b, a));
526
+ }
527
+ }
528
+
529
+ static VALUE
530
+ type_lt(self, other)
531
+ VALUE self, other;
532
+ {
533
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
534
+ return Qnil;
535
+ else {
536
+ GType a = rbgobj_gtype_get(self);
537
+ GType b = rbgobj_gtype_get(other);
538
+ return CBOOL2RVAL(g_type_is_a(a, b) && a != b);
539
+ }
540
+ }
541
+
542
+ static VALUE
543
+ type_gt(self, other)
544
+ VALUE self, other;
545
+ {
546
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
547
+ return Qnil;
548
+ else {
549
+ GType a = rbgobj_gtype_get(self);
550
+ GType b = rbgobj_gtype_get(other);
551
+ return CBOOL2RVAL(g_type_is_a(b, a) && a != b);
552
+ }
553
+ }
554
+
555
+ static VALUE
556
+ type_to_int(self)
557
+ VALUE self;
558
+ {
559
+ return rb_ivar_get(self, id_gtype);
560
+ }
561
+
562
+ static VALUE
563
+ type_to_class(self)
564
+ VALUE self;
565
+ {
566
+ return GTYPE2CLASS(rbgobj_gtype_get(self));
567
+ }
568
+
569
+ static VALUE
570
+ type_fundamental(self)
571
+ VALUE self;
572
+ {
573
+ return rbgobj_gtype_new(G_TYPE_FUNDAMENTAL(rbgobj_gtype_get(self)));
574
+ }
575
+
576
+ static VALUE
577
+ type_is_fundamental(self)
578
+ VALUE self;
579
+ {
580
+ return CBOOL2RVAL(G_TYPE_IS_FUNDAMENTAL(rbgobj_gtype_get(self)));
581
+ }
582
+
583
+ static VALUE
584
+ type_is_derived(self)
585
+ VALUE self;
586
+ {
587
+ return CBOOL2RVAL(G_TYPE_IS_DERIVED(rbgobj_gtype_get(self)));
588
+ }
589
+
590
+ static VALUE
591
+ type_is_interface(self)
592
+ VALUE self;
593
+ {
594
+ return CBOOL2RVAL(G_TYPE_IS_INTERFACE(rbgobj_gtype_get(self)));
595
+ }
596
+
597
+ static VALUE
598
+ type_is_classed(self)
599
+ VALUE self;
600
+ {
601
+ return CBOOL2RVAL(G_TYPE_IS_CLASSED(rbgobj_gtype_get(self)));
602
+ }
603
+
604
+ static VALUE
605
+ type_is_instantiatable(self)
606
+ VALUE self;
607
+ {
608
+ return CBOOL2RVAL(G_TYPE_IS_INSTANTIATABLE(rbgobj_gtype_get(self)));
609
+ }
610
+
611
+ static VALUE
612
+ type_is_derivable(self)
613
+ VALUE self;
614
+ {
615
+ return CBOOL2RVAL(G_TYPE_IS_DERIVABLE(rbgobj_gtype_get(self)));
616
+ }
617
+
618
+ static VALUE
619
+ type_is_deep_derivable(self)
620
+ VALUE self;
621
+ {
622
+ return CBOOL2RVAL(G_TYPE_IS_DEEP_DERIVABLE(rbgobj_gtype_get(self)));
623
+ }
624
+
625
+ static VALUE
626
+ type_is_abstract(self)
627
+ VALUE self;
628
+ {
629
+ return CBOOL2RVAL(G_TYPE_IS_ABSTRACT(rbgobj_gtype_get(self)));
630
+ }
631
+
632
+ static VALUE
633
+ type_is_value_abstract(self)
634
+ VALUE self;
635
+ {
636
+ return CBOOL2RVAL(G_TYPE_IS_VALUE_ABSTRACT(rbgobj_gtype_get(self)));
637
+ }
638
+
639
+ static VALUE
640
+ type_is_value_type(self)
641
+ VALUE self;
642
+ {
643
+ return CBOOL2RVAL(G_TYPE_IS_VALUE_TYPE(rbgobj_gtype_get(self)));
644
+ }
645
+
646
+ static VALUE
647
+ type_has_value_table(self)
648
+ VALUE self;
649
+ {
650
+ return CBOOL2RVAL(G_TYPE_HAS_VALUE_TABLE(rbgobj_gtype_get(self)));
651
+ }
652
+
653
+ static VALUE
654
+ type_name(self)
655
+ VALUE self;
656
+ {
657
+ return rb_str_new2(g_type_name(rbgobj_gtype_get(self)));
658
+ }
659
+
660
+ static VALUE
661
+ type_parent(self)
662
+ VALUE self;
663
+ {
664
+ GType parent = g_type_parent(rbgobj_gtype_get(self));
665
+ return parent ? rbgobj_gtype_new(parent) : Qnil;
666
+ }
667
+
668
+ static VALUE
669
+ type_depth(self)
670
+ VALUE self;
671
+ {
672
+ return UINT2NUM(g_type_depth(rbgobj_gtype_get(self)));
673
+ }
674
+
675
+ static VALUE
676
+ type_next_base(leaf_type, root_type)
677
+ VALUE leaf_type, root_type;
678
+ {
679
+ GType ret = g_type_next_base(rbgobj_gtype_get(leaf_type),
680
+ rbgobj_gtype_get(root_type));
681
+ return ret ? rbgobj_gtype_new(ret) : Qnil;
682
+ }
683
+
684
+ static VALUE
685
+ type_is_a(self, is_a_type)
686
+ VALUE self, is_a_type;
687
+ {
688
+ return CBOOL2RVAL(g_type_is_a(rbgobj_gtype_get(self), rbgobj_gtype_get(is_a_type)));
689
+ }
690
+
691
+ #if 0
692
+ gpointer g_type_class_ref (GType type);
693
+ gpointer g_type_class_peek (GType type);
694
+ void g_type_class_unref (gpointer g_class);
695
+ gpointer g_type_class_peek_parent (gpointer g_class);
696
+ gpointer g_type_interface_peek (gpointer instance_class,
697
+ GType iface_type);
698
+ gpointer g_type_interface_peek_parent (gpointer g_iface);
699
+ #endif
700
+
701
+ static VALUE
702
+ type_children(self)
703
+ VALUE self;
704
+ {
705
+ guint n_children;
706
+ GType* types;
707
+ VALUE result;
708
+ int i;
709
+
710
+ types = g_type_children(rbgobj_gtype_get(self), &n_children);
711
+ result = rb_ary_new2(n_children);
712
+ for (i = 0; i < n_children; i++)
713
+ rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
714
+ g_free(types);
715
+
716
+ return result;
717
+ }
718
+
719
+ static VALUE
720
+ type_interfaces(self)
721
+ VALUE self;
722
+ {
723
+ guint n_interfaces;
724
+ GType* types;
725
+ VALUE result;
726
+ int i;
727
+
728
+ types = g_type_interfaces(rbgobj_gtype_get(self), &n_interfaces);
729
+ result = rb_ary_new2(n_interfaces);
730
+ for (i = 0; i < n_interfaces; i++)
731
+ rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
732
+ g_free(types);
733
+
734
+ return result;
735
+ }
736
+
737
+ static VALUE
738
+ type_class_size(self)
739
+ VALUE self;
740
+ {
741
+ GTypeQuery query;
742
+ g_type_query(rbgobj_gtype_get(self), &query);
743
+ return UINT2NUM(query.class_size);
744
+ }
745
+
746
+ static VALUE
747
+ type_instance_size(self)
748
+ VALUE self;
749
+ {
750
+ GTypeQuery query;
751
+ g_type_query(rbgobj_gtype_get(self), &query);
752
+ return UINT2NUM(query.instance_size);
753
+ }
754
+
755
+
756
+ static inline
757
+ void _def_fundamental_type(VALUE ary, GType gtype, const char* name)
758
+ {
759
+ VALUE c = rbgobj_gtype_new(gtype);
760
+ rb_define_const(rbgobj_cType, name, c);
761
+ rb_ary_push(ary, c);
762
+ }
763
+
764
+ static void
765
+ Init_type()
766
+ {
767
+ rb_cMutex = rb_const_get(rb_cObject, rb_intern("Mutex"));
768
+ id_lock = rb_intern("lock");
769
+ id_unlock = rb_intern("unlock");
770
+ lookup_class_mutex = rb_funcall(rb_cMutex, id_new, 0);
771
+ rb_iv_set(mGLib, "lookup_class_mutex", lookup_class_mutex);
772
+
773
+ dynamic_gtype_list = g_hash_table_new(g_str_hash, g_str_equal);
774
+ id_gtype = rb_intern("__gobject_gtype__");
775
+
776
+ rbgobj_cType = rb_define_class_under(mGLib, "Type", rb_cObject);
777
+
778
+ rb_define_alias(CLASS_OF(rbgobj_cType), "[]", "new");
779
+ rb_define_method(rbgobj_cType, "initialize", type_initialize, 1);
780
+ rb_define_method(rbgobj_cType, "inspect", type_inspect, 0);
781
+ rb_define_method(rbgobj_cType, "<=>", type_compare, 1);
782
+ rb_define_method(rbgobj_cType, "==", type_eq, 1);
783
+ rb_define_method(rbgobj_cType, "<=", type_lt_eq, 1);
784
+ rb_define_method(rbgobj_cType, ">=", type_gt_eq, 1);
785
+ rb_define_method(rbgobj_cType, "<", type_lt, 1);
786
+ rb_define_method(rbgobj_cType, ">", type_gt, 1);
787
+ rb_define_method(rbgobj_cType, "eql?", type_eq, 1);
788
+ rb_define_method(rbgobj_cType, "hash", type_to_int, 0);
789
+ rb_define_method(rbgobj_cType, "to_i", type_to_int, 0);
790
+ rb_define_method(rbgobj_cType, "to_int", type_to_int, 0);
791
+ rb_define_method(rbgobj_cType, "to_class", type_to_class, 0);
792
+
793
+ rb_define_method(rbgobj_cType, "fundamental", type_fundamental, 0);
794
+ rb_define_method(rbgobj_cType, "fundamental?", type_is_fundamental, 0);
795
+ rb_define_method(rbgobj_cType, "derived?", type_is_derived, 0);
796
+ rb_define_method(rbgobj_cType, "interface?", type_is_interface, 0);
797
+ rb_define_method(rbgobj_cType, "classed?", type_is_classed, 0);
798
+ rb_define_method(rbgobj_cType, "instantiatable?", type_is_instantiatable, 0);
799
+ rb_define_method(rbgobj_cType, "derivable?", type_is_derivable, 0);
800
+ rb_define_method(rbgobj_cType, "deep_derivable?", type_is_deep_derivable, 0);
801
+ rb_define_method(rbgobj_cType, "abstract?", type_is_abstract, 0);
802
+ rb_define_method(rbgobj_cType, "value_abstract?", type_is_value_abstract, 0);
803
+ rb_define_method(rbgobj_cType, "value_type?", type_is_value_type, 0);
804
+ rb_define_method(rbgobj_cType, "has_value_table", type_has_value_table, 0);
805
+
806
+ rb_define_method(rbgobj_cType, "name", type_name, 0);
807
+ rb_define_method(rbgobj_cType, "to_s", type_name, 0);
808
+ rb_define_method(rbgobj_cType, "parent", type_parent, 0);
809
+ rb_define_method(rbgobj_cType, "depth", type_depth, 0);
810
+ rb_define_method(rbgobj_cType, "next_base", type_next_base, 1);
811
+ rb_define_method(rbgobj_cType, "type_is_a?", type_is_a, 1);
812
+ rb_define_method(rbgobj_cType, "children", type_children, 0);
813
+ rb_define_method(rbgobj_cType, "interfaces", type_interfaces, 0);
814
+ rb_define_method(rbgobj_cType, "class_size", type_class_size, 0);
815
+ rb_define_method(rbgobj_cType, "instance_size", type_instance_size, 0);
816
+
817
+ {
818
+ VALUE ary = rb_ary_new();
819
+ rb_define_const(rbgobj_cType, "FUNDAMENTAL_MAX", INT2FIX(G_TYPE_FUNDAMENTAL_MAX));
820
+ _def_fundamental_type(ary, G_TYPE_NONE, "NONE");
821
+ _def_fundamental_type(ary, G_TYPE_INTERFACE, "INTERFACE");
822
+ _def_fundamental_type(ary, G_TYPE_CHAR, "CHAR");
823
+ _def_fundamental_type(ary, G_TYPE_UCHAR, "UCHAR");
824
+ _def_fundamental_type(ary, G_TYPE_BOOLEAN, "BOOLEAN");
825
+ _def_fundamental_type(ary, G_TYPE_INT, "INT");
826
+ _def_fundamental_type(ary, G_TYPE_UINT, "UINT");
827
+ _def_fundamental_type(ary, G_TYPE_LONG, "LONG");
828
+ _def_fundamental_type(ary, G_TYPE_ULONG, "ULONG");
829
+ _def_fundamental_type(ary, G_TYPE_INT64, "INT64");
830
+ _def_fundamental_type(ary, G_TYPE_UINT64, "UINT64");
831
+ _def_fundamental_type(ary, G_TYPE_ENUM, "ENUM");
832
+ _def_fundamental_type(ary, G_TYPE_FLAGS, "FLAGS");
833
+ _def_fundamental_type(ary, G_TYPE_FLOAT, "FLOAT");
834
+ _def_fundamental_type(ary, G_TYPE_DOUBLE, "DOUBLE");
835
+ _def_fundamental_type(ary, G_TYPE_STRING, "STRING");
836
+ _def_fundamental_type(ary, G_TYPE_POINTER, "POINTER");
837
+ _def_fundamental_type(ary, G_TYPE_BOXED, "BOXED");
838
+ _def_fundamental_type(ary, G_TYPE_PARAM, "PARAM");
839
+ _def_fundamental_type(ary, G_TYPE_OBJECT, "OBJECT");
840
+ rb_define_const(rbgobj_cType, "FUNDAMENTAL_TYPES", ary); /* FIXME: better name */
841
+ }
842
+ }
843
+
844
+ /**********************************************************************/
845
+
846
+ void Init_gobject_gtype()
847
+ {
848
+ g_type_init();
849
+ Init_typemap();
850
+ Init_type();
851
+ }