1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/tk/tkutil/tkutil.c (tk_conv_args): forget to revert

thread_critical and gc_disable when raise ArgumentError.
* ext/tk/lib/remote-tk.rb: RemoteTkIp doesn't need to include TkUtil.
* ext/tk/tcltklib.c: add TclTkIp#has_mainwindow? method.
* ext/tk/lib/tk.rb: add Tk.has_mainwindow? method.
* ext/tk/lib/multi-tk.rb: add MultiTkIp#has_mainwindow? method.
* ext/tk/lib/remote-tk.rb: add RemoteTkIp#has_mainwindow? method.
* ext/tk/lib/multi-tk.rb: slave IP fail to exit itself when $SAFE==4.
* ext/tk/lib/multi-tk.rb: remove constants from MultiTkIp module to
  avoid access from external.
* ext/tk/lib/multi-tk.rb: check_root flag is ignored on slave IPs'
  mainloop.
* ext/tk/lib/multi-tk.rb: hang-up Tk.mainloop called on a slave IP
  with $SAFE==4.
* ext/tk/lib/multi-tk.rb: MultiTkIp#bg_eval_proc doesn't work
  properly.
* ext/tk/lib/multi-tk.rb: add MultiTkIp#set_cb_error(proc) and
  cb_error(exc) to log errors at callbacks on safe slave IPs.
* ext/tk/lib/multi-tk.rb: fail to get an available slave IP object
  when call Tk.mainloop in the block which is given to new_* method,
  because cannot finish initialize while the root widget is alive.
* ext/tk/lib/multi-tk.rb: fail to control a slave IP when Tk.mainloop
  runs on the IP.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8818 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2005-07-21 22:05:04 +00:00
parent 0580cf2696
commit 17743ce0a8
8 changed files with 223 additions and 64 deletions

View file

@ -1,3 +1,42 @@
Fri Jul 22 07:01:42 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/tkutil/tkutil.c (tk_conv_args): forget to revert
thread_critical and gc_disable when raise ArgumentError.
* ext/tk/lib/remote-tk.rb: RemoteTkIp doesn't need to include TkUtil.
* ext/tk/tcltklib.c: add TclTkIp#has_mainwindow? method.
* ext/tk/lib/tk.rb: add Tk.has_mainwindow? method.
* ext/tk/lib/multi-tk.rb: add MultiTkIp#has_mainwindow? method.
* ext/tk/lib/remote-tk.rb: add RemoteTkIp#has_mainwindow? method.
* ext/tk/lib/multi-tk.rb: slave IP fail to exit itself when $SAFE==4.
* ext/tk/lib/multi-tk.rb: remove constants from MultiTkIp module to
avoid access from external.
* ext/tk/lib/multi-tk.rb: check_root flag is ignored on slave IPs'
mainloop.
* ext/tk/lib/multi-tk.rb: hang-up Tk.mainloop called on a slave IP
with $SAFE==4.
* ext/tk/lib/multi-tk.rb: MultiTkIp#bg_eval_proc doesn't work
properly.
* ext/tk/lib/multi-tk.rb: add MultiTkIp#set_cb_error(proc) and
cb_error(exc) to log errors at callbacks on safe slave IPs.
* ext/tk/lib/multi-tk.rb: fail to get an available slave IP object
when call Tk.mainloop in the block which is given to new_* method,
because cannot finish initialize while the root widget is alive.
* ext/tk/lib/multi-tk.rb: fail to control a slave IP when Tk.mainloop
runs on the IP.
Thu Jul 21 01:00:00 2005 NARUSE, Yui <naruse@ruby-lang.org> Thu Jul 21 01:00:00 2005 NARUSE, Yui <naruse@ruby-lang.org>
* ext/nkf/nkf-utf8/{nkf.c,utf8tbl.c,config.h}: * ext/nkf/nkf-utf8/{nkf.c,utf8tbl.c,config.h}:

View file

@ -310,6 +310,11 @@ class TclTkIp
: Check whether the interpreter is already deleted. : Check whether the interpreter is already deleted.
: If deleted, returns true. : If deleted, returns true.
has_mainwindow?
: Check whether the interpreter has a MainWindow (root widget).
: If has, returns true. If doesn't, returns false.
: If IP is already deleted, returns nil.
restart restart
: Restart Tk part of the interpreter. : Restart Tk part of the interpreter.
: Use this when you need Tk functions after destroying the : Use this when you need Tk functions after destroying the

View file

@ -422,6 +422,11 @@ require "tcltklib"
: delete 済みでコマンドを受け付けない状態になっているならば : delete 済みでコマンドを受け付けない状態になっているならば
: true を返す. : true を返す.
has_mainwindow?
: Tcl/Tk インタープリタにメインウィンドウ (root widget) が
: 存在すれば true を,存在しなければ false を返す.
: インタープリタが既に delete 済みであれば nil を返す.
restart restart
: Tcl/Tk インタープリタの Tk 部分の初期化,再起動を行う. : Tcl/Tk インタープリタの Tk 部分の初期化,再起動を行う.
: 一旦 root widget を破壊した後に再度 Tk の機能が必要と : 一旦 root widget を破壊した後に再度 Tk の機能が必要と

View file

@ -7,7 +7,7 @@ require 'tkutil'
require 'thread' require 'thread'
if defined? Tk if defined? Tk
fail RuntimeError, "'multi-tk' library must be required before requiring 'tk'" fail RuntimeError,"'multi-tk' library must be required before requiring 'tk'"
end end
################################################ ################################################
@ -54,7 +54,7 @@ MultiTkIp_OK.freeze
################################################ ################################################
# methods for construction # methods for construction
class MultiTkIp class MultiTkIp
SLAVE_IP_ID = ['slave'.freeze, '0'.taint].freeze @@SLAVE_IP_ID = ['slave'.freeze, '0'.taint].freeze
@@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)
@ -86,9 +86,26 @@ class MultiTkIp
@ip.cb_eval(@cmd, *args) @ip.cb_eval(@cmd, *args)
rescue TkCallbackBreak, TkCallbackContinue => e rescue TkCallbackBreak, TkCallbackContinue => e
fail e fail e
rescue SecurityError => e
# in 'exit', 'exit!', and 'abort' : security error --> delete IP
if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/
@ip.delete
elsif @ip.safe?
if @ip.respond_to?(:cb_error)
@ip.cb_error(e)
else
nil # ignore
end
else
fail e
end
rescue Exception => e rescue Exception => e
if @ip.safe? if @ip.safe?
nil # ignore if @ip.respond_to?(:cb_error)
@ip.cb_error(e)
else
nil # ignore
end
else else
fail e fail e
end end
@ -161,6 +178,18 @@ class MultiTkIp
###################################### ######################################
def set_cb_error(cmd = Proc.new)
@cb_error_proc[0] = cmd
end
def cb_error(e)
if @cb_error_proc[0].respond_to?(:call)
@cb_error_proc[0].call(e)
end
end
######################################
def set_safe_level(safe) def set_safe_level(safe)
if safe > @safe_level[0] if safe > @safe_level[0]
@safe_level[0] = safe @safe_level[0] = safe
@ -192,7 +221,7 @@ class MultiTkIp
end end
def running_mainloop? def running_mainloop?
@wait_on_mainloop[1] @wait_on_mainloop[1] > 0
end end
def _destroy_slaves_of_slaveIP(ip) def _destroy_slaves_of_slaveIP(ip)
@ -442,13 +471,21 @@ class MultiTkIp
private :_receiver_eval_proc, :_receiver_eval_proc_core private :_receiver_eval_proc, :_receiver_eval_proc_core
def _receiver_mainloop(check_root) def _receiver_mainloop(check_root)
Thread.new{ if @evloop_thread[0] && @evloop_thread[0].alive?
while !@interp.deleted? @evloop_thread[0]
inf = @interp._invoke_without_enc('info', 'command', '.') else
break if !inf.kind_of?(String) || inf != '.' @evloop_thread[0] = Thread.new{
sleep 0.5 while !@interp.deleted?
end #if check_root
} # inf = @interp._invoke_without_enc('info', 'command', '.')
# break if !inf.kind_of?(String) || inf != '.'
#end
break if check_root && !@interp.has_mainwindow?
sleep 0.5
end
}
@evloop_thread[0]
end
end end
def _create_receiver_and_watchdog(lvl = $SAFE) def _create_receiver_and_watchdog(lvl = $SAFE)
@ -456,7 +493,7 @@ class MultiTkIp
# command-procedures receiver # command-procedures receiver
receiver = Thread.new(lvl){|safe_level| receiver = Thread.new(lvl){|safe_level|
last_thread = nil last_thread = {}
loop do loop do
break if @interp.deleted? break if @interp.deleted?
@ -479,8 +516,9 @@ class MultiTkIp
else else
# procedure # procedure
last_thread = _receiver_eval_proc(last_thread, safe_level, last_thread[thread] = _receiver_eval_proc(last_thread[thread],
thread, cmd, *args) safe_level, thread,
cmd, *args)
end end
end end
} }
@ -539,6 +577,8 @@ class MultiTkIp
@slave_ip_top = {}.taint @slave_ip_top = {}.taint
@evloop_thread = [].taint
unless keys.kind_of? Hash unless keys.kind_of? Hash
fail ArgumentError, "expecting a Hash object for the 2nd argument" fail ArgumentError, "expecting a Hash object for the 2nd argument"
end end
@ -548,7 +588,7 @@ class MultiTkIp
@system = Object.new @system = Object.new
@wait_on_mainloop = [true, false] @wait_on_mainloop = [true, 0].taint
@threadgroup = Thread.current.group @threadgroup = Thread.current.group
@ -657,7 +697,7 @@ class MultiTkIp
###################################### ######################################
SAFE_OPT_LIST = [ @@SAFE_OPT_LIST = [
'accessPath'.freeze, 'accessPath'.freeze,
'statics'.freeze, 'statics'.freeze,
'nested'.freeze, 'nested'.freeze,
@ -676,7 +716,7 @@ class MultiTkIp
name = v name = v
elsif k_str == 'safe' elsif k_str == 'safe'
safe = v safe = v
elsif SAFE_OPT_LIST.member?(k_str) elsif @@SAFE_OPT_LIST.member?(k_str)
safe_opts[k_str] = v safe_opts[k_str] = v
else else
tk_opts[k_str] = v tk_opts[k_str] = v
@ -692,8 +732,8 @@ class MultiTkIp
private :_parse_slaveopts private :_parse_slaveopts
def _create_slave_ip_name def _create_slave_ip_name
name = SLAVE_IP_ID.join('') name = @@SLAVE_IP_ID.join('')
SLAVE_IP_ID[1].succ! @@SLAVE_IP_ID[1].succ!
name name
end end
private :_create_slave_ip_name private :_create_slave_ip_name
@ -924,11 +964,15 @@ class MultiTkIp
@tk_table_list = [] @tk_table_list = []
@slave_ip_tbl = {} @slave_ip_tbl = {}
@slave_ip_top = {} @slave_ip_top = {}
@cb_error_proc = []
@evloop_thread = []
@tk_windows.taint unless @tk_windows.tainted? @tk_windows.taint unless @tk_windows.tainted?
@tk_table_list.taint unless @tk_table_list.tainted? @tk_table_list.taint unless @tk_table_list.tainted?
@slave_ip_tbl.taint unless @slave_ip_tbl.tainted? @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
@slave_ip_top.taint unless @slave_ip_top.tainted? @slave_ip_top.taint unless @slave_ip_top.tainted?
@cb_error_proc.taint unless @cb_error_proc.tainted?
@evloop_thread.taint unless @evloop_thread.tainted?
name, safe, safe_opts, tk_opts = _parse_slaveopts(keys) name, safe, safe_opts, tk_opts = _parse_slaveopts(keys)
@ -975,7 +1019,8 @@ class MultiTkIp
@system = Object.new @system = Object.new
@wait_on_mainloop = [true, false] @wait_on_mainloop = [true, 0].taint
# @wait_on_mainloop = [false, 0].taint
@threadgroup = ThreadGroup.new @threadgroup = ThreadGroup.new
@ -1088,7 +1133,10 @@ class << MultiTkIp
end end
ip = __new(__getip, nil, keys) ip = __new(__getip, nil, keys)
ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? #ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
end
ip ip
end end
@ -1109,7 +1157,10 @@ class << MultiTkIp
end end
ip = __new(__getip, false, keys) ip = __new(__getip, false, keys)
ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
end
ip ip
end end
alias new_trusted_slave new_slave alias new_trusted_slave new_slave
@ -1127,7 +1178,10 @@ class << MultiTkIp
end end
ip = __new(__getip, true, keys) ip = __new(__getip, true, keys)
ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
end
ip ip
end end
alias new_safeTk new_safe_slave alias new_safeTk new_safe_slave
@ -1504,7 +1558,11 @@ class MultiTkIp
backup_ip = current['callback_ip'] backup_ip = current['callback_ip']
current['callback_ip'] = self current['callback_ip'] = self
begin begin
eval_proc_core(false, cmd, safe_level, *args) eval_proc_core(false,
proc{|safe, *params|
$SAFE=safe if $SAFE < safe
cmd.call(*params)
}, safe_level, *args)
ensure ensure
current['callback_ip'] = backup_ip current['callback_ip'] = backup_ip
end end
@ -1514,7 +1572,7 @@ class MultiTkIp
$SAFE=safe if $SAFE < safe $SAFE=safe if $SAFE < safe
Thread.new(*params, &cmd).value Thread.new(*params, &cmd).value
}, },
*args) safe_level, *args)
end end
end end
alias call eval_proc alias call eval_proc
@ -1528,15 +1586,19 @@ class MultiTkIp
end end
end end
Thread.new{ Thread.new{
eval_proc(cmd, *args)
=begin
eval_proc_core(false, eval_proc_core(false,
proc{|safe, *params| proc{|safe, *params|
$SAFE=safe if $SAFE < safe $SAFE=safe if $SAFE < safe
Thread.new(*params, &cmd).value Thread.new(*params, &cmd).value
}, },
*args) safe_level, *args)
=end
} }
end end
alias background_eval_proc bg_eval_proc alias background_eval_proc bg_eval_proc
alias thread_eval_proc bg_eval_proc
alias bg_call bg_eval_proc alias bg_call bg_eval_proc
alias background_call bg_eval_proc alias background_call bg_eval_proc
@ -1550,7 +1612,7 @@ class MultiTkIp
proc{|safe| proc{|safe|
$SAFE=safe if $SAFE < safe $SAFE=safe if $SAFE < safe
Kernel.eval(cmd, *eval_args) Kernel.eval(cmd, *eval_args)
}) }, safe_level)
end end
alias eval_str eval_string alias eval_str eval_string
@ -1564,7 +1626,7 @@ class MultiTkIp
proc{|safe| proc{|safe|
$SAFE=safe if $SAFE < safe $SAFE=safe if $SAFE < safe
Kernel.eval(cmd, *eval_args) Kernel.eval(cmd, *eval_args)
}) }, safe_level)
} }
end end
alias background_eval_string bg_eval_string alias background_eval_string bg_eval_string
@ -1679,6 +1741,10 @@ class << MultiTkIp
__getip.deleted? __getip.deleted?
end end
def has_mainwindow?
__getip.has_mainwindow?
end
def invalid_namespace? def invalid_namespace?
__getip.invalid_namespace? __getip.invalid_namespace?
end end
@ -1860,22 +1926,24 @@ class MultiTkIp
if self != @@DEFAULT_MASTER if self != @@DEFAULT_MASTER
if @wait_on_mainloop[0] if @wait_on_mainloop[0]
begin begin
@wait_on_mainloop[1] = true @wait_on_mainloop[1] += 1
@cmd_queue.enq([@system, 'call_mainloop', if $SAFE >= 4
Thread.current, check_root]) _receiver_mainloop(check_root).join
Thread.stop else
@cmd_queue.enq([@system, 'call_mainloop',
Thread.current, check_root])
Thread.stop
end
rescue MultiTkIp_OK => ret rescue MultiTkIp_OK => ret
# return value # return value
@wait_on_mainloop[1] = false
if ret.value.kind_of?(Thread) if ret.value.kind_of?(Thread)
return ret.value.value return ret.value.value
else else
return ret.value return ret.value
end end
rescue SystemExit rescue SystemExit => e
# exit IP # exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
@wait_on_mainloop[1] = false
begin begin
self._eval_without_enc('exit') self._eval_without_enc('exit')
rescue Exception rescue Exception
@ -1887,17 +1955,18 @@ class MultiTkIp
((e.message.length > 0)? ' "' + e.message + '"': '') + ((e.message.length > 0)? ' "' + e.message + '"': '') +
" on " + self.inspect) " on " + self.inspect)
end end
@wait_on_mainloop[1] = false
return e return e
rescue Exception => e
return e
ensure ensure
@wait_on_mainloop[1] = false @wait_on_mainloop[1] -= 1
end end
end end
return return
end end
unless restart_on_dead unless restart_on_dead
@wait_on_mainloop[1] = true @wait_on_mainloop[1] += 1
=begin =begin
begin begin
@interp.mainloop(check_root) @interp.mainloop(check_root)
@ -1909,11 +1978,13 @@ class MultiTkIp
end end
end end
=end =end
@interp.mainloop(check_root) begin
@wait_on_mainloop[1] = false @interp.mainloop(check_root)
ensure
@wait_on_mainloop[1] -= 1
end
else else
loop do loop do
@wait_on_mainloop[1] = true
break unless self.alive? break unless self.alive?
if check_root if check_root
begin begin
@ -1924,6 +1995,7 @@ class MultiTkIp
end end
break if @interp.deleted? break if @interp.deleted?
begin begin
@wait_on_mainloop[1] += 1
@interp.mainloop(check_root) @interp.mainloop(check_root)
rescue StandardError => e rescue StandardError => e
if TclTkLib.mainloop_abort_on_exception != nil if TclTkLib.mainloop_abort_on_exception != nil
@ -1948,7 +2020,7 @@ class MultiTkIp
=end =end
raise e raise e
ensure ensure
@wait_on_mainloop[1] = false @wait_on_mainloop[1] -= 1
Thread.pass # avoid eventloop conflict Thread.pass # avoid eventloop conflict
end end
end end
@ -2040,6 +2112,10 @@ class MultiTkIp
@interp.deleted? @interp.deleted?
end end
def has_mainwindow?
@interp.has_mainwindow?
end
def invalid_namespace? def invalid_namespace?
@interp.invalid_namespace? @interp.invalid_namespace?
end end

