glib2 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/glib2/extconf.rb +1 -0
- data/ext/glib2/glib2.def +23 -0
- data/ext/glib2/rbgcompat.h +19 -5
- data/ext/glib2/rbglib.c +607 -160
- data/ext/glib2/rbglib.h +81 -26
- data/ext/glib2/rbglib2conversions.h +57 -0
- data/ext/glib2/rbglib_bookmarkfile.c +117 -107
- data/ext/glib2/rbglib_completion.c +37 -26
- data/ext/glib2/rbglib_convert.c +42 -30
- data/ext/glib2/rbglib_error.c +20 -10
- data/ext/glib2/rbglib_fileutils.c +48 -37
- data/ext/glib2/rbglib_i18n.c +24 -14
- data/ext/glib2/rbglib_int64.c +24 -16
- data/ext/glib2/rbglib_iochannel.c +146 -204
- data/ext/glib2/rbglib_iochannel_win32_socket.c +56 -0
- data/ext/glib2/rbglib_iochannelerror.c +49 -0
- data/ext/glib2/rbglib_keyfile.c +171 -182
- data/ext/glib2/rbglib_maincontext.c +107 -92
- data/ext/glib2/rbglib_mainloop.c +34 -21
- data/ext/glib2/rbglib_messages.c +53 -44
- data/ext/glib2/rbglib_pollfd.c +37 -26
- data/ext/glib2/rbglib_shell.c +29 -22
- data/ext/glib2/rbglib_shellerror.c +34 -0
- data/ext/glib2/rbglib_source.c +49 -36
- data/ext/glib2/rbglib_spawn.c +50 -61
- data/ext/glib2/rbglib_spawnerror.c +53 -0
- data/ext/glib2/rbglib_threads.c +28 -16
- data/ext/glib2/rbglib_timer.c +35 -24
- data/ext/glib2/rbglib_ucs4.c +79 -0
- data/ext/glib2/rbglib_unichar.c +209 -0
- data/ext/glib2/rbglib_unicode.c +34 -584
- data/ext/glib2/rbglib_utf16.c +78 -0
- data/ext/glib2/rbglib_utf8.c +259 -0
- data/ext/glib2/rbglib_utils.c +95 -91
- data/ext/glib2/rbglib_win32.c +52 -45
- data/ext/glib2/rbglibdeprecated.c +56 -0
- data/ext/glib2/rbglibdeprecated.h +34 -0
- data/ext/glib2/rbgobj_boxed.c +40 -33
- data/ext/glib2/rbgobj_closure.c +45 -34
- data/ext/glib2/rbgobj_convert.c +19 -9
- data/ext/glib2/rbgobj_enumflags.c +109 -0
- data/ext/glib2/rbgobj_enums.c +67 -646
- data/ext/glib2/rbgobj_flags.c +522 -0
- data/ext/glib2/rbgobj_fundamental.c +19 -6
- data/ext/glib2/rbgobj_object.c +90 -81
- data/ext/glib2/rbgobj_param.c +78 -83
- data/ext/glib2/rbgobj_paramspecs.c +20 -12
- data/ext/glib2/rbgobj_signal.c +248 -193
- data/ext/glib2/rbgobj_strv.c +20 -10
- data/ext/glib2/rbgobj_type.c +153 -149
- data/ext/glib2/rbgobj_typeinstance.c +49 -39
- data/ext/glib2/rbgobj_typeinterface.c +37 -27
- data/ext/glib2/rbgobj_typemodule.c +39 -29
- data/ext/glib2/rbgobj_typeplugin.c +36 -26
- data/ext/glib2/rbgobj_value.c +41 -11
- data/ext/glib2/rbgobj_valuearray.c +59 -23
- data/ext/glib2/rbgobj_valuetypes.c +27 -17
- data/ext/glib2/rbgobject.c +26 -40
- data/ext/glib2/rbgobject.h +38 -20
- data/ext/glib2/rbgprivate.h +87 -5
- data/ext/glib2/rbgutil.c +52 -238
- data/ext/glib2/rbgutil.h +55 -42
- data/ext/glib2/rbgutil_callback.c +47 -12
- data/ext/glib2/rbgutil_list.c +173 -0
- data/ext/glib2/rbgutil_list.h +85 -0
- data/ext/glib2/rbgutildeprecated.c +252 -0
- data/ext/glib2/rbgutildeprecated.h +63 -0
- data/lib/glib-mkenums.rb +2 -2
- data/lib/glib2.rb +2 -25
- data/lib/glib2/deprecatable.rb +149 -0
- data/lib/gnome2-raketask.rb +45 -15
- data/lib/gnome2-win32-binary-downloader.rb +1 -1
- data/lib/mkmf-gnome2.rb +37 -18
- data/test/test_flags.rb +129 -0
- data/test/test_key_file.rb +6 -2
- data/test/test_spawn.rb +33 -0
- metadata +26 -7
- data/ChangeLog +0 -3513
@@ -0,0 +1,522 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright (C) 2011 Ruby-GNOME2 Project Team
|
4
|
+
* Copyright (C) 2004-2006 Ruby-GNOME2 Project Team
|
5
|
+
* Copyright (C) 2002,2003 Masahiro Sakai
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20
|
+
* MA 02110-1301 USA
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include "rbgprivate.h"
|
24
|
+
#include <ctype.h>
|
25
|
+
|
26
|
+
#define RG_TARGET_NAMESPACE rbgobj_cFlags
|
27
|
+
|
28
|
+
VALUE RG_TARGET_NAMESPACE;
|
29
|
+
|
30
|
+
static ID id_new;
|
31
|
+
static ID id_module_eval;
|
32
|
+
static ID id_or;
|
33
|
+
|
34
|
+
/**********************************************************************/
|
35
|
+
|
36
|
+
static VALUE
|
37
|
+
resolve_flags_value(VALUE klass, VALUE nick_or_nicks)
|
38
|
+
{
|
39
|
+
int i, len;
|
40
|
+
VALUE flags_value;
|
41
|
+
|
42
|
+
if (!RVAL2CBOOL(rb_obj_is_kind_of(nick_or_nicks, rb_cArray)))
|
43
|
+
return rg_enum_resolve_value(klass, nick_or_nicks);
|
44
|
+
|
45
|
+
len = RARRAY_LEN(nick_or_nicks);
|
46
|
+
flags_value = rb_funcall(klass, id_new, 0);
|
47
|
+
for (i = 0; i < len; i++) {
|
48
|
+
VALUE value;
|
49
|
+
|
50
|
+
value = rg_enum_resolve_value(klass, RARRAY_PTR(nick_or_nicks)[i]);
|
51
|
+
if (NIL_P(value))
|
52
|
+
return Qnil;
|
53
|
+
|
54
|
+
flags_value = rb_funcall(flags_value, id_or, 1, value);
|
55
|
+
}
|
56
|
+
|
57
|
+
return flags_value;
|
58
|
+
}
|
59
|
+
|
60
|
+
void
|
61
|
+
rg_flags_add_constants(VALUE mod, GType flags_type, const gchar *strip_prefix)
|
62
|
+
{
|
63
|
+
GFlagsClass *gclass;
|
64
|
+
guint i;
|
65
|
+
int prefix_len = strlen(strip_prefix);
|
66
|
+
|
67
|
+
gclass = G_FLAGS_CLASS(g_type_class_ref(flags_type));
|
68
|
+
|
69
|
+
for (i = 0; i < gclass->n_values; i++) {
|
70
|
+
const GFlagsValue* value = &gclass->values[i];
|
71
|
+
|
72
|
+
if (strncmp(value->value_name, strip_prefix, prefix_len)) {
|
73
|
+
g_warning("\"%s\" doesn't have prefix \"%s\"",
|
74
|
+
value->value_name, strip_prefix);
|
75
|
+
} else {
|
76
|
+
const char* name = value->value_name + prefix_len;
|
77
|
+
rbgobj_define_const(mod, name,
|
78
|
+
rbgobj_make_flags(value->value, flags_type));
|
79
|
+
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
g_type_class_unref(gclass);
|
84
|
+
}
|
85
|
+
|
86
|
+
/**********************************************************************/
|
87
|
+
|
88
|
+
typedef struct {
|
89
|
+
GFlagsClass* gclass;
|
90
|
+
guint value;
|
91
|
+
GFlagsValue* info;
|
92
|
+
} flags_holder;
|
93
|
+
|
94
|
+
static void
|
95
|
+
flags_free(flags_holder* p)
|
96
|
+
{
|
97
|
+
g_type_class_unref(p->gclass);
|
98
|
+
free(p);
|
99
|
+
}
|
100
|
+
|
101
|
+
static flags_holder*
|
102
|
+
flags_get_holder(VALUE obj)
|
103
|
+
{
|
104
|
+
flags_holder* p;
|
105
|
+
Data_Get_Struct(obj, flags_holder, p);
|
106
|
+
return p;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE
|
110
|
+
make_flags(guint n, VALUE klass)
|
111
|
+
{
|
112
|
+
return rb_funcall(klass, id_new, 1, UINT2NUM(n));
|
113
|
+
}
|
114
|
+
|
115
|
+
VALUE
|
116
|
+
rbgobj_make_flags(guint n, GType gtype)
|
117
|
+
{
|
118
|
+
return make_flags(n, GTYPE2CLASS(gtype));
|
119
|
+
}
|
120
|
+
|
121
|
+
guint
|
122
|
+
rbgobj_get_flags(VALUE obj, GType gtype)
|
123
|
+
{
|
124
|
+
VALUE klass;
|
125
|
+
|
126
|
+
if (!g_type_is_a(gtype, G_TYPE_FLAGS))
|
127
|
+
rb_raise(rb_eTypeError, "%s is not a %s",
|
128
|
+
g_type_name(gtype), g_type_name(G_TYPE_FLAGS));
|
129
|
+
|
130
|
+
/* for compatibility */
|
131
|
+
if (rb_obj_is_kind_of(obj, rb_cInteger))
|
132
|
+
obj = rbgobj_make_flags(NUM2UINT(obj), gtype);
|
133
|
+
|
134
|
+
klass = GTYPE2CLASS(gtype);
|
135
|
+
|
136
|
+
if (!rb_obj_is_kind_of(obj, klass)) {
|
137
|
+
VALUE flags_value = Qnil;
|
138
|
+
|
139
|
+
flags_value = resolve_flags_value(klass, obj);
|
140
|
+
if (!NIL_P(flags_value))
|
141
|
+
obj = flags_value;
|
142
|
+
}
|
143
|
+
|
144
|
+
if (rb_obj_is_kind_of(obj, klass))
|
145
|
+
return flags_get_holder(obj)->value;
|
146
|
+
else
|
147
|
+
rb_raise(rb_eTypeError, "not a %s: %s",
|
148
|
+
rb_class2name(klass), RBG_INSPECT(obj));
|
149
|
+
}
|
150
|
+
|
151
|
+
/**********************************************************************/
|
152
|
+
|
153
|
+
void
|
154
|
+
rbgobj_init_flags_class(VALUE klass)
|
155
|
+
{
|
156
|
+
GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
157
|
+
GString* source = g_string_new(NULL);
|
158
|
+
guint i;
|
159
|
+
|
160
|
+
for (i = 0; i < gclass->n_values; i++) {
|
161
|
+
GFlagsValue* entry = &(gclass->values[i]);
|
162
|
+
gchar* nick;
|
163
|
+
gchar* p;
|
164
|
+
gchar* replace_nick;
|
165
|
+
|
166
|
+
replace_nick = rg_obj_constant_lookup(entry->value_nick);
|
167
|
+
if (replace_nick){
|
168
|
+
nick = g_strdup(replace_nick);
|
169
|
+
} else {
|
170
|
+
nick = g_strdup(entry->value_nick);
|
171
|
+
}
|
172
|
+
|
173
|
+
for (p = nick; *p; p++)
|
174
|
+
if (*p == '-' || *p == ' ')
|
175
|
+
*p = '_';
|
176
|
+
else
|
177
|
+
*p = tolower(*p);
|
178
|
+
|
179
|
+
g_string_append_printf(
|
180
|
+
source,
|
181
|
+
"def %s%s?; self >= self.class.new(%d); end\n",
|
182
|
+
g_ascii_isdigit(nick[0]) ? "_" : "",
|
183
|
+
nick, entry->value);
|
184
|
+
|
185
|
+
for (p = nick; *p; p++)
|
186
|
+
*p = g_ascii_toupper(*p);
|
187
|
+
|
188
|
+
#if 0
|
189
|
+
{
|
190
|
+
ID id = rb_intern(nick);
|
191
|
+
if (rb_is_const_id(id)) {
|
192
|
+
rb_define_const(klass, nick, make_flags(entry->value, klass));
|
193
|
+
}
|
194
|
+
}
|
195
|
+
#else
|
196
|
+
{
|
197
|
+
rbgobj_define_const(klass, nick, make_flags(entry->value, klass));
|
198
|
+
}
|
199
|
+
#endif
|
200
|
+
|
201
|
+
g_free(nick);
|
202
|
+
}
|
203
|
+
|
204
|
+
rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str));
|
205
|
+
g_string_free(source, TRUE);
|
206
|
+
|
207
|
+
g_type_class_unref(gclass);
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE
|
211
|
+
rg_s_mask(VALUE klass)
|
212
|
+
{
|
213
|
+
GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
214
|
+
VALUE result = UINT2NUM(gclass->mask);
|
215
|
+
g_type_class_unref(gclass);
|
216
|
+
return result;
|
217
|
+
}
|
218
|
+
|
219
|
+
static VALUE
|
220
|
+
rg_s_values(VALUE klass)
|
221
|
+
{
|
222
|
+
GFlagsClass *gclass;
|
223
|
+
VALUE result;
|
224
|
+
guint i;
|
225
|
+
|
226
|
+
gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
227
|
+
result = rb_ary_new();
|
228
|
+
for (i = 0; i < gclass->n_values; i++) {
|
229
|
+
GFlagsValue *p = &(gclass->values[i]);
|
230
|
+
rb_ary_push(result, make_flags(p->value, klass));
|
231
|
+
}
|
232
|
+
g_type_class_unref(gclass);
|
233
|
+
|
234
|
+
return result;
|
235
|
+
}
|
236
|
+
|
237
|
+
static VALUE
|
238
|
+
flags_s_allocate(VALUE self)
|
239
|
+
{
|
240
|
+
GType gtype = CLASS2GTYPE(self);
|
241
|
+
|
242
|
+
if (G_TYPE_IS_ABSTRACT(gtype)) {
|
243
|
+
rb_raise(rb_eTypeError, "abstract class");
|
244
|
+
} else {
|
245
|
+
flags_holder* p;
|
246
|
+
VALUE result = Data_Make_Struct(self, flags_holder, NULL, flags_free, p);
|
247
|
+
p->gclass = g_type_class_ref(gtype);
|
248
|
+
p->value = 0;
|
249
|
+
p->info = NULL;
|
250
|
+
return result;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE
|
255
|
+
rg_initialize(int argc, VALUE* argv, VALUE self)
|
256
|
+
{
|
257
|
+
flags_holder* p = flags_get_holder(self);
|
258
|
+
VALUE arg;
|
259
|
+
|
260
|
+
rb_scan_args(argc, argv, "01", &arg);
|
261
|
+
|
262
|
+
if (argc == 0) {
|
263
|
+
p->value = 0;
|
264
|
+
} else {
|
265
|
+
if (rb_respond_to(arg, rb_intern("to_str"))) {
|
266
|
+
const char* str = StringValuePtr(arg);
|
267
|
+
p->info = g_flags_get_value_by_name(p->gclass, str);
|
268
|
+
if (!p->info)
|
269
|
+
p->info = g_flags_get_value_by_nick(p->gclass, str);
|
270
|
+
if (!p->info)
|
271
|
+
rb_raise(rb_eArgError, "invalid argument");
|
272
|
+
p->value = p->info->value;
|
273
|
+
} else {
|
274
|
+
p->value = NUM2UINT(arg);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
if (!p->info) {
|
279
|
+
guint i;
|
280
|
+
for (i = 0; i < p->gclass->n_values; i++){
|
281
|
+
GFlagsValue* val = &(p->gclass->values[i]);
|
282
|
+
if (val->value == p->value){
|
283
|
+
p->info = val;
|
284
|
+
break;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
return Qnil;
|
290
|
+
}
|
291
|
+
|
292
|
+
static VALUE
|
293
|
+
rg_to_i(VALUE self)
|
294
|
+
{
|
295
|
+
flags_holder* p = flags_get_holder(self);
|
296
|
+
return UINT2NUM(p->value);
|
297
|
+
}
|
298
|
+
|
299
|
+
static VALUE
|
300
|
+
rg_name(VALUE self)
|
301
|
+
{
|
302
|
+
flags_holder* p = flags_get_holder(self);
|
303
|
+
return p->info ? rb_str_new2(p->info->value_name) : Qnil;
|
304
|
+
}
|
305
|
+
|
306
|
+
static VALUE
|
307
|
+
rg_nick(VALUE self)
|
308
|
+
{
|
309
|
+
flags_holder* p = flags_get_holder(self);
|
310
|
+
return p->info ? rb_str_new2(p->info->value_nick) : Qnil;
|
311
|
+
}
|
312
|
+
|
313
|
+
#define FLAGS_COMP_EQUAL 0
|
314
|
+
#define FLAGS_COMP_GREATER 1
|
315
|
+
#define FLAGS_COMP_LESS -1
|
316
|
+
#define FLAGS_COMP_ELSE -2
|
317
|
+
#define FLAGS_COMP_INCOMPARABLE -3
|
318
|
+
|
319
|
+
static gint
|
320
|
+
flags_compare(VALUE self, VALUE rhs)
|
321
|
+
{
|
322
|
+
flags_holder* p = flags_get_holder(self);
|
323
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
324
|
+
VALUE klass = GTYPE2CLASS(gtype);
|
325
|
+
guint rhs_val;
|
326
|
+
|
327
|
+
if (!rb_obj_is_kind_of(rhs, rb_cInteger)) {
|
328
|
+
rhs = resolve_flags_value(klass, rhs);
|
329
|
+
if (CLASS_OF(rhs) != CLASS_OF(self))
|
330
|
+
return FLAGS_COMP_INCOMPARABLE;
|
331
|
+
}
|
332
|
+
|
333
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
334
|
+
|
335
|
+
if (p->value == rhs_val)
|
336
|
+
return FLAGS_COMP_EQUAL;
|
337
|
+
else if ((p->value & rhs_val) == rhs_val)
|
338
|
+
return FLAGS_COMP_GREATER;
|
339
|
+
else if ((p->value & rhs_val) == p->value)
|
340
|
+
return FLAGS_COMP_LESS;
|
341
|
+
else
|
342
|
+
return FLAGS_COMP_ELSE;
|
343
|
+
}
|
344
|
+
|
345
|
+
static VALUE
|
346
|
+
rg_operator_flags_compare(VALUE self, VALUE rhs)
|
347
|
+
{
|
348
|
+
gint ret = flags_compare(self, rhs);
|
349
|
+
switch (ret) {
|
350
|
+
case FLAGS_COMP_EQUAL:
|
351
|
+
case FLAGS_COMP_GREATER:
|
352
|
+
case FLAGS_COMP_LESS:
|
353
|
+
return INT2FIX(ret);
|
354
|
+
default:
|
355
|
+
return Qnil;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
|
359
|
+
static VALUE
|
360
|
+
rg_operator_flags_eqv(VALUE self, VALUE rhs)
|
361
|
+
{
|
362
|
+
gint ret = flags_compare(self, rhs);
|
363
|
+
if (ret == FLAGS_COMP_INCOMPARABLE)
|
364
|
+
return Qnil;
|
365
|
+
return CBOOL2RVAL(ret == FLAGS_COMP_EQUAL);
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE
|
369
|
+
rg_operator_flags_gt_eq(VALUE self, VALUE rhs)
|
370
|
+
{
|
371
|
+
gint ret = flags_compare(self, rhs);
|
372
|
+
if (ret == FLAGS_COMP_INCOMPARABLE)
|
373
|
+
return Qnil;
|
374
|
+
return CBOOL2RVAL(ret == FLAGS_COMP_GREATER || ret == FLAGS_COMP_EQUAL);
|
375
|
+
}
|
376
|
+
|
377
|
+
static VALUE
|
378
|
+
rg_operator_flags_lt_eq(VALUE self, VALUE rhs)
|
379
|
+
{
|
380
|
+
gint ret = flags_compare(self, rhs);
|
381
|
+
if (ret == FLAGS_COMP_INCOMPARABLE)
|
382
|
+
return Qnil;
|
383
|
+
return CBOOL2RVAL(ret == FLAGS_COMP_LESS || ret == FLAGS_COMP_EQUAL);
|
384
|
+
}
|
385
|
+
|
386
|
+
static VALUE
|
387
|
+
rg_operator_flags_gt(VALUE self, VALUE rhs)
|
388
|
+
{
|
389
|
+
gint ret = flags_compare(self, rhs);
|
390
|
+
if (ret == FLAGS_COMP_INCOMPARABLE)
|
391
|
+
return Qnil;
|
392
|
+
return CBOOL2RVAL(ret == FLAGS_COMP_GREATER);
|
393
|
+
}
|
394
|
+
|
395
|
+
static VALUE
|
396
|
+
rg_operator_flags_lt(VALUE self, VALUE rhs)
|
397
|
+
{
|
398
|
+
gint ret = flags_compare(self, rhs);
|
399
|
+
if (ret == FLAGS_COMP_INCOMPARABLE)
|
400
|
+
return Qnil;
|
401
|
+
return CBOOL2RVAL(ret == FLAGS_COMP_LESS);
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE
|
405
|
+
rg_operator_flags_not(VALUE self, G_GNUC_UNUSED VALUE rhs)
|
406
|
+
{
|
407
|
+
flags_holder* p = flags_get_holder(self);
|
408
|
+
return rbgobj_make_flags((~ p->value) & p->gclass->mask,
|
409
|
+
G_TYPE_FROM_CLASS(p->gclass));
|
410
|
+
}
|
411
|
+
|
412
|
+
#define LIFT_BINARY_OP(funcname, op) \
|
413
|
+
static VALUE \
|
414
|
+
funcname(VALUE self, VALUE rhs) \
|
415
|
+
{ \
|
416
|
+
flags_holder* p = flags_get_holder(self); \
|
417
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass); \
|
418
|
+
return rbgobj_make_flags(p->value op rbgobj_get_flags(rhs, gtype), \
|
419
|
+
gtype); \
|
420
|
+
}
|
421
|
+
|
422
|
+
LIFT_BINARY_OP(flags_and, &)
|
423
|
+
LIFT_BINARY_OP(flags_or, |)
|
424
|
+
LIFT_BINARY_OP(flags_xor, ^)
|
425
|
+
|
426
|
+
static VALUE
|
427
|
+
rg_operator_flags_minus(VALUE self, VALUE rhs)
|
428
|
+
{
|
429
|
+
flags_holder* p = flags_get_holder(self);
|
430
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
431
|
+
return rbgobj_make_flags(p->value & ~rbgobj_get_flags(rhs, gtype),
|
432
|
+
gtype);
|
433
|
+
}
|
434
|
+
|
435
|
+
static VALUE
|
436
|
+
rg_empty_p(VALUE self)
|
437
|
+
{
|
438
|
+
flags_holder* p = flags_get_holder(self);
|
439
|
+
return CBOOL2RVAL(p->value == 0);
|
440
|
+
}
|
441
|
+
|
442
|
+
static VALUE
|
443
|
+
rg_hash(VALUE self)
|
444
|
+
{
|
445
|
+
flags_holder* p = flags_get_holder(self);
|
446
|
+
return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass));
|
447
|
+
}
|
448
|
+
|
449
|
+
static VALUE
|
450
|
+
rg_coerce(VALUE self, VALUE other)
|
451
|
+
{
|
452
|
+
flags_holder *holder;
|
453
|
+
GType gtype;
|
454
|
+
|
455
|
+
if (rb_obj_is_kind_of(other, rb_cInteger))
|
456
|
+
rb_raise(rb_eTypeError, "can't coerce");
|
457
|
+
|
458
|
+
holder = flags_get_holder(self);
|
459
|
+
gtype = G_TYPE_FROM_CLASS(holder->gclass);
|
460
|
+
other = rbgobj_make_flags(NUM2UINT(other), gtype);
|
461
|
+
return rb_ary_new3(2, other, self);
|
462
|
+
}
|
463
|
+
|
464
|
+
static VALUE
|
465
|
+
rg_nonzero_p(VALUE self)
|
466
|
+
{
|
467
|
+
flags_holder* p = flags_get_holder(self);
|
468
|
+
return CBOOL2RVAL(p->value != 0);
|
469
|
+
}
|
470
|
+
|
471
|
+
/**********************************************************************/
|
472
|
+
|
473
|
+
void
|
474
|
+
Init_gobject_gflags(void)
|
475
|
+
{
|
476
|
+
id_module_eval = rb_intern("module_eval");
|
477
|
+
id_new = rb_intern("new");
|
478
|
+
id_or = rb_intern("|");
|
479
|
+
|
480
|
+
RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_FLAGS, "Flags", mGLib);
|
481
|
+
|
482
|
+
rb_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0);
|
483
|
+
rb_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0);
|
484
|
+
|
485
|
+
RG_DEF_SMETHOD(mask, 0);
|
486
|
+
RG_DEF_SMETHOD(values, 0);
|
487
|
+
|
488
|
+
rb_define_alloc_func(RG_TARGET_NAMESPACE, flags_s_allocate);
|
489
|
+
|
490
|
+
RG_DEF_METHOD(initialize, -1);
|
491
|
+
|
492
|
+
RG_DEF_METHOD(to_i, 0);
|
493
|
+
RG_DEF_ALIAS("to_int", "to_i");
|
494
|
+
RG_DEF_METHOD(name, 0);
|
495
|
+
RG_DEF_METHOD(nick, 0);
|
496
|
+
|
497
|
+
/*
|
498
|
+
rb_define_method(RG_TARGET_NAMESPACE, "inspect", flags_inspect, 0);
|
499
|
+
*/
|
500
|
+
|
501
|
+
RG_DEF_METHOD_OPERATOR("<=>", flags_compare, 1);
|
502
|
+
RG_DEF_METHOD_OPERATOR("==", flags_eqv, 1);
|
503
|
+
RG_DEF_METHOD_OPERATOR(">=", flags_gt_eq, 1);
|
504
|
+
RG_DEF_METHOD_OPERATOR("<=", flags_lt_eq, 1);
|
505
|
+
RG_DEF_METHOD_OPERATOR(">", flags_gt, 1);
|
506
|
+
RG_DEF_METHOD_OPERATOR("<", flags_lt, 1);
|
507
|
+
RG_DEF_METHOD_OPERATOR("~", flags_not, 0);
|
508
|
+
rb_define_method(RG_TARGET_NAMESPACE, "&", flags_and, 1);
|
509
|
+
rb_define_method(RG_TARGET_NAMESPACE, "|", flags_or, 1);
|
510
|
+
rb_define_method(RG_TARGET_NAMESPACE, "^", flags_xor, 1);
|
511
|
+
RG_DEF_METHOD_OPERATOR("-", flags_minus, 1);
|
512
|
+
|
513
|
+
RG_DEF_METHOD_P(empty, 0);
|
514
|
+
|
515
|
+
RG_DEF_METHOD(hash, 0);
|
516
|
+
RG_DEF_ALIAS("eql?", "==");
|
517
|
+
|
518
|
+
/* for compatibility */
|
519
|
+
RG_DEF_METHOD(coerce, 1);
|
520
|
+
RG_DEF_ALIAS("zero?", "empty?");
|
521
|
+
RG_DEF_METHOD_P(nonzero, 0);
|
522
|
+
}
|