зеркало из https://github.com/github/ruby.git
* tcltklib.c (lib_mainloop_core): fixed signal-trap bug
* multi-tk.rb, tk.rb, tkafter.rb, tkcanvas.rb, tkfont.rb, tktext.rb, tkvirtevent.rb : Ruby/Tk works at $SAFE == 4 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
a7357c1965
Коммит
865ff7fb4f
|
@ -1,3 +1,9 @@
|
||||||
|
Sun Sep 7 16:08:28 2003 <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tcltklib/tcltklib.c (lib_mainloop_core): fixed signal-trap bug
|
||||||
|
|
||||||
|
* ext/tk/lib/*.rb : Ruby/Tk works at $SAFE == 4
|
||||||
|
|
||||||
Fri Sep 6 02:26:34 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
Fri Sep 6 02:26:34 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
||||||
|
|
||||||
* test/ruby/test_*.rb: assert_same, assert_match, and so on.
|
* test/ruby/test_*.rb: assert_same, assert_match, and so on.
|
||||||
|
|
|
@ -192,13 +192,16 @@ require "tcltklib"
|
||||||
: ( 監視スレッドを生成した後にイベントループを実行する ).
|
: ( 監視スレッドを生成した後にイベントループを実行する ).
|
||||||
: 引数の意味は mainloop と同じである.
|
: 引数の意味は mainloop と同じである.
|
||||||
|
|
||||||
do_one_event(flag = TclTkLib::EventFlag::ALL)
|
do_one_event(flag = TclTkLib::EventFlag::ALL |
|
||||||
|
TclTkLib::EventFlag::DONT_WAIT)
|
||||||
: 処理待ちのイベント 1 個を実行する.
|
: 処理待ちのイベント 1 個を実行する.
|
||||||
: イベントを処理した場合は true を返す.
|
: イベントを処理した場合は true を返す.
|
||||||
: フラグで DONT_WAIT を指定していない場合,フラグで処理対
|
: フラグで DONT_WAIT を指定していない場合,フラグで処理対
|
||||||
: 象となっている種類のイベントが発生するまで待ち続ける.
|
: 象となっている種類のイベントが発生するまで待ち続ける.
|
||||||
: DONT_WAIT を指定していた場合,処理対象イベントがなくても
|
: DONT_WAIT を指定していた場合,処理対象イベントがなくても
|
||||||
: すぐに終了し false を返す.
|
: すぐに終了し false を返す.
|
||||||
|
: $SAFE >= 4 か,$SAFE >= 1 かつ flag が汚染されているならば
|
||||||
|
: flag には DONT_WAIT が強制的に付けられる.
|
||||||
|
|
||||||
set_eventloop_tick(timer_tick)
|
set_eventloop_tick(timer_tick)
|
||||||
: イベントループと同時に別スレッドが稼働している場合に,時
|
: イベントループと同時に別スレッドが稼働している場合に,時
|
||||||
|
@ -213,6 +216,7 @@ require "tcltklib"
|
||||||
: 定される.
|
: 定される.
|
||||||
: 詳細な説明は略すが,これは CPU パワーを節約しつつ安全で
|
: 詳細な説明は略すが,これは CPU パワーを節約しつつ安全で
|
||||||
: 安定した動作を実現するために実装した仕様である.
|
: 安定した動作を実現するために実装した仕様である.
|
||||||
|
: $SAFE >= 4 では実行が禁止される.
|
||||||
|
|
||||||
get_eventloop_tick
|
get_eventloop_tick
|
||||||
: timer_tick の現在値を返す.
|
: timer_tick の現在値を返す.
|
||||||
|
@ -222,6 +226,7 @@ require "tcltklib"
|
||||||
: く存在しなかった際に sleep 状態に入る時間長を指定する.
|
: く存在しなかった際に sleep 状態に入る時間長を指定する.
|
||||||
: 稼働スレッドがイベントループだけの場合には意味をなさない.
|
: 稼働スレッドがイベントループだけの場合には意味をなさない.
|
||||||
: デフォルトの値は 20 (ms)
|
: デフォルトの値は 20 (ms)
|
||||||
|
: $SAFE >= 4 では実行が禁止される.
|
||||||
|
|
||||||
get_no_event_wait
|
get_no_event_wait
|
||||||
: no_event_wait の現在値を返す.
|
: no_event_wait の現在値を返す.
|
||||||
|
@ -239,6 +244,7 @@ require "tcltklib"
|
||||||
: が全く発生しないままに 80 回の処理待ちイベント検査が完了
|
: が全く発生しないままに 80 回の処理待ちイベント検査が完了
|
||||||
: するとかでカウントが 800 以上になるとスレッドスイッチング
|
: するとかでカウントが 800 以上になるとスレッドスイッチング
|
||||||
: が発生することになる.
|
: が発生することになる.
|
||||||
|
: $SAFE >= 4 では実行が禁止される.
|
||||||
|
|
||||||
get_eventloop_weight
|
get_eventloop_weight
|
||||||
: 現在の loop_max と no_event_tick との値を返す.
|
: 現在の loop_max と no_event_tick との値を返す.
|
||||||
|
@ -258,6 +264,7 @@ require "tcltklib"
|
||||||
: 他のインタープリタの処理継続が不可能になることがある.その
|
: 他のインタープリタの処理継続が不可能になることがある.その
|
||||||
: ような場合でもエラーを無視してイベントループが稼働を続ける
|
: ような場合でもエラーを無視してイベントループが稼働を続ける
|
||||||
: ことで,他のインタープリタが正常に動作し続けることができる.
|
: ことで,他のインタープリタが正常に動作し続けることができる.
|
||||||
|
: $SAFE >= 4 では実行が禁止される.
|
||||||
|
|
||||||
mainloop_abort_on_exception
|
mainloop_abort_on_exception
|
||||||
: Tk インタープリタ上で例外を発生した際に,イベントループをエ
|
: Tk インタープリタ上で例外を発生した際に,イベントループをエ
|
||||||
|
@ -295,6 +302,7 @@ require "tcltklib"
|
||||||
: たとえ明確に false を指定していたとしても,親となるインター
|
: たとえ明確に false を指定していたとしても,親となるインター
|
||||||
: プリタが safe インタープリタであれば,その設定を引き継いで
|
: プリタが safe インタープリタであれば,その設定を引き継いで
|
||||||
: safe インタープリタとして生成される.
|
: safe インタープリタとして生成される.
|
||||||
|
: $SAFE >= 4 では,safe インタープリタ以外の生成が禁止される.
|
||||||
|
|
||||||
make_safe
|
make_safe
|
||||||
: Tcl/Tk インタープリタを safe インタープリタに変更する.
|
: Tcl/Tk インタープリタを safe インタープリタに変更する.
|
||||||
|
@ -319,6 +327,7 @@ require "tcltklib"
|
||||||
: Tcl/Tk インタープリタの Tk 部分の初期化,再起動を行う.
|
: Tcl/Tk インタープリタの Tk 部分の初期化,再起動を行う.
|
||||||
: 一旦 root widget を破壊した後に再度 Tk の機能が必要と
|
: 一旦 root widget を破壊した後に再度 Tk の機能が必要と
|
||||||
: なった場合に用いる.
|
: なった場合に用いる.
|
||||||
|
: $SAFE >= 4 では実行が禁止される.
|
||||||
|
|
||||||
_eval(str)
|
_eval(str)
|
||||||
_invoke(*args)
|
_invoke(*args)
|
||||||
|
|
|
@ -154,6 +154,8 @@ set_eventloop_tick(self, tick)
|
||||||
{
|
{
|
||||||
int ttick = NUM2INT(tick);
|
int ttick = NUM2INT(tick);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
|
|
||||||
if (ttick < 0) {
|
if (ttick < 0) {
|
||||||
rb_raise(rb_eArgError,
|
rb_raise(rb_eArgError,
|
||||||
"timer-tick parameter must be 0 or positive number");
|
"timer-tick parameter must be 0 or positive number");
|
||||||
|
@ -209,6 +211,8 @@ set_no_event_wait(self, wait)
|
||||||
{
|
{
|
||||||
int t_wait = NUM2INT(wait);
|
int t_wait = NUM2INT(wait);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
|
|
||||||
if (t_wait <= 0) {
|
if (t_wait <= 0) {
|
||||||
rb_raise(rb_eArgError,
|
rb_raise(rb_eArgError,
|
||||||
"no_event_wait parameter must be positive number");
|
"no_event_wait parameter must be positive number");
|
||||||
|
@ -256,6 +260,8 @@ set_eventloop_weight(self, loop_max, no_event)
|
||||||
int lpmax = NUM2INT(loop_max);
|
int lpmax = NUM2INT(loop_max);
|
||||||
int no_ev = NUM2INT(no_event);
|
int no_ev = NUM2INT(no_event);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
|
|
||||||
if (lpmax <= 0 || no_ev <= 0) {
|
if (lpmax <= 0 || no_ev <= 0) {
|
||||||
rb_raise(rb_eArgError, "weight parameters must be positive numbers");
|
rb_raise(rb_eArgError, "weight parameters must be positive numbers");
|
||||||
}
|
}
|
||||||
|
@ -336,6 +342,7 @@ ip_evloop_abort_on_exc_set(self, val)
|
||||||
{
|
{
|
||||||
struct tcltkip *ptr = get_ip(self);
|
struct tcltkip *ptr = get_ip(self);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
|
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
|
||||||
/* slave IP */
|
/* slave IP */
|
||||||
return lib_evloop_abort_on_exc(self);
|
return lib_evloop_abort_on_exc(self);
|
||||||
|
@ -392,6 +399,8 @@ lib_mainloop_core(check_root_widget)
|
||||||
if (run_timer_flag) {
|
if (run_timer_flag) {
|
||||||
DUMP1("timer interrupt");
|
DUMP1("timer interrupt");
|
||||||
run_timer_flag = 0;
|
run_timer_flag = 0;
|
||||||
|
DUMP1("call rb_trap_exec()");
|
||||||
|
rb_trap_exec();
|
||||||
DUMP1("check Root Widget");
|
DUMP1("check Root Widget");
|
||||||
if (check && Tk_GetNumMainWindows() == 0) {
|
if (check && Tk_GetNumMainWindows() == 0) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -619,15 +628,18 @@ lib_do_one_event_core(argc, argv, self, is_ip)
|
||||||
{
|
{
|
||||||
VALUE vflags;
|
VALUE vflags;
|
||||||
int flags;
|
int flags;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (rb_scan_args(argc, argv, "01", &vflags) == 0) {
|
if (rb_scan_args(argc, argv, "01", &vflags) == 0) {
|
||||||
flags = TCL_ALL_EVENTS;
|
flags = TCL_ALL_EVENTS | TCL_DONT_WAIT;
|
||||||
} else {
|
} else {
|
||||||
Check_Type(vflags, T_FIXNUM);
|
Check_Type(vflags, T_FIXNUM);
|
||||||
flags = FIX2INT(vflags);
|
flags = FIX2INT(vflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rb_safe_level() >= 4 || (rb_safe_level() >=1 && OBJ_TAINTED(vflags))) {
|
||||||
|
flags |= TCL_DONT_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_ip) {
|
if (is_ip) {
|
||||||
/* check IP */
|
/* check IP */
|
||||||
struct tcltkip *ptr = get_ip(self);
|
struct tcltkip *ptr = get_ip(self);
|
||||||
|
@ -637,8 +649,7 @@ lib_do_one_event_core(argc, argv, self, is_ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = Tcl_DoOneEvent(flags);
|
if (Tcl_DoOneEvent(flags)) {
|
||||||
if (ret) {
|
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
} else {
|
} else {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
@ -681,6 +692,8 @@ lib_restart(self)
|
||||||
{
|
{
|
||||||
struct tcltkip *ptr = get_ip(self);
|
struct tcltkip *ptr = get_ip(self);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
|
|
||||||
/* destroy the root wdiget */
|
/* destroy the root wdiget */
|
||||||
ptr->return_value = Tcl_Eval(ptr->ip, "destroy .");
|
ptr->return_value = Tcl_Eval(ptr->ip, "destroy .");
|
||||||
/* ignore ERROR */
|
/* ignore ERROR */
|
||||||
|
@ -715,6 +728,7 @@ ip_restart(self)
|
||||||
{
|
{
|
||||||
struct tcltkip *ptr = get_ip(self);
|
struct tcltkip *ptr = get_ip(self);
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
|
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
|
||||||
/* slave IP */
|
/* slave IP */
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -912,6 +926,7 @@ ip_create_slave(argc, argv, self)
|
||||||
safe = 1;
|
safe = 1;
|
||||||
} else if (safemode == Qfalse || safemode == Qnil) {
|
} else if (safemode == Qfalse || safemode == Qnil) {
|
||||||
safe = 0;
|
safe = 0;
|
||||||
|
rb_secure(4);
|
||||||
} else {
|
} else {
|
||||||
safe = 1;
|
safe = 1;
|
||||||
}
|
}
|
||||||
|
@ -961,7 +976,7 @@ ip_delete(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct tcltkip *ptr = get_ip(self);
|
struct tcltkip *ptr = get_ip(self);
|
||||||
|
|
||||||
Tcl_DeleteInterp(ptr->ip);
|
Tcl_DeleteInterp(ptr->ip);
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -1131,7 +1146,6 @@ ip_invoke_real(argc, argv, obj)
|
||||||
|
|
||||||
/* ip is deleted? */
|
/* ip is deleted? */
|
||||||
if (Tcl_InterpDeleted(ptr->ip)) {
|
if (Tcl_InterpDeleted(ptr->ip)) {
|
||||||
Tcl_ResetResult(ptr->ip);
|
|
||||||
return rb_tainted_str_new2("");
|
return rb_tainted_str_new2("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1139,7 +1153,7 @@ ip_invoke_real(argc, argv, obj)
|
||||||
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
|
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
|
||||||
/* if (event_loop_abort_on_exc || cmd[0] != '.') { */
|
/* if (event_loop_abort_on_exc || cmd[0] != '.') { */
|
||||||
if (event_loop_abort_on_exc > 0) {
|
if (event_loop_abort_on_exc > 0) {
|
||||||
/*rb_ip_raise(obj, rb_eNameError, "invalid command name `%s'", cmd);*/
|
/*rb_ip_raise(obj,rb_eNameError,"invalid command name `%s'",cmd);*/
|
||||||
return create_ip_exc(obj, rb_eNameError,
|
return create_ip_exc(obj, rb_eNameError,
|
||||||
"invalid command name `%s'", cmd);
|
"invalid command name `%s'", cmd);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1349,11 +1363,11 @@ ip_invoke(argc, argv, obj)
|
||||||
|
|
||||||
/* get result & free allocated memory */
|
/* get result & free allocated memory */
|
||||||
result = *alloc_result;
|
result = *alloc_result;
|
||||||
if (rb_obj_is_kind_of(result, rb_eException)) {
|
|
||||||
rb_exc_raise(result);
|
|
||||||
}
|
|
||||||
free(alloc_argv);
|
free(alloc_argv);
|
||||||
free(alloc_result);
|
free(alloc_result);
|
||||||
|
if (rb_obj_is_kind_of(result, rb_eException)) {
|
||||||
|
rb_exc_raise(result);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ MultiTkIp_OK.freeze
|
||||||
################################################
|
################################################
|
||||||
# methods for construction
|
# methods for construction
|
||||||
class MultiTkIp
|
class MultiTkIp
|
||||||
SLAVE_IP_ID = ['slave'.freeze, '0'].freeze
|
SLAVE_IP_ID = ['slave'.freeze, '0'.taint].freeze
|
||||||
|
|
||||||
@@IP_TABLE = {}
|
@@IP_TABLE = {}.taint
|
||||||
|
|
||||||
@@INIT_IP_ENV = [] # table of Procs
|
@@INIT_IP_ENV = [].taint # table of Procs
|
||||||
@@ADD_TK_PROCS = [] # table of [name, args, body]
|
@@ADD_TK_PROCS = [].taint # table of [name, args, body]
|
||||||
|
|
||||||
@@TK_TABLE_LIST = []
|
@@TK_TABLE_LIST = [].taint
|
||||||
|
|
||||||
@@TK_CMD_TBL = {}
|
@@TK_CMD_TBL = {}.taint
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class MultiTkIp
|
||||||
rescue Exception
|
rescue Exception
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}.freeze
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
|
|
||||||
|
@ -200,13 +200,13 @@ class MultiTkIp
|
||||||
|
|
||||||
@@DEFAULT_MASTER = self.allocate
|
@@DEFAULT_MASTER = self.allocate
|
||||||
@@DEFAULT_MASTER.instance_eval{
|
@@DEFAULT_MASTER.instance_eval{
|
||||||
@encoding = []
|
@encoding = [].taint
|
||||||
|
|
||||||
@tk_windows = {}
|
@tk_windows = {}.taint
|
||||||
|
|
||||||
@tk_table_list = []
|
@tk_table_list = [].taint
|
||||||
|
|
||||||
@slave_ip_tbl = {}
|
@slave_ip_tbl = {}.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"
|
||||||
|
@ -266,6 +266,7 @@ class MultiTkIp
|
||||||
'nested'.freeze,
|
'nested'.freeze,
|
||||||
'deleteHook'.freeze
|
'deleteHook'.freeze
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
def _parse_slaveopts(keys)
|
def _parse_slaveopts(keys)
|
||||||
name = nil
|
name = nil
|
||||||
safe = false
|
safe = false
|
||||||
|
@ -462,18 +463,24 @@ class MultiTkIp
|
||||||
fail SecurityError, "slave-ip cannot create master-ip"
|
fail SecurityError, "slave-ip cannot create master-ip"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if safeip == nil && $SAFE >= 4
|
||||||
|
fail SecurityError, "cannot create master-ip at level #{$SAFE}"
|
||||||
|
end
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@encoding = []
|
@encoding = []
|
||||||
|
|
||||||
@tk_windows = {}
|
@tk_windows = {}
|
||||||
|
|
||||||
@tk_table_list = []
|
@tk_table_list = []
|
||||||
|
|
||||||
@slave_ip_tbl = {}
|
@slave_ip_tbl = {}
|
||||||
|
|
||||||
|
@encoding.taint unless @encoding.tainted?
|
||||||
|
@tk_windows.taint unless @tk_windows.tainted?
|
||||||
|
@tk_table_list.taint unless @tk_table_list.tainted?
|
||||||
|
@slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
|
||||||
|
|
||||||
name, safe, safe_opts, tk_opts = _parse_slaveopts(keys)
|
name, safe, safe_opts, tk_opts = _parse_slaveopts(keys)
|
||||||
|
|
||||||
if safeip == nil
|
if safeip == nil
|
||||||
|
@ -508,7 +515,10 @@ class MultiTkIp
|
||||||
|
|
||||||
@@IP_TABLE[@threadgroup] = self
|
@@IP_TABLE[@threadgroup] = self
|
||||||
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
|
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
|
||||||
@@TK_TABLE_LIST.size.times{ @tk_table_list << {} }
|
@@TK_TABLE_LIST.size.times{
|
||||||
|
(tbl = {}).tainted? || tbl.taint
|
||||||
|
@tk_table_list << tbl
|
||||||
|
}
|
||||||
|
|
||||||
self.freeze # defend against modification
|
self.freeze # defend against modification
|
||||||
end
|
end
|
||||||
|
@ -661,7 +671,10 @@ class MultiTkIp
|
||||||
end
|
end
|
||||||
|
|
||||||
def _add_new_tables
|
def _add_new_tables
|
||||||
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{ @tk_table_list << {} }
|
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{
|
||||||
|
(tbl = {}).tainted? || tbl.taint
|
||||||
|
@tk_table_list << tbl
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def _init_ip_env(script)
|
def _init_ip_env(script)
|
||||||
|
@ -701,9 +714,9 @@ class MultiTkIp
|
||||||
__getip._tk_table_list[id]
|
__getip._tk_table_list[id]
|
||||||
end
|
end
|
||||||
def self.create_table
|
def self.create_table
|
||||||
if __getip.slave?
|
#if __getip.slave?
|
||||||
raise SecurityError, "slave-IP has no permission creating a new table"
|
# raise SecurityError, "slave-IP has no permission creating a new table"
|
||||||
end
|
#end
|
||||||
id = @@TK_TABLE_LIST.size
|
id = @@TK_TABLE_LIST.size
|
||||||
obj = Object.new
|
obj = Object.new
|
||||||
@@TK_TABLE_LIST << obj
|
@@TK_TABLE_LIST << obj
|
||||||
|
|
|
@ -8,7 +8,7 @@ require "tcltklib"
|
||||||
require "tkutil"
|
require "tkutil"
|
||||||
|
|
||||||
module TkComm
|
module TkComm
|
||||||
WidgetClassNames = {}
|
WidgetClassNames = {}.taint
|
||||||
|
|
||||||
None = Object.new
|
None = Object.new
|
||||||
def None.to_s
|
def None.to_s
|
||||||
|
@ -18,7 +18,7 @@ module TkComm
|
||||||
|
|
||||||
#Tk_CMDTBL = {}
|
#Tk_CMDTBL = {}
|
||||||
#Tk_WINDOWS = {}
|
#Tk_WINDOWS = {}
|
||||||
Tk_IDs = ["00000", "00000"].freeze # [0]-cmdid, [1]-winid
|
Tk_IDs = ["00000".taint, "00000".taint].freeze # [0]-cmdid, [1]-winid
|
||||||
|
|
||||||
# for backward compatibility
|
# for backward compatibility
|
||||||
Tk_CMDTBL = Object.new
|
Tk_CMDTBL = Object.new
|
||||||
|
@ -33,7 +33,7 @@ module TkComm
|
||||||
Tk_WINDOWS.freeze
|
Tk_WINDOWS.freeze
|
||||||
|
|
||||||
self.instance_eval{
|
self.instance_eval{
|
||||||
@cmdtbl = []
|
@cmdtbl = [].taint
|
||||||
}
|
}
|
||||||
|
|
||||||
def error_at
|
def error_at
|
||||||
|
@ -332,6 +332,7 @@ module TkComm
|
||||||
#Tk_CMDTBL[id] = cmd
|
#Tk_CMDTBL[id] = cmd
|
||||||
TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)
|
TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)
|
||||||
@cmdtbl = [] unless defined? @cmdtbl
|
@cmdtbl = [] unless defined? @cmdtbl
|
||||||
|
@cmdtbl.taint unless @cmdtbl.tainted?
|
||||||
@cmdtbl.push id
|
@cmdtbl.push id
|
||||||
return format("rb_out %s", id);
|
return format("rb_out %s", id);
|
||||||
end
|
end
|
||||||
|
@ -679,13 +680,13 @@ module TkCore
|
||||||
end
|
end
|
||||||
|
|
||||||
INTERP.instance_eval{
|
INTERP.instance_eval{
|
||||||
@tk_cmd_tbl = {}
|
@tk_cmd_tbl = {}.taint
|
||||||
@tk_windows = {}
|
@tk_windows = {}.taint
|
||||||
|
|
||||||
@tk_table_list = []
|
@tk_table_list = [].taint
|
||||||
|
|
||||||
@init_ip_env = [] # table of Procs
|
@init_ip_env = [].taint # table of Procs
|
||||||
@add_tk_procs = [] # table of [name, args, body]
|
@add_tk_procs = [].taint # table of [name, args, body]
|
||||||
|
|
||||||
@cb_entry_class = Class.new{|c|
|
@cb_entry_class = Class.new{|c|
|
||||||
def initialize(ip, cmd)
|
def initialize(ip, cmd)
|
||||||
|
@ -711,7 +712,8 @@ module TkCore
|
||||||
end
|
end
|
||||||
def INTERP.create_table
|
def INTERP.create_table
|
||||||
id = @tk_table_list.size
|
id = @tk_table_list.size
|
||||||
@tk_table_list << {}
|
(tbl = {}).tainted? || tbl.taint
|
||||||
|
@tk_table_list << tbl
|
||||||
obj = Object.new
|
obj = Object.new
|
||||||
obj.instance_eval <<-EOD
|
obj.instance_eval <<-EOD
|
||||||
def self.method_missing(m, *args)
|
def self.method_missing(m, *args)
|
||||||
|
@ -1636,7 +1638,7 @@ class TkBindTag
|
||||||
|
|
||||||
#BTagID_TBL = {}
|
#BTagID_TBL = {}
|
||||||
BTagID_TBL = TkCore::INTERP.create_table
|
BTagID_TBL = TkCore::INTERP.create_table
|
||||||
Tk_BINDTAG_ID = ["btag".freeze, "00000"].freeze
|
Tk_BINDTAG_ID = ["btag".freeze, "00000".taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ BTagID_TBL.clear }
|
TkCore::INTERP.init_ip_env{ BTagID_TBL.clear }
|
||||||
|
|
||||||
|
@ -1713,7 +1715,7 @@ class TkVariable
|
||||||
#TkVar_ID_TBL = {}
|
#TkVar_ID_TBL = {}
|
||||||
TkVar_CB_TBL = TkCore::INTERP.create_table
|
TkVar_CB_TBL = TkCore::INTERP.create_table
|
||||||
TkVar_ID_TBL = TkCore::INTERP.create_table
|
TkVar_ID_TBL = TkCore::INTERP.create_table
|
||||||
Tk_VARIABLE_ID = ["v".freeze, "00000"].freeze
|
Tk_VARIABLE_ID = ["v".freeze, "00000".taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.add_tk_procs('rb_var', 'args',
|
TkCore::INTERP.add_tk_procs('rb_var', 'args',
|
||||||
"ruby [format \"TkVariable.callback %%Q!%s!\" $args]")
|
"ruby [format \"TkVariable.callback %%Q!%s!\" $args]")
|
||||||
|
@ -3004,20 +3006,76 @@ module TkOptionDB
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(pat, value, pri=None)
|
def add(pat, value, pri=None)
|
||||||
|
if $SAFE >= 4
|
||||||
|
fail SecurityError, "can't call 'TkOptionDB.add' at $SAFE >= 4"
|
||||||
|
end
|
||||||
tk_call 'option', 'add', pat, value, pri
|
tk_call 'option', 'add', pat, value, pri
|
||||||
end
|
end
|
||||||
def clear
|
def clear
|
||||||
|
if $SAFE >= 4
|
||||||
|
fail SecurityError, "can't call 'TkOptionDB.crear' at $SAFE >= 4"
|
||||||
|
end
|
||||||
tk_call 'option', 'clear'
|
tk_call 'option', 'clear'
|
||||||
end
|
end
|
||||||
def get(win, name, klass)
|
def get(win, name, klass)
|
||||||
tk_call('option', 'get', win ,name, klass).taint
|
tk_call('option', 'get', win ,name, klass)
|
||||||
end
|
end
|
||||||
def readfile(file, pri=None)
|
def readfile(file, pri=None)
|
||||||
tk_call 'option', 'readfile', file, pri
|
tk_call 'option', 'readfile', file, pri
|
||||||
end
|
end
|
||||||
module_function :add, :clear, :get, :readfile
|
module_function :add, :clear, :get, :readfile
|
||||||
|
|
||||||
|
def read_entries(file, f_enc=nil)
|
||||||
|
if TkCore::INTERP.safe?
|
||||||
|
fail SecurityError,
|
||||||
|
"can't call 'TkOptionDB.read_entries' on a safe interpreter"
|
||||||
|
end
|
||||||
|
|
||||||
|
i_enc = Tk.encoding()
|
||||||
|
|
||||||
|
unless f_enc
|
||||||
|
f_enc = i_enc
|
||||||
|
end
|
||||||
|
|
||||||
|
ent = []
|
||||||
|
cline = ''
|
||||||
|
open(file, 'r') {|f|
|
||||||
|
while line = f.gets
|
||||||
|
cline += line.chomp!
|
||||||
|
case cline
|
||||||
|
when /\\$/ # continue
|
||||||
|
cline.chop!
|
||||||
|
next
|
||||||
|
when /^!/ # coment
|
||||||
|
cline = ''
|
||||||
|
next
|
||||||
|
when /^([^:]+):\s(.*)$/
|
||||||
|
pat = $1
|
||||||
|
val = $2
|
||||||
|
p "ResourceDB: #{[pat, val].inspect}" if $DEBUG
|
||||||
|
pat = TkCore::INTERP._toUTF8(pat, f_enc)
|
||||||
|
pat = TkCore::INTERP._fromUTF8(pat, i_enc)
|
||||||
|
val = TkCore::INTERP._toUTF8(val, f_enc)
|
||||||
|
val = TkCore::INTERP._fromUTF8(val, i_enc)
|
||||||
|
ent << [pat, val]
|
||||||
|
cline = ''
|
||||||
|
else # unknown --> ignore
|
||||||
|
cline = ''
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
ent
|
||||||
|
end
|
||||||
|
module_function :read_entries
|
||||||
|
|
||||||
def read_with_encoding(file, f_enc=nil, pri=None)
|
def read_with_encoding(file, f_enc=nil, pri=None)
|
||||||
|
# try to read the file as an OptionDB file
|
||||||
|
readfile(file, pri).each{|pat, val|
|
||||||
|
add(pat, val, pri)
|
||||||
|
}
|
||||||
|
|
||||||
|
=begin
|
||||||
i_enc = Tk.encoding()
|
i_enc = Tk.encoding()
|
||||||
|
|
||||||
unless f_enc
|
unless f_enc
|
||||||
|
@ -3051,6 +3109,7 @@ module TkOptionDB
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
end
|
end
|
||||||
module_function :read_with_encoding
|
module_function :read_with_encoding
|
||||||
|
|
||||||
|
@ -4101,7 +4160,10 @@ class TkWindow<TkObject
|
||||||
TkCore::INTERP.tk_windows.delete(path)
|
TkCore::INTERP.tk_windows.delete(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
tk_call 'destroy', epath
|
begin
|
||||||
|
tk_call 'destroy', epath
|
||||||
|
rescue
|
||||||
|
end
|
||||||
uninstall_win
|
uninstall_win
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ class TkTimer
|
||||||
|
|
||||||
TkCommandNames = ['after'.freeze].freeze
|
TkCommandNames = ['after'.freeze].freeze
|
||||||
|
|
||||||
Tk_CBID = ['a'.freeze, '00000'].freeze
|
Tk_CBID = ['a'.freeze, '00000'.taint].freeze
|
||||||
Tk_CBTBL = {}
|
Tk_CBTBL = {}.taint
|
||||||
|
|
||||||
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
|
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
|
||||||
if {[set st [catch {ruby [format "TkTimer.callback %%Q!%s!" $id]} ret]] != 0} {
|
if {[set st [catch {ruby [format "TkTimer.callback %%Q!%s!" $id]} ret]] != 0} {
|
||||||
|
|
|
@ -557,7 +557,7 @@ class TkcTag<TkObject
|
||||||
include TkcTagAccess
|
include TkcTagAccess
|
||||||
|
|
||||||
CTagID_TBL = TkCore::INTERP.create_table
|
CTagID_TBL = TkCore::INTERP.create_table
|
||||||
Tk_CanvasTag_ID = ['ctag'.freeze, '00000'].freeze
|
Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ CTagID_TBL.clear }
|
TkCore::INTERP.init_ip_env{ CTagID_TBL.clear }
|
||||||
|
|
||||||
|
@ -688,7 +688,7 @@ class TkcTagCurrent<TkcTag
|
||||||
end
|
end
|
||||||
|
|
||||||
class TkcGroup<TkcTag
|
class TkcGroup<TkcTag
|
||||||
Tk_cGroup_ID = ['tkcg'.freeze, '00000'].freeze
|
Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint].freeze
|
||||||
def create_self(parent, *args)
|
def create_self(parent, *args)
|
||||||
if not parent.kind_of?(TkCanvas)
|
if not parent.kind_of?(TkCanvas)
|
||||||
fail format("%s need to be TkCanvas", parent.inspect)
|
fail format("%s need to be TkCanvas", parent.inspect)
|
||||||
|
@ -851,7 +851,7 @@ class TkImage<TkObject
|
||||||
TkCommandNames = ['image'.freeze].freeze
|
TkCommandNames = ['image'.freeze].freeze
|
||||||
|
|
||||||
Tk_IMGTBL = TkCore::INTERP.create_table
|
Tk_IMGTBL = TkCore::INTERP.create_table
|
||||||
Tk_Image_ID = ['i'.freeze, '00000'].freeze
|
Tk_Image_ID = ['i'.freeze, '00000'.taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ Tk_IMGTBL.clear }
|
TkCore::INTERP.init_ip_env{ Tk_IMGTBL.clear }
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ class TkFont
|
||||||
|
|
||||||
TkCommandNames = ['font'.freeze].freeze
|
TkCommandNames = ['font'.freeze].freeze
|
||||||
|
|
||||||
Tk_FontID = ["@font".freeze, "00000"].freeze
|
Tk_FontID = ["@font".freeze, "00000".taint].freeze
|
||||||
Tk_FontNameTBL = TkCore::INTERP.create_table
|
Tk_FontNameTBL = TkCore::INTERP.create_table
|
||||||
Tk_FontUseTBL = TkCore::INTERP.create_table
|
Tk_FontUseTBL = TkCore::INTERP.create_table
|
||||||
|
|
||||||
|
|
|
@ -807,7 +807,7 @@ class TkTextTag<TkObject
|
||||||
include TkTreatTagFont
|
include TkTreatTagFont
|
||||||
|
|
||||||
TTagID_TBL = TkCore::INTERP.create_table
|
TTagID_TBL = TkCore::INTERP.create_table
|
||||||
Tk_TextTag_ID = ['tag'.freeze, '00000'].freeze
|
Tk_TextTag_ID = ['tag'.freeze, '00000'.taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ TTagID_TBL.clear }
|
TkCore::INTERP.init_ip_env{ TTagID_TBL.clear }
|
||||||
|
|
||||||
|
@ -1023,7 +1023,7 @@ end
|
||||||
|
|
||||||
class TkTextMark<TkObject
|
class TkTextMark<TkObject
|
||||||
TMarkID_TBL = TkCore::INTERP.create_table
|
TMarkID_TBL = TkCore::INTERP.create_table
|
||||||
Tk_TextMark_ID = ['mark'.freeze, '00000'].freeze
|
Tk_TextMark_ID = ['mark'.freeze, '00000'.taint].freeze
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear }
|
TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear }
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ class TkVirtualEvent<TkObject
|
||||||
|
|
||||||
TkCommandNames = ['event'.freeze].freeze
|
TkCommandNames = ['event'.freeze].freeze
|
||||||
|
|
||||||
TkVirtualEventID = ["<VirtEvent".freeze, "00000", ">".freeze].freeze
|
TkVirtualEventID = ["<VirtEvent".freeze, "00000".taint, ">".freeze].freeze
|
||||||
TkVirtualEventTBL = TkCore::INTERP.create_table
|
TkVirtualEventTBL = TkCore::INTERP.create_table
|
||||||
|
|
||||||
TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear }
|
TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear }
|
||||||
|
|
|
@ -8,5 +8,6 @@
|
||||||
*hello.text: HELLO
|
*hello.text: HELLO
|
||||||
*quit.text: QUIT
|
*quit.text: QUIT
|
||||||
*BTN_CMD.show_msg: {|arg| print "($SAFE=#{$SAFE}) ";\
|
*BTN_CMD.show_msg: {|arg| print "($SAFE=#{$SAFE}) ";\
|
||||||
print "Hello!! This is a sample of #{arg}.\n"}
|
print "Hello!! This is a sample of #{arg}.";\
|
||||||
*BTN_CMD.bye_msg: {print "($SAFE=#{$SAFE}) Good-bye¡¥\n"}
|
print "(<<< $SAFE=#{$SAFE})\n"}
|
||||||
|
*BTN_CMD.bye_msg: {print "($SAFE=#{$SAFE} >>>) Good-bye¡¥(<<< $SAFE=#{$SAFE})\n"}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*BtnFrame.Button.foreground: red
|
*BtnFrame.Button.foreground: red
|
||||||
*hello.text: こんにちは
|
*hello.text: こんにちは
|
||||||
*quit.text: 終了
|
*quit.text: 終了
|
||||||
*BTN_CMD.show_msg: {|arg| print "($SAFE=#{$SAFE}) ";\
|
*BTN_CMD.show_msg: {|arg| print "($SAFE=#{$SAFE} >>>) ";\
|
||||||
print "こんにちは!! #{arg} のサンプルです.\n"}
|
print "こんにちは!! #{arg} のサンプルです.";\
|
||||||
*BTN_CMD.bye_msg: {print "($SAFE=#{$SAFE}) さようなら.\n"}
|
print "(<<< $SAFE=#{$SAFE})\n"}
|
||||||
|
*BTN_CMD.bye_msg: {print "($SAFE=#{$SAFE} >>>) さようなら.(<<< $SAFE=#{$SAFE})\n"}
|
||||||
|
|
|
@ -86,6 +86,13 @@ TkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start
|
||||||
TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start
|
TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start
|
||||||
TkTimer.new(2000, -1, proc{p ['trusted', trusted_slave.deleted?]}).start
|
TkTimer.new(2000, -1, proc{p ['trusted', trusted_slave.deleted?]}).start
|
||||||
|
|
||||||
|
TkTimer.new(7000, 1,
|
||||||
|
proc{
|
||||||
|
safe_slave1.eval_proc{Tk.root.destroy}
|
||||||
|
safe_slave1.delete
|
||||||
|
print "*** The safe_slave1 is deleted by the timer.\n"
|
||||||
|
}).start
|
||||||
|
|
||||||
TkTimer.new(10000, 1,
|
TkTimer.new(10000, 1,
|
||||||
proc{
|
proc{
|
||||||
trusted_slave.eval_proc{Tk.root.destroy}
|
trusted_slave.eval_proc{Tk.root.destroy}
|
||||||
|
|
|
@ -5,6 +5,6 @@ TkButton.new(nil,
|
||||||
'command' => proc{print "hello\n"}).pack('fill'=>'x')
|
'command' => proc{print "hello\n"}).pack('fill'=>'x')
|
||||||
TkButton.new(nil,
|
TkButton.new(nil,
|
||||||
'text' => 'quit',
|
'text' => 'quit',
|
||||||
'command' => 'exit').pack('fill'=>'x')
|
'command' => proc{exit}).pack('fill'=>'x')
|
||||||
|
|
||||||
Tk.mainloop
|
Tk.mainloop
|
||||||
|
|
|
@ -113,7 +113,6 @@ TkFrame.new{|f|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
TkFrame.new(:borderwidth=>2, :relief=>:sunken,
|
TkFrame.new(:borderwidth=>2, :relief=>:sunken,
|
||||||
:height=>5).pack(:side=>:top, :fill=>:x, :padx=>20)
|
:height=>5).pack(:side=>:top, :fill=>:x, :padx=>20)
|
||||||
|
|
|
@ -5,6 +5,9 @@ require 'multi-tk'
|
||||||
TkMessage.new(:text => <<EOM).pack
|
TkMessage.new(:text => <<EOM).pack
|
||||||
This is a sample of the safe-Tk slave interpreter. \
|
This is a sample of the safe-Tk slave interpreter. \
|
||||||
On the slave interpreter, 'tkoptdb.rb' demo is running.
|
On the slave interpreter, 'tkoptdb.rb' demo is running.
|
||||||
|
( Attention:: a safe-Tk interpreter can't read options \
|
||||||
|
from a file. Options are given by the master interpreter \
|
||||||
|
in this script. )
|
||||||
The window shown this message is a root widget of \
|
The window shown this message is a root widget of \
|
||||||
the default master interpreter. The other window \
|
the default master interpreter. The other window \
|
||||||
is a toplevel widget of the master interpreter, and it \
|
is a toplevel widget of the master interpreter, and it \
|
||||||
|
@ -12,7 +15,21 @@ has a container frame of the safe-Tk slave interpreter. \
|
||||||
You can delete the slave by the button on the toplevel widget.
|
You can delete the slave by the button on the toplevel widget.
|
||||||
EOM
|
EOM
|
||||||
|
|
||||||
|
if ENV['LANG'] =~ /^ja/
|
||||||
|
# read Japanese resource
|
||||||
|
ent = TkOptionDB.read_entries(File.expand_path('resource.ja',
|
||||||
|
File.dirname(__FILE__)),
|
||||||
|
'euc-jp')
|
||||||
|
else
|
||||||
|
# read English resource
|
||||||
|
ent = TkOptionDB.read_entries(File.expand_path('resource.en',
|
||||||
|
File.dirname(__FILE__)))
|
||||||
|
end
|
||||||
file = File.expand_path('tkoptdb.rb', File.dirname(__FILE__))
|
file = File.expand_path('tkoptdb.rb', File.dirname(__FILE__))
|
||||||
MultiTkIp.new_safeTk{load file}
|
MultiTkIp.new_safeTk{
|
||||||
|
ent.each{|pat, val| TkOptionDB.add(pat, val)}
|
||||||
|
load file
|
||||||
|
}
|
||||||
|
# Tk.mainloop is ignored on the slave-IP
|
||||||
|
|
||||||
# mainloop is started on 'tkoptdb.rb'
|
Tk.mainloop
|
||||||
|
|
|
@ -8,26 +8,29 @@
|
||||||
#
|
#
|
||||||
require "tk"
|
require "tk"
|
||||||
|
|
||||||
if ENV['LANG'] =~ /^ja/
|
if __FILE__ == $0 || !TkCore::INTERP.safe?
|
||||||
# read Japanese resource
|
if ENV['LANG'] =~ /^ja/
|
||||||
TkOptionDB.read_with_encoding(File.expand_path('resource.ja',
|
# read Japanese resource
|
||||||
File.dirname(__FILE__)),
|
TkOptionDB.read_with_encoding(File.expand_path('resource.ja',
|
||||||
'euc-jp')
|
File.dirname(__FILE__)),
|
||||||
else
|
'euc-jp')
|
||||||
# read English resource
|
else
|
||||||
TkOptionDB.readfile(File.expand_path('resource.en', File.dirname(__FILE__)))
|
# read English resource
|
||||||
|
TkOptionDB.readfile(File.expand_path('resource.en',
|
||||||
|
File.dirname(__FILE__)))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 'show_msg' and 'bye_msg' procedures can be defined on BTN_CMD resource.
|
# 'show_msg' and 'bye_msg' procedures can be defined on BTN_CMD resource.
|
||||||
# Those procedures are called under $SAFE==2
|
# Those procedures are called under $SAFE==2
|
||||||
cmd = TkOptionDB.new_proc_class(:BTN_CMD, [:show_msg, :bye_msg], 2) {
|
cmd = TkOptionDB.new_proc_class(:BTN_CMD, [:show_msg, :bye_msg], 3) {
|
||||||
# If you want to check resource string (str),
|
# If you want to check resource string (str),
|
||||||
# please define __check_proc_string__(str) like this.
|
# please define __check_proc_string__(str) like this.
|
||||||
class << self
|
class << self
|
||||||
def __check_proc_string__(str)
|
def __check_proc_string__(str)
|
||||||
print "($SAFE=#{$SAFE}) check!! str.tainted?::#{str.tainted?}"
|
print "($SAFE=#{$SAFE} >>>) check!! str.tainted?::#{str.tainted?}"
|
||||||
str.untaint
|
str.untaint
|
||||||
print "==>#{str.tainted?} : "
|
print "==>#{str.tainted?} (<<< $SAFE=#{$SAFE}): "
|
||||||
str
|
str
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,12 +41,18 @@ TkFrame.new(:class=>'BtnFrame'){|f|
|
||||||
pack(:padx=>5, :pady=>5)
|
pack(:padx=>5, :pady=>5)
|
||||||
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
||||||
command proc{
|
command proc{
|
||||||
print "($SAFE=#{$SAFE}) : "
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
cmd.show_msg(TkOptionDB.inspect)
|
cmd.show_msg(TkOptionDB.inspect)
|
||||||
|
print "(<<< $SAFE=#{$SAFE})"
|
||||||
}
|
}
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
TkButton.new(:command=>proc{print "($SAFE=#{$SAFE}) : "; cmd.bye_msg; exit},
|
TkButton.new(:command=>proc{
|
||||||
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
|
cmd.bye_msg
|
||||||
|
print "(<<< $SAFE=#{$SAFE} ) : "
|
||||||
|
exit
|
||||||
|
},
|
||||||
:parent=>f, :widgetname=>'quit'){
|
:parent=>f, :widgetname=>'quit'){
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
|
@ -54,12 +63,18 @@ BtnFrame.new{|f|
|
||||||
pack(:padx=>5, :pady=>5)
|
pack(:padx=>5, :pady=>5)
|
||||||
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
||||||
command proc{
|
command proc{
|
||||||
print "($SAFE=#{$SAFE}) : "
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
cmd.show_msg(TkOptionDB.inspect)
|
cmd.show_msg(TkOptionDB.inspect)
|
||||||
|
print "(<<< $SAFE=#{$SAFE})"
|
||||||
}
|
}
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
TkButton.new(:command=>proc{print "($SAFE=#{$SAFE}) : "; cmd.bye_msg; exit},
|
TkButton.new(:command=>proc{
|
||||||
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
|
cmd.bye_msg
|
||||||
|
print "(<<< $SAFE=#{$SAFE})"
|
||||||
|
exit
|
||||||
|
},
|
||||||
:parent=>f, :widgetname=>'quit'){
|
:parent=>f, :widgetname=>'quit'){
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
|
@ -70,12 +85,18 @@ TkFrame.new(:class=>'BtnFrame2'){|f|
|
||||||
pack(:padx=>5, :pady=>5)
|
pack(:padx=>5, :pady=>5)
|
||||||
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
TkButton.new(:parent=>f, :widgetname=>'hello'){
|
||||||
command proc{
|
command proc{
|
||||||
print "($SAFE=#{$SAFE}) : "
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
cmd.show_msg(TkOptionDB.inspect)
|
cmd.show_msg(TkOptionDB.inspect)
|
||||||
|
print "(<<< $SAFE=#{$SAFE})"
|
||||||
}
|
}
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
TkButton.new(:command=>proc{print "($SAFE=#{$SAFE}) : "; cmd.bye_msg; exit},
|
TkButton.new(:command=>proc{
|
||||||
|
print "($SAFE=#{$SAFE} >>>) : "
|
||||||
|
cmd.bye_msg
|
||||||
|
print "(<<< $SAFE=#{$SAFE})"
|
||||||
|
exit
|
||||||
|
},
|
||||||
:parent=>f, :widgetname=>'quit'){
|
:parent=>f, :widgetname=>'quit'){
|
||||||
pack(:fill=>:x, :padx=>10, :pady=>10)
|
pack(:fill=>:x, :padx=>10, :pady=>10)
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче