module TkCore
Constants
- EventFlag
- INTERP
methods for construction
get target IP
get info
instance methods to treat tables
class methods to treat tables
for callback operation
pseudo-toplevel operation support
evaluate a procedure on the proper interpreter
event loop all master/slave IPs are controlled by only one event-loop
depend on
TclTkIp
interp command support
- Safe Base
-
manipulating safe interpreter
- INTERP_MUTEX
- INTERP_ROOT_CHECK
- INTERP_THREAD
- INTERP_THREAD_STATUS
- RUN_EVENTLOOP_ON_MAIN_THREAD
Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!
- WIDGET_DESTROY_HOOK
- WITH_ENCODING
- WITH_RUBY_VM
Public Class Methods
# File lib/tk.rb, line 1528 def TkCore.callback(*arg) begin if TkCore::INTERP.tk_cmd_tbl.kind_of?(Hash) #TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) normal_ret = false ret = catch(:IRB_EXIT) do # IRB hack retval = TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) normal_ret = true retval end unless normal_ret # catch IRB_EXIT exit(ret) end ret end rescue SystemExit=>e exit(e.status) rescue Interrupt=>e fail(e) rescue Exception => e begin msg = _toUTF8(e.class.inspect) + ': ' + _toUTF8(e.message) + "\n" + "\n---< backtrace of Ruby side >-----\n" + _toUTF8(e.backtrace.join("\n")) + "\n---< backtrace of Tk side >-------" if TkCore::WITH_ENCODING msg.force_encoding('utf-8') else msg.instance_variable_set(:@encoding, 'utf-8') end rescue Exception msg = e.class.inspect + ': ' + e.message + "\n" + "\n---< backtrace of Ruby side >-----\n" + e.backtrace.join("\n") + "\n---< backtrace of Tk side >-------" end # TkCore::INTERP._set_global_var('errorInfo', msg) # fail(e) fail(e, msg) end end
# File lib/tk.rb, line 1325 def inspect sprintf("#<Class(TkCallbackEntry):%0x>", self.__id__) end
# File lib/tk.rb, line 1331 def initialize(ip, cmd) @ip = ip @cmd = cmd end
Public Instance Methods
# File lib/tk.rb, line 1999 def _tk_call_to_list_core(depth, arg_enc, val_enc, *args) args = _conv_args([], arg_enc, *args) val = _tk_call_core(false, *args) if !depth.kind_of?(Integer) || depth == 0 tk_split_simplelist(val, false, val_enc) else tk_split_list(val, depth, false, val_enc) end end
# File lib/tk.rb, line 1614 def after(ms, cmd=nil, &block) cmd ||= block cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret}) after_id = tk_call_without_enc("after",ms,cmdid) after_id.instance_variable_set('@cmdid', cmdid) after_id end
# File lib/tk.rb, line 1630 def after_cancel(afterId) tk_call_without_enc('after','cancel',afterId) if (cmdid = afterId.instance_variable_get('@cmdid')) afterId.instance_variable_set('@cmdid', nil) uninstall_cmd(cmdid) end afterId end
# File lib/tk.rb, line 1622 def after_idle(cmd=nil, &block) cmd ||= block cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret}) after_id = tk_call_without_enc('after','idle',cmdid) after_id.instance_variable_set('@cmdid', cmdid) after_id end
# File lib/tk.rb, line 1671 def appname(name=None) tk_call('tk', 'appname', name) end
# File lib/tk.rb, line 1679 def appsend(interp, async, *args) if async != true && async != false && async != nil args.unshift(async) async = false end if async tk_call('send', '-async', '--', interp, *args) else tk_call('send', '--', interp, *args) end end
# File lib/tk.rb, line 1675 def appsend_deny tk_call('rename', 'send', '') end
# File lib/tk.rb, line 1704 def appsend_displayof(interp, win, async, *args) win = '.' if win == nil if async != true && async != false && async != nil args.unshift(async) async = false end if async tk_call('send', '-async', '-displayof', win, '--', interp, *args) else tk_call('send', '-displayor', win, '--', interp, *args) end end
# File lib/tk.rb, line 1336 def call(*args) @ip.cb_eval(@cmd, *args) end
# File lib/tk.rb, line 1516 def callback_break fail TkCallbackBreak, "Tk callback returns 'break' status" end
# File lib/tk.rb, line 1520 def callback_continue fail TkCallbackContinue, "Tk callback returns 'continue' status" end
# File lib/tk.rb, line 1524 def callback_return fail TkCallbackReturn, "Tk callback returns 'return' status" end
# File lib/tk.rb, line 1891 def chooseColor(keys = nil) tk_call('tk_chooseColor', *hash_kv(keys)) end
# File lib/tk.rb, line 1895 def chooseDirectory(keys = nil) tk_call('tk_chooseDirectory', *hash_kv(keys)) end
# File lib/tk.rb, line 1820 def do_one_event(flag = TclTkLib::EventFlag::ALL) TclTkLib.do_one_event(flag) end
# File lib/tk.rb, line 1861 def event_generate(win, context, keys=nil) #win = win.path if win.kind_of?(TkObject) if context.kind_of?(TkEvent::Event) context.generate(win, ((keys)? keys: {})) elsif keys tk_call_without_enc('event', 'generate', win, "<#{tk_event_sequence(context)}>", *hash_kv(keys, true)) else tk_call_without_enc('event', 'generate', win, "<#{tk_event_sequence(context)}>") end nil end
# File lib/tk.rb, line 1883 def getMultipleOpenFile(keys = nil) simplelist(tk_call('tk_getOpenFile', '-multiple', '1', *hash_kv(keys))) end
# File lib/tk.rb, line 1880 def getOpenFile(keys = nil) tk_call('tk_getOpenFile', *hash_kv(keys)) end
# File lib/tk.rb, line 1887 def getSaveFile(keys = nil) tk_call('tk_getSaveFile', *hash_kv(keys)) end
# File lib/tk.rb, line 1828 def get_eventloop_tick() TclTkLib.get_eventloop_tick end
# File lib/tk.rb, line 1844 def get_eventloop_weight() TclTkLib.get_eventloop_weight end
# File lib/tk.rb, line 1836 def get_no_event_wait() TclTkLib.get_no_eventloop_wait end
# File lib/tk.rb, line 1658 def inactive Integer(tk_call_without_enc('tk', 'inactive')) end
# File lib/tk.rb, line 1661 def inactive_displayof(win) Integer(tk_call_without_enc('tk', 'inactive', '-displayof', win)) end
# File lib/tk.rb, line 1339 def inspect sprintf("#<cb_entry:%0x>", self.__id__) end
# File lib/tk.rb, line 1915 def ip_eval(cmd_string) _ip_eval_core(nil, cmd_string) end
# File lib/tk.rb, line 1923 def ip_eval_with_enc(cmd_string) _ip_eval_core(true, cmd_string) end
# File lib/tk.rb, line 1919 def ip_eval_without_enc(cmd_string) _ip_eval_core(false, cmd_string) end
# File lib/tk.rb, line 1943 def ip_invoke(*args) _ip_invoke_core(nil, *args) end
# File lib/tk.rb, line 1951 def ip_invoke_with_enc(*args) _ip_invoke_core(true, *args) end
# File lib/tk.rb, line 1947 def ip_invoke_without_enc(*args) _ip_invoke_core(false, *args) end
# File lib/tk.rb, line 1811 def is_mainloop? TclTkLib.mainloop_thread? == true end
def TkCore.callback(arg_str) # arg = tk_split_list(arg_str) arg = tk_split_simplelist(arg_str) #_get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg)) #_get_eval_string(TkUtil.eval_cmd(TkCore::INTERP.tk_cmd_tbl[arg.shift], # *arg)) # TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) begin TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) rescue Exception => e raise(e, e.class.inspect + ': ' + e.message + "\n" + "\n---< backtrace of Ruby side >-----\n" + e.backtrace.join("\n") + "\n---< backtrace of Tk side >-------") end
#=begin # cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift]
# unless $DEBUG # cb_obj.call(*arg) # else # begin # raise ‘check backtrace’ # rescue # # ignore backtrace before ‘callback’ # pos = -($!.backtrace.size) # end # begin # cb_obj.call(*arg) # rescue # trace = $!.backtrace # raise $!, “n#{trace}: #{$!.message} (#{$!.class})n” + # “tfrom #{trace.join(”ntfrom “)}” # end # end #=end
end
# File lib/tk.rb, line 1610 def load_cmd_on_ip(tk_cmd) bool(tk_call('auto_load', tk_cmd)) end
# File lib/tk.rb, line 1735 def mainloop(check_root = true) if !TkCore::WITH_RUBY_VM TclTkLib.mainloop(check_root) elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD # if TclTkLib::WINDOWING_SYSTEM == 'aqua' && #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='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 if Thread.current != Thread.main raise RuntimeError, "Tk.mainloop is allowed on the main thread only" end TclTkLib.mainloop(check_root) else ### Ruby 1.9 !!!!! unless TkCore::INTERP.default_master? # [MultiTkIp] slave interp ? return TkCore::INTERP._thread_tkwait('window', '.') if check_root end # like as 1.8, withdraw a root widget before calling Tk.mainloop TkCore::INTERP._eval_without_enc('catch {unset __initial_state_of_rubytk__}') INTERP_THREAD.run begin TclTkLib.set_eventloop_window_mode(true) # force run the eventloop TkCore::INTERP._eval_without_enc('update') TkCore::INTERP._eval_without_enc('catch {set __initial_state_of_rubytk__}') INTERP_THREAD.run if check_root INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.wait(INTERP_MUTEX) status = INTERP_THREAD_STATUS.value if status && TkCore::INTERP.default_master? INTERP_THREAD_STATUS.value = nil raise status if status.kind_of?(Exception) end } else # INTERP_THREAD.value begin INTERP_THREAD.value rescue Exception => e raise e end end rescue Exception => e raise e ensure TclTkLib.set_eventloop_window_mode(false) end end end
# File lib/tk.rb, line 1807 def mainloop_exist? TclTkLib.mainloop_thread? != nil end
# File lib/tk.rb, line 1794 def mainloop_thread? # true : current thread is mainloop # nil : there is no mainloop # false : mainloop is running on the other thread # ( At then, it is dangerous to call Tk interpreter directly. ) if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD ### Ruby 1.9 !!!!!!!!!!! TclTkLib.mainloop_thread? else Thread.current == INTERP_THREAD end end
# File lib/tk.rb, line 1815 def mainloop_watchdog(check_root = true) # watchdog restarts mainloop when mainloop is dead TclTkLib.mainloop_watchdog(check_root) end
# File lib/tk.rb, line 1876 def messageBox(keys) tk_call('tk_messageBox', *hash_kv(keys)) end
# File lib/tk.rb, line 1691 def rb_appsend(interp, async, *args) if async != true && async != false && async != nil args.unshift(async) async = false end #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} # args.push(').to_s"') # appsend(interp, async, 'ruby "(', *args) args.push('}.call)"') appsend(interp, async, 'ruby "TkComm._get_eval_string(proc{', *args) end
# File lib/tk.rb, line 1717 def rb_appsend_displayof(interp, win, async, *args) win = '.' if win == nil if async != true && async != false && async != nil args.unshift(async) async = false end #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} # args.push(').to_s"') # appsend_displayof(interp, win, async, 'ruby "(', *args) args.push('}.call)"') appsend(interp, win, async, 'ruby "TkComm._get_eval_string(proc{', *args) end
# File lib/tk.rb, line 1664 def reset_inactive tk_call_without_enc('tk', 'inactive', 'reset') end
# File lib/tk.rb, line 1667 def reset_inactive_displayof(win) tk_call_without_enc('tk', 'inactive', '-displayof', win, 'reset') end
# File lib/tk.rb, line 1848 def restart(app_name = nil, keys = {}) TkCore::INTERP.init_ip_internal tk_call('set', 'argv0', app_name) if app_name if keys.kind_of?(Hash) # tk_call('set', 'argc', keys.size * 2) tk_call('set', 'argv', hash_kv(keys).join(' ')) end INTERP.restart nil end
# File lib/tk.rb, line 1643 def scaling(scale=nil) if scale tk_call_without_enc('tk', 'scaling', scale) else Float(number(tk_call_without_enc('tk', 'scaling'))) end end
# File lib/tk.rb, line 1650 def scaling_displayof(win, scale=nil) if scale tk_call_without_enc('tk', 'scaling', '-displayof', win, scale) else Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling'))) end end
# File lib/tk.rb, line 1824 def set_eventloop_tick(timer_tick) TclTkLib.set_eventloop_tick(timer_tick) end
# File lib/tk.rb, line 1840 def set_eventloop_weight(loop_max, no_event_tick) TclTkLib.set_eventloop_weight(loop_max, no_event_tick) end
# File lib/tk.rb, line 1832 def set_no_event_wait(wait) TclTkLib.set_no_even_wait(wait) end
# File lib/tk.rb, line 1987 def tk_call(*args) _tk_call_core(nil, *args) end
private :_tk_call_to_list_core
# File lib/tk.rb, line 2010 def tk_call_to_list(*args) _tk_call_to_list_core(-1, nil, true, *args) end
# File lib/tk.rb, line 2018 def tk_call_to_list_with_enc(*args) _tk_call_to_list_core(-1, true, true, *args) end
# File lib/tk.rb, line 2014 def tk_call_to_list_without_enc(*args) _tk_call_to_list_core(-1, false, false, *args) end
# File lib/tk.rb, line 2022 def tk_call_to_simplelist(*args) _tk_call_to_list_core(0, nil, true, *args) end
# File lib/tk.rb, line 2030 def tk_call_to_simplelist_with_enc(*args) _tk_call_to_list_core(0, true, true, *args) end
# File lib/tk.rb, line 2026 def tk_call_to_simplelist_without_enc(*args) _tk_call_to_list_core(0, false, false, *args) end
# File lib/tk.rb, line 1995 def tk_call_with_enc(*args) _tk_call_core(true, *args) end
# File lib/tk.rb, line 1991 def tk_call_without_enc(*args) _tk_call_core(false, *args) end
# File lib/tk.rb, line 1639 def windowingsystem tk_call_without_enc('tk', 'windowingsystem') end
Private Instance Methods
# File lib/tk.rb, line 1899 def _ip_eval_core(enc_mode, cmd_string) case enc_mode when nil res = INTERP._eval(cmd_string) when false res = INTERP._eval_without_enc(cmd_string) when true res = INTERP._eval_with_enc(cmd_string) end if INTERP._return_value() != 0 fail RuntimeError, res, error_at end return res end
# File lib/tk.rb, line 1927 def _ip_invoke_core(enc_mode, *args) case enc_mode when false res = INTERP._invoke_without_enc(*args) when nil res = INTERP._invoke(*args) when true res = INTERP._invoke_with_enc(*args) end if INTERP._return_value() != 0 fail RuntimeError, res, error_at end return res end
# File lib/tk.rb, line 1955 def _tk_call_core(enc_mode, *args) ### puts args.inspect if $DEBUG #args.collect! {|x|ruby2tcl(x, enc_mode)} #args.compact! #args.flatten! args = _conv_args([], enc_mode, *args) puts 'invoke args => ' + args.inspect if $DEBUG ### print "=> ", args.join(" ").inspect, "\n" if $DEBUG begin # res = INTERP._invoke(enc_mode, *args) res = _ip_invoke_core(enc_mode, *args) # >>>>> _invoke returns a TAINTED string <<<<< rescue NameError => err # err = $! begin args.unshift "unknown" #res = INTERP._invoke(enc_mode, *args) res = _ip_invoke_core(enc_mode, *args) # >>>>> _invoke returns a TAINTED string <<<<< rescue StandardError => err2 fail err2 unless /^invalid command/ =~ err2.message fail err end end if INTERP._return_value() != 0 fail RuntimeError, res, error_at end ### print "==> ", res.inspect, "\n" if $DEBUG return res end
# File lib/tk.rb, line 1731 def info(*args) tk_call('info', *args) end