View file

@ -60,8 +60,6 @@ class << RemoteTkIp
end end
class RemoteTkIp class RemoteTkIp
include TkUtil
def initialize(remote_ip, displayof=nil, timeout=5) def initialize(remote_ip, displayof=nil, timeout=5)
if $SAFE >= 4 if $SAFE >= 4
fail SecurityError, "cannot access another interpreter at level #{$SAFE}" fail SecurityError, "cannot access another interpreter at level #{$SAFE}"
@ -96,7 +94,7 @@ class RemoteTkIp
@safe_level = [$SAFE] @safe_level = [$SAFE]
@wait_on_mainloop = [true, false] @wait_on_mainloop = [true, 0]
@cmd_queue = Queue.new @cmd_queue = Queue.new
@ -179,7 +177,7 @@ class RemoteTkIp
fail SecurityError, "cannot send tainted commands at level #{$SAFE}" fail SecurityError, "cannot send tainted commands at level #{$SAFE}"
end end
cmds = @interp._merge_tklist(*_conv_args([], enc_mode, *cmds)) cmds = @interp._merge_tklist(*TkUtil::_conv_args([], enc_mode, *cmds))
if @displayof if @displayof
if async if async
@interp.__invoke('send', '-async', '-displayof', @displayof, @interp.__invoke('send', '-async', '-displayof', @displayof,
@ -283,6 +281,19 @@ class RemoteTkIp
end end
end end
def has_mainwindow?
begin
inf = @interp._invoke_without_enc('info', 'command', '.')
rescue Exception
return nil
end
if !inf.kind_of?(String) || inf != '.'
false
else
true
end
end
def invalid_namespace? def invalid_namespace?
false false
end end
@ -343,25 +354,25 @@ class RemoteTkIp
def _get_variable(var_name, flag) def _get_variable(var_name, flag)
# ignore flag # ignore flag
_appsend(false, 'set', _get_eval_string(var_name)) _appsend(false, 'set', TkComm::_get_eval_string(var_name))
end end
def _get_variable2(var_name, index_name, flag) def _get_variable2(var_name, index_name, flag)
# ignore flag # ignore flag
_appsend(false, 'set', "#{_get_eval_string(var_name)}(#{_get_eval_string(index_name)})") _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})")
end end
def _set_variable(var_name, value, flag) def _set_variable(var_name, value, flag)
# ignore flag # ignore flag
_appsend(false, 'set', _get_eval_string(var_name), _get_eval_string(value)) _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value))
end end
def _set_variable2(var_name, index_name, value, flag) def _set_variable2(var_name, index_name, value, flag)
# ignore flag # ignore flag
_appsend(false, 'set', "#{_get_eval_string(var_name)}(#{_get_eval_string(index_name)})", _get_eval_string(value)) _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})", TkComm::_get_eval_string(value))
end end
def _unset_variable(var_name, flag) def _unset_variable(var_name, flag)
# ignore flag # ignore flag
_appsend(false, 'unset', _get_eval_string(var_name)) _appsend(false, 'unset', TkComm::_get_eval_string(var_name))
end end
def _unset_variable2(var_name, index_name, flag) def _unset_variable2(var_name, index_name, flag)
# ignore flag # ignore flag
@ -369,21 +380,21 @@ class RemoteTkIp
end end
def _get_global_var(var_name) def _get_global_var(var_name)
_appsend(false, 'set', _get_eval_string(var_name)) _appsend(false, 'set', TkComm::_get_eval_string(var_name))
end end
def _get_global_var2(var_name, index_name) def _get_global_var2(var_name, index_name)
_appsend(false, 'set', "#{_get_eval_string(var_name)}(#{_get_eval_string(index_name)})") _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})")
end end
def _set_global_var(var_name, value) def _set_global_var(var_name, value)
_appsend(false, 'set', _get_eval_string(var_name), _get_eval_string(value)) _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value))
end end
def _set_global_var2(var_name, index_name, value) def _set_global_var2(var_name, index_name, value)
_appsend(false, 'set', "#{_get_eval_string(var_name)}(#{_get_eval_string(index_name)})", _get_eval_string(value)) _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})", TkComm::_get_eval_string(value))
end end
def _unset_global_var(var_name) def _unset_global_var(var_name)
_appsend(false, 'unset', _get_eval_string(var_name)) _appsend(false, 'unset', TkComm::_get_eval_string(var_name))
end end
def _unset_global_var2(var_name, index_name) def _unset_global_var2(var_name, index_name)
_appsend(false, 'unset', "#{var_name}(#{index_name})") _appsend(false, 'unset', "#{var_name}(#{index_name})")

View file

@ -1833,6 +1833,10 @@ module Tk
code code
end end
def Tk.has_mainwindow?
INTERP.has_mainwindow?
end
def root def root
TkRoot.new TkRoot.new
end end
@ -4195,7 +4199,7 @@ end
#Tk.freeze #Tk.freeze
module Tk module Tk
RELEASE_DATE = '2005-07-19'.freeze RELEASE_DATE = '2005-07-22'.freeze
autoload :AUTO_PATH, 'tk/variable' autoload :AUTO_PATH, 'tk/variable'
autoload :TCL_PACKAGE_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable'

View file

@ -4,7 +4,7 @@
* Oct. 24, 1997 Y. Matsumoto * Oct. 24, 1997 Y. Matsumoto
*/ */
#define TCLTKLIB_RELEASE_DATE "2005-07-19" #define TCLTKLIB_RELEASE_DATE "2005-07-22"
#include "ruby.h" #include "ruby.h"
#include "rubysig.h" #include "rubysig.h"
@ -511,6 +511,7 @@ get_ip(self)
} }
if (ptr->ip == (Tcl_Interp*)NULL) { if (ptr->ip == (Tcl_Interp*)NULL) {
/* rb_raise(rb_eRuntimeError, "deleted IP"); */ /* rb_raise(rb_eRuntimeError, "deleted IP"); */
return((struct tcltkip *)NULL);
} }
return ptr; return ptr;
} }
@ -5293,6 +5294,22 @@ ip_is_deleted_p(self)
} }
} }
static VALUE
ip_has_mainwindow_p(self)
VALUE self;
{
struct tcltkip *ptr = get_ip(self);
if (ptr == (struct tcltkip *)NULL || ptr->ip == (Tcl_Interp *)NULL
|| Tcl_InterpDeleted(ptr->ip)) {
return Qnil;
} else if (Tk_MainWindow(ptr->ip) == (Tk_Window)NULL) {
return Qfalse;
} else {
return Qtrue;
}
}
static VALUE static VALUE
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
@ -8557,6 +8574,7 @@ Init_tcltklib()
rb_define_method(ip, "allow_ruby_exit=", ip_allow_ruby_exit_set, 1); rb_define_method(ip, "allow_ruby_exit=", ip_allow_ruby_exit_set, 1);
rb_define_method(ip, "delete", ip_delete, 0); rb_define_method(ip, "delete", ip_delete, 0);
rb_define_method(ip, "deleted?", ip_is_deleted_p, 0); rb_define_method(ip, "deleted?", ip_is_deleted_p, 0);
rb_define_method(ip, "has_mainwindow?", ip_has_mainwindow_p, 0);
rb_define_method(ip, "invalid_namespace?", ip_has_invalid_namespace_p, 0); rb_define_method(ip, "invalid_namespace?", ip_has_invalid_namespace_p, 0);
rb_define_method(ip, "_eval", ip_eval, 1); rb_define_method(ip, "_eval", ip_eval, 1);
rb_define_method(ip, "_toUTF8", ip_toUTF8, -1); rb_define_method(ip, "_toUTF8", ip_toUTF8, -1);

