fxruby 1.6.39-x86-mingw32 → 1.6.40-x86-mingw32
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.
- checksums.yaml +5 -5
- data/.travis.yml +3 -14
- data/Gemfile +2 -2
- data/History.md +10 -0
- data/appveyor.yml +4 -15
- data/ext/fox16_c/FXRbApp.cpp +3 -3
- data/ext/fox16_c/FXRuby.cpp +15 -15
- data/ext/fox16_c/extconf.rb +10 -13
- data/ext/fox16_c/include/FXRbApp.h +2 -2
- data/ext/fox16_c/include/FXRuby.h +1 -1
- data/fxruby.gemspec +1 -0
- data/lib/fox16/aliases.rb +3 -0
- data/lib/fox16/calendar.rb +6 -8
- data/lib/fox16/canvas.rb +17 -17
- data/lib/fox16/core.rb +18 -18
- data/lib/fox16/undolist.rb +8 -8
- data/lib/fox16/version.rb +1 -1
- data/rdoc-sources/FXImage.rb +5 -0
- data/swig-interfaces/FXImage.i +9 -4
- data/swig-interfaces/FXMemoryBuffer.i +2 -2
- data/test/TC_FXImage.rb +8 -0
- data/test/TC_FXList.rb +8 -8
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 575b5dcabc7bee35d19ec1731e40dbc3c7cce8bc4f9ae9d51591174dbe0b152d
|
4
|
+
data.tar.gz: 5084118956a37b08a3d69aab3aeab9cad15bcccd7011daa57155f01aab1144e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aadbc1f3f2af32f54af88329c516c09cecb4abc26836d22b4111c6781df73e5fc17fdbe202acda8a0dc635c265cbe1f773a8c7da54fbd655dc81c96edb4fe22
|
7
|
+
data.tar.gz: 891b669a04a587bd5908f58f0f197ebf96e4efb3cedfa63b3475458968b8247ca4557f1f700b41bea3f4df5957876e2d329e928e602a6ab05a5c7007f5a57ee2
|
data/.travis.yml
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
dist:
|
2
|
-
sudo: false
|
3
|
-
group: beta
|
1
|
+
dist: xenial
|
4
2
|
language: ruby
|
5
3
|
|
6
4
|
addons:
|
@@ -31,15 +29,6 @@ after_script:
|
|
31
29
|
- "xpra stop :9"
|
32
30
|
|
33
31
|
rvm:
|
34
|
-
- "2.0.0"
|
35
|
-
- "2.1"
|
36
|
-
- "2.2"
|
37
|
-
- "2.3.1"
|
38
|
-
- "2.4.0"
|
39
32
|
- "ruby-head"
|
40
|
-
|
41
|
-
|
42
|
-
matrix:
|
43
|
-
allow_failures:
|
44
|
-
- rvm: ruby-head
|
45
|
-
- rvm: rbx-3
|
33
|
+
- "2.6.0"
|
34
|
+
- "2.2"
|
data/Gemfile
CHANGED
@@ -9,9 +9,9 @@ gem 'mini_portile2'
|
|
9
9
|
|
10
10
|
group :development do
|
11
11
|
gem 'rake-compiler', '~> 1.0'
|
12
|
-
gem 'rake-compiler-dock', '~> 0.
|
12
|
+
gem 'rake-compiler-dock', '~> 0.7.0'
|
13
13
|
gem 'yard', '~> 0.8'
|
14
|
-
gem "bundler", "
|
14
|
+
gem "bundler", ">= 1.12", "< 3.a"
|
15
15
|
gem "rake", "~> 12.0"
|
16
16
|
end
|
17
17
|
|
data/History.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 1.6.40 / 2018-12-28
|
2
|
+
|
3
|
+
* Fix some library classes which failed, when Fox was not included into the global namespace.
|
4
|
+
* Add new accessor FXImage#dataPtr to access raw image data from FFI, Fiddle or OpenGL.
|
5
|
+
* Ensure zero terminated strings in values of C-argv.
|
6
|
+
* Remove various Ruby and C++ warnings.
|
7
|
+
* Update libfox to 1.6.57.
|
8
|
+
* Add support for RubyInstaller-2.6
|
9
|
+
* Set minimum required ruby version to 2.2.
|
10
|
+
|
1
11
|
=== 1.6.39 / 2017-12-26
|
2
12
|
|
3
13
|
* Fix FXGLVisual.supported and .supported?
|
data/appveyor.yml
CHANGED
@@ -3,14 +3,14 @@ init:
|
|
3
3
|
- SET RAKEOPT=-rdevkit
|
4
4
|
install:
|
5
5
|
- ps: |
|
6
|
-
if ($env:
|
7
|
-
$(new-object net.webclient).DownloadFile("https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller
|
6
|
+
if ($env:ruby_version -like "*head*") {
|
7
|
+
$(new-object net.webclient).DownloadFile("https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller-$env:ruby_version.exe", "$pwd/ruby-setup.exe")
|
8
8
|
cmd /c ruby-setup.exe /verysilent /dir=C:/Ruby$env:ruby_version
|
9
9
|
}
|
10
10
|
- ruby --version
|
11
11
|
- gem --version
|
12
12
|
- ridk version
|
13
|
-
- c:/msys64/usr/bin/bash -lc "pacman -Syu --noconfirm"
|
13
|
+
- c:/msys64/usr/bin/bash -lc "pacman -Syu --noconfirm --ask 20"
|
14
14
|
- c:/msys64/usr/bin/bash -lc "pacman -Su --noconfirm"
|
15
15
|
- c:/msys64/usr/bin/bash -lc "pacman -S --noconfirm --needed ${MINGW_PACKAGE_PREFIX}-fox ${MINGW_PACKAGE_PREFIX}-swig"
|
16
16
|
- swig -version
|
@@ -23,20 +23,9 @@ test_script:
|
|
23
23
|
- bundle exec rake test
|
24
24
|
environment:
|
25
25
|
matrix:
|
26
|
-
- ruby_version: "head"
|
27
|
-
RUBYDOWNLOAD: x86
|
28
|
-
MINGW_PACKAGE_PREFIX: "mingw-w64-i686"
|
29
|
-
MSYSTEM: "MINGW32"
|
30
|
-
- ruby_version: "24-x64"
|
26
|
+
- ruby_version: "head-x64"
|
31
27
|
MINGW_PACKAGE_PREFIX: "mingw-w64-x86_64"
|
32
28
|
MSYSTEM: "MINGW64"
|
33
29
|
- ruby_version: "24"
|
34
30
|
MINGW_PACKAGE_PREFIX: "mingw-w64-i686"
|
35
31
|
MSYSTEM: "MINGW32"
|
36
|
-
- ruby_version: "head"
|
37
|
-
RUBYDOWNLOAD: x64
|
38
|
-
MINGW_PACKAGE_PREFIX: "mingw-w64-x86_64"
|
39
|
-
MSYSTEM: "MINGW64"
|
40
|
-
matrix:
|
41
|
-
allow_failures:
|
42
|
-
- ruby_version: "head"
|
data/ext/fox16_c/FXRbApp.cpp
CHANGED
@@ -85,7 +85,7 @@ void FXRbApp::setThreadsEnabled(FXbool enabled){
|
|
85
85
|
interrupt_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
86
86
|
addInput(interrupt_event,INPUT_READ,this,ID_CHORE_THREADS);
|
87
87
|
#else
|
88
|
-
pipe(interrupt_fds);
|
88
|
+
if(pipe(interrupt_fds) == -1) rb_fatal("failed to allocate pipe for interrupt events");
|
89
89
|
fcntl(interrupt_fds[0], F_SETFL, O_NONBLOCK);
|
90
90
|
addInput(interrupt_fds[0],INPUT_READ,this,ID_CHORE_THREADS);
|
91
91
|
#endif
|
@@ -130,7 +130,7 @@ long FXRbApp::onChoreThreads(FXObject *obj,FXSelector sel,void *p){
|
|
130
130
|
#else
|
131
131
|
char byte;
|
132
132
|
// clear the pipe
|
133
|
-
read(interrupt_fds[0], &byte, 1);
|
133
|
+
if(read(interrupt_fds[0], &byte, 1) != 1) rb_fatal("failed to read from pipe for interrupt events");
|
134
134
|
#endif
|
135
135
|
#endif
|
136
136
|
return FXRbApp_onChoreThreads(this, obj, sel, p);
|
@@ -172,7 +172,7 @@ void fxrb_wakeup_fox(void *){
|
|
172
172
|
#ifdef WIN32
|
173
173
|
SetEvent(FXRbApp::interrupt_event);
|
174
174
|
#else
|
175
|
-
write(FXRbApp::interrupt_fds[1], "X", 1);
|
175
|
+
if(write(FXRbApp::interrupt_fds[1], "X", 1) != 1) rb_fatal("failed to write to pipe for interrupt events");
|
176
176
|
#endif
|
177
177
|
}
|
178
178
|
#endif
|
data/ext/fox16_c/FXRuby.cpp
CHANGED
@@ -1237,9 +1237,9 @@ void FXRbRange2LoHi(VALUE range,FXint& lo,FXint& hi){
|
|
1237
1237
|
rb_raise(rb_eTypeError,"wrong argument type %s (expected %s)",rb_class2name(CLASS_OF(range)),rb_class2name(rb_cRange));
|
1238
1238
|
}
|
1239
1239
|
else{
|
1240
|
-
VALUE beg=rb_funcall(range,id_begin,0
|
1241
|
-
VALUE end=rb_funcall(range,id_end,0
|
1242
|
-
VALUE excl=rb_funcall(range,id_exclude_endp,0
|
1240
|
+
VALUE beg=rb_funcall(range,id_begin,0);
|
1241
|
+
VALUE end=rb_funcall(range,id_end,0);
|
1242
|
+
VALUE excl=rb_funcall(range,id_exclude_endp,0);
|
1243
1243
|
lo=NUM2INT(beg);
|
1244
1244
|
hi=NUM2INT(end);
|
1245
1245
|
if(excl==Qtrue){
|
@@ -1253,9 +1253,9 @@ void FXRbRange2LoHi(VALUE range,FXdouble& lo,FXdouble& hi){
|
|
1253
1253
|
rb_raise(rb_eTypeError,"wrong argument type %s (expected %s)",rb_class2name(CLASS_OF(range)),rb_class2name(rb_cRange));
|
1254
1254
|
}
|
1255
1255
|
else{
|
1256
|
-
VALUE beg=rb_funcall(range,id_begin,0
|
1257
|
-
VALUE end=rb_funcall(range,id_end,0
|
1258
|
-
VALUE excl=rb_funcall(range,id_exclude_endp,0
|
1256
|
+
VALUE beg=rb_funcall(range,id_begin,0);
|
1257
|
+
VALUE end=rb_funcall(range,id_end,0);
|
1258
|
+
VALUE excl=rb_funcall(range,id_exclude_endp,0);
|
1259
1259
|
lo=NUM2DBL(beg);
|
1260
1260
|
hi=NUM2DBL(end);
|
1261
1261
|
if(excl==Qtrue){
|
@@ -1270,13 +1270,13 @@ void FXRbCallVoidMethod_gvlcb(FXObject* recv, const char *func) {
|
|
1270
1270
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1271
1271
|
FXASSERT(!NIL_P(obj));
|
1272
1272
|
FXASSERT(!FXRbIsInGC(recv));
|
1273
|
-
rb_funcall(obj,rb_intern(func),0
|
1273
|
+
rb_funcall(obj,rb_intern(func),0);
|
1274
1274
|
}
|
1275
1275
|
|
1276
1276
|
void FXRbCallVoidMethod_gvlcb(FXDC* recv,const char *func) {
|
1277
1277
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1278
1278
|
FXASSERT(!NIL_P(obj));
|
1279
|
-
rb_funcall(obj,rb_intern(func),0
|
1279
|
+
rb_funcall(obj,rb_intern(func),0);
|
1280
1280
|
}
|
1281
1281
|
|
1282
1282
|
//----------------------------------------------------------------------
|
@@ -1284,7 +1284,7 @@ void FXRbCallVoidMethod_gvlcb(FXDC* recv,const char *func) {
|
|
1284
1284
|
bool FXRbCallBoolMethod_gvlcb(const FXObject* recv,const char *func){
|
1285
1285
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1286
1286
|
FXASSERT(!NIL_P(obj));
|
1287
|
-
VALUE v=rb_funcall(obj,rb_intern(func),0
|
1287
|
+
VALUE v=rb_funcall(obj,rb_intern(func),0);
|
1288
1288
|
return (v==Qtrue);
|
1289
1289
|
}
|
1290
1290
|
|
@@ -1294,7 +1294,7 @@ bool FXRbCallBoolMethod_gvlcb(const FXObject* recv,const char *func){
|
|
1294
1294
|
FXint FXRbCallIntMethod_gvlcb(const FXObject* recv,const char *func){
|
1295
1295
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1296
1296
|
FXASSERT(!NIL_P(obj));
|
1297
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1297
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1298
1298
|
return static_cast<FXint>(NUM2INT(result));
|
1299
1299
|
}
|
1300
1300
|
|
@@ -1304,7 +1304,7 @@ FXint FXRbCallIntMethod_gvlcb(const FXObject* recv,const char *func){
|
|
1304
1304
|
FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLObject* recv,const char *func){
|
1305
1305
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1306
1306
|
FXASSERT(!NIL_P(obj));
|
1307
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1307
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1308
1308
|
return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
|
1309
1309
|
}
|
1310
1310
|
|
@@ -1392,7 +1392,7 @@ FXIcon* FXRbCallIconMethod_gvlcb(const FXTableItem* recv,const char *func){
|
|
1392
1392
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1393
1393
|
FXASSERT(!NIL_P(obj));
|
1394
1394
|
if(!NIL_P(obj)){
|
1395
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1395
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1396
1396
|
return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
|
1397
1397
|
}
|
1398
1398
|
else{
|
@@ -1415,7 +1415,7 @@ FXWindow* FXRbCallWindowMethod_gvlcb(const FXTableItem* recv,const char *func,FX
|
|
1415
1415
|
FXRangef FXRbCallRangeMethod_gvlcb(FXObject* recv,const char *func){
|
1416
1416
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1417
1417
|
FXASSERT(!NIL_P(obj));
|
1418
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1418
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1419
1419
|
return *reinterpret_cast<FXRangef*>(DATA_PTR(result));
|
1420
1420
|
}
|
1421
1421
|
|
@@ -1425,7 +1425,7 @@ FXRangef FXRbCallRangeMethod_gvlcb(FXObject* recv,const char *func){
|
|
1425
1425
|
FXString FXRbCallStringMethod_gvlcb(const FXObject* recv, const char *func){
|
1426
1426
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1427
1427
|
FXASSERT(!NIL_P(obj));
|
1428
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1428
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1429
1429
|
return FXString(StringValuePtr(result));
|
1430
1430
|
}
|
1431
1431
|
|
@@ -1452,7 +1452,7 @@ const FXchar* FXRbCallCStringMethod_gvlcb(const FXObject* recv, const char *func
|
|
1452
1452
|
FXwchar FXRbCallWCharMethod_gvlcb(const FXObject* recv, const char *func){
|
1453
1453
|
VALUE obj=FXRbGetRubyObj(recv,false);
|
1454
1454
|
FXASSERT(!NIL_P(obj));
|
1455
|
-
VALUE result=rb_funcall(obj,rb_intern(func),0
|
1455
|
+
VALUE result=rb_funcall(obj,rb_intern(func),0);
|
1456
1456
|
return static_cast<FXwchar>(NUM2ULONG(result));
|
1457
1457
|
}
|
1458
1458
|
|
data/ext/fox16_c/extconf.rb
CHANGED
@@ -24,20 +24,20 @@ end
|
|
24
24
|
LIBZ_VERSION = ENV['LIBZ_VERSION'] || '1.2.7.3'
|
25
25
|
LIBZ_SOURCE_URI = "http://zlib.net/fossils/zlib-#{LIBZ_VERSION}.tar.gz"
|
26
26
|
|
27
|
-
LIBPNG_VERSION = ENV['LIBPNG_VERSION'] || '1.6.
|
27
|
+
LIBPNG_VERSION = ENV['LIBPNG_VERSION'] || '1.6.36'
|
28
28
|
LIBPNG_SOURCE_URI = "http://prdownloads.sourceforge.net/libpng/libpng-#{LIBPNG_VERSION}.tar.gz"
|
29
29
|
|
30
30
|
# LIBJPEG_VERSION = ENV['LIBJPEG_VERSION'] || '9b'
|
31
31
|
# LIBJPEG_SOURCE_URI = "http://www.ijg.org/files/jpegsrc.v#{LIBJPEG_VERSION}.tar.gz"
|
32
32
|
|
33
|
-
LIBJPEG_VERSION = ENV['LIBJPEG_VERSION'] || '1.5.
|
33
|
+
LIBJPEG_VERSION = ENV['LIBJPEG_VERSION'] || '1.5.3'
|
34
34
|
LIBJPEG_SOURCE_URI = "https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-#{LIBJPEG_VERSION}.tar.gz"
|
35
35
|
|
36
|
-
LIBTIFF_VERSION = ENV['LIBTIFF_VERSION'] || '4.0.
|
36
|
+
LIBTIFF_VERSION = ENV['LIBTIFF_VERSION'] || '4.0.10'
|
37
37
|
LIBTIFF_SOURCE_URI = "http://download.osgeo.org/libtiff/tiff-#{LIBTIFF_VERSION}.tar.gz"
|
38
38
|
|
39
|
-
LIBFOX_VERSION = ENV['LIBFOX_VERSION'] || '1.6.
|
40
|
-
LIBFOX_SOURCE_URI = "http://
|
39
|
+
LIBFOX_VERSION = ENV['LIBFOX_VERSION'] || '1.6.57'
|
40
|
+
LIBFOX_SOURCE_URI = "http://fox-toolkit.org/ftp/fox-#{LIBFOX_VERSION}.tar.gz"
|
41
41
|
|
42
42
|
LIBFXSCINTILLA_VERSION = ENV['LIBFXSCINTILLA_VERSION'] || '2.28.0'
|
43
43
|
LIBFXSCINTILLA_SOURCE_URI = "http://download.savannah.gnu.org/releases/fxscintilla/fxscintilla-#{LIBFXSCINTILLA_VERSION}.tar.gz"
|
@@ -158,13 +158,6 @@ def do_rake_compiler_setup
|
|
158
158
|
"CPPFLAGS=-I#{libjpeg_recipe.path}/include -I#{libpng_recipe.path}/include -I#{libtiff_recipe.path}/include -I#{libz_recipe.path}/include -DUNICODE=1 #{debug ? "-ggdb" : ""}",
|
159
159
|
"LDFLAGS=-L#{libjpeg_recipe.path}/lib -L#{libpng_recipe.path}/lib -L#{libtiff_recipe.path}/lib -L#{libz_recipe.path}/lib #{debug ? "-ggdb" : ""}",
|
160
160
|
]
|
161
|
-
class << recipe
|
162
|
-
def compile
|
163
|
-
# Add param -no-undefined to libtool to build a win32 shared lib
|
164
|
-
execute "compile", "#{ENV['MAKE'] || "make"} libFOX_1_6_la_LDFLAGS='-version-info 0:49:0 -export-dynamic -no-undefined'"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
161
|
recipe.cook_and_activate
|
169
162
|
end
|
170
163
|
|
@@ -312,7 +305,6 @@ if enable_config("debug")
|
|
312
305
|
else
|
313
306
|
$CPPFLAGS += " -DNDEBUG"
|
314
307
|
end
|
315
|
-
$CPPFLAGS += " -Wno-unused-function"
|
316
308
|
|
317
309
|
# Platform-specific modifications
|
318
310
|
do_rake_compiler_setup
|
@@ -321,6 +313,11 @@ $CFLAGS += " -DRUBY_1_8" if RUBY_VERSION =~ /1\.8\./
|
|
321
313
|
$CFLAGS += " -DRUBY_1_9" if RUBY_VERSION =~ /1\.9\./
|
322
314
|
$CFLAGS += " -DRUBY_2_0" if RUBY_VERSION =~ /2\.0\./
|
323
315
|
|
316
|
+
if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
317
|
+
$CXXFLAGS += " -Wno-unused-function"
|
318
|
+
$CXXFLAGS += " -Wno-maybe-uninitialized"
|
319
|
+
end
|
320
|
+
|
324
321
|
# Last step: build the makefile
|
325
322
|
create_header
|
326
323
|
create_makefile("fox16_c")
|
@@ -73,7 +73,7 @@ static void cls ## _init(cls* self,VALUE ary,bool connect){ \
|
|
73
73
|
argv[0]=const_cast<char *>("foo"); \
|
74
74
|
for(i=1;i<argc;i++){ \
|
75
75
|
VALUE e=rb_ary_entry(ary,i-1); \
|
76
|
-
argv[i]=
|
76
|
+
argv[i]=StringValueCStr(e); \
|
77
77
|
} \
|
78
78
|
argv[argc]=0; \
|
79
79
|
self->cls::init(argc,argv,connect); \
|
@@ -127,7 +127,7 @@ inline void cls ## _exit(cls *self,FXint code){ \
|
|
127
127
|
argc=static_cast<int>(RARRAY_LEN(ary)+1); \
|
128
128
|
for(i=1; i<argc; i++){ \
|
129
129
|
VALUE e=rb_ary_entry(ary,i-1); \
|
130
|
-
argv[i]=
|
130
|
+
argv[i]=StringValueCStr(e); \
|
131
131
|
} \
|
132
132
|
} \
|
133
133
|
void cls::exit(FXint code){ \
|
@@ -535,7 +535,7 @@ void FXRbCallVoidMethod_gvlcb(FXObject* recv,const char *func,TYPE1& arg1,TYPE2
|
|
535
535
|
|
536
536
|
// Call function with "FXbool" return value
|
537
537
|
inline bool FXRbCallBoolMethod_gvlcb(FXStream* recv,const char *func){
|
538
|
-
VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),rb_intern(func),0
|
538
|
+
VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),rb_intern(func),0);
|
539
539
|
return (v==Qtrue);
|
540
540
|
}
|
541
541
|
|
data/fxruby.gemspec
CHANGED
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
|
|
48
48
|
spec.require_paths = ["lib"]
|
49
49
|
spec.extensions = ["ext/fox16_c/extconf.rb"]
|
50
50
|
spec.metadata['msys2_mingw_dependencies'] = 'fox'
|
51
|
+
spec.required_ruby_version = "~> 2.2"
|
51
52
|
|
52
53
|
spec.add_runtime_dependency 'mini_portile2', '~> 2.1'
|
53
54
|
end
|
data/lib/fox16/aliases.rb
CHANGED
data/lib/fox16/calendar.rb
CHANGED
@@ -99,7 +99,7 @@ module Fox
|
|
99
99
|
btn.connect(SEL_COMMAND) do |send, sel, ev|
|
100
100
|
@selected = Time.local(@date_showing.year, @date_showing.month,
|
101
101
|
send.text.to_i)
|
102
|
-
target.handle(self, MKUINT(selector, SEL_COMMAND), @selected) if target
|
102
|
+
target.handle(self, Fox.MKUINT(selector, SEL_COMMAND), @selected) if target
|
103
103
|
end
|
104
104
|
end
|
105
105
|
_build_date_matrix()
|
@@ -202,16 +202,14 @@ end
|
|
202
202
|
|
203
203
|
if __FILE__ == $0
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
app = FXApp.new('Calendar', 'FXRuby')
|
205
|
+
app = Fox::FXApp.new('Calendar', 'FXRuby')
|
208
206
|
app.init(ARGV)
|
209
|
-
mainwin = FXMainWindow.new(app, "Calendar Test", nil, nil, DECOR_ALL, 0, 0, 500, 500)
|
210
|
-
calendar = FXCalendar.new(mainwin, Time.now, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
211
|
-
calendar.connect(SEL_COMMAND) do |sender, sel, data|
|
207
|
+
mainwin = Fox::FXMainWindow.new(app, "Calendar Test", nil, nil, Fox::DECOR_ALL, 0, 0, 500, 500)
|
208
|
+
calendar = Fox::FXCalendar.new(mainwin, Time.now, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
|
209
|
+
calendar.connect(Fox::SEL_COMMAND) do |sender, sel, data|
|
212
210
|
puts data.to_s
|
213
211
|
end
|
214
212
|
app.create
|
215
|
-
mainwin.show(PLACEMENT_SCREEN)
|
213
|
+
mainwin.show(Fox::PLACEMENT_SCREEN)
|
216
214
|
app.run
|
217
215
|
end
|
data/lib/fox16/canvas.rb
CHANGED
@@ -312,7 +312,7 @@ module Fox
|
|
312
312
|
shape.select
|
313
313
|
@canvas.updateShape(shape)
|
314
314
|
if notify && (@canvas.target != nil)
|
315
|
-
@canvas.target.handle(@canvas, MKUINT(@canvas.message, SEL_SELECTED), shape)
|
315
|
+
@canvas.target.handle(@canvas, Fox.MKUINT(@canvas.message, SEL_SELECTED), shape)
|
316
316
|
end
|
317
317
|
end
|
318
318
|
end
|
@@ -322,7 +322,7 @@ module Fox
|
|
322
322
|
shape.deselect
|
323
323
|
@canvas.updateShape(shape)
|
324
324
|
if notify && (@canvas.target != nil)
|
325
|
-
@canvas.target.handle(@canvas, MKUINT(@canvas.message, SEL_DESELECTED), shape)
|
325
|
+
@canvas.target.handle(@canvas, Fox.MKUINT(@canvas.message, SEL_DESELECTED), shape)
|
326
326
|
end
|
327
327
|
end
|
328
328
|
end
|
@@ -463,7 +463,7 @@ module Fox
|
|
463
463
|
updateShape(shape)
|
464
464
|
changes = true
|
465
465
|
if notify && (target != nil)
|
466
|
-
target.handle(self, MKUINT(message, SEL_DESELECTED), shape)
|
466
|
+
target.handle(self, Fox.MKUINT(message, SEL_DESELECTED), shape)
|
467
467
|
end
|
468
468
|
end
|
469
469
|
end
|
@@ -486,7 +486,7 @@ module Fox
|
|
486
486
|
def onMotion(sender, sel, evt)
|
487
487
|
# Drag and drop mode
|
488
488
|
if (@flags & FLAG_DODRAG) != 0
|
489
|
-
handle(self, MKUINT(0, SEL_DRAGGED), evt)
|
489
|
+
handle(self, Fox.MKUINT(0, SEL_DRAGGED), evt)
|
490
490
|
return 1
|
491
491
|
end
|
492
492
|
|
@@ -494,7 +494,7 @@ module Fox
|
|
494
494
|
if (@flags & FLAG_TRYDRAG) != 0
|
495
495
|
if evt.moved?
|
496
496
|
@flags &= ~FLAG_TRYDRAG
|
497
|
-
if handle(this, MKUINT(0, SEL_BEGINDRAG), evt) != 0
|
497
|
+
if handle(this, Fox.MKUINT(0, SEL_BEGINDRAG), evt) != 0
|
498
498
|
@flags |= FLAG_DODRAG
|
499
499
|
end
|
500
500
|
end
|
@@ -504,13 +504,13 @@ module Fox
|
|
504
504
|
|
505
505
|
# Left button press
|
506
506
|
def onLeftBtnPress(sender, sel, evt)
|
507
|
-
handle(self, MKUINT(0, SEL_FOCUS_SELF), evt)
|
507
|
+
handle(self, Fox.MKUINT(0, SEL_FOCUS_SELF), evt)
|
508
508
|
if enabled?
|
509
509
|
grab
|
510
510
|
flags &= ~FLAG_UPDATE
|
511
511
|
|
512
512
|
# Give target the first chance at handling this
|
513
|
-
return 1 if target && (target.handle(self, MKUINT(message, SEL_LEFTBUTTONPRESS), evt) != 0)
|
513
|
+
return 1 if target && (target.handle(self, Fox.MKUINT(message, SEL_LEFTBUTTONPRESS), evt) != 0)
|
514
514
|
|
515
515
|
# Locate shape
|
516
516
|
shape = findShape(evt.win_x, evt.win_y)
|
@@ -548,11 +548,11 @@ module Fox
|
|
548
548
|
@flags &= ~(FLAG_PRESSED|FLAG_TRYDRAG|FLAG_LASSO|FLAG_DODRAG)
|
549
549
|
|
550
550
|
# First chance callback
|
551
|
-
return 1 if target && target.handle(self, MKUINT(message, SEL_LEFTBUTTONRELEASE), evt) != 0
|
551
|
+
return 1 if target && target.handle(self, Fox.MKUINT(message, SEL_LEFTBUTTONRELEASE), evt) != 0
|
552
552
|
|
553
553
|
# Was dragging
|
554
554
|
if (flg & FLAG_DODRAG) != 0
|
555
|
-
handle(self, MKUINT(0, SEL_ENDDRAG), evt)
|
555
|
+
handle(self, Fox.MKUINT(0, SEL_ENDDRAG), evt)
|
556
556
|
return 1
|
557
557
|
end
|
558
558
|
|
@@ -565,16 +565,16 @@ module Fox
|
|
565
565
|
|
566
566
|
# Generate clicked callbacks
|
567
567
|
if evt.click_count == 1
|
568
|
-
handle(self, MKUINT(0, SEL_CLICKED), @currentShape)
|
568
|
+
handle(self, Fox.MKUINT(0, SEL_CLICKED), @currentShape)
|
569
569
|
elsif evt.click_count == 2
|
570
|
-
handle(self, MKUINT(0, SEL_DOUBLECLICKED), @currentShape)
|
570
|
+
handle(self, Fox.MKUINT(0, SEL_DOUBLECLICKED), @currentShape)
|
571
571
|
elseif evt.click_count == 3
|
572
|
-
handle(self, MKUINT(0, SEL_TRIPLECLICKED), @currentShape)
|
572
|
+
handle(self, Fox.MKUINT(0, SEL_TRIPLECLICKED), @currentShape)
|
573
573
|
end
|
574
574
|
|
575
575
|
# Generate command callback only when clicked on item
|
576
576
|
if @currentShape && @currentShape.enabled?
|
577
|
-
handle(self, MKUINT(0, SEL_COMMAND), @currentShape)
|
577
|
+
handle(self, Fox.MKUINT(0, SEL_COMMAND), @currentShape)
|
578
578
|
end
|
579
579
|
return 1
|
580
580
|
end
|
@@ -584,22 +584,22 @@ module Fox
|
|
584
584
|
|
585
585
|
# Command message
|
586
586
|
def onCommand(sender, sel, ptr)
|
587
|
-
return target && target.handle(self, MKUINT(message, SEL_COMMAND), ptr)
|
587
|
+
return target && target.handle(self, Fox.MKUINT(message, SEL_COMMAND), ptr)
|
588
588
|
end
|
589
589
|
|
590
590
|
# Clicked on canvas
|
591
591
|
def onClicked(sender, sel, ptr)
|
592
|
-
return target && target.handle(self, MKUINT(message, SEL_CLICKED), ptr)
|
592
|
+
return target && target.handle(self, Fox.MKUINT(message, SEL_CLICKED), ptr)
|
593
593
|
end
|
594
594
|
|
595
595
|
# Double-clicked on canvas
|
596
596
|
def onDoubleClicked(sender, sel, ptr)
|
597
|
-
return target && target.handle(self, MKUINT(message, SEL_DOUBLECLICKED), ptr)
|
597
|
+
return target && target.handle(self, Fox.MKUINT(message, SEL_DOUBLECLICKED), ptr)
|
598
598
|
end
|
599
599
|
|
600
600
|
# Triple-clicked on canvas
|
601
601
|
def onTripleClicked(sender, sel, ptr)
|
602
|
-
return target && target.handle(self, MKUINT(message, SEL_TRIPLECLICKED), ptr)
|
602
|
+
return target && target.handle(self, Fox.MKUINT(message, SEL_TRIPLECLICKED), ptr)
|
603
603
|
end
|
604
604
|
end
|
605
605
|
end
|
data/lib/fox16/core.rb
CHANGED
@@ -421,24 +421,24 @@ module Fox
|
|
421
421
|
#
|
422
422
|
def FXStreamError.makeStreamError(status)
|
423
423
|
case status
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
424
|
+
when FXStreamEnd
|
425
|
+
FXStreamEndError
|
426
|
+
when FXStreamFull
|
427
|
+
FXStreamFullError
|
428
|
+
when FXStreamNoWrite
|
429
|
+
FXStreamNoWriteError
|
430
|
+
when FXStreamNoRead
|
431
|
+
FXStreamNoReadError
|
432
|
+
when FXStreamFormat
|
433
|
+
FXStreamFormatError
|
434
|
+
when FXStreamUnknown
|
435
|
+
FXStreamUnknownError
|
436
|
+
when FXStreamAlloc
|
437
|
+
FXStreamAllocError
|
438
|
+
when FXStreamFailure
|
439
|
+
FXStreamFailureError
|
440
|
+
else
|
441
|
+
FXStreamError
|
442
442
|
end
|
443
443
|
end
|
444
444
|
end
|
data/lib/fox16/undolist.rb
CHANGED
@@ -344,9 +344,9 @@ module Fox
|
|
344
344
|
|
345
345
|
def onUpdUndo(sender, sel, ptr) # :nodoc:
|
346
346
|
if canUndo?
|
347
|
-
sender.handle(self, MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
347
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
348
348
|
else
|
349
|
-
sender.handle(self, MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
349
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
350
350
|
end
|
351
351
|
return 1
|
352
352
|
end
|
@@ -358,9 +358,9 @@ module Fox
|
|
358
358
|
|
359
359
|
def onUpdRedo(sender, sel, ptr) # :nodoc:
|
360
360
|
if canRedo?
|
361
|
-
sender.handle(self, MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
361
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
362
362
|
else
|
363
|
-
sender.handle(self, MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
363
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
364
364
|
end
|
365
365
|
return 1
|
366
366
|
end
|
@@ -372,9 +372,9 @@ module Fox
|
|
372
372
|
|
373
373
|
def onUpdClear(sender, sel, ptr) # :nodoc:
|
374
374
|
if canUndo? || canRedo?
|
375
|
-
sender.handle(self, MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
375
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
376
376
|
else
|
377
|
-
sender.handle(self, MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
377
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
378
378
|
end
|
379
379
|
return 1
|
380
380
|
end
|
@@ -386,9 +386,9 @@ module Fox
|
|
386
386
|
|
387
387
|
def onUpdRevert(sender, sel, ptr) # :nodoc:
|
388
388
|
if canRevert?
|
389
|
-
sender.handle(self, MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
389
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_ENABLE, SEL_COMMAND), nil)
|
390
390
|
else
|
391
|
-
sender.handle(self, MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
391
|
+
sender.handle(self, Fox.MKUINT(FXWindow::ID_DISABLE, SEL_COMMAND), nil)
|
392
392
|
end
|
393
393
|
return 1
|
394
394
|
end
|
data/lib/fox16/version.rb
CHANGED
data/rdoc-sources/FXImage.rb
CHANGED
@@ -45,6 +45,11 @@ module Fox
|
|
45
45
|
# [deprecated] Pixel data {FXMemoryBuffer}
|
46
46
|
attr_reader :data
|
47
47
|
|
48
|
+
# The pointer to the raw color representation of all image pixels.
|
49
|
+
#
|
50
|
+
# It can be used to pass raw image data to FFI, Fiddle or OpenGL.
|
51
|
+
attr_reader :dataPtr
|
52
|
+
|
48
53
|
# Array of colors of all image pixels. Can also be written as String of raw [RGBA] values.
|
49
54
|
attr_accessor :pixels
|
50
55
|
|
data/swig-interfaces/FXImage.i
CHANGED
@@ -58,7 +58,7 @@ public:
|
|
58
58
|
FXImage(FXApp* a,VALUE string_or_ary=Qnil,FXuint opts=0,FXint w=1,FXint h=1){
|
59
59
|
FXColor* pix=0;
|
60
60
|
if(!NIL_P(string_or_ary)){
|
61
|
-
|
61
|
+
FXint len=FXRbNumberOfFXColors(string_or_ary);
|
62
62
|
if(w*h != len){
|
63
63
|
rb_raise( rb_eArgError, "Array size does not match image size" );
|
64
64
|
}
|
@@ -76,6 +76,11 @@ public:
|
|
76
76
|
return 0;
|
77
77
|
}
|
78
78
|
}
|
79
|
+
|
80
|
+
/// Get a pointer to the pixel data
|
81
|
+
VALUE getDataPtr() const {
|
82
|
+
return ULL2NUM((uintptr_t)self->getData());
|
83
|
+
}
|
79
84
|
}
|
80
85
|
|
81
86
|
/// To get to the option flags
|
@@ -92,9 +97,9 @@ public:
|
|
92
97
|
* This can be done by calling render().
|
93
98
|
*/
|
94
99
|
void setPixels(VALUE string_or_ary,FXuint opts=0,VALUE w=Qnil,VALUE h=Qnil){
|
95
|
-
|
100
|
+
FXint len=FXRbNumberOfFXColors(string_or_ary);
|
96
101
|
if( ( (NIL_P(w) || NIL_P(h)) && self->getWidth()*self->getHeight() != len) ||
|
97
|
-
(!(NIL_P(w) || NIL_P(h)) &&
|
102
|
+
(!(NIL_P(w) || NIL_P(h)) && NUM2INT(w)*NUM2INT(h) != len)){
|
98
103
|
rb_raise( rb_eArgError, "Array size does not match image size" );
|
99
104
|
}
|
100
105
|
|
@@ -111,7 +116,7 @@ public:
|
|
111
116
|
if (data) {
|
112
117
|
FXuint size = self->getWidth()*self->getHeight();
|
113
118
|
VALUE ary = rb_ary_new2(size);
|
114
|
-
for (
|
119
|
+
for (FXuint i = 0; i < size; i++)
|
115
120
|
rb_ary_store(ary, i, UINT2NUM(data[i]));
|
116
121
|
return ary;
|
117
122
|
} else {
|
@@ -27,7 +27,7 @@
|
|
27
27
|
class FXMemoryBuffer {
|
28
28
|
public:
|
29
29
|
// Create an memory buffer object
|
30
|
-
FXMemoryBuffer(FXColor *data,
|
30
|
+
FXMemoryBuffer(FXColor *data,FXint size);
|
31
31
|
|
32
32
|
// Returns the size (in bytes)
|
33
33
|
FXuint getSize() const;
|
@@ -39,7 +39,7 @@ public:
|
|
39
39
|
if (data) {
|
40
40
|
FXuint size = self->getSize();
|
41
41
|
VALUE ary = rb_ary_new2(size);
|
42
|
-
for (
|
42
|
+
for (FXuint i = 0; i < size; i++)
|
43
43
|
rb_ary_store(ary, i, UINT2NUM(data[i]));
|
44
44
|
return ary;
|
45
45
|
}
|
data/test/TC_FXImage.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'testcase'
|
3
3
|
require 'fox16'
|
4
|
+
require 'fiddle'
|
4
5
|
|
5
6
|
class TC_FXImage < Fox::TestCase
|
6
7
|
include Fox
|
@@ -80,6 +81,13 @@ class TC_FXImage < Fox::TestCase
|
|
80
81
|
assert_equal("rgbaRGBA", img.pixel_string)
|
81
82
|
end
|
82
83
|
|
84
|
+
def test_dataPtr
|
85
|
+
img = FXImage.new(app, nil, 0, 2, 1)
|
86
|
+
img.pixels = "rgbaRGBA"
|
87
|
+
assert_equal(0, img.options)
|
88
|
+
assert_equal("rgbaRGBA", Fiddle::Pointer.new(img.dataPtr)[0, 8])
|
89
|
+
end
|
90
|
+
|
83
91
|
def test_create
|
84
92
|
#
|
85
93
|
# If the image owns its pixel data and IMAGE_KEEP was not specified,
|
data/test/TC_FXList.rb
CHANGED
@@ -46,17 +46,17 @@ class TC_FXList < Fox::TestCase
|
|
46
46
|
|
47
47
|
def test_appendItem_byText
|
48
48
|
assert_equal(0, @list.numItems)
|
49
|
-
|
49
|
+
assert_equal 0, @list.appendItem("")
|
50
50
|
assert_equal(1, @list.numItems)
|
51
|
-
|
51
|
+
assert_equal 1, @list.appendItem("anItem")
|
52
52
|
assert_equal(2, @list.numItems)
|
53
|
-
|
53
|
+
assert_equal 2, @list.appendItem("anItem", nil)
|
54
54
|
assert_equal(3, @list.numItems)
|
55
|
-
|
55
|
+
assert_equal 3, @list.appendItem("anItem", nil, "someData")
|
56
56
|
assert_equal(4, @list.numItems)
|
57
|
-
|
57
|
+
assert_equal 4, @list.appendItem("anItem", nil, "someData", true)
|
58
58
|
assert_equal(5, @list.numItems)
|
59
|
-
|
59
|
+
assert_equal 5, @list.appendItem("anItem", nil, "someData", false)
|
60
60
|
assert_equal(6, @list.numItems)
|
61
61
|
assert_raises(ArgumentError) do
|
62
62
|
@list.appendItem("anItem", nil, "someData", 42) # last argument must be true or false
|
@@ -103,9 +103,9 @@ class TC_FXList < Fox::TestCase
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def test_makeItemVisible
|
106
|
-
items = []
|
107
106
|
0.upto(2) { |i|
|
108
|
-
|
107
|
+
itemIndex = @list.appendItem("item#{i}")
|
108
|
+
assert_equal i, itemIndex
|
109
109
|
}
|
110
110
|
assert_raises(IndexError) {
|
111
111
|
@list.makeItemVisible(-1)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fxruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.40
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Lyle Johnson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mini_portile2
|
@@ -426,12 +426,11 @@ files:
|
|
426
426
|
- ext/fox16_c/unregisterOwnedObjects.cpp
|
427
427
|
- fxruby.gemspec
|
428
428
|
- index.html
|
429
|
-
- lib/2.0/fox16_c.so
|
430
|
-
- lib/2.1/fox16_c.so
|
431
429
|
- lib/2.2/fox16_c.so
|
432
430
|
- lib/2.3/fox16_c.so
|
433
431
|
- lib/2.4/fox16_c.so
|
434
432
|
- lib/2.5/fox16_c.so
|
433
|
+
- lib/2.6/fox16_c.so
|
435
434
|
- lib/fox16.rb
|
436
435
|
- lib/fox16/accel_table.rb
|
437
436
|
- lib/fox16/aliases.rb
|
@@ -1004,10 +1003,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1004
1003
|
requirements:
|
1005
1004
|
- - ">="
|
1006
1005
|
- !ruby/object:Gem::Version
|
1007
|
-
version: '2.
|
1006
|
+
version: '2.2'
|
1008
1007
|
- - "<"
|
1009
1008
|
- !ruby/object:Gem::Version
|
1010
|
-
version:
|
1009
|
+
version: 2.7.dev
|
1011
1010
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1012
1011
|
requirements:
|
1013
1012
|
- - ">="
|
@@ -1015,7 +1014,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1015
1014
|
version: '0'
|
1016
1015
|
requirements: []
|
1017
1016
|
rubyforge_project:
|
1018
|
-
rubygems_version: 2.
|
1017
|
+
rubygems_version: 2.7.8
|
1019
1018
|
signing_key:
|
1020
1019
|
specification_version: 4
|
1021
1020
|
summary: FXRuby is the Ruby binding to the FOX GUI toolkit.
|