[ruby-list:45293] Re: ソース:インストール:MacOSX10.3.9
From:
Hidetoshi NAGAI <nagai@...>
Date:
2008-08-02 18:25:14 UTC
List:
ruby-list #45293
永井@知能.九工大です. From: Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> Subject: [ruby-list:45218] Re: ソース:インストール:MacOSX10.3.9 Date: Fri, 11 Jul 2008 12:00:05 +0900 Message-ID: <20080711.120411.74738005.nagai@ai.kyutech.ac.jp> > どうやら現状では, > 「Ruby1.9 + TkAqua では main thread で eventloop を動かさねばならない」 > というのを known bug としておくしかなさそうですね. > > というわけで,あとは TkAqua の場合に > うまく RUN_EVENTLOOP_ON_MAIN_THREAD = true 相当の動作に > 持っていくための判断方法を考えねばなりません. > できれば,tcltklib ライブラリを読み込んだ後, > Tcl/Tk インタープリタを生成する前に判断する基準が欲しいのですが, > 何か良さそうな案があればご提案いただますと助かります. ものすごく遅くなってしまってすみません. 添付のパッチのようにしてみましたが,どうでしょうか? -- 永井 秀利 (nagai@ai.kyutech.ac.jp) 九州工業大学 大学院情報工学研究院 知能情報工学研究系
Attachments (1)
for-tkaqua.patch
(6.41 KB, text/x-diff)
Index: ext/tk/tcltklib.c
===================================================================
--- ext/tk/tcltklib.c (revision 18321)
+++ ext/tk/tcltklib.c (working copy)
@@ -49,16 +49,16 @@
#include "stubs.h"
#ifndef TCL_ALPHA_RELEASE
-#define TCL_ALPHA_RELEASE 0
-#define TCL_BETA_RELEASE 1
-#define TCL_FINAL_RELEASE 2
+#define TCL_ALPHA_RELEASE 0 /* "alpha" */
+#define TCL_BETA_RELEASE 1 /* "beta" */
+#define TCL_FINAL_RELEASE 2 /* "final" */
#endif
static struct {
int major;
int minor;
+ int type; /* ALPHA==0, BETA==1, FINAL==2 */
int patchlevel;
- int type;
} tcltk_version = {0, 0, 0, 0};
static void
@@ -9098,28 +9098,30 @@
lib_getversion(self)
VALUE self;
{
- volatile VALUE type_name;
+ set_tcltk_version();
+ return rb_ary_new3(4, INT2NUM(tcltk_version.major),
+ INT2NUM(tcltk_version.minor),
+ INT2NUM(tcltk_version.type),
+ INT2NUM(tcltk_version.patchlevel));
+}
+
+static VALUE
+lib_get_reltype_name(self)
+ VALUE self;
+{
set_tcltk_version();
switch(tcltk_version.type) {
case TCL_ALPHA_RELEASE:
- type_name = rb_str_new2("alpha");
- break;
+ return rb_str_new2("alpha");
case TCL_BETA_RELEASE:
- type_name = rb_str_new2("beta");
- break;
+ return rb_str_new2("beta");
case TCL_FINAL_RELEASE:
- type_name = rb_str_new2("final");
- break;
+ return rb_str_new2("final");
default:
- type_name = rb_str_new2("unknown");
+ rb_raise(rb_eRuntimeError, "tcltklib has invalid release type number");
}
-
- return rb_ary_new3(5, INT2NUM(tcltk_version.major),
- INT2NUM(tcltk_version.minor),
- INT2NUM(tcltk_version.type), type_name,
- INT2NUM(tcltk_version.patchlevel));
}
@@ -9898,6 +9900,24 @@
/* --------------------------------------------------------------- */
+#ifdef __WIN32__
+#define TK_WINDOWING_SYSTEM "win32"
+#else
+#ifdef MAC_TCL
+#define TK_WINDOWING_SYSTEM "classic"
+#else
+#ifdef MAC_OSX_TK
+#define TK_WINDOWING_SYSTEM "aqua"
+#else
+#define TK_WINDOWING_SYSTEM "x11"
+#endif
+#endif
+#endif
+ rb_define_const(lib, "WINDOWING_SYSTEM",
+ rb_obj_freeze(rb_str_new2(TK_WINDOWING_SYSTEM)));
+
+ /* --------------------------------------------------------------- */
+
rb_define_const(ev_flag, "NONE", INT2FIX(0));
rb_define_const(ev_flag, "WINDOW", INT2FIX(TCL_WINDOW_EVENTS));
rb_define_const(ev_flag, "FILE", INT2FIX(TCL_FILE_EVENTS));
@@ -9927,6 +9947,8 @@
/* --------------------------------------------------------------- */
rb_define_module_function(lib, "get_version", lib_getversion, -1);
+ rb_define_module_function(lib, "get_release_type_name",
+ lib_get_reltype_name, -1);
rb_define_const(release_type, "ALPHA", INT2FIX(TCL_ALPHA_RELEASE));
rb_define_const(release_type, "BETA", INT2FIX(TCL_BETA_RELEASE));
Index: ext/tk/lib/tk.rb
===================================================================
--- ext/tk/lib/tk.rb (revision 18321)
+++ ext/tk/lib/tk.rb (working copy)
@@ -1112,7 +1112,15 @@
WITH_RUBY_VM = Object.const_defined?(:VM) && ::VM.class == Class
WITH_ENCODING = defined?(::Encoding.default_external) && true
#WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
-
+ if TclTkLib::WINDOWING_SYSTEM == 'aqua'
+ if (TclTkLib.get_version <=> [8, 4, TclTkLib::RELEASE_TYPE::FINAL, 9]) > 0
+ # *** KNOWN BUG ***
+ # Main event loop thread of TkAqua (> Tk8.4.9) must be the main
+ # application thread. So, ruby1.9 users must call Tk.mainloop on
+ # the main application thread.
+ RUN_EVENTLOOP_ON_MAIN_THREAD = true
+ end
+ end
unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!
RUN_EVENTLOOP_ON_MAIN_THREAD = false
@@ -1671,8 +1679,18 @@
end
def mainloop(check_root = true)
- if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
+ if !TkCore::WITH_RUBY_VM
TclTkLib.mainloop(check_root)
+
+ elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
+ if TclTkLib::WINDOWING_SYSTEM == 'aqua' &&
+ Thread.current != Thread.main &&
+ (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
+ raise RuntimeError,
+ "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+ end
+ TclTkLib.mainloop(check_root)
+
else ### Ruby 1.9 !!!!!
unless TkCore::INTERP.default_master?
# [MultiTkIp] slave interp ?
Index: ext/tk/lib/tk/variable.rb
===================================================================
--- ext/tk/lib/tk/variable.rb (revision 18321)
+++ ext/tk/lib/tk/variable.rb (working copy)
@@ -26,7 +26,7 @@
TkVar_ID_TBL.mutex.synchronize{ TkVar_ID_TBL.clear }
}
- major, minor, type, type_name, patchlevel = TclTkLib.get_version
+ major, minor, type, patchlevel = TclTkLib.get_version
USE_OLD_TRACE_OPTION_STYLE = (major < 8) || (major == 8 && minor < 4)
#TkCore::INTERP.add_tk_procs('rb_var', 'args',
Index: ext/tk/lib/tk/autoload.rb
===================================================================
--- ext/tk/lib/tk/autoload.rb (revision 18321)
+++ ext/tk/lib/tk/autoload.rb (working copy)
@@ -394,7 +394,7 @@
############################################
# depend on the version of Tcl/Tk
-# major, minor, type, type_name, patchlevel = TclTkLib.get_version
+# major, minor, type, patchlevel = TclTkLib.get_version
############################################
# Ttk (Tile) support
Index: ext/tk/extconf.rb
===================================================================
--- ext/tk/extconf.rb (revision 18321)
+++ ext/tk/extconf.rb (working copy)
@@ -376,11 +376,11 @@
tclver, tkver = check_tcltk_version(tcltk_version)
-if have_header("tcl.h") && have_header("tk.h") &&
- ( tcltk_framework ||
- ( ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&
- find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&
- find_tk(tklib, stubs, tkver, *tk_ldir_list) ) )
+if ( tcltk_framework ||
+ ( have_header("tcl.h") && have_header("tk.h") &&
+ ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&
+ find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&
+ find_tk(tklib, stubs, tkver, *tk_ldir_list) ) )
$CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs
$CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM