From: Hidetoshi NAGAI Date: 2008-08-03T03:25:14+09:00 Subject: [ruby-list:45293] Re: ソース:インストール:MacOSX10.3.9 ----Next_Part(Sun_Aug__3_03:26:24_2008_424)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Sun_Aug__3_03:26:24_2008_424)--" ----Next_Part(Sun_Aug__3_03:26:24_2008_424)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 永井@知能.九工大です. From: Hidetoshi NAGAI 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) 九州工業大学 大学院情報工学研究院 知能情報工学研究系 ----Next_Part(Sun_Aug__3_03:26:24_2008_424)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="for-tkaqua.patch" 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 ----Next_Part(Sun_Aug__3_03:26:24_2008_424)---- ----Next_Part(Sun_Aug__3_03:26:24_2008_424)----