fxruby 1.6.29-x64-mingw32 → 1.6.30-x64-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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +11 -0
  3. data/Manifest.txt +5 -0
  4. data/Rakefile +8 -2
  5. data/examples/gltest.rb +0 -7
  6. data/examples/groupbox.rb +5 -3
  7. data/examples/thread.rb +55 -0
  8. data/ext/fox16_c/FXRbApp.cpp +67 -5
  9. data/ext/fox16_c/FXRuby.cpp +142 -110
  10. data/ext/fox16_c/extconf.rb +36 -28
  11. data/ext/fox16_c/gvl_wrappers.cpp +12 -0
  12. data/ext/fox16_c/include/FXRbApp.h +41 -6
  13. data/ext/fox16_c/include/FXRbBitmap.h +12 -12
  14. data/ext/fox16_c/include/FXRbCommon.h +3 -0
  15. data/ext/fox16_c/include/FXRbCursor.h +2 -2
  16. data/ext/fox16_c/include/FXRbDC.h +62 -62
  17. data/ext/fox16_c/include/FXRbDialogBox.h +2 -2
  18. data/ext/fox16_c/include/FXRbDockBar.h +3 -3
  19. data/ext/fox16_c/include/FXRbDockSite.h +4 -4
  20. data/ext/fox16_c/include/FXRbDrawable.h +1 -1
  21. data/ext/fox16_c/include/FXRbFileDict.h +3 -3
  22. data/ext/fox16_c/include/FXRbFoldingList.h +28 -28
  23. data/ext/fox16_c/include/FXRbFont.h +18 -18
  24. data/ext/fox16_c/include/FXRbGLCanvas.h +4 -4
  25. data/ext/fox16_c/include/FXRbGLObject.h +8 -8
  26. data/ext/fox16_c/include/FXRbGLShape.h +1 -1
  27. data/ext/fox16_c/include/FXRbGLViewer.h +3 -3
  28. data/ext/fox16_c/include/FXRbHeader.h +7 -7
  29. data/ext/fox16_c/include/FXRbIconList.h +28 -28
  30. data/ext/fox16_c/include/FXRbIconSource.h +12 -12
  31. data/ext/fox16_c/include/FXRbId.h +3 -3
  32. data/ext/fox16_c/include/FXRbImage.h +19 -19
  33. data/ext/fox16_c/include/FXRbList.h +21 -21
  34. data/ext/fox16_c/include/FXRbListBox.h +1 -1
  35. data/ext/fox16_c/include/FXRbMDIChild.h +4 -4
  36. data/ext/fox16_c/include/FXRbMDIClient.h +4 -4
  37. data/ext/fox16_c/include/FXRbObject.h +2 -2
  38. data/ext/fox16_c/include/FXRbPopup.h +2 -2
  39. data/ext/fox16_c/include/FXRbRealSpinner.h +1 -1
  40. data/ext/fox16_c/include/FXRbScrollArea.h +4 -4
  41. data/ext/fox16_c/include/FXRbShutter.h +1 -1
  42. data/ext/fox16_c/include/FXRbSpinner.h +1 -1
  43. data/ext/fox16_c/include/FXRbStream.h +3 -3
  44. data/ext/fox16_c/include/FXRbTabBar.h +1 -1
  45. data/ext/fox16_c/include/FXRbTable.h +53 -53
  46. data/ext/fox16_c/include/FXRbText.h +23 -23
  47. data/ext/fox16_c/include/FXRbTopWindow.h +5 -5
  48. data/ext/fox16_c/include/FXRbTranslator.h +1 -1
  49. data/ext/fox16_c/include/FXRbTreeList.h +28 -28
  50. data/ext/fox16_c/include/FXRbTreeListBox.h +1 -1
  51. data/ext/fox16_c/include/FXRbWindow.h +31 -31
  52. data/ext/fox16_c/include/FXRuby.h +200 -94
  53. data/ext/fox16_c/include/gvl_wrappers.h +594 -0
  54. data/lib/2.0/fox16_c.so +0 -0
  55. data/lib/2.1/fox16_c.so +0 -0
  56. data/lib/2.2/fox16_c.so +0 -0
  57. data/lib/fox16.rb +1 -0
  58. data/lib/fox16/thread.rb +51 -0
  59. data/lib/fox16/version.rb +1 -1
  60. data/lib/x64-mingw32/libFOX-1.6-0.dll +0 -0
  61. data/lib/x64-mingw32/libfxscintilla-20.dll +0 -0
  62. data/lib/x64-mingw32/libgcc_s_sjlj-1.dll +0 -0
  63. data/lib/x64-mingw32/libjpeg-8.dll +0 -0
  64. data/lib/x64-mingw32/libpng15-15.dll +0 -0
  65. data/lib/x64-mingw32/libstdc++-6.dll +0 -0
  66. data/lib/x64-mingw32/libtiff-5.dll +0 -0
  67. data/lib/x64-mingw32/libwinpthread-1.dll +0 -0
  68. data/lib/x64-mingw32/zlib1.dll +0 -0
  69. data/rdoc-sources/FXApp.rb +5 -0
  70. data/rdoc-sources/FXId.rb +5 -0
  71. data/swig-interfaces/FXApp.i +14 -78
  72. data/swig-interfaces/macros.i +56 -0
  73. data/test/TC_FXApp.rb +60 -10
  74. data/test/TC_FXJPGImage.rb +47 -0
  75. metadata +24 -103
  76. checksums.yaml.gz.sig +0 -0
  77. data.tar.gz.sig +0 -3
  78. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62ea05a13170399b0045b4f1b8dc4676e6406e99
4
- data.tar.gz: 31ce6631312ea1da5af8f6ba9364ed66f24834df
3
+ metadata.gz: f0bf4b64f57d2446d2c482c5ede727e3f5309d1c
4
+ data.tar.gz: 9cd6ad3dc5da44c86521d8e4c6411f3b4aff4309
5
5
  SHA512:
6
- metadata.gz: eea35082e677a3c2474d8e96859b16b731b9d097e25280476e13f7501cc5cd7fd644c015463a3dcbe142002539352918126510292bca7609b76a672292ee18ef
7
- data.tar.gz: 97c99cf164f67bd0dd8ddb20fa30724b3dfd7c58b57538fe4467bc94c38a64fa46d69f2766e365461c1afecdf5a8ba4b0ca683a89d3e609341a0f9038ba9eb66
6
+ metadata.gz: 863622f0b1f4ecfda39f3b20e2de8ff82aa00c0aedffa7d63f2561ea1d9ba6e3e5f82c1208207c85a280a0095a03f2f2aa5d23c9718f00e0243ead9794013e72
7
+ data.tar.gz: c90aa625b0ecf622a93bc89b953510ec362bab6a5c65815c50e05ed1b530e1f3b4b5155524621ed24b52422e1f1b7a3c9399af871060db7140af4940624e830d
@@ -1,3 +1,14 @@
1
+ === 1.6.30 / 2015-07-07
2
+
3
+ * Fix crashes in rb_gc_mark(): 0x00000003f54af8 is T_ZOMBIE / T_NONE
4
+ * Release Ruby's GVL while calls to FXImage#savePixels, #loadPixels
5
+ and FXApp#run* methods.
6
+ * Add a working version for FXApp#addInput event handling on Windows.
7
+ This works for sockets only for now.
8
+ * Add FXApp#runOnUiThread and FXId#runOnUiThread .
9
+ This allows to safely execute GUI code from other threads.
10
+ * Use rake-compiler-dock for building windows binary gems.
11
+
1
12
  === 1.6.29 / 2015-02-17
2
13
 
3
14
  * Add Windows binaries for Ruby-2.1 and 2.2.
@@ -128,6 +128,7 @@ examples/textedit/commands.rb
128
128
  examples/textedit/helpwindow.rb
129
129
  examples/textedit/prefdialog.rb
130
130
  examples/textedit/textedit.rb
131
+ examples/thread.rb
131
132
  examples/unicode.rb
132
133
  ext/fox16_c/FXRbApp.cpp
133
134
  ext/fox16_c/FXRbDataTarget.cpp
@@ -135,6 +136,7 @@ ext/fox16_c/FXRbGLViewer.cpp
135
136
  ext/fox16_c/FXRuby.cpp
136
137
  ext/fox16_c/MANIFEST
137
138
  ext/fox16_c/extconf.rb
139
+ ext/fox16_c/gvl_wrappers.cpp
138
140
  ext/fox16_c/impl.cpp
139
141
  ext/fox16_c/include/FXMemoryBuffer.h
140
142
  ext/fox16_c/include/FXRb4Splitter.h
@@ -357,6 +359,7 @@ ext/fox16_c/include/FXRbXBMImage.h
357
359
  ext/fox16_c/include/FXRbXPMIcon.h
358
360
  ext/fox16_c/include/FXRbXPMImage.h
359
361
  ext/fox16_c/include/FXRuby.h
362
+ ext/fox16_c/include/gvl_wrappers.h
360
363
  ext/fox16_c/include/impl.h
361
364
  ext/fox16_c/make_impl.rb
362
365
  ext/fox16_c/markfuncs.cpp
@@ -675,6 +678,7 @@ lib/fox16/scintilla.rb
675
678
  lib/fox16/settings.rb
676
679
  lib/fox16/signal.rb
677
680
  lib/fox16/splashscreen.rb
681
+ lib/fox16/thread.rb
678
682
  lib/fox16/timeout.rb
679
683
  lib/fox16/tkcompat.rb
680
684
  lib/fox16/undolist.rb
@@ -1142,6 +1146,7 @@ test/TC_FXIconDict.rb
1142
1146
  test/TC_FXIconList.rb
1143
1147
  test/TC_FXId.rb
1144
1148
  test/TC_FXImage.rb
1149
+ test/TC_FXJPGImage.rb
1145
1150
  test/TC_FXLight.rb
1146
1151
  test/TC_FXList.rb
1147
1152
  test/TC_FXListBox.rb
data/Rakefile CHANGED
@@ -21,7 +21,6 @@ PKG_VERSION = Fox.fxrubyversion
21
21
 
22
22
  SWIG = (RUBY_PLATFORM =~ /mingw/) ? "swig.exe" : "swig"
23
23
  SWIGFLAGS = "-c++ -ruby -nodefaultdtor -nodefaultctor -w302 -features compactdefaultargs -I../fox-includes"