View file

@ -8,7 +8,7 @@
************************************************/ ************************************************/
#define TKUTIL_RELEASE_DATE "2005-07-05" #define TKUTIL_RELEASE_DATE "2005-07-22"
#include "ruby.h" #include "ruby.h"
#include "rubysig.h" #include "rubysig.h"
@ -892,14 +892,14 @@ tk_conv_args(argc, argv, self)
int thr_crit_bup; int thr_crit_bup;
VALUE old_gc; VALUE old_gc;
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qtrue;
old_gc = rb_gc_disable();
if (argc < 2) { if (argc < 2) {
rb_raise(rb_eArgError, "too few arguments"); rb_raise(rb_eArgError, "too few arguments");
} }
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qtrue;
old_gc = rb_gc_disable();
for(size = 0, idx = 2; idx < argc; idx++) { for(size = 0, idx = 2; idx < argc; idx++) {
if (TYPE(argv[idx]) == T_HASH) { if (TYPE(argv[idx]) == T_HASH) {
size += 2 * RHASH(argv[idx])->tbl->num_entries; size += 2 * RHASH(argv[idx])->tbl->num_entries;
@ -1605,6 +1605,7 @@ Init_tkutil()
tk_get_eval_string, -1); tk_get_eval_string, -1);
rb_define_singleton_method(mTK, "_get_eval_enc_str", rb_define_singleton_method(mTK, "_get_eval_enc_str",
tk_get_eval_enc_str, 1); tk_get_eval_enc_str, 1);
rb_define_singleton_method(mTK, "_conv_args", tk_conv_args, -1);
rb_define_singleton_method(mTK, "bool", tcl2rb_bool, 1); rb_define_singleton_method(mTK, "bool", tcl2rb_bool, 1);
rb_define_singleton_method(mTK, "number", tcl2rb_number, 1); rb_define_singleton_method(mTK, "number", tcl2rb_number, 1);