glib2 0.20.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/ChangeLog +3023 -0
- data/README +28 -0
- data/Rakefile +87 -0
- data/extconf.rb +61 -0
- data/sample/bookmarkfile.rb +66 -0
- data/sample/completion.rb +45 -0
- data/sample/idle.rb +41 -0
- data/sample/iochannel.rb +44 -0
- data/sample/keyfile.rb +62 -0
- data/sample/shell.rb +36 -0
- data/sample/spawn.rb +25 -0
- data/sample/timeout.rb +28 -0
- data/sample/timeout2.rb +35 -0
- data/sample/timer.rb +40 -0
- data/sample/type-register.rb +103 -0
- data/sample/type-register2.rb +104 -0
- data/sample/utils.rb +54 -0
- data/src/glib-enum-types.c +1032 -0
- data/src/glib-enum-types.h +140 -0
- data/src/lib/glib-mkenums.rb +199 -0
- data/src/lib/glib2.rb +220 -0
- data/src/lib/mkmf-gnome2.rb +390 -0
- data/src/lib/pkg-config.rb +137 -0
- data/src/rbgcompat.h +30 -0
- data/src/rbglib.c +320 -0
- data/src/rbglib.h +96 -0
- data/src/rbglib_bookmarkfile.c +595 -0
- data/src/rbglib_completion.c +192 -0
- data/src/rbglib_convert.c +195 -0
- data/src/rbglib_error.c +95 -0
- data/src/rbglib_fileutils.c +83 -0
- data/src/rbglib_i18n.c +44 -0
- data/src/rbglib_int64.c +157 -0
- data/src/rbglib_iochannel.c +883 -0
- data/src/rbglib_keyfile.c +846 -0
- data/src/rbglib_maincontext.c +917 -0
- data/src/rbglib_mainloop.c +87 -0
- data/src/rbglib_messages.c +150 -0
- data/src/rbglib_pollfd.c +111 -0
- data/src/rbglib_shell.c +68 -0
- data/src/rbglib_source.c +190 -0
- data/src/rbglib_spawn.c +345 -0
- data/src/rbglib_threads.c +51 -0
- data/src/rbglib_timer.c +127 -0
- data/src/rbglib_unicode.c +611 -0
- data/src/rbglib_utils.c +386 -0
- data/src/rbglib_win32.c +136 -0
- data/src/rbgobj_boxed.c +251 -0
- data/src/rbgobj_closure.c +337 -0
- data/src/rbgobj_convert.c +167 -0
- data/src/rbgobj_enums.c +961 -0
- data/src/rbgobj_fundamental.c +30 -0
- data/src/rbgobj_object.c +892 -0
- data/src/rbgobj_param.c +390 -0
- data/src/rbgobj_paramspecs.c +305 -0
- data/src/rbgobj_signal.c +963 -0
- data/src/rbgobj_strv.c +61 -0
- data/src/rbgobj_type.c +851 -0
- data/src/rbgobj_typeinstance.c +121 -0
- data/src/rbgobj_typeinterface.c +148 -0
- data/src/rbgobj_typemodule.c +66 -0
- data/src/rbgobj_typeplugin.c +49 -0
- data/src/rbgobj_value.c +313 -0
- data/src/rbgobj_valuearray.c +59 -0
- data/src/rbgobj_valuetypes.c +298 -0
- data/src/rbgobject.c +406 -0
- data/src/rbgobject.h +265 -0
- data/src/rbgprivate.h +88 -0
- data/src/rbgutil.c +222 -0
- data/src/rbgutil.h +82 -0
- data/src/rbgutil_callback.c +231 -0
- data/test/glib-test-init.rb +6 -0
- data/test/glib-test-utils.rb +12 -0
- data/test/run-test.rb +25 -0
- data/test/test_enum.rb +99 -0
- data/test/test_file_utils.rb +15 -0
- data/test/test_glib2.rb +120 -0
- data/test/test_iochannel.rb +275 -0
- data/test/test_key_file.rb +38 -0
- data/test/test_mkenums.rb +25 -0
- data/test/test_signal.rb +20 -0
- data/test/test_timeout.rb +28 -0
- data/test/test_unicode.rb +369 -0
- data/test/test_utils.rb +37 -0
- data/test/test_win32.rb +13 -0
- metadata +165 -0
data/src/rbgobj_signal.c
ADDED
@@ -0,0 +1,963 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/**********************************************************************
|
3
|
+
|
4
|
+
rbgobj_signal.c -
|
5
|
+
|
6
|
+
$Author: ssimons $
|
7
|
+
$Date: 2007/07/25 17:04:28 $
|
8
|
+
created at: Sat Jul 27 16:56:01 JST 2002
|
9
|
+
|
10
|
+
Copyright (C) 2002-2004 Ruby-GNOME2 Project Team
|
11
|
+
Copyright (C) 2002,2003 Masahiro Sakai
|
12
|
+
|
13
|
+
**********************************************************************/
|
14
|
+
|
15
|
+
#include "rbgprivate.h"
|
16
|
+
|
17
|
+
static VALUE cSignal;
|
18
|
+
VALUE rbgobj_signal_wrap(guint sig_id);
|
19
|
+
|
20
|
+
#define default_handler_method_prefix "signal_do_"
|
21
|
+
|
22
|
+
/**********************************************************************/
|
23
|
+
|
24
|
+
static VALUE signal_func_table;
|
25
|
+
|
26
|
+
void
|
27
|
+
rbgobj_set_signal_func(klass, sig_name, func)
|
28
|
+
VALUE klass;
|
29
|
+
gchar* sig_name;
|
30
|
+
GValToRValSignalFunc func;
|
31
|
+
{
|
32
|
+
VALUE obj = Data_Wrap_Struct(rb_cData, NULL, NULL, func);
|
33
|
+
guint signal_id = g_signal_lookup(sig_name, CLASS2GTYPE(klass));
|
34
|
+
rb_hash_aset(signal_func_table, UINT2NUM(signal_id), obj);
|
35
|
+
}
|
36
|
+
|
37
|
+
GValToRValSignalFunc
|
38
|
+
rbgobj_get_signal_func(guint signal_id)
|
39
|
+
{
|
40
|
+
GValToRValSignalFunc func = NULL;
|
41
|
+
VALUE func_obj = rb_hash_aref(signal_func_table, UINT2NUM(signal_id));
|
42
|
+
if (!NIL_P(func_obj))
|
43
|
+
Data_Get_Struct(func_obj, void, func);
|
44
|
+
return func;
|
45
|
+
}
|
46
|
+
|
47
|
+
/**********************************************************************/
|
48
|
+
|
49
|
+
static VALUE eNoSignalError;
|
50
|
+
|
51
|
+
// FIXME: use rb_protect
|
52
|
+
static gboolean
|
53
|
+
accumulator_func(GSignalInvocationHint* ihint,
|
54
|
+
GValue* return_accu,
|
55
|
+
const GValue* handler_return,
|
56
|
+
gpointer data)
|
57
|
+
{
|
58
|
+
VALUE proc = (VALUE)data;
|
59
|
+
VALUE val = GVAL2RVAL(return_accu);
|
60
|
+
VALUE new = GVAL2RVAL(handler_return);
|
61
|
+
VALUE hint = Qnil; // FIXME
|
62
|
+
VALUE tmp;
|
63
|
+
gboolean continue_emission = TRUE;
|
64
|
+
|
65
|
+
tmp = rb_funcall(proc, rb_intern("call"), 3, hint, val, new);
|
66
|
+
/* FIXME */
|
67
|
+
if (TYPE(tmp) == T_ARRAY) {
|
68
|
+
continue_emission = RVAL2CBOOL(rb_ary_entry(tmp, 0));
|
69
|
+
val = rb_ary_entry(tmp, 1);
|
70
|
+
} else {
|
71
|
+
val = tmp;
|
72
|
+
}
|
73
|
+
rbgobj_rvalue_to_gvalue(val, return_accu);
|
74
|
+
|
75
|
+
return continue_emission;
|
76
|
+
}
|
77
|
+
|
78
|
+
static VALUE
|
79
|
+
gobj_s_signal_new(int argc, VALUE* argv, VALUE self)
|
80
|
+
{
|
81
|
+
const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
|
82
|
+
VALUE signal_name, signal_flags, accumulator, return_type, params;
|
83
|
+
GClosure* class_closure;
|
84
|
+
GType* param_types;
|
85
|
+
guint n_params;
|
86
|
+
int i;
|
87
|
+
guint sig;
|
88
|
+
|
89
|
+
rb_scan_args(argc, argv, "4*", &signal_name, &signal_flags,
|
90
|
+
&accumulator, &return_type, ¶ms);
|
91
|
+
|
92
|
+
if (cinfo->klass != self)
|
93
|
+
rb_raise(rb_eTypeError, "%s isn't registerd class",
|
94
|
+
rb_class2name(self));
|
95
|
+
|
96
|
+
if (SYMBOL_P(signal_name))
|
97
|
+
signal_name = rb_str_new2(rb_id2name(SYM2ID(signal_name)));
|
98
|
+
else
|
99
|
+
StringValue(signal_name);
|
100
|
+
|
101
|
+
{
|
102
|
+
VALUE factory;
|
103
|
+
VALUE proc;
|
104
|
+
ID method_id;
|
105
|
+
|
106
|
+
method_id = rb_to_id(rb_str_concat(rb_str_new2(default_handler_method_prefix), signal_name));
|
107
|
+
|
108
|
+
factory = rb_eval_string(
|
109
|
+
"lambda{|klass, id|\n"
|
110
|
+
" lambda{|instance,*args|\n"
|
111
|
+
" klass.instance_method(id).bind(instance).call(*args)\n"
|
112
|
+
" }\n"
|
113
|
+
"}\n");
|
114
|
+
proc = rb_funcall(factory, rb_intern("call"), 2, self, ID2SYM(method_id));
|
115
|
+
|
116
|
+
class_closure = g_rclosure_new(proc, Qnil, NULL);
|
117
|
+
g_rclosure_attach(class_closure, self);
|
118
|
+
}
|
119
|
+
|
120
|
+
if (NIL_P(params)) {
|
121
|
+
n_params = 0;
|
122
|
+
param_types = NULL;
|
123
|
+
} else {
|
124
|
+
n_params = RARRAY_LEN(params);
|
125
|
+
param_types = ALLOCA_N(GType, n_params);
|
126
|
+
for (i = 0; i < n_params; i++)
|
127
|
+
param_types[i] = rbgobj_gtype_get(RARRAY_PTR(params)[i]);
|
128
|
+
}
|
129
|
+
|
130
|
+
sig = g_signal_newv(StringValuePtr(signal_name),
|
131
|
+
cinfo->gtype,
|
132
|
+
NUM2INT(signal_flags),
|
133
|
+
class_closure,
|
134
|
+
NIL_P(accumulator) ? NULL : accumulator_func,
|
135
|
+
NIL_P(accumulator) ? NULL : (gpointer)accumulator,
|
136
|
+
NULL, /* c_marshaller */
|
137
|
+
rbgobj_gtype_get(return_type),
|
138
|
+
n_params,
|
139
|
+
param_types);
|
140
|
+
|
141
|
+
if (!sig)
|
142
|
+
rb_raise(rb_eRuntimeError, "g_signal_newv failed");
|
143
|
+
|
144
|
+
if (!NIL_P(accumulator))
|
145
|
+
G_RELATIVE(self, accumulator); /* FIXME */
|
146
|
+
|
147
|
+
return rbgobj_signal_wrap(sig);
|
148
|
+
}
|
149
|
+
|
150
|
+
static void
|
151
|
+
_signal_list(VALUE result, GType gtype)
|
152
|
+
{
|
153
|
+
guint n_ids, i;
|
154
|
+
guint* ids = g_signal_list_ids(gtype, &n_ids);
|
155
|
+
for (i = 0; i < n_ids; i++)
|
156
|
+
rb_ary_push(result, rb_str_new2(g_signal_name(ids[i])));
|
157
|
+
g_free(ids);
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
gobj_s_signals(int argc, VALUE* argv, VALUE self)
|
162
|
+
{
|
163
|
+
GType gtype;
|
164
|
+
VALUE inherited_too, result;
|
165
|
+
|
166
|
+
if (rb_scan_args(argc, argv, "01", &inherited_too) == 0)
|
167
|
+
inherited_too = Qtrue;
|
168
|
+
gtype = CLASS2GTYPE(self);
|
169
|
+
result = rb_ary_new();
|
170
|
+
|
171
|
+
if (RVAL2CBOOL(inherited_too)){
|
172
|
+
guint n_interfaces, i;
|
173
|
+
GType* interfaces = g_type_interfaces(gtype, &n_interfaces);
|
174
|
+
for (i = 0; i < n_interfaces; i++)
|
175
|
+
_signal_list(result, interfaces[i]);
|
176
|
+
g_free(interfaces);
|
177
|
+
|
178
|
+
for (; gtype; gtype = g_type_parent(gtype))
|
179
|
+
_signal_list(result, gtype);
|
180
|
+
} else if (GTYPE2CLASS(gtype) == self) {
|
181
|
+
_signal_list(result, gtype);
|
182
|
+
}
|
183
|
+
|
184
|
+
return result;
|
185
|
+
}
|
186
|
+
|
187
|
+
static VALUE
|
188
|
+
gobj_s_signal(VALUE self, VALUE name)
|
189
|
+
{
|
190
|
+
const char* sig_name;
|
191
|
+
guint sig_id;
|
192
|
+
|
193
|
+
if (SYMBOL_P(name))
|
194
|
+
sig_name = rb_id2name(SYM2ID(name));
|
195
|
+
else
|
196
|
+
sig_name = StringValuePtr(name);
|
197
|
+
|
198
|
+
sig_id = g_signal_lookup(sig_name, CLASS2GTYPE(self));
|
199
|
+
if (!sig_id)
|
200
|
+
rb_raise(eNoSignalError, "no such signal: %s", sig_name);
|
201
|
+
|
202
|
+
return rbgobj_signal_wrap(sig_id);
|
203
|
+
}
|
204
|
+
|
205
|
+
static VALUE
|
206
|
+
gobj_sig_has_handler_pending(argc, argv, self)
|
207
|
+
int argc;
|
208
|
+
VALUE *argv;
|
209
|
+
VALUE self;
|
210
|
+
{
|
211
|
+
VALUE sig, may_be_blocked;
|
212
|
+
const char* sig_name;
|
213
|
+
guint signal_id;
|
214
|
+
GQuark detail;
|
215
|
+
|
216
|
+
rb_scan_args(argc, argv, "11", &sig, &may_be_blocked);
|
217
|
+
|
218
|
+
if (SYMBOL_P(sig))
|
219
|
+
sig_name = rb_id2name(SYM2ID(sig));
|
220
|
+
else
|
221
|
+
sig_name = StringValuePtr(sig);
|
222
|
+
|
223
|
+
if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE))
|
224
|
+
rb_raise(eNoSignalError, "no such signal: %s", sig_name);
|
225
|
+
|
226
|
+
return CBOOL2RVAL(g_signal_has_handler_pending(RVAL2GOBJ(self),
|
227
|
+
signal_id, detail,
|
228
|
+
RVAL2CBOOL(may_be_blocked)));
|
229
|
+
}
|
230
|
+
|
231
|
+
static VALUE
|
232
|
+
gobj_sig_connect_impl(after, argc, argv, self)
|
233
|
+
gboolean after;
|
234
|
+
int argc;
|
235
|
+
VALUE *argv;
|
236
|
+
VALUE self;
|
237
|
+
{
|
238
|
+
VALUE sig, rest;
|
239
|
+
int i;
|
240
|
+
GClosure* rclosure;
|
241
|
+
const char* sig_name;
|
242
|
+
guint signal_id;
|
243
|
+
GQuark detail;
|
244
|
+
VALUE func;
|
245
|
+
GObject *g_object;
|
246
|
+
gchar *tag;
|
247
|
+
|
248
|
+
rb_scan_args(argc, argv, "1*", &sig, &rest);
|
249
|
+
|
250
|
+
if (NIL_P(rest)) rest = rb_ary_new();
|
251
|
+
|
252
|
+
if (SYMBOL_P(sig))
|
253
|
+
sig_name = rb_id2name(SYM2ID(sig));
|
254
|
+
else
|
255
|
+
sig_name = StringValuePtr(sig);
|
256
|
+
|
257
|
+
if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE))
|
258
|
+
rb_raise(eNoSignalError, "no such signal: %s", sig_name);
|
259
|
+
|
260
|
+
func = rb_block_proc();
|
261
|
+
rclosure = g_rclosure_new(func, rest,
|
262
|
+
rbgobj_get_signal_func(signal_id));
|
263
|
+
g_rclosure_attach((GClosure *)rclosure, self);
|
264
|
+
g_object = RVAL2GOBJ(self);
|
265
|
+
tag = g_strdup_printf("%s::%s",
|
266
|
+
G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(g_object)),
|
267
|
+
sig_name);
|
268
|
+
g_rclosure_set_tag((GClosure *)rclosure, tag);
|
269
|
+
g_free(tag);
|
270
|
+
i = g_signal_connect_closure_by_id(g_object, signal_id, detail, rclosure, after);
|
271
|
+
|
272
|
+
return INT2FIX(i);
|
273
|
+
}
|
274
|
+
|
275
|
+
static VALUE
|
276
|
+
gobj_sig_connect(argc, argv, self)
|
277
|
+
int argc;
|
278
|
+
VALUE *argv;
|
279
|
+
VALUE self;
|
280
|
+
{
|
281
|
+
return gobj_sig_connect_impl(FALSE, argc, argv, self);
|
282
|
+
}
|
283
|
+
|
284
|
+
static VALUE
|
285
|
+
gobj_sig_connect_after(argc, argv, self)
|
286
|
+
int argc;
|
287
|
+
VALUE *argv;
|
288
|
+
VALUE self;
|
289
|
+
{
|
290
|
+
return gobj_sig_connect_impl(TRUE, argc, argv, self);
|
291
|
+
}
|
292
|
+
|
293
|
+
#if 0
|
294
|
+
static VALUE
|
295
|
+
gobj_sig_get_invocation_hint(self)
|
296
|
+
VALUE self;
|
297
|
+
{
|
298
|
+
GSignalInvocationHint* hint;
|
299
|
+
hint = g_signal_get_invocation_hint(RVAL2GOBJ(self));
|
300
|
+
return rb_ary_new3(3,
|
301
|
+
rbgobj_signal_wrap(hint->signal_id),
|
302
|
+
hint->detail ? rb_str_new2(g_quark_to_string(hint->detail)) : Qnil,
|
303
|
+
INT2NUM(hint->run_type));
|
304
|
+
}
|
305
|
+
#endif
|
306
|
+
|
307
|
+
struct emit_arg{
|
308
|
+
VALUE self;
|
309
|
+
VALUE args;
|
310
|
+
|
311
|
+
GSignalQuery query;
|
312
|
+
GQuark detail;
|
313
|
+
GValueArray* instance_and_params;
|
314
|
+
};
|
315
|
+
|
316
|
+
static VALUE
|
317
|
+
emit_body(struct emit_arg* arg)
|
318
|
+
{
|
319
|
+
GValue param = { 0, };
|
320
|
+
|
321
|
+
g_value_init(¶m, G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self)));
|
322
|
+
rbgobj_rvalue_to_gvalue(arg->self, ¶m);
|
323
|
+
g_value_array_append(arg->instance_and_params, ¶m);
|
324
|
+
g_value_unset(¶m);
|
325
|
+
|
326
|
+
{
|
327
|
+
int i;
|
328
|
+
for (i = 0; i < arg->query.n_params; i++){
|
329
|
+
GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
|
330
|
+
|
331
|
+
g_value_init(¶m, gtype);
|
332
|
+
|
333
|
+
rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), ¶m);
|
334
|
+
g_value_array_append(arg->instance_and_params, ¶m);
|
335
|
+
g_value_unset(¶m);
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
{
|
340
|
+
gboolean use_ret = (arg->query.return_type != G_TYPE_NONE);
|
341
|
+
GValue return_value = {0,};
|
342
|
+
|
343
|
+
if (use_ret)
|
344
|
+
g_value_init(&return_value,
|
345
|
+
arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
346
|
+
|
347
|
+
g_signal_emitv(arg->instance_and_params->values,
|
348
|
+
arg->query.signal_id, arg->detail,
|
349
|
+
(use_ret) ? &return_value : NULL);
|
350
|
+
|
351
|
+
if (use_ret) {
|
352
|
+
VALUE ret = GVAL2RVAL(&return_value);
|
353
|
+
g_value_unset(&return_value);
|
354
|
+
return ret;
|
355
|
+
} else {
|
356
|
+
return Qnil;
|
357
|
+
}
|
358
|
+
}
|
359
|
+
}
|
360
|
+
|
361
|
+
static VALUE
|
362
|
+
emit_ensure(struct emit_arg* arg)
|
363
|
+
{
|
364
|
+
g_value_array_free(arg->instance_and_params);
|
365
|
+
return Qnil;
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE
|
369
|
+
gobj_sig_emit(argc, argv, self)
|
370
|
+
int argc;
|
371
|
+
VALUE *argv;
|
372
|
+
VALUE self;
|
373
|
+
{
|
374
|
+
VALUE sig;
|
375
|
+
const char* sig_name;
|
376
|
+
guint signal_id;
|
377
|
+
struct emit_arg arg;
|
378
|
+
|
379
|
+
rb_scan_args(argc, argv, "1*", &sig, &arg.args);
|
380
|
+
|
381
|
+
if (SYMBOL_P(sig))
|
382
|
+
sig_name = rb_id2name(SYM2ID(sig));
|
383
|
+
else
|
384
|
+
sig_name = StringValuePtr(sig);
|
385
|
+
|
386
|
+
if (!g_signal_parse_name(sig_name,
|
387
|
+
CLASS2GTYPE(CLASS_OF(self)),
|
388
|
+
&signal_id, &arg.detail, FALSE))
|
389
|
+
rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name);
|
390
|
+
|
391
|
+
g_signal_query(signal_id, &arg.query);
|
392
|
+
|
393
|
+
if (arg.query.n_params != RARRAY_LEN(arg.args))
|
394
|
+
rb_raise(rb_eArgError, "wrong number of arguments(%ld for %d)",
|
395
|
+
RARRAY_LEN(arg.args) + 1,
|
396
|
+
arg.query.n_params + 1);
|
397
|
+
|
398
|
+
arg.self = self;
|
399
|
+
arg.instance_and_params = g_value_array_new(1 + arg.query.n_params);
|
400
|
+
|
401
|
+
return rb_ensure(emit_body, (VALUE)&arg, emit_ensure, (VALUE)&arg);
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE
|
405
|
+
gobj_sig_emit_stop(self, sig)
|
406
|
+
VALUE self, sig;
|
407
|
+
{
|
408
|
+
gpointer instance = RVAL2GOBJ(self);
|
409
|
+
const char* sig_name;
|
410
|
+
guint signal_id;
|
411
|
+
GQuark detail;
|
412
|
+
|
413
|
+
if (SYMBOL_P(sig))
|
414
|
+
sig_name = rb_id2name(SYM2ID(sig));
|
415
|
+
else
|
416
|
+
sig_name = StringValuePtr(sig);
|
417
|
+
|
418
|
+
if (!g_signal_parse_name(sig_name,
|
419
|
+
CLASS2GTYPE(CLASS_OF(self)),
|
420
|
+
&signal_id, &detail, FALSE))
|
421
|
+
rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name);
|
422
|
+
|
423
|
+
g_signal_stop_emission(instance, signal_id, detail);
|
424
|
+
return self;
|
425
|
+
}
|
426
|
+
|
427
|
+
static VALUE gobj_sig_handler_unblock(VALUE self, VALUE id);
|
428
|
+
|
429
|
+
static VALUE
|
430
|
+
_sig_handler_block_ensure(arg)
|
431
|
+
VALUE arg;
|
432
|
+
{
|
433
|
+
VALUE self = RARRAY_PTR(arg)[0];
|
434
|
+
VALUE id = RARRAY_PTR(arg)[1];
|
435
|
+
gobj_sig_handler_unblock(self, id);
|
436
|
+
return Qnil;
|
437
|
+
}
|
438
|
+
|
439
|
+
static VALUE
|
440
|
+
gobj_sig_handler_block(self, id)
|
441
|
+
VALUE self, id;
|
442
|
+
{
|
443
|
+
g_signal_handler_block(RVAL2GOBJ(self), NUM2ULONG(id));
|
444
|
+
if (rb_block_given_p())
|
445
|
+
rb_ensure(rb_yield, self, _sig_handler_block_ensure,
|
446
|
+
rb_ary_new3(2, self, id));
|
447
|
+
return self;
|
448
|
+
}
|
449
|
+
|
450
|
+
static VALUE
|
451
|
+
gobj_sig_handler_unblock(self, id)
|
452
|
+
VALUE self, id;
|
453
|
+
{
|
454
|
+
g_signal_handler_unblock(RVAL2GOBJ(self), NUM2ULONG(id));
|
455
|
+
return self;
|
456
|
+
}
|
457
|
+
|
458
|
+
static VALUE
|
459
|
+
gobj_sig_handler_disconnect(self, id)
|
460
|
+
VALUE self, id;
|
461
|
+
{
|
462
|
+
g_signal_handler_disconnect(RVAL2GOBJ(self), NUM2ULONG(id));
|
463
|
+
return self;
|
464
|
+
}
|
465
|
+
|
466
|
+
static VALUE
|
467
|
+
gobj_sig_handler_is_connected(self, id)
|
468
|
+
VALUE self, id;
|
469
|
+
{
|
470
|
+
return CBOOL2RVAL(g_signal_handler_is_connected(RVAL2GOBJ(self), NUM2ULONG(id)));
|
471
|
+
}
|
472
|
+
|
473
|
+
#if 0
|
474
|
+
gulong g_signal_handler_find (gpointer instance,
|
475
|
+
GSignalMatchType mask,
|
476
|
+
guint signal_id,
|
477
|
+
GQuark detail,
|
478
|
+
GClosure *closure,
|
479
|
+
gpointer func,
|
480
|
+
gpointer data);
|
481
|
+
guint g_signal_handlers_block_matched (gpointer instance,
|
482
|
+
GSignalMatchType mask,
|
483
|
+
guint signal_id,
|
484
|
+
GQuark detail,
|
485
|
+
GClosure *closure,
|
486
|
+
gpointer func,
|
487
|
+
gpointer data);
|
488
|
+
guint g_signal_handlers_unblock_matched (gpointer instance,
|
489
|
+
GSignalMatchType mask,
|
490
|
+
guint signal_id,
|
491
|
+
GQuark detail,
|
492
|
+
GClosure *closure,
|
493
|
+
gpointer func,
|
494
|
+
gpointer data);
|
495
|
+
guint g_signal_handlers_disconnect_matched (gpointer instance,
|
496
|
+
GSignalMatchType mask,
|
497
|
+
guint signal_id,
|
498
|
+
GQuark detail,
|
499
|
+
GClosure *closure,
|
500
|
+
gpointer func,
|
501
|
+
gpointer data);
|
502
|
+
#endif
|
503
|
+
|
504
|
+
static VALUE
|
505
|
+
chain_from_overridden_body(struct emit_arg* arg)
|
506
|
+
{
|
507
|
+
g_value_init(arg->instance_and_params->values,
|
508
|
+
G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self)));
|
509
|
+
rbgobj_rvalue_to_gvalue(arg->self, arg->instance_and_params->values);
|
510
|
+
|
511
|
+
{
|
512
|
+
GValue* params = arg->instance_and_params->values + 1;
|
513
|
+
int i;
|
514
|
+
for (i = 0; i < arg->query.n_params; i++) {
|
515
|
+
GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
|
516
|
+
g_value_init(params + i, gtype);
|
517
|
+
rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), params + i);
|
518
|
+
}
|
519
|
+
}
|
520
|
+
|
521
|
+
{
|
522
|
+
gboolean use_ret = (arg->query.return_type != G_TYPE_NONE);
|
523
|
+
GValue return_value = {0,};
|
524
|
+
|
525
|
+
if (use_ret)
|
526
|
+
g_value_init(&return_value,
|
527
|
+
arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
528
|
+
|
529
|
+
g_signal_chain_from_overridden(arg->instance_and_params->values,
|
530
|
+
(use_ret) ? &return_value : NULL);
|
531
|
+
|
532
|
+
if (use_ret) {
|
533
|
+
VALUE ret = GVAL2RVAL(&return_value);
|
534
|
+
g_value_unset(&return_value);
|
535
|
+
return ret;
|
536
|
+
} else {
|
537
|
+
return Qnil;
|
538
|
+
}
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
542
|
+
static VALUE
|
543
|
+
gobj_sig_chain_from_overridden(argc, argv, self)
|
544
|
+
int argc;
|
545
|
+
VALUE* argv;
|
546
|
+
VALUE self;
|
547
|
+
{
|
548
|
+
struct emit_arg arg;
|
549
|
+
|
550
|
+
{
|
551
|
+
GSignalInvocationHint* hint;
|
552
|
+
hint = g_signal_get_invocation_hint(RVAL2GOBJ(self));
|
553
|
+
if (!hint)
|
554
|
+
rb_raise(rb_eRuntimeError, "can't get signal invocation hint");
|
555
|
+
g_signal_query(hint->signal_id, &arg.query);
|
556
|
+
}
|
557
|
+
|
558
|
+
if (arg.query.n_params != argc)
|
559
|
+
rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
|
560
|
+
argc, arg.query.n_params);
|
561
|
+
|
562
|
+
arg.self = self;
|
563
|
+
arg.args = rb_ary_new4(argc, argv);
|
564
|
+
arg.instance_and_params = g_value_array_new(1 + argc);
|
565
|
+
|
566
|
+
return rb_ensure(chain_from_overridden_body, (VALUE)&arg,
|
567
|
+
emit_ensure, (VALUE)&arg);
|
568
|
+
}
|
569
|
+
|
570
|
+
static VALUE
|
571
|
+
gobj_s_method_added(klass, id)
|
572
|
+
VALUE klass, id;
|
573
|
+
{
|
574
|
+
const RGObjClassInfo* cinfo = rbgobj_lookup_class(klass);
|
575
|
+
const char* name = rb_id2name(SYM2ID(id));
|
576
|
+
const int prefix_len = strlen(default_handler_method_prefix);
|
577
|
+
guint signal_id;
|
578
|
+
|
579
|
+
if (cinfo->klass != klass) return Qnil;
|
580
|
+
if (strncmp(default_handler_method_prefix, name, prefix_len)) return Qnil;
|
581
|
+
|
582
|
+
signal_id = g_signal_lookup(name + prefix_len, cinfo->gtype);
|
583
|
+
if (!signal_id) return Qnil;
|
584
|
+
|
585
|
+
{
|
586
|
+
GSignalQuery query;
|
587
|
+
g_signal_query(signal_id, &query);
|
588
|
+
if (query.itype == cinfo->gtype)
|
589
|
+
return Qnil;
|
590
|
+
}
|
591
|
+
|
592
|
+
{
|
593
|
+
VALUE f = rb_eval_string(
|
594
|
+
"lambda{|klass, id|\n"
|
595
|
+
" lambda{|instance,*args|\n"
|
596
|
+
" klass.instance_method(id).bind(instance).call(*args)\n"
|
597
|
+
" }\n"
|
598
|
+
"}\n");
|
599
|
+
VALUE proc = rb_funcall(f, rb_intern("call"), 2, klass, id);
|
600
|
+
GClosure* rclosure = g_rclosure_new(proc, Qnil,
|
601
|
+
rbgobj_get_signal_func(signal_id));
|
602
|
+
g_rclosure_attach((GClosure *)rclosure, klass);
|
603
|
+
g_signal_override_class_closure(signal_id, cinfo->gtype, rclosure);
|
604
|
+
}
|
605
|
+
|
606
|
+
{
|
607
|
+
VALUE mod = rb_define_module_under(klass, RubyGObjectHookModule);
|
608
|
+
rb_include_module(klass, mod);
|
609
|
+
rb_define_method(mod, name, gobj_sig_chain_from_overridden, -1);
|
610
|
+
}
|
611
|
+
|
612
|
+
return Qnil;
|
613
|
+
}
|
614
|
+
|
615
|
+
static void
|
616
|
+
Init_signal_misc()
|
617
|
+
{
|
618
|
+
signal_func_table = rb_hash_new();
|
619
|
+
rb_global_variable(&signal_func_table);
|
620
|
+
|
621
|
+
rb_define_method(mMetaInterface, "signal_new", gobj_s_signal_new, -1);
|
622
|
+
rb_define_method(mMetaInterface, "signals", gobj_s_signals, -1);
|
623
|
+
rb_define_method(mMetaInterface, "signal", gobj_s_signal, 1);
|
624
|
+
|
625
|
+
rb_define_method(cInstantiatable, "signal_has_handler_pending?",
|
626
|
+
gobj_sig_has_handler_pending, -1);
|
627
|
+
rb_define_method(cInstantiatable, "signal_connect", gobj_sig_connect, -1);
|
628
|
+
rb_define_method(cInstantiatable, "signal_connect_after",
|
629
|
+
gobj_sig_connect_after, -1);
|
630
|
+
|
631
|
+
#if 0
|
632
|
+
rb_define_method(cInstantiatable, "signal_invocation_hint",
|
633
|
+
gobj_sig_get_invocation_hint, 0);
|
634
|
+
#endif
|
635
|
+
|
636
|
+
rb_define_method(cInstantiatable, "signal_emit",
|
637
|
+
gobj_sig_emit, -1);
|
638
|
+
rb_define_method(cInstantiatable, "signal_emit_stop",
|
639
|
+
gobj_sig_emit_stop, 1);
|
640
|
+
rb_define_method(cInstantiatable, "signal_handler_block",
|
641
|
+
gobj_sig_handler_block, 1);
|
642
|
+
rb_define_method(cInstantiatable, "signal_handler_unblock",
|
643
|
+
gobj_sig_handler_unblock, 1);
|
644
|
+
rb_define_method(cInstantiatable, "signal_handler_disconnect",
|
645
|
+
gobj_sig_handler_disconnect, 1);
|
646
|
+
|
647
|
+
rb_define_method(cInstantiatable, "signal_handler_is_connected?",
|
648
|
+
gobj_sig_handler_is_connected, 1);
|
649
|
+
|
650
|
+
rb_define_singleton_method(cInstantiatable, "method_added",
|
651
|
+
gobj_s_method_added, 1);
|
652
|
+
}
|
653
|
+
|
654
|
+
/**********************************************************************/
|
655
|
+
|
656
|
+
VALUE
|
657
|
+
rbgobj_signal_wrap(sig_id)
|
658
|
+
guint sig_id;
|
659
|
+
{
|
660
|
+
VALUE result;
|
661
|
+
GSignalQuery* query;
|
662
|
+
|
663
|
+
result = Data_Make_Struct(cSignal, GSignalQuery, NULL, free, query);
|
664
|
+
g_signal_query(sig_id, query);
|
665
|
+
return result;
|
666
|
+
}
|
667
|
+
|
668
|
+
static VALUE
|
669
|
+
query_signal_id(self)
|
670
|
+
VALUE self;
|
671
|
+
{
|
672
|
+
GSignalQuery* query;
|
673
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
674
|
+
return UINT2NUM(query->signal_id);
|
675
|
+
}
|
676
|
+
|
677
|
+
static VALUE
|
678
|
+
query_signal_name(self)
|
679
|
+
VALUE self;
|
680
|
+
{
|
681
|
+
GSignalQuery* query;
|
682
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
683
|
+
return rb_str_new2(query->signal_name);
|
684
|
+
}
|
685
|
+
|
686
|
+
static VALUE
|
687
|
+
query_itype(self)
|
688
|
+
VALUE self;
|
689
|
+
{
|
690
|
+
GSignalQuery* query;
|
691
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
692
|
+
return rbgobj_gtype_new(query->itype);
|
693
|
+
}
|
694
|
+
|
695
|
+
static VALUE
|
696
|
+
query_owner(self)
|
697
|
+
VALUE self;
|
698
|
+
{
|
699
|
+
GSignalQuery* query;
|
700
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
701
|
+
return GTYPE2CLASS(query->itype);
|
702
|
+
}
|
703
|
+
|
704
|
+
static VALUE
|
705
|
+
query_return_type(self)
|
706
|
+
VALUE self;
|
707
|
+
{
|
708
|
+
GSignalQuery* query;
|
709
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
710
|
+
return rbgobj_gtype_new(query->return_type);
|
711
|
+
}
|
712
|
+
|
713
|
+
static VALUE
|
714
|
+
query_signal_flags(self)
|
715
|
+
VALUE self;
|
716
|
+
{
|
717
|
+
GSignalQuery* query;
|
718
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
719
|
+
return UINT2NUM(query->signal_flags);
|
720
|
+
}
|
721
|
+
|
722
|
+
static VALUE
|
723
|
+
query_param_types(self)
|
724
|
+
VALUE self;
|
725
|
+
{
|
726
|
+
GSignalQuery* query;
|
727
|
+
VALUE result;
|
728
|
+
int i;
|
729
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
730
|
+
|
731
|
+
result = rb_ary_new2(query->n_params);
|
732
|
+
for (i = 0; i < query->n_params; i++)
|
733
|
+
rb_ary_store(result, i, rbgobj_gtype_new(query->param_types[i]));
|
734
|
+
|
735
|
+
return result;
|
736
|
+
}
|
737
|
+
|
738
|
+
static VALUE
|
739
|
+
query_inspect(self)
|
740
|
+
VALUE self;
|
741
|
+
{
|
742
|
+
GSignalQuery* query;
|
743
|
+
gchar* s;
|
744
|
+
VALUE result, v;
|
745
|
+
|
746
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
747
|
+
|
748
|
+
v = rb_inspect(GTYPE2CLASS(query->itype));
|
749
|
+
|
750
|
+
s = g_strdup_printf("#<%s: %s#%s>",
|
751
|
+
rb_class2name(CLASS_OF(self)),
|
752
|
+
StringValuePtr(v),
|
753
|
+
query->signal_name);
|
754
|
+
result = rb_str_new2(s);
|
755
|
+
g_free(s);
|
756
|
+
|
757
|
+
return result;
|
758
|
+
}
|
759
|
+
|
760
|
+
#define query_is_flag(flag) \
|
761
|
+
static VALUE \
|
762
|
+
query_is_##flag(self) \
|
763
|
+
VALUE self; \
|
764
|
+
{ \
|
765
|
+
GSignalQuery* query; \
|
766
|
+
Data_Get_Struct(self, GSignalQuery, query); \
|
767
|
+
return CBOOL2RVAL(query->signal_flags & flag); \
|
768
|
+
}
|
769
|
+
|
770
|
+
query_is_flag(G_SIGNAL_RUN_FIRST)
|
771
|
+
query_is_flag(G_SIGNAL_RUN_LAST)
|
772
|
+
query_is_flag(G_SIGNAL_RUN_CLEANUP)
|
773
|
+
query_is_flag(G_SIGNAL_NO_RECURSE)
|
774
|
+
query_is_flag(G_SIGNAL_DETAILED)
|
775
|
+
query_is_flag(G_SIGNAL_ACTION)
|
776
|
+
query_is_flag(G_SIGNAL_NO_HOOKS)
|
777
|
+
|
778
|
+
|
779
|
+
static gboolean
|
780
|
+
hook_func(GSignalInvocationHint* ihint,
|
781
|
+
guint n_param_values,
|
782
|
+
const GValue* param_values,
|
783
|
+
gpointer data)
|
784
|
+
{
|
785
|
+
GClosure* closure = data;
|
786
|
+
GValue ret_val ={0,};
|
787
|
+
gboolean ret;
|
788
|
+
|
789
|
+
g_value_init(&ret_val, G_TYPE_BOOLEAN);
|
790
|
+
g_closure_invoke(closure, &ret_val, n_param_values, param_values, ihint);
|
791
|
+
ret = g_value_get_boolean(&ret_val);
|
792
|
+
g_value_unset(&ret_val);
|
793
|
+
|
794
|
+
return ret;
|
795
|
+
}
|
796
|
+
|
797
|
+
static gulong
|
798
|
+
g_signal_add_emission_hook_closure (guint signal_id,
|
799
|
+
GQuark detail,
|
800
|
+
GClosure* closure)
|
801
|
+
{
|
802
|
+
guint hook_id;
|
803
|
+
g_closure_ref(closure);
|
804
|
+
g_closure_sink(closure);
|
805
|
+
hook_id = g_signal_add_emission_hook(signal_id, detail,
|
806
|
+
&hook_func, closure,
|
807
|
+
(GDestroyNotify)&g_closure_unref);
|
808
|
+
return hook_id;
|
809
|
+
}
|
810
|
+
|
811
|
+
static VALUE
|
812
|
+
signal_add_emission_hook(int argc, VALUE* argv, VALUE self)
|
813
|
+
{
|
814
|
+
GSignalQuery* query;
|
815
|
+
VALUE proc;
|
816
|
+
guint hook_id;
|
817
|
+
GQuark detail = 0;
|
818
|
+
GClosure* closure;
|
819
|
+
|
820
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
821
|
+
|
822
|
+
if (query->signal_flags & G_SIGNAL_DETAILED) {
|
823
|
+
VALUE detail_obj;
|
824
|
+
if (rb_scan_args(argc, argv, "01&", &detail_obj, &proc) == 1) {
|
825
|
+
if (SYMBOL_P(detail_obj))
|
826
|
+
detail = g_quark_from_string(rb_id2name(SYM2ID(detail_obj)));
|
827
|
+
else
|
828
|
+
detail = g_quark_from_string(StringValuePtr(detail_obj));
|
829
|
+
}
|
830
|
+
} else {
|
831
|
+
rb_scan_args(argc, argv, "00&", &proc);
|
832
|
+
}
|
833
|
+
|
834
|
+
closure = g_rclosure_new(proc, Qnil,
|
835
|
+
rbgobj_get_signal_func(query->signal_id));
|
836
|
+
g_rclosure_attach(closure, self);
|
837
|
+
hook_id = g_signal_add_emission_hook_closure(query->signal_id, detail, closure);
|
838
|
+
return ULONG2NUM(hook_id);
|
839
|
+
}
|
840
|
+
|
841
|
+
static VALUE
|
842
|
+
signal_remove_emission_hook(VALUE self, VALUE hook_id)
|
843
|
+
{
|
844
|
+
GSignalQuery* query;
|
845
|
+
Data_Get_Struct(self, GSignalQuery, query);
|
846
|
+
g_signal_remove_emission_hook(query->signal_id, NUM2ULONG(hook_id));
|
847
|
+
return Qnil;
|
848
|
+
}
|
849
|
+
|
850
|
+
static void
|
851
|
+
Init_signal_class()
|
852
|
+
{
|
853
|
+
VALUE cSignalFlags, cSignalMatchType;
|
854
|
+
|
855
|
+
cSignal = rb_define_class_under(mGLib, "Signal", rb_cData);
|
856
|
+
|
857
|
+
rb_define_method(cSignal, "id", query_signal_id, 0);
|
858
|
+
rb_define_method(cSignal, "name", query_signal_name, 0);
|
859
|
+
rb_define_method(cSignal, "flags", query_signal_flags, 0);
|
860
|
+
rb_define_method(cSignal, "itype", query_itype, 0);
|
861
|
+
rb_define_method(cSignal, "owner", query_owner, 0);
|
862
|
+
rb_define_method(cSignal, "return_type", query_return_type, 0);
|
863
|
+
rb_define_method(cSignal, "param_types", query_param_types, 0);
|
864
|
+
rb_define_method(cSignal, "inspect", query_inspect, 0);
|
865
|
+
|
866
|
+
rb_define_method(cSignal, "add_emission_hook", signal_add_emission_hook, -1);
|
867
|
+
rb_define_method(cSignal, "remove_emission_hook", signal_remove_emission_hook, 1);
|
868
|
+
|
869
|
+
/* GSignalFlags */
|
870
|
+
cSignalFlags = G_DEF_CLASS(G_TYPE_SIGNAL_FLAGS, "SignalFlags", mGLib);
|
871
|
+
G_DEF_CONSTANTS(cSignal, G_TYPE_SIGNAL_FLAGS, "G_SIGNAL_");
|
872
|
+
rb_define_const(cSignalFlags, "MASK", INT2NUM(G_SIGNAL_FLAGS_MASK));
|
873
|
+
rb_define_const(cSignal, "FLAGS_MASK", INT2NUM(G_SIGNAL_FLAGS_MASK));
|
874
|
+
|
875
|
+
rb_define_method(cSignal, "run_first?", query_is_G_SIGNAL_RUN_FIRST, 0);
|
876
|
+
rb_define_method(cSignal, "run_last?", query_is_G_SIGNAL_RUN_LAST, 0);
|
877
|
+
rb_define_method(cSignal, "run_cleanup?", query_is_G_SIGNAL_RUN_CLEANUP, 0);
|
878
|
+
rb_define_method(cSignal, "no_recurse?", query_is_G_SIGNAL_NO_RECURSE, 0);
|
879
|
+
rb_define_method(cSignal, "detailed?", query_is_G_SIGNAL_DETAILED, 0);
|
880
|
+
rb_define_method(cSignal, "action?", query_is_G_SIGNAL_ACTION, 0);
|
881
|
+
rb_define_method(cSignal, "no_hooks?", query_is_G_SIGNAL_NO_HOOKS, 0);
|
882
|
+
|
883
|
+
|
884
|
+
/* GConnectFlags */
|
885
|
+
G_DEF_CLASS(G_TYPE_CONNECT_FLAGS, "ConnectFlags", mGLib);
|
886
|
+
G_DEF_CONSTANTS(cSignal, G_TYPE_CONNECT_FLAGS, "G_");
|
887
|
+
|
888
|
+
/* GSignalMatchType */
|
889
|
+
cSignalMatchType = G_DEF_CLASS(G_TYPE_SIGNAL_MATCH_TYPE,
|
890
|
+
"SignalMatchType", mGLib);
|
891
|
+
G_DEF_CONSTANTS(cSignal, G_TYPE_SIGNAL_MATCH_TYPE, "G_SIGNAL_");
|
892
|
+
rb_define_const(cSignalMatchType, "MASK", INT2NUM(G_SIGNAL_MATCH_MASK));
|
893
|
+
rb_define_const(cSignal, "MATCH_MASK", INT2NUM(G_SIGNAL_MATCH_MASK));
|
894
|
+
|
895
|
+
rb_define_const(cSignal, "TYPE_STATIC_SCOPE", INT2FIX(G_SIGNAL_TYPE_STATIC_SCOPE));
|
896
|
+
|
897
|
+
eNoSignalError = rb_define_class_under(mGLib, "NoSignalError", rb_eNameError);
|
898
|
+
}
|
899
|
+
|
900
|
+
/**********************************************************************/
|
901
|
+
|
902
|
+
void
|
903
|
+
rbgobj_define_action_methods(VALUE klass)
|
904
|
+
{
|
905
|
+
GType gtype = CLASS2GTYPE(klass);
|
906
|
+
GString* source;
|
907
|
+
guint n_ids;
|
908
|
+
guint* ids;
|
909
|
+
int i;
|
910
|
+
|
911
|
+
if (gtype == G_TYPE_INTERFACE)
|
912
|
+
return;
|
913
|
+
|
914
|
+
ids = g_signal_list_ids(gtype, &n_ids);
|
915
|
+
if (n_ids == 0)
|
916
|
+
return;
|
917
|
+
|
918
|
+
source = g_string_new(NULL);
|
919
|
+
for (i = 0; i < n_ids; i++){
|
920
|
+
GSignalQuery query;
|
921
|
+
g_signal_query(ids[i], &query);
|
922
|
+
|
923
|
+
if (query.signal_flags & G_SIGNAL_ACTION) {
|
924
|
+
gchar* method_name = g_strdup(query.signal_name);
|
925
|
+
gchar* p;
|
926
|
+
GString* args;
|
927
|
+
int j;
|
928
|
+
|
929
|
+
for (p = method_name; *p; p++)
|
930
|
+
if (*p == '-')
|
931
|
+
*p = '_';
|
932
|
+
|
933
|
+
args = g_string_new(NULL);
|
934
|
+
for (j = 0; j < query.n_params; j++)
|
935
|
+
g_string_append_printf(args, ",x%d", j);
|
936
|
+
|
937
|
+
g_string_append_printf(
|
938
|
+
source,
|
939
|
+
"def %s(%s)\n signal_emit('%s'%s)\nend\n",
|
940
|
+
method_name,
|
941
|
+
(query.n_params > 0) ? args->str + 1 : "", // hack
|
942
|
+
query.signal_name,
|
943
|
+
args->str);
|
944
|
+
|
945
|
+
g_free(method_name);
|
946
|
+
g_string_free(args, TRUE);
|
947
|
+
}
|
948
|
+
}
|
949
|
+
|
950
|
+
if (source->len > 0)
|
951
|
+
rb_funcall(klass, rb_intern("module_eval"), 1, rb_str_new2(source->str));
|
952
|
+
g_string_free(source, TRUE);
|
953
|
+
}
|
954
|
+
|
955
|
+
/**********************************************************************/
|
956
|
+
|
957
|
+
void
|
958
|
+
Init_gobject_gsignal()
|
959
|
+
{
|
960
|
+
Init_signal_class();
|
961
|
+
Init_signal_misc();
|
962
|
+
}
|
963
|
+
|