summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/tk/extconf.rb91
-rw-r--r--ext/tk/lib/tk.rb48
-rw-r--r--ext/tk/lib/tk/autoload.rb2
-rw-r--r--ext/tk/lib/tk/variable.rb2
-rw-r--r--ext/tk/tcltklib.c70
5 files changed, 147 insertions, 66 deletions
diff --git a/ext/tk/extconf.rb b/ext/tk/extconf.rb
index a0e964a5f9..419c79ceda 100644
--- a/ext/tk/extconf.rb
+++ b/ext/tk/extconf.rb
@@ -64,6 +64,18 @@ tcltk_version = with_config("tcltkversion")
use_X = with_config("X11", (! is_win32))
+def parse_tclConfig(file)
+ # check tclConfig.sh/tkConfig.sh
+ tbl = {}
+ IO.foreach(file){|line|
+ line.strip!
+ next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/
+ key, val = $1, $3
+ tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s| tbl[$1]} rescue nil
+ }
+ tbl
+end
+
def check_tcltk_version(version)
return [nil, nil] unless version
@@ -118,7 +130,7 @@ def find_tcl(tcllib, stubs, version, *opt_paths)
if version && ! version.empty?
versions = [version]
else
- versions = %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
end
if tcllib
@@ -161,7 +173,7 @@ def find_tk(tklib, stubs, version, *opt_paths)
if version && ! version.empty?
versions = [version]
else
- versions = %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
end
if tklib
@@ -185,6 +197,35 @@ def find_tk(tklib, stubs, version, *opt_paths)
st
end
+def find_tcltk_header(tclver, tkver)
+ base_dir = ['/usr/local/include', '/usr/pkg/include', '/usr/include']
+ base_dir << '/Tcl/include' # default for ActiveTcl
+
+ unless have_tcl_h = have_header('tcl.h')
+ if tclver && ! tclver.empty?
+ versions = [tclver]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ end
+ paths = base_dir.dup
+ versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tcl' + ver})}
+ have_tcl_h = find_header('tcl.h', *paths)
+ end
+
+ unless have_tk_h = have_header("tk.h")
+ if tkver && ! tkver.empty?
+ versions = [tkver]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ end
+ paths = base_dir.dup
+ versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tk' + ver})}
+ have_tk_h = find_header('tk.h', *paths)
+ end
+
+ have_tcl_h && have_tk_h
+end
+
def find_X11(*opt_paths)
default_paths =
[ "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib" ]
@@ -218,37 +259,19 @@ def pthread_check()
else
# tcl-thread is unknown and tclConfig.sh is given
begin
- open(tclConfig, "r") do |cfg|
- while line = cfg.gets()
- if line =~ /^\s*TCL_THREADS=(0|1)/
- tcl_enable_thread = ($1 == "1")
- break
- end
-
- if line =~ /^\s*TCL_MAJOR_VERSION=("|')(\d+)\1/
- tcl_major_ver = $2
- if tcl_major_ver =~ /^[1-7]$/
- tcl_enable_thread = false
- break
- end
- if tcl_major_ver == "8" && tcl_minor_ver == "0"
- tcl_enable_thread = false
- break
- end
- end
-
- if line =~ /^\s*TCL_MINOR_VERSION=("|')(\d+)\1/
- tcl_minor_ver = $2
- if tcl_major_ver == "8" && tcl_minor_ver == "0"
- tcl_enable_thread = false
- break
- end
- end
+ tbl = parse_tclConfig(tclConfig)
+ if tbl['TCL_THREADS']
+ tcl_enable_thread = (tbl['TCL_THREADS'] == "1")
+ else
+ tcl_major_ver = tbl['TCL_MAJOR_VERSION'].to_i
+ tcl_minor_ver = tbl['TCL_MINOR_VERSION'].to_i
+ if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0)
+ tcl_enable_thread = false
end
end
if tcl_enable_thread == nil
- # not find definition
+ # cannot find definition
if tcl_major_ver
puts("Warning: '#{tclConfig}' doesn't include TCL_THREADS definition.")
else
@@ -376,11 +399,11 @@ end
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 ||
+ ( find_tcltk_header(tclver, tkver) &&
+ ( !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
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index c3401dfadb..67069abc32 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -1112,7 +1112,15 @@ module TkCore
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 @@ module TkCore
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 ?
@@ -2389,6 +2407,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
BINARY_NAME = 'binary'.freeze
UTF8_NAME = 'utf-8'.freeze
DEFAULT_EXTERNAL_NAME = RubyEncoding.default_external.name.freeze
+ DEFAULT_INTERNAL_NAME = RubyEncoding.default_internal.name.freeze rescue nil
BINARY = RubyEncoding.find(BINARY_NAME)
UNKNOWN = RubyEncoding.find('ASCII-8BIT')
@@ -2528,7 +2547,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
def tk_encoding_names
#TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1]))
TkComm.simplelist(TkCore::INTERP._invoke_without_enc('encoding', 'names'))
- end
+ end
def encoding_names
self.tk_encoding_names.find_all{|name|
Tk::Encoding::ENCODING_TABLE.get_name(name) rescue false
@@ -2721,7 +2740,12 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
enc_name ||=
Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil
- unless enc_name
+ if enc_name
+ # str has its encoding information
+ encstr = __toUTF8(str, enc_name)
+ encstr.force_encoding(Tk::Encoding::UTF8_NAME)
+ return encstr
+ else
# str.encoding isn't supported by Tk -> try to convert on Ruby
begin
return str.encode(Tk::Encoding::UTF8_NAME) # new string
@@ -2976,6 +3000,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
else ### Ruby 1.9 !!!!!!!!!!!!
loc_enc_obj = ::Encoding.find(::Encoding.locale_charmap)
ext_enc_obj = ::Encoding.default_external
+ int_enc_obj = ::Encoding.default_internal || ext_enc_obj
tksys_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding_system)
# p [Tk.encoding, Tk.encoding_system, loc_enc_obj, ext_enc_obj]
@@ -3052,7 +3077,8 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
end
unless enc_name
- if ext_enc_obj == Tk::Encoding::UNKNOWN
+ #if ext_enc_obj == Tk::Encoding::UNKNOWN
+ if int_enc_obj == Tk::Encoding::UNKNOWN
if loc_enc_obj == Tk::Encoding::UNKNOWN
# use Tk.encoding_system
enc_name = tksys_enc_name
@@ -3060,7 +3086,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
# use locale_charmap
begin
loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj)
- if loc_enc_name && loc_enc_name != tksys_enc_name
+ if loc_enc_name
# use locale_charmap
enc_name = loc_enc_name
else
@@ -3074,10 +3100,12 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
end
else
begin
- ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)
- if ext_enc_name && ext_enc_name != tksys_enc_name
+ #ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)
+ #if ext_enc_name && ext_enc_name != tksys_enc_name
+ int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj)
+ if int_enc_name
# use default_external
- enc_name = ext_enc_name
+ enc_name = int_enc_name
else
# use Tk.encoding_system
enc_name = tksys_enc_name
@@ -5501,7 +5529,7 @@ TkWidget = TkWindow
#Tk.freeze
module Tk
- RELEASE_DATE = '2008-06-17'.freeze
+ RELEASE_DATE = '2008-10-20'.freeze
autoload :AUTO_PATH, 'tk/variable'
autoload :TCL_PACKAGE_PATH, 'tk/variable'
diff --git a/ext/tk/lib/tk/autoload.rb b/ext/tk/lib/tk/autoload.rb
index 0773f7708d..79b6e01eb8 100644
--- a/ext/tk/lib/tk/autoload.rb
+++ b/ext/tk/lib/tk/autoload.rb
@@ -394,7 +394,7 @@ Tk.default_widget_set = :Tk
############################################
# 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
diff --git a/ext/tk/lib/tk/variable.rb b/ext/tk/lib/tk/variable.rb
index f738a96ee7..b73a4677da 100644
--- a/ext/tk/lib/tk/variable.rb
+++ b/ext/tk/lib/tk/variable.rb
@@ -26,7 +26,7 @@ class TkVariable
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',
diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c
index a8829d3b69..34b66f76e6 100644
--- a/ext/tk/tcltklib.c
+++ b/ext/tk/tcltklib.c
@@ -4,7 +4,7 @@
* Oct. 24, 1997 Y. Matsumoto
*/
-#define TCLTKLIB_RELEASE_DATE "2008-06-17"
+#define TCLTKLIB_RELEASE_DATE "2008-10-20"
#include "ruby.h"
@@ -44,9 +44,9 @@
#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 VALUE rb_thread_critical; /* dummy */
@@ -55,8 +55,8 @@ int rb_thread_check_trap_pending();
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
@@ -9070,28 +9070,30 @@ static VALUE
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));
}
@@ -9294,14 +9296,22 @@ encoding_table_get_name_core(table, enc_arg, error_mode)
enc = rb_funcall(interp, ID_encoding_name, 0, 0);
}
}
- /* 2nd: encoding system of Tcl/Tk */
+ /* 2nd: Encoding.default_internal */
+ if (NIL_P(enc)) {
+ enc = rb_enc_default_internal();
+ }
+ /* 3rd: encoding system of Tcl/Tk */
if (NIL_P(enc)) {
enc = rb_str_new2(Tcl_GetEncodingName((Tcl_Encoding)NULL));
}
- /* 3rd: Encoding.default_external */
+ /* 4th: Encoding.default_external */
if (NIL_P(enc)) {
enc = rb_enc_default_external();
}
+ /* 5th: Encoding.locale_charmap */
+ if (NIL_P(enc)) {
+ enc = rb_locale_charmap(rb_cEncoding);
+ }
if (RTEST(rb_obj_is_kind_of(enc, cRubyEncoding))) {
/* Ruby's Encoding object */
@@ -9870,6 +9880,24 @@ Init_tcltklib()
/* --------------------------------------------------------------- */
+#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));
@@ -9899,6 +9927,8 @@ Init_tcltklib()
/* --------------------------------------------------------------- */
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));