24
- SWIG_LIB = `#{SWIG} -swiglib`.chomp
25
24
  SWIG_MODULES = {
26
25
  "core.i" => "core_wrap.cpp",
27
26
  "dcmodule.i" => "dc_wrap.cpp",
@@ -47,7 +46,7 @@ SWIG_MODULES = {
47
46
  hoe = Hoe.spec "fxruby" do
48
47
  # ... project specific data ...
49
48
  self.blog_categories = %w{FXRuby}
50
- self.clean_globs = [".config", "ext/fox16_c/Makefile", "ext/fox16_c/*.o", "ext/fox16_c/*.bundle", "ext/fox16_c/mkmf.log", "ext/fox16_c/conftest.dSYM", "ext/fox16_c/include/swigrubyrun.h", "ext/fox16_c/librb.c", "ext/fox16_c/include/inlinestubs.h", "ext/fox16_c/*_wrap.cpp"]
49
+ self.clean_globs = [".config", "ext/fox16_c/Makefile", "ext/fox16_c/*.o", "ext/fox16_c/*.bundle", "ext/fox16_c/mkmf.log", "ext/fox16_c/conftest.dSYM", "ext/fox16_c/include/swigrubyrun.h", "ext/fox16_c/librb.c", "ext/fox16_c/include/inlinestubs.h", "ext/fox16_c/*_wrap.cpp", "tmp", "ports/*.installed", "ports/*mingw32*"]
51
50
  developer("Lyle Johnson", "lyle@lylejohnson.name")
52
51
  developer("Lars Kanis", "kanis@comcard.de")
53
52
  self.extra_rdoc_files = ["rdoc-sources", File.join("rdoc-sources", "README.rdoc")]
@@ -63,6 +62,7 @@ hoe = Hoe.spec "fxruby" do
63
62
  self.version = PKG_VERSION
64
63
  self.readme_file = 'README.rdoc'
65
64
  self.extra_rdoc_files << self.readme_file
65
+ self.extra_deps << ['mini_portile', '~> 0.6']
66
66
 
67
67
  spec_extras[:files] = File.read_utf("Manifest.txt").split(/\r?\n\r?/).reject{|f| f=~/^fox-includes|^web/ }
68
68
  spec_extras[:files] += SWIG_MODULES.values.map{|f| File.join("ext/fox16_c", f) }
@@ -126,6 +126,12 @@ ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
126
126
  end
127
127
  end
128
128
 
129
+ desc "Build the windows binary gems"
130
+ task 'gem:windows' => 'gem' do
131
+ require 'rake_compiler_dock'
132
+ RakeCompilerDock.sh "rake cross native gem RUBYOPT=--disable-rubygems MAKE=\"nice make V=1 -j `nproc`\" "
133
+ end
134
+
129
135
  # Set environment variable SWIG_LIB to
130
136
  # c:/ruby-1.8.6-p383-preview2/devkit/msys/1.0.11/usr/local/share/swig/1.3.22
131
137
  # before running swig on MinGW.
@@ -312,13 +312,6 @@ if __FILE__ == $0
312
312
  # Construct the application
313
313
  application = FXApp.new("GLTest", "FoxTest")
314
314
 
315
- # To ensure that the chores-based spin will run as fast as possible,
316
- # we can disable the chore in FXRuby's event loop that tries to schedule
317
- # other threads. This is OK for this program because there aren't any
318
- # other Ruby threads running.
319
-
320
- application.disableThreads
321
-
322
315
  # Construct the main window
323
316
  GLTestWindow.new(application)
324
317
 
@@ -361,12 +361,14 @@ class GroupWindow < FXMainWindow
361
361
  show(PLACEMENT_SCREEN)
362
362
 
363
363
  # Create a thread to update the clock
364
- @clockThread = Thread.new(@clockLabel) { |clockLabel|
364
+ @clockThread = Thread.new(@clockLabel) do |clockLabel|
365
365
  while true
366
- clockLabel.text = Time.now.strftime("%I:%M:%S %p")
366
+ runOnUiThread do
367
+ clockLabel.text = Time.now.strftime("%I:%M:%S %p")
368
+ end
367
369
  sleep(1)
368
370
  end
369
- }
371
+ end
370
372
  end
371
373
  end
372
374
 
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fox16'
4
+
5
+ class ThreadedWindow < Fox::FXMainWindow
6
+ include Fox
7
+
8
+ def initialize(app)
9
+ # Call the base class initializer first
10
+ super(app, "Threaded Widget Test", :opts => DECOR_ALL, width: 200, height: 500)
11
+
12
+ @vframe = FXVerticalFrame.new(self,
13
+ FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0) do |frame|
14
+ FXButton.new(frame, "Klick to add", opts: FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X) do |button|
15
+ button.connect(SEL_COMMAND, method(:on_button_clicked))
16
+ end
17
+ end
18
+ end
19
+
20
+ def on_button_clicked(sender, sel, ptr)
21
+ FXHorizontalFrame.new(@vframe,
22
+ FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 10) do |frame|
23
+
24
+ label = FXLabel.new frame, "..."
25
+
26
+ Thread.new do
27
+ 50.times do |seconds|
28
+ runOnUiThread do
29
+ label.text = "#{(50 - seconds)/10.0} seconds to remove"
30
+ end
31
+ sleep 0.1
32
+ end
33
+
34
+ runOnUiThread do
35
+ @vframe.removeChild(frame)
36
+ @vframe.create; @vframe.show; @vframe.recalc
37
+ end
38
+ end
39
+ end
40
+ @vframe.create; @vframe.show; @vframe.recalc
41
+ end
42
+
43
+ # Create and show this window
44
+ def create
45
+ super
46
+ show(PLACEMENT_SCREEN)
47
+ end
48
+ end
49
+
50
+ if __FILE__ == $0
51
+ application = Fox::FXApp.new("ThreadApp", "FoxTest")
52
+ ThreadedWindow.new(application)
53
+ application.create
54
+ application.run
55
+ end
@@ -36,19 +36,31 @@ extern "C" {
36
36
  #include <sys/time.h> /* For struct timeval */
37
37
  #endif
38
38
 
39
+ #ifndef WIN32
40
+ #include <fcntl.h>
41
+ #endif
42
+
39
43
  // Message map
40
44
  FXDEFMAP(FXRbApp) FXRbAppMap[]={
45
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
46
+ FXMAPFUNC(SEL_IO_READ,FXRbApp::ID_CHORE_THREADS,FXRbApp::onChoreThreads),
47
+ #else
41
48
  FXMAPFUNC(SEL_CHORE,FXRbApp::ID_CHORE_THREADS,FXRbApp::onChoreThreads),
49
+ #endif
42
50
  };
43
51
 
44
52
  // Class implementation
45
53
  FXRbIMPLEMENT(FXRbApp,FXApp,FXRbAppMap,ARRAYNUMBER(FXRbAppMap))
46
54
 
55
+ #ifdef WIN32
56
+ WSAEVENT FXRbApp::interrupt_event = NULL;
57
+ #else
58
+ int FXRbApp::interrupt_fds[2] = {-1, -1};
59
+ #endif
60
+
47
61
  // Constructor
48
- FXRbApp::FXRbApp(const FXchar* appname,const FXchar* vendor) : FXApp(appname,vendor),m_bThreadsEnabled(TRUE),sleepTime(100){
49
- if(m_bThreadsEnabled){
50
- addChore(this,ID_CHORE_THREADS);
51
- }
62
+ FXRbApp::FXRbApp(const FXchar* appname,const FXchar* vendor) : FXApp(appname,vendor),m_bThreadsEnabled(FALSE),sleepTime(100){
63
+ setThreadsEnabled(TRUE);
52
64
  }
53
65
 
54
66
 
@@ -67,12 +79,33 @@ void FXRbApp::setThreadsEnabled(FXbool enabled){
67
79
  if(enabled){
68
80
  if(!m_bThreadsEnabled){
69
81
  m_bThreadsEnabled=TRUE;
82
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
83
+ #ifdef WIN32
84
+ interrupt_event = CreateEvent(NULL, TRUE, FALSE, NULL);
85
+ addInput(interrupt_event,INPUT_READ,this,ID_CHORE_THREADS);
86
+ #else
87
+ pipe2(interrupt_fds, O_NONBLOCK);
88
+ addInput(interrupt_fds[0],INPUT_READ,this,ID_CHORE_THREADS);
89
+ #endif
90
+ #else
70
91
  addChore(this,ID_CHORE_THREADS);
92
+ #endif
71
93
  }
72
94
  }
73
95
  else{
74
96
  m_bThreadsEnabled=FALSE;
97
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
98
+ #ifdef WIN32
99
+ removeInput(interrupt_event,INPUT_READ);
100
+ CloseHandle(interrupt_event); interrupt_event = NULL;
101
+ #else
102
+ removeInput(interrupt_fds[0],INPUT_READ);
103
+ close(interrupt_fds[0]); interrupt_fds[0] = -1;
104
+ close(interrupt_fds[1]); interrupt_fds[1] = -1;
105
+ #endif
106
+ #else
75
107
  removeChore(this,ID_CHORE_THREADS);
108
+ #endif
76
109
  }
77
110
  }
78
111
 
@@ -88,9 +121,27 @@ FXuint FXRbApp::getSleepTime() const {
88
121
  return sleepTime;
89
122
  }
90
123
 
124
+ long FXRbApp::onChoreThreads(FXObject *obj,FXSelector sel,void *p){
125
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
126
+ #ifdef WIN32
127
+ ResetEvent(interrupt_event);
128
+ #else
129
+ char byte;
130
+ // clear the pipe
131
+ read(interrupt_fds[0], &byte, 1);
132
+ #endif
133
+ #endif
134
+ return FXRbApp_onChoreThreads(this, obj, sel, p);
135
+ }
136
+
137
+ long FXRbApp_onChoreThreads_gvlcb(FXRbApp *self,FXObject *obj,FXSelector sel,void *p){
138
+ return self->onChoreThreads_gvlcb(obj, sel, p);
139
+ }
91
140
 
92
141
  // Process threads
93
- long FXRbApp::onChoreThreads(FXObject*,FXSelector,void*){
142
+ long FXRbApp::onChoreThreads_gvlcb(FXObject*,FXSelector,void*){
143
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
144
+ #else
94
145
  // Pause for 'sleepTime' millseconds
95
146
  struct timeval wait;
96
147
  wait.tv_sec=0;
@@ -108,16 +159,27 @@ long FXRbApp::onChoreThreads(FXObject*,FXSelector,void*){
108
159
 
109
160
  // Re-register this chore for next time
110
161
  addChore(this,ID_CHORE_THREADS);
162
+ #endif
111
163
 
112
164
  // Back to work...
113
165
  return 1;
114
166
  }
115
167
 
168
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
169
+ void fxrb_wakeup_fox(void *){
170
+ #ifdef WIN32
171
+ SetEvent(FXRbApp::interrupt_event);
172
+ #else
173
+ write(FXRbApp::interrupt_fds[1], "X", 1);
174
+ #endif
175
+ }
176
+ #endif
116
177
 
117
178
  // Destructor
118
179
  FXRbApp::~FXRbApp(){
119
180
  FXTRACE((100,"FXRbApp::~FXRbApp()\n"));
120
181
  VALUE myRegistry;
182
+ setThreadsEnabled(FALSE);
121
183
  FXRbDestroyAppSensitiveObjects();
122
184
  myRegistry=FXRbGetRubyObj(&(reg()),true);
123
185
  if(!NIL_P(myRegistry)){
@@ -115,7 +115,7 @@ VALUE FXRbNewPointerObj(void *ptr,swig_type_info* ty){
115
115
  FXRubyObjDesc *desc;
116
116
  if(FXMALLOC(&desc,FXRubyObjDesc,1)){
117
117
  obj=SWIG_Ruby_NewPointerObj(ptr,ty,1);
118
- FXTRACE((1,"FXRbNewPointerObj(rubyObj=%d,foxObj=%p)\n",static_cast<int>(obj),ptr));
118
+ FXTRACE((1,"FXRbNewPointerObj(foxObj=%p) => rubyObj=%p (%s)\n",ptr,(void *)obj,rb_obj_classname(obj)));
119
119
  desc->obj=obj;
120
120
  desc->borrowed=true;
121
121
  desc->in_gc=false;
@@ -185,23 +185,38 @@ void* FXRbConvertPtr(VALUE obj,swig_type_info* ty){
185
185
  FXbool FXRbCatchExceptions=FALSE;
186
186
 
187
187
  // Returns an FXInputHandle for this Ruby file object
188
- FXInputHandle FXRbGetReadFileHandle(VALUE obj) {
188
+ FXInputHandle FXRbGetReadFileHandle(VALUE obj,FXuint mode) {
189
189
  int fd;
190
190
  fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0));
191
191
  #ifdef WIN32
192
192
  #ifdef __CYGWIN__
193
193
  return (FXInputHandle) get_osfhandle(fd);
194
194
  #else
195
- return (FXInputHandle) _get_osfhandle(fd);
195
+ WSAEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
196
+ long events = 0;
197
+ if(mode&INPUT_READ) events |= FD_READ|FD_ACCEPT|FD_OOB;
198
+ if(mode&INPUT_EXCEPT) events |= FD_CLOSE|FD_QOS|FD_GROUP_QOS|FD_ROUTING_INTERFACE_CHANGE|FD_ADDRESS_LIST_CHANGE;
199
+ if ( WSAEventSelect(_get_osfhandle(fd), hEvent, events) == SOCKET_ERROR ) {
200
+ WSACloseEvent( hEvent );
201
+ rb_raise( rb_eRuntimeError, "WSAEventSelect sockett error: %d", WSAGetLastError() );
202
+ }
203
+ rb_iv_set(obj, "FXRuby::FXRbGetReadFileHandle", ULL2NUM((intptr_t)hEvent));
204
+ return (FXInputHandle) hEvent;
196
205
  #endif
197
206
  #else
198
207
  return (FXInputHandle) fd;
199
208
  #endif
200
209
  }
201
210
 
211
+ void FXRbRemoveReadFileHandle(VALUE obj,FXuint mode) {
212
+ #ifdef WIN32
213
+ WSAEVENT hEvent = (HANDLE)NUM2ULL(rb_iv_get(obj, "FXRuby::FXRbGetReadFileHandle"));
214
+ CloseHandle( hEvent );
215
+ #endif
216
+ }
202
217
 
203
218
  // Returns an FXInputHandle for this Ruby file object
204
- FXInputHandle FXRbGetWriteFileHandle(VALUE obj) {
219
+ FXInputHandle FXRbGetWriteFileHandle(VALUE obj,FXuint mode) {
205
220
  int fd;
206
221
  #if defined(RUBINIUS)
207
222
  VALUE vwrite = rb_intern("@write");
@@ -223,20 +238,36 @@ FXInputHandle FXRbGetWriteFileHandle(VALUE obj) {
223
238
  #ifdef __CYGWIN__
224
239
  return (FXInputHandle) get_osfhandle(fd);
225
240
  #else
226
- return (FXInputHandle) _get_osfhandle(fd);
241
+ WSAEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
242
+ long events = 0;
243
+ if(mode&INPUT_WRITE) events |= FD_WRITE|FD_CONNECT;
244
+ if(mode&INPUT_EXCEPT) events |= FD_CLOSE|FD_QOS|FD_GROUP_QOS|FD_ROUTING_INTERFACE_CHANGE|FD_ADDRESS_LIST_CHANGE;
245
+ if ( WSAEventSelect(_get_osfhandle(fd), hEvent, events) == SOCKET_ERROR ) {
246
+ WSACloseEvent( hEvent );
247
+ rb_raise( rb_eRuntimeError, "WSAEventSelect sockettt error: %d", WSAGetLastError() );
248
+ }
249
+ rb_iv_set(obj, "FXRuby::FXRbGetWriteFileHandle", ULL2NUM((intptr_t)hEvent));
250
+ return (FXInputHandle) hEvent;
227
251
  #endif
228
252
  #else
229
253
  return (FXInputHandle) fd;
230
254
  #endif
231
255
  }
232
256
 
257
+ void FXRbRemoveWriteFileHandle(VALUE obj,FXuint mode) {
258
+ #ifdef WIN32
259
+ WSAEVENT hEvent = (HANDLE)NUM2ULL(rb_iv_get(obj, "FXRuby::FXRbGetWriteFileHandle"));
260
+ CloseHandle( hEvent );
261
+ #endif
262
+ }
263
+
233
264
 
234
265
  // Register this Ruby class instance
235
266
  void FXRbRegisterRubyObj(VALUE rubyObj,const void* foxObj) {
236
267
  FXASSERT(!NIL_P(rubyObj));
237
268
  FXASSERT(foxObj!=0);
238
269
  FXRubyObjDesc* desc;
239
- FXTRACE((1,"FXRbRegisterRubyObj(rubyObj=%d,foxObj=%p)\n",static_cast<int>(rubyObj),foxObj));
270
+ FXTRACE((1,"FXRbRegisterRubyObj(rubyObj=%p (%s),foxObj=%p)\n",(void *)rubyObj,rb_obj_classname(rubyObj),foxObj));
240
271
  if(st_lookup(FXRuby_Objects,reinterpret_cast<st_data_t>(const_cast<void*>(foxObj)),reinterpret_cast<st_data_t *>(&desc))!=0){
241
272
  FXASSERT(desc->borrowed);
242
273
  /* There is already a Ruby object registered for this foxObj.
@@ -269,10 +300,15 @@ void FXRbRegisterRubyObj(VALUE rubyObj,const void* foxObj) {
269
300
  * Remove this mapping between a Ruby instance and a C++ object
270
301
  */
271
302
  void FXRbUnregisterRubyObj(const void* foxObj){
303
+ FXRbUnregisterRubyObj2(foxObj, true);
304
+ }
305
+
306
+ void FXRbUnregisterRubyObj2(const void* foxObj, bool alsoOwned){
272
307
  if(foxObj!=0){
273
308
  FXRubyObjDesc* desc;
274
309
  if(st_lookup(FXRuby_Objects,reinterpret_cast<st_data_t>(const_cast<void*>(foxObj)),reinterpret_cast<st_data_t *>(&desc))!=0){
275
- FXTRACE((1,"FXRbUnregisterRubyObj(rubyObj=%d,foxObj=%p)\n",static_cast<int>(desc->obj),foxObj));
310
+ if( !alsoOwned && !desc->borrowed ) return;
311
+ FXTRACE((1,"FXRbUnregisterRubyObj(rubyObj=%p (%s),foxObj=%p)\n",(void *)desc->obj,rb_obj_classname(desc->obj),foxObj));
276
312
  DATA_PTR(desc->obj)=0;
277
313
  FXFREE(&desc);
278
314
  st_delete(FXRuby_Objects,reinterpret_cast<st_data_t *>(const_cast<void**>(&foxObj)),reinterpret_cast<st_data_t *>(0));
@@ -281,6 +317,22 @@ void FXRbUnregisterRubyObj(const void* foxObj){
281
317
  }
282
318
  }
283
319
 
320
+ void FXRbUnregisterBorrowedRubyObj(const void* foxObj){
321
+ FXRbUnregisterRubyObj2( foxObj, false );
322
+ };
323
+ void FXRbUnregisterBorrowedRubyObj(FXlong foxObj){
324
+ };
325
+ void FXRbUnregisterBorrowedRubyObj(FXString& foxObj){
326
+ };
327
+ void FXRbUnregisterBorrowedRubyObj(FXRegion& foxObj){
328
+ FXRbUnregisterRubyObj2( &foxObj, false );
329
+ };
330
+ void FXRbUnregisterBorrowedRubyObj(FXRectangle& foxObj){
331
+ FXRbUnregisterRubyObj2( &foxObj, false );
332
+ };
333
+ void FXRbUnregisterBorrowedRubyObj(FXDC& foxObj){
334
+ FXRbUnregisterRubyObj2( &foxObj, false );
335
+ };
284
336
 
285
337
  VALUE to_ruby(const FXObject* obj){
286
338
  if(obj!=0){
@@ -299,20 +351,16 @@ VALUE to_ruby(const FXObject* obj){
299
351
  * Return the registered Ruby class instance associated with this
300
352
  * FOX object, or Qnil if not found.
301
353
  */
302
- VALUE FXRbGetRubyObj(const void *foxObj,bool searchBoth){
354
+ VALUE FXRbGetRubyObj(const void *foxObj,bool alsoBorrowed){
303
355
  FXRubyObjDesc* desc;
304
356
  if(foxObj!=0 && st_lookup(FXRuby_Objects,reinterpret_cast<st_data_t>(const_cast<void*>(foxObj)),reinterpret_cast<st_data_t *>(&desc))!=0){
305
357
  FXASSERT(desc!=0);
306
- if(searchBoth){
358
+ if(alsoBorrowed || !desc->borrowed){
359
+ FXTRACE((2,"FXRbGetRubyObj(foxObj=%p) => rubyObj=%p (%s)\n",foxObj,(void *)desc->obj,rb_obj_classname(desc->obj)));
307
360
  return desc->obj;
308
361
  }
309
- else{
310
- return desc->borrowed ? Qnil : desc->obj;
311
- }
312
- }
313
- else{
314
- return Qnil;
315
362
  }
363
+ return Qnil;
316
364
  }
317
365
 
318
366
  /**
@@ -1229,7 +1277,7 @@ static ID id_assocs;
1229
1277
  * or return zero if the designated receiver doesn't handle this
1230
1278
  * message.
1231
1279
  */
1232
- ID FXRbLookupHandler(FXObject* recv,FXSelector key){
1280
+ ID FXRbLookupHandler_gvlcb(FXObject* recv,FXSelector key){
1233
1281
  FXTRACE((100,"FXRbLookupHandler(recv=%p(%s),FXSEL(%d,%d))\n",recv,recv->getClassName(),FXSELTYPE(key),FXSELID(key)));
1234
1282
  ID id=0;
1235
1283
  VALUE rubyObj=to_ruby(recv);
@@ -1291,7 +1339,7 @@ static VALUE handle_rescue(VALUE args,VALUE error){
1291
1339
 
1292
1340
 
1293
1341
  // Call the designated function and return its result (which should be a long).
1294
- long FXRbHandleMessage(FXObject* recv,ID func,FXObject* sender,FXSelector key,void* ptr){
1342
+ long FXRbHandleMessage_gvlcb(FXObject* recv,ID func,FXObject* sender,FXSelector key,void* ptr){
1295
1343
  FXRbHandleArgs hArgs;
1296
1344
  hArgs.recv=to_ruby(recv);
1297
1345
  hArgs.sender=to_ruby(sender);
@@ -1312,6 +1360,10 @@ long FXRbHandleMessage(FXObject* recv,ID func,FXObject* sender,FXSelector key,vo
1312
1360
  retval=handle_body(reinterpret_cast<VALUE>(&hArgs));
1313
1361
  }
1314
1362
 
1363
+ FXRbUnregisterBorrowedRubyObj(recv);
1364
+ FXRbUnregisterBorrowedRubyObj(sender);
1365
+ FXRbUnregisterBorrowedRubyObj(ptr);
1366
+
1315
1367
  /**
1316
1368
  * Process the return value. For boolean return values, convert "true"
1317
1369
  * to 1 and "false" to zero. For numeric types, convert it to a long value
@@ -1380,70 +1432,70 @@ void FXRbRange2LoHi(VALUE range,FXdouble& lo,FXdouble& hi){
1380
1432
 
1381
1433
  //----------------------------------------------------------------------
1382
1434
 
1383
- void FXRbCallVoidMethod(FXObject* recv, ID func) {
1435
+ void FXRbCallVoidMethod_gvlcb(FXObject* recv, const char *func) {
1384
1436
  VALUE obj=FXRbGetRubyObj(recv,false);
1385
1437
  FXASSERT(!NIL_P(obj));
1386
1438
  FXASSERT(!FXRbIsInGC(recv));
1387
- rb_funcall(obj,func,0,NULL);
1439
+ rb_funcall(obj,rb_intern(func),0,NULL);
1388
1440
  }
1389
1441
 
1390
- void FXRbCallVoidMethod(FXDC* recv,ID func) {
1442
+ void FXRbCallVoidMethod_gvlcb(FXDC* recv,const char *func) {
1391
1443
  VALUE obj=FXRbGetRubyObj(recv,false);
1392
1444
  FXASSERT(!NIL_P(obj));
1393
- rb_funcall(obj,func,0,NULL);
1445
+ rb_funcall(obj,rb_intern(func),0,NULL);
1394
1446
  }
1395
1447
 
1396
1448
  //----------------------------------------------------------------------
1397
1449
 
1398
- bool FXRbCallBoolMethod(const FXObject* recv,ID func){
1450
+ bool FXRbCallBoolMethod_gvlcb(const FXObject* recv,const char *func){
1399
1451
  VALUE obj=FXRbGetRubyObj(recv,false);
1400
1452
  FXASSERT(!NIL_P(obj));
1401
- VALUE v=rb_funcall(obj,func,0,NULL);
1453
+ VALUE v=rb_funcall(obj,rb_intern(func),0,NULL);
1402
1454
  return (v==Qtrue);
1403
1455
  }
1404
1456
 
1405
1457
  //----------------------------------------------------------------------
1406
1458
 
1407
1459
  // Call function with "FXint" return value
1408
- FXint FXRbCallIntMethod(const FXObject* recv,ID func){
1460
+ FXint FXRbCallIntMethod_gvlcb(const FXObject* recv,const char *func){
1409
1461
  VALUE obj=FXRbGetRubyObj(recv,false);
1410
1462
  FXASSERT(!NIL_P(obj));
1411
- VALUE result=rb_funcall(obj,func,0,NULL);
1463
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1412
1464
  return static_cast<FXint>(NUM2INT(result));
1413
1465
  }
1414
1466
 
1415
1467
  //----------------------------------------------------------------------
1416
1468
 
1417
1469
  // Call function with "FXGLObject*" return value
1418
- FXGLObject* FXRbCallGLObjectMethod(FXGLObject* recv,ID func){
1470
+ FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLObject* recv,const char *func){
1419
1471
  VALUE obj=FXRbGetRubyObj(recv,false);
1420
1472
  FXASSERT(!NIL_P(obj));
1421
- VALUE result=rb_funcall(obj,func,0,NULL);
1473
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1422
1474
  return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1423
1475
  }
1424
1476
 
1425
- FXGLObject* FXRbCallGLObjectMethod(FXGLViewer* recv,ID func,FXint x,FXint y){
1477
+ FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLViewer* recv,const char *func,FXint x,FXint y){
1426
1478
  VALUE obj=FXRbGetRubyObj(recv,false);
1427
1479
  FXASSERT(!NIL_P(obj));
1428
- VALUE result=rb_funcall(obj,func,2,INT2NUM(x),INT2NUM(y));
1480
+ VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1429
1481
  return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1430
1482
  }
1431
1483
 
1432
- FXGLObject* FXRbCallGLObjectMethod(FXGLObject* recv,ID func,FXuint* path,FXint n){
1484
+ FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLObject* recv,const char *func,FXuint* path,FXint n){
1433
1485
  VALUE obj=FXRbGetRubyObj(recv,false);
1434
1486
  FXASSERT(!NIL_P(obj));
1435
- VALUE result=rb_funcall(obj,func,1,FXRbMakeArray(path,n));
1487
+ VALUE result=rb_funcall(obj,rb_intern(func),1,FXRbMakeArray(path,n));
1436
1488
  return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1437
1489
  }
1438
1490
 
1439
1491
  //----------------------------------------------------------------------
1440
1492
 
1441
1493
  // Call function with "FXGLObject**" return value
1442
- FXGLObject** FXRbCallGLObjectArrayMethod(FXGLViewer* recv,ID func,FXint x,FXint y,FXint w,FXint h){
1494
+ FXGLObject** FXRbCallGLObjectArrayMethod_gvlcb(FXGLViewer* recv,const char *func,FXint x,FXint y,FXint w,FXint h){
1443
1495
  FXGLObject** objects=NULL;
1444
1496
  VALUE obj=FXRbGetRubyObj(recv,false);
1445
1497
  FXASSERT(!NIL_P(obj));
1446
- VALUE result=rb_funcall(obj,func,4,INT2NUM(x),INT2NUM(y),INT2NUM(w),INT2NUM(h));
1498
+ VALUE result=rb_funcall(obj,rb_intern(func),4,INT2NUM(x),INT2NUM(y),INT2NUM(w),INT2NUM(h));
1447
1499
  if(!NIL_P(result)){
1448
1500
  Check_Type(result,T_ARRAY);
1449
1501
  if(FXMALLOC(&objects,FXGLObject*,RARRAY_LEN(result)+1)){
@@ -1458,55 +1510,56 @@ FXGLObject** FXRbCallGLObjectArrayMethod(FXGLViewer* recv,ID func,FXint x,FXint
1458
1510
 
1459
1511
  //----------------------------------------------------------------------
1460
1512
 
1461
- FXTableItem* FXRbCallTableItemMethod(FXTable* recv,ID func,const FXString& text,FXIcon* icon,void* ptr){
1513
+ FXTableItem* FXRbCallTableItemMethod_gvlcb(FXTable* recv,const char *func,const FXString& text,FXIcon* icon,void* ptr){
1462
1514
  VALUE itemData=(ptr==0)?Qnil:reinterpret_cast<VALUE>(ptr);
1463
1515
  VALUE obj=FXRbGetRubyObj(recv,false);
1464
1516
  FXASSERT(!NIL_P(obj));
1465
- VALUE result=rb_funcall(obj,func,3,to_ruby(text),to_ruby(icon),itemData);
1517
+ VALUE result=rb_funcall(obj,rb_intern(func),3,to_ruby(text),to_ruby(icon),itemData);
1518
+ FXRbUnregisterBorrowedRubyObj(icon);
1466
1519
  return NIL_P(result)?0:reinterpret_cast<FXTableItem*>(DATA_PTR(result));
1467
1520
  }
1468
1521
 
1469
- FXTableItem* FXRbCallTableItemMethod(FXTable* recv,ID func,FXint row,FXint col,FXbool notify){
1522
+ FXTableItem* FXRbCallTableItemMethod_gvlcb(FXTable* recv,const char *func,FXint row,FXint col,FXbool notify){
1470
1523
  VALUE obj=FXRbGetRubyObj(recv,false);
1471
1524
  FXASSERT(!NIL_P(obj));
1472
- VALUE result=rb_funcall(obj,func,3,to_ruby(row),to_ruby(col),to_ruby(notify));
1525
+ VALUE result=rb_funcall(obj,rb_intern(func),3,to_ruby(row),to_ruby(col),to_ruby(notify));
1473
1526
  return NIL_P(result)?0:reinterpret_cast<FXTableItem*>(DATA_PTR(result));
1474
1527
  }
1475
1528
 
1476
1529
  //----------------------------------------------------------------------
1477
1530
 
1478
- FXTreeItem* FXRbCallTreeItemMethod(const FXTreeList* recv,ID func,FXint x,FXint y){
1531
+ FXTreeItem* FXRbCallTreeItemMethod_gvlcb(const FXTreeList* recv,const char *func,FXint x,FXint y){
1479
1532
  VALUE obj=FXRbGetRubyObj(recv,false);
1480
1533
  FXASSERT(!NIL_P(obj));
1481
- VALUE result=rb_funcall(obj,func,2,INT2NUM(x),INT2NUM(y));
1534
+ VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1482
1535
  return NIL_P(result) ? 0 : reinterpret_cast<FXTreeItem*>(DATA_PTR(result));
1483
1536
  }
1484
1537
 
1485
1538
  //----------------------------------------------------------------------
1486
1539
 
1487
- FXFoldingItem* FXRbCallFoldingItemMethod(const FXFoldingList* recv,ID func,FXint x,FXint y){
1540
+ FXFoldingItem* FXRbCallFoldingItemMethod_gvlcb(const FXFoldingList* recv,const char *func,FXint x,FXint y){
1488
1541
  VALUE obj=FXRbGetRubyObj(recv,false);
1489
1542
  FXASSERT(!NIL_P(obj));
1490
- VALUE result=rb_funcall(obj,func,2,INT2NUM(x),INT2NUM(y));
1543
+ VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1491
1544
  return NIL_P(result) ? 0 : reinterpret_cast<FXFoldingItem*>(DATA_PTR(result));
1492
1545
  }
1493
1546
 
1494
1547
  //----------------------------------------------------------------------
1495
1548
 
1496
- FXFileAssoc* FXRbCallFileAssocMethod(const FXFileDict* recv,ID func,const FXchar* pathname){
1549
+ FXFileAssoc* FXRbCallFileAssocMethod_gvlcb(const FXFileDict* recv,const char *func,const FXchar* pathname){
1497
1550
  VALUE obj=FXRbGetRubyObj(recv,false);
1498
1551
  FXASSERT(!NIL_P(obj));
1499
- VALUE result=rb_funcall(obj,func,1,to_ruby(pathname));
1552
+ VALUE result=rb_funcall(obj,rb_intern(func),1,to_ruby(pathname));
1500
1553
  return NIL_P(result) ? 0 : reinterpret_cast<FXFileAssoc*>(DATA_PTR(result));
1501
1554
  }
1502
1555
 
1503
1556
  //----------------------------------------------------------------------
1504
1557
 
1505
- FXIcon* FXRbCallIconMethod(const FXTableItem* recv,ID func){
1558
+ FXIcon* FXRbCallIconMethod_gvlcb(const FXTableItem* recv,const char *func){
1506
1559
  VALUE obj=FXRbGetRubyObj(recv,false);
1507
1560
  FXASSERT(!NIL_P(obj));
1508
1561
  if(!NIL_P(obj)){
1509
- VALUE result=rb_funcall(obj,func,0,NULL);
1562
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1510
1563
  return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
1511
1564
  }
1512
1565
  else{
@@ -1516,60 +1569,73 @@ FXIcon* FXRbCallIconMethod(const FXTableItem* recv,ID func){
1516
1569
 
1517
1570
  //----------------------------------------------------------------------
1518
1571
 
1519
- FXWindow* FXRbCallWindowMethod(const FXTableItem* recv,ID func,FXTable* table){
1572
+ FXWindow* FXRbCallWindowMethod_gvlcb(const FXTableItem* recv,const char *func,FXTable* table){
1520
1573
  VALUE obj=FXRbGetRubyObj(recv,false);
1521
1574
  FXASSERT(!NIL_P(obj));
1522
- VALUE result=rb_funcall(obj,func,1,to_ruby(table));
1575
+ VALUE result=rb_funcall(obj,rb_intern(func),1,to_ruby(table));
1576
+ FXRbUnregisterBorrowedRubyObj(table);
1523
1577
  return NIL_P(result) ? 0 : reinterpret_cast<FXWindow*>(DATA_PTR(result));
1524
1578
  }
1525
1579
 
1526
1580
  //----------------------------------------------------------------------
1527
1581
 
1528
1582
  // Call function with "FXRange" return value
1529
- FXRangef FXRbCallRangeMethod(FXObject* recv,ID func){
1583
+ FXRangef FXRbCallRangeMethod_gvlcb(FXObject* recv,const char *func){
1530
1584
  VALUE obj=FXRbGetRubyObj(recv,false);
1531
1585
  FXASSERT(!NIL_P(obj));
1532
- VALUE result=rb_funcall(obj,func,0,NULL);
1586
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1533
1587
  return *reinterpret_cast<FXRangef*>(DATA_PTR(result));
1534
1588
  }
1535
1589
 
1536
1590
  //----------------------------------------------------------------------
1537
1591
 
1538
1592
  // Call functions with FXString return value
1539
- FXString FXRbCallStringMethod(const FXObject* recv, ID func){
1593
+ FXString FXRbCallStringMethod_gvlcb(const FXObject* recv, const char *func){
1540
1594
  VALUE obj=FXRbGetRubyObj(recv,false);
1541
1595
  FXASSERT(!NIL_P(obj));
1542
- VALUE result=rb_funcall(obj,func,0,NULL);
1596
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1543
1597
  return FXString(StringValuePtr(result));
1544
1598
  }
1545
1599
 
1546
1600
  //----------------------------------------------------------------------
1547
1601
 
1548
1602
  // Call functions with const FXchar* return value
1549
- const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar* message, const FXchar* hint){
1603
+ const FXchar* FXRbCallCStringMethod_gvlcb(const FXObject* recv, const char *func, const FXchar* message, const FXchar* hint){
1550
1604
  VALUE obj=FXRbGetRubyObj(recv,false);
1551
1605
  FXASSERT(!NIL_P(obj));
1552
- VALUE result=rb_funcall(obj,func,2,to_ruby(message),to_ruby(hint));
1606
+ VALUE result=rb_funcall(obj,rb_intern(func),2,to_ruby(message),to_ruby(hint));
1553
1607
  return NIL_P(result) ? 0 : StringValuePtr(result);
1554
1608
  }
1555
1609
 
1556
1610
  // Call functions with const FXchar* return value
1557
- const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar* context, const FXchar* message, const FXchar* hint){
1611
+ const FXchar* FXRbCallCStringMethod_gvlcb(const FXObject* recv, const char *func, const FXchar* context, const FXchar* message, const FXchar* hint){
1558
1612
  VALUE obj=FXRbGetRubyObj(recv,false);
1559
1613
  FXASSERT(!NIL_P(obj));
1560
- VALUE result=rb_funcall(obj,func,3,to_ruby(context),to_ruby(message),to_ruby(hint));
1614
+ VALUE result=rb_funcall(obj,rb_intern(func),3,to_ruby(context),to_ruby(message),to_ruby(hint));
1561
1615
  return NIL_P(result) ? 0 : StringValuePtr(result);
1562
1616
  }
1563
1617
  //----------------------------------------------------------------------
1564
1618
 
1565
1619
  // Call functions with FXwchar return value
1566
- FXwchar FXRbCallWCharMethod(const FXObject* recv, ID func){
1620
+ FXwchar FXRbCallWCharMethod_gvlcb(const FXObject* recv, const char *func){
1567
1621
  VALUE obj=FXRbGetRubyObj(recv,false);
1568
1622
  FXASSERT(!NIL_P(obj));
1569
- VALUE result=rb_funcall(obj,func,0,NULL);
1623
+ VALUE result=rb_funcall(obj,rb_intern(func),0,NULL);
1570
1624
  return static_cast<FXwchar>(NUM2ULONG(result));
1571
1625
  }
1572
1626
 
1627
+ void FXRbCallSetDashes_gvlcb(FXDC* recv,const char *func,FXuint dashoffset,const FXchar *dashpattern,FXuint dashlength){
1628
+ rb_funcall(FXRbGetRubyObj(recv,false),rb_intern(func),2,to_ruby(dashoffset),FXRbMakeArray(dashpattern,dashlength));
1629
+ }
1630
+
1631
+ void FXRbCallDCDrawMethod_gvlcb(FXDC* recv, const char * func, FXint x,FXint y,const FXString& string){
1632
+ rb_funcall(FXRbGetRubyObj(recv,false),rb_intern(func),3,to_ruby(x),to_ruby(y),to_ruby(string)); \
1633
+ }
1634
+
1635
+ void FXRbCallDCDrawMethod_gvlcb(FXDC* recv, const char * func, FXint x,FXint y,const FXchar* string,FXuint length){
1636
+ rb_funcall(FXRbGetRubyObj(recv,false),rb_intern(func),3,to_ruby(x),to_ruby(y),to_ruby(string,length)); \
1637
+ }
1638
+
1573
1639
  //----------------------------------------------------------------------
1574
1640
 
1575
1641
  // Special destructors to handle order dependencies
@@ -1684,59 +1750,25 @@ void FXRbFoldingList::enumerateItems(FXFoldingItem* fm,FXFoldingItem* to,FXObjec
1684
1750
 
1685
1751
  static ID id_cmp;
1686
1752
 
1687
- // Sort function stand-in for FXComboBox
1688
- FXint FXRbComboBox::sortFunc(const FXListItem* a,const FXListItem* b){
1689
- VALUE itemA = FXRbGetRubyObj(const_cast<FXListItem*>(a), "FXListItem *");
1690
- VALUE itemB = FXRbGetRubyObj(const_cast<FXListItem*>(b), "FXListItem *");
1691
- VALUE result=rb_funcall(itemA,id_cmp,1,itemB);
1692
- return static_cast<FXint>(NUM2INT(result));
1693
- }
1694
-
1695
-
1696
- // Sort function stand-in for FXFoldingList
1697
- FXint FXRbFoldingList::sortFunc(const FXFoldingItem* a,const FXFoldingItem* b){
1698
- VALUE itemA = FXRbGetRubyObj(const_cast<FXFoldingItem*>(a), "FXFoldingItem *");
1699
- VALUE itemB = FXRbGetRubyObj(const_cast<FXFoldingItem*>(b), "FXFoldingItem *");
1700
- VALUE result=rb_funcall(itemA,id_cmp,1,itemB);
1701
- return static_cast<FXint>(NUM2INT(result));
1702
- }
1703
-
1704
-
1705
- // Sort function stand-in for FXIconList
1706
- FXint FXRbIconList::sortFunc(const FXIconItem* a,const FXIconItem* b){
1707
- VALUE itemA = FXRbGetRubyObj(const_cast<FXIconItem*>(a), "FXIconItem *");
1708
- VALUE itemB = FXRbGetRubyObj(const_cast<FXIconItem*>(b), "FXIconItem *");
1709
- VALUE result = rb_funcall(itemA,id_cmp,1,itemB);
1710
- return static_cast<FXint>(NUM2INT(result));
1711
- }
1712
-
1713
-
1714
- // Sort function stand-in for FXList
1715
- FXint FXRbList::sortFunc(const FXListItem* a,const FXListItem* b){
1716
- VALUE itemA = FXRbGetRubyObj(const_cast<FXListItem*>(a), "FXListItem *");
1717
- VALUE itemB = FXRbGetRubyObj(const_cast<FXListItem*>(b), "FXListItem *");
1718
- VALUE result=rb_funcall(itemA,id_cmp,1,itemB);
1719
- return static_cast<FXint>(NUM2INT(result));
1720
- }
1721
-
1722
-
1723
- // Sort function stand-in for FXListBox
1724
- FXint FXRbListBox::sortFunc(const FXListItem* a,const FXListItem* b){
1725
- VALUE itemA = FXRbGetRubyObj(const_cast<FXListItem*>(a), "FXListItem *");
1726
- VALUE itemB = FXRbGetRubyObj(const_cast<FXListItem*>(b), "FXListItem *");
1727
- VALUE result=rb_funcall(itemA,id_cmp,1,itemB);
1728
- return static_cast<FXint>(NUM2INT(result));
1729
- }
1730
-
1731
-
1732
- // Sort function stand-in for FXTreeList
1733
- FXint FXRbTreeList::sortFunc(const FXTreeItem* a,const FXTreeItem* b){
1734
- VALUE itemA = FXRbGetRubyObj(const_cast<FXTreeItem*>(a), "FXTreeItem *");
1735
- VALUE itemB = FXRbGetRubyObj(const_cast<FXTreeItem*>(b), "FXTreeItem *");
1736
- VALUE result=rb_funcall(itemA,id_cmp,1,itemB);
1737
- return static_cast<FXint>(NUM2INT(result));
1738
- }
1739
-
1753
+ #define SORTFUNC(list, item) \
1754
+ FXint list::sortFunc(const item* a,const item* b){ \
1755
+ return list##_sortFunc(a, b); \
1756
+ } \
1757
+ FXint list##_sortFunc_gvlcb(const item* a,const item* b){ \
1758
+ VALUE itemA = FXRbGetRubyObj(const_cast<item*>(a), #item " *"); \
1759
+ VALUE itemB = FXRbGetRubyObj(const_cast<item*>(b), #item " *"); \
1760
+ VALUE result=rb_funcall(itemA,id_cmp,1,itemB); \
1761
+ return static_cast<FXint>(NUM2INT(result)); \
1762
+ }
1763
+
1764
+ SORTFUNC( FXRbComboBox, FXListItem )
1765
+ SORTFUNC( FXRbFoldingList, FXFoldingItem )
1766
+ SORTFUNC( FXRbIconList, FXIconItem )
1767
+ SORTFUNC( FXRbList, FXListItem )
1768
+ SORTFUNC( FXRbListBox, FXListItem )
1769
+ SORTFUNC( FXRbTreeList, FXTreeItem )
1770
+
1771
+ #undef SORTFUNC
1740
1772
 
1741
1773
  // Feedback buffer sort routine stand-in for FXGLViewer
1742
1774
  FXbool FXRbGLViewer::sortProc(FXfloat*& buffer,FXint& used,FXint& size){