summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-29 08:34:14 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-29 08:34:14 +0000
commit24ff3f444882ba60418a6736d6c5d57ba3c0b80c (patch)
tree813a69918ff8435617ca58e193f9440c06febdb7
parent22a5aec4b322c1be9eced78967e5cfd0ae54b6cb (diff)
* doc/ChangeLog-1.8.0: add changes of Ruby/Tk
* ext/tcltklib/tcltklib.c : some methods have no effect if on slave-IP * ext/tcltklib/tcltklib.c : can create a interpreter without Tk * ext/tcltklib/tcltklib.c : bug fix on handling exceptions * ext/tcltklib/MANUAL.euc : modify * ext/tk/lib/tk.rb : freeze some core modules * ext/tk/lib/multi-tk.rb : more secure * ext/tk/lib/tk.rb: TkVariable.new(array) --> treat the array as the Tk's list * ext/tk/lib/tk.rb: improve accessibility of TkVariable object * ext/tk/lib/tk.rb, ext/tk/lib/tkfont.rb, ext/tk/lib/tkcanvas.rb, ext/tk/lib/tktext.rb : fix bug of font handling * ext/tk/lib/tkfont.rb TkFont.new() accepts compound fonts * process.c: bug fix * process.c: add rb_secure(2) to methods of Process::{UID,GID,Sys} * process.c: deny handling IDs during evaluating the block given to the Process::{UID,GID}.switch method git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4456 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog31
-rw-r--r--doc/ChangeLog-1.8.0468
-rw-r--r--ext/tcltklib/MANUAL.euc40
-rw-r--r--ext/tcltklib/tcltklib.c304
-rw-r--r--ext/tk/lib/multi-tk.rb196
-rw-r--r--ext/tk/lib/tk.rb308
-rw-r--r--ext/tk/lib/tkcanvas.rb22
-rw-r--r--ext/tk/lib/tkfont.rb239
-rw-r--r--ext/tk/lib/tktext.rb34
-rw-r--r--process.c188
10 files changed, 1660 insertions, 170 deletions
diff --git a/ChangeLog b/ChangeLog
index c95e6987b3..bd24db3704 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+Fri Aug 29 17:30:15 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * process.c: bug fix
+
+ * process.c: add rb_secure(2) to methods of Process::{UID,GID,Sys}
+
+ * process.c: deny handling IDs during evaluating the block given to
+ the Process::{UID,GID}.switch method
+
+ * ext/tcltklib/tcltklib.c : some methods have no effect if on slave-IP
+
+ * ext/tcltklib/tcltklib.c : can create a interpreter without Tk
+
+ * ext/tcltklib/tcltklib.c : bug fix on handling exceptions
+
+ * ext/tcltklib/MANUAL.euc : modify
+
+ * ext/tk/lib/tk.rb : freeze some core modules
+
+ * ext/tk/lib/multi-tk.rb : more secure
+
+ * ext/tk/lib/tk.rb: TkVariable.new(array) --> treat the array as the
+ Tk's list
+
+ * ext/tk/lib/tk.rb: improve accessibility of TkVariable object
+
+ * ext/tk/lib/tk.rb, ext/tk/lib/tkfont.rb, ext/tk/lib/tkcanvas.rb,
+ ext/tk/lib/tktext.rb : fix bug of font handling
+
+ * ext/tk/lib/tkfont.rb TkFont.new() accepts compound fonts
+
Thu Aug 28 17:30:24 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (rb_const_get_0): should check constants defined in
diff --git a/doc/ChangeLog-1.8.0 b/doc/ChangeLog-1.8.0
index 6acb8ff20f..d168a50f80 100644
--- a/doc/ChangeLog-1.8.0
+++ b/doc/ChangeLog-1.8.0
@@ -40,6 +40,13 @@ Sun Aug 3 23:56:50 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_call_super): should propagate previous block for
super call. [ruby-talk:77884]
+Sun Aug 3 22:07:47 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkentry.rb: support 'validatecommand' option of
+ TkEntry/TkSpinbox widget
+
+ * ext/tk/sample/{demos-en,demos-jp}/spin.rb: add
+
Sun Aug 3 19:25:28 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (call_trace_func): clear exception flag temporarily.
@@ -51,6 +58,21 @@ Sun Aug 3 18:03:44 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/un.h (help): new. % ruby -run -e help cp
+Sun Aug 3 08:53:06 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/sample/{demos-en,demos-jp}/image3.rb: add
+
+ * ext/tk/lib/tkcanvas.rb: bug fix on Tk object ID management
+
+ * ext/tk/lib/tktext.rb: ditto
+
+Sun Aug 3 02:55:52 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * process.c: modify macro to detect 'MacOS X' [ruby-talk:77849]
+
+ * ext/tcltklib/lib/tcltk.rb: bug fix ( NOT MAINTAINED : only
+ for running 'line2.rb' demo. )
+
Sun Aug 3 02:45:06 2003 Koji Arai <jca02266@nifty.ne.jp>
* numeric.c (flo_to_s): get rid of buffer overflow.
@@ -60,6 +82,14 @@ Sat Aug 2 23:51:52 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (appendline): clearerr(3) before raising exception, since
exception may be captured by rescue. [ruby-talk:77794]
+Sat Aug 2 09:58:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix --- TkGrid failed to treat
+ RELATIVE PLACEMENT
+
+ * ext/tk/sample/demos-en/, demos-jp/: add or modify some
+ widget demo scripts
+
Sat Aug 2 20:59:38 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* lib/webrick/https.rb: change an option name.
@@ -90,6 +120,24 @@ Sat Aug 2 14:02:39 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* variable.c (classname): find regular class name if not set.
[ruby-dev:20496]
+Sat Aug 2 09:58:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix --- forgot to entry a widget class
+ name of 'labelframe' widget
+
+ * ext/tk/sample/{demos-en,demos-jp}/{labelframe.rb,paned1.rb,
+ paned2.rb,spin.rb}: add demo-scripts to the JP/EN widget demos
+
+Sat Aug 2 05:04:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkentry.rb: bug fix of TkEntry#delete
+
+ * ext/tk/samples/: bug fix of some widget demos
+
+ * ext/tk/lib/tk.rb: support <TkVariable object> == <Symbol>
+
+ * ext/tk/lib/*.rb: freeze some object for security reason
+
Sat Aug 2 03:30:25 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_obj_singleton_methods): should not go up to
@@ -141,6 +189,10 @@ Fri Aug 1 19:48:56 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (rb_gc): should mark backing store region on IA64.
+Fri Aug 1 18:51:10 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * process.c: bug fix --- preprocessor errors occur on OpenBSD-current
+
Fri Aug 1 17:13:23 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/openssl/extconf.rb: should replace literally.
@@ -184,6 +236,13 @@ Fri Aug 1 09:54:38 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* hash.c (env_clear): ditto.
+Fri Aug 1 04:58:55 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix --- forget to eval given block to
+ TkRoot.new method
+
+ * ext/tk/sample/tkoptdb-safeTk.rb: new sample script
+
Fri Aug 1 00:52:58 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (Init_stack): IA64 requires STACK_LEVEL_MAX to be less than
@@ -194,11 +253,38 @@ Thu Jul 31 23:44:00 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* lib/erb.rb: import erb-2.0.4b4.
+Thu Jul 31 23:04:45 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/sample/resource.en, ext/tk/sample/resource.jp:
+ wrong resource file format
+
+ * ext/tk/lib/tk.rb: add Tk::Encoding.{encoding_convertfrom,
+ encoding_convertto}
+
+ * ext/tk/lib/tk.rb: add TkOptionDB.read_with_encoding to read
+ non-utf8 resource file
+
Thu Jul 31 23:02:47 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/etc/etc.c: revert getenv()'s prototype. use it only when _WIN32
is not defined.
+Thu Jul 31 20:52:40 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: (IMPORTANT BUG FIX) scan of event keywords
+ doesn't work on recent versions of Tck/Tk
+
+ * ext/tk/lib/tk.rb: initialize error of instance variable on
+ TkComposite
+
+ * ext/tk/lib/multi-tk.rb: initialize error on encoding-system on
+ MultiTkIp
+
+ * ext/tk/lib/tk.rb: trouble on destroying widgets
+
+ * ext/tk/sample/demos-en/, demos-jp/: add JP and EN version of
+ Ruby/Tk widget demos
+
Thu Jul 31 15:25:12 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* array.c (rb_ary_collect): must get length of array for each
@@ -223,6 +309,17 @@ Thu Jul 31 08:18:00 2003 Nathaniel Talbott <ntalbott@ruby-lang.org>
* lib/test/unit.rb: A useful return code is now set if tests fail when
running automatically using the Console::TestRunner.
+Thu Jul 31 07:59:18 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: wrap the command-proc of TkScale --- pass
+ the numeric object to the proc
+
+ * ext/tk/lib/tk.rb: better support for widgets created on
+ Tk interpreter (without Ruby)
+
+ * ext/tk/lib/multi-tk.rb: a little more stable on Multiple Tk
+ interpreters running
+
Thu Jul 31 00:17:19 2003 Shugo Maeda <shugo@ruby-lang.org>
* lib/net/ftp.rb (return_code): obsolete.
@@ -310,6 +407,23 @@ Wed Jul 30 09:31:55 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/socket.c (sock_initialize): rename from sock_init()
to get rid of conflict with OS/2 socket library.
+Wed Jul 30 07:23:14 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkentry.rb: fix lack of methods for TkEntry
+
+ * ext/tk/lib/multi-tk.rb, ext/tk/lib/tk.rb,
+ ext/tk/lib/tkdialog.rb, ext/tk/lib/tkentry.rb,
+ ext/tk/sample/safe-tk.rb, ext/tk/sample/tktimer2.rb: bug fix
+
+ * ext/tk/lib/multi-tk.rb: MultiTkIp.new_* accept a block to
+ eval under the new interpreter
+
+Wed Jul 30 04:36:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c,
+ ext/tk/lib/tk.rb, ext/tk/lib/tkafter.rb: additional check of
+ Tk interpreters' status for a little more safety
+
Wed Jul 30 02:37:12 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* marshal.c (w_object): if object responds to 'marshal_dump',
@@ -398,6 +512,18 @@ Mon Jul 28 22:57:52 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (rb_f_getc): $stdin may not be IO. [ruby-dev:20973]
+Tue Jul 29 16:20:36 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: bug fix and
+ change mainloop_abort_on_no_widget_cmd => mainloop_abort_on_exception
+ ( to avoid thread timing trouble on accessing destroyed widgets )
+
+ * ext/tk/lib/multi-tk.rb: change default mode of
+ mainloop_abort_on_exception on multi-tk.rb
+
+ * ext/tk/lib/multi-tk.rb: fix a bug of the procedure for
+ 'Delete' button on the safe-Tk frmae
+
Tue Jul 29 12:22:28 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/token.c: prefixed many constants and definitions
@@ -413,6 +539,12 @@ Tue Jul 29 12:15:37 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.h: add arguments to definitions of functions if possible.
+Tue Jul 29 08:05:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb, ext/tk/lib/tkdialog.rb, ext/tk/lib/tktext.rb,
+ ext/tk/sample/tkbiff.rb, ext/tk/sample/tkdialog.rb,
+ ext/tk/sample/tkform.rb: bug fix ( tested with Ruby/Tk widget demo )
+
Tue Jul 29 04:22:08 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/syck.h: Added 'syck' yacc prefixes.
@@ -428,6 +560,20 @@ Tue Jul 29 03:53:28 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/lib/net/https.rb (use_ssl=): raise ProtocolError if
connection is set up already.
+Tue Jul 29 01:45:32 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: use RTEST()
+
+Tue Jul 29 01:24:32 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: bug fix
+
+ * ext/tk/lib/multi-tk.rb: bug fix and pack options are pssed
+ to the safeTk container
+
+ * ext/tk/sample/safe-tk.rb: add example for pack options of
+ safeTk container
+
Mon Jul 28 23:23:08 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* file.c (Init_File): IO should include File::Const.
@@ -460,6 +606,16 @@ Mon Jul 28 15:32:04 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (argf_forward): utility function to forward method to
current_file.
+Mon Jul 28 06:10:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: bug fix
+
+ * ext/lib/tk/multi-tk.rb: bug fix
+
+ * ext/lib/tk/multi-tk.rb: add methods depend on Tcl's 'interp' command
+
+ * ext/lib/tk/multi-tk.rb: suppot safe-level control of each interpreter
+
Mon Jul 28 03:08:47 2003 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb: each() should return self.
@@ -482,6 +638,22 @@ Sun Jul 27 21:16:30 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* mkconfig.rb: initialize global variables to avoid warnings.
+Sun Jul 27 19:35:06 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: add some methods to support
+ multiple interpreters (low level)
+
+ * ext/tk/lib/multi-tk.rb: new library to support multiple Tk
+ interpreters (high level)
+
+ * ext/tcltklib/demo/safeTk.rb: new sample of safeTk interpreter
+
+ * ext/tk/sample/safe-tk.rb: new sample of multi-tk.rb
+
+ * ext/tk/lib/tk.rb: bug fix and add feature to supprt multi-tk
+
+ * ext/tk/lib/tkafter.rb: ditto
+
Sun Jul 27 14:43:37 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
* lib/debug.rb: fix breakpoint parameter parsing/checking.
@@ -558,6 +730,18 @@ Fri Jul 26 00:04:25 2003 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
- cert_store_view.rb: certificate store viewer with FXRuby. Uses
c_rehash.rb, crlstore.rb and certstore.rb.
+Fri Jul 25 16:43:03 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: add TclTkIp#create_slave,
+ TclTkIp#_make_safe and TclTkIp#safe?
+
+ * ext/tcltklib/MANUAL.euc: modify descriptions
+
+ * ext/tk/lib/tk.rb: bug fix [ruby-talk:76980] and modify to
+ support multi Tk IPs
+
+ * ext/tk/lib/tkafter.rb: modify to support multi Tk IPs
+
Fri Jul 25 15:47:39 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/extconf.rb: add check for BN_rand_range() and
@@ -725,6 +909,18 @@ Wed Jul 23 18:21:52 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/io/wait: imported.
+Wed Jul 23 16:07:35 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * process.c: unify indentation
+
+ * configure.in: add --enable-setreuid option
+
+ * ext/tcltklib/tcltklib.c: TclTkIp.new accepts 'ip-name' and 'options'
+
+ * ext/tk/lib/tk.rb: support arguments of TclTkIp.new
+
+ * ext/tk/lib/tk*.rb: preparations for multi-Tk interpreter support
+
Wed Jul 23 15:49:01 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c (rb_str_lstrip_bang): strip NUL along with white
@@ -743,6 +939,12 @@ Wed Jul 23 10:11:15 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/iconv/iconv.c (iconv_convert): stringify argument.
+Wed Jul 23 02:39:46 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * process.c: add a module for raw syscalls to control UID/GID
+
+ * process.c: add modules for portable UID/GID control
+
Tue Jul 22 19:16:40 2003 Tanaka Akira <akr@m17n.org>
* ext/iconv/iconv.c (iconv_failure_initialize): limit
@@ -906,6 +1108,11 @@ Thu Jul 17 13:42:53 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/ftools.rb (File::makedirs): do not handle "//" as a directory.
+Thu Jul 17 06:40:28 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: recover and fix typo : Tk.chooseDirectory
+ (Tk8.4 feature)
+
Wed Jul 16 16:23:58 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_proc_new): call svalue_to_avalue for yield argument.
@@ -987,6 +1194,13 @@ Fri Jul 11 16:09:09 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* util.c (ruby_strtod): exp should be less than MDMAXEXPT.
+Fri Jul 11 07:17:47 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: not create a Tcl/Tk interpreter if already
+ defined TkCore::INTERP
+
+ * ext/tk/lib/tk.rb: bugfix on TkWindow#configure
+
Thu Jul 10 14:42:02 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* math.c (math_log): nan takes a dummy argument on Cygwin 1.5.0.
@@ -1176,6 +1390,13 @@ Wed Jul 2 01:32:40 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/net/pop.rb (Net::POP3#start): typofix.
+Tue Jul 1 22:08:19 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: TkWindow include TkWinfo
+
+ * ext/tk/lib/tk.rb: treat unknown widget classes as subclasses
+ of TkWindow
+
Tue Jul 1 19:02:12 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* parse.y (rb_intern): should use mbclen instead of mblen.
@@ -1236,17 +1457,48 @@ Thu Jun 26 21:34:49 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
arguement type mismatch, and inline method_list().
[ruby-core:01198]
+Wed Jun 25 14:40:33 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: add and modify methods ---
+ TkWidget.database_class, TkWidget.database_classname,
+ TkWidget#database_class, TkWidget#database_classname
+
+ * ext/tk/lib/tk.rb: instances of a subclass of TkToplevel or
+ TkFrame are created with ":class=>subclass" option as default.
+
+ * ext/tk/sample/tkoptdb.rb: add a new part
+
Wed Jun 25 12:52:58 2003 Matthew Dempsky <jivera@flame.org>
* class.c (rb_generic_class_instance_methods): merge argument
check (and warning) into one function; following DRY principle.
[ruby-core:01193]
+Wed Jun 25 05:49:10 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: add widget destroy hook binding to TkBindTag::ALL
+
+ * ext/tk/lib/tkcanvas.rb: Although requiring manual control of GC,
+ memory eating problem of TkCanvas Items is fixed.
+
+ * ext/tk/lib/tktext.rb: add some methods and bug fix
+
Wed Jun 25 00:14:30 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (autoload_delete): should delete Qundef from iv_tbl.
(ruby-bugs-ja PR#504)
+Tue Jun 24 16:46:07 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix on TkToplevel, TkFrame,
+ TkPanedwindow, TkOptionDB
+
+ * ext/tk/lib/tk.rb: TkOptionDB --- make it more secure to use procs
+ defined on resourceDB
+
+ * ext/tk/sample/tkoptdb.rb, resource.ja, resource.en:
+ sample script how to use TkOptionDB.
+
Tue Jun 24 14:22:41 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* lib/yaml/types.rb: replaced Kernel::Hash reference with Object::Hash
@@ -1318,6 +1570,10 @@ Mon Jun 23 16:18:12 2003 Tanaka Akira <akr@m17n.org>
* time.c (time_arg): initialize v[6] even when argc is 10 to
avoid valgrind error.
+Mon Jun 23 14:22:44 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix on TkRoot and TkToplevel
+
Mon Jun 23 08:24:01 2003 Florian Frank <flori@nixe.ping.de>
* string.c (rb_str_upto): generate sequence according to "succ"
@@ -1352,6 +1608,18 @@ Sun Jun 22 23:42:20 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* file.c (rb_file_s_readlink): expand buffer until readlink
succeed.
+Sun Jun 22 16:17:02 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm
+ commands as elements
+
+ * ext/tk/lib/tk.rb: TkMenu --- add some methods
+
+ * ext/tk/lib/tk.rb: TkOptionMenubutton --- bug fix
+
+ * ext/tk/sample/tkmenubutton.rb: sample of TkMenubutton and
+ TkOptionMenubutton
+
Sat Jun 21 23:15:08 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate distination tag if
@@ -1366,6 +1634,25 @@ Sat Jun 21 13:56:09 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>
* wince/resource.rb: include winver.h in wince3.0.
+Sat Jun 21 12:55:17 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm commands
+ as elements of a hash argument.
+
+ * ext/tk/sample/tktimer2.rb: add comments about the usage of a
+ TkTimer object.
+
+Sat Jun 21 08:47:22 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk*.rb: remove direct-accesses to TkComm::INTERP and
+ TkComm::INITIALIZE_TARGETS
+
+ * ext/tk/lib/tk*.rb: use TkINTERP_SETUP_SCRIPTS constant for setting
+ up the interpreter
+
+ * ext/tcltklib/tcltklib.c: support to create a safe interpreter
+ with safe-Tk
+
Fri Jun 20 23:28:27 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate TAG_BREAK and
@@ -1385,6 +1672,10 @@ Fri Jun 20 15:04:28 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* ruby.c (proc_options): ditto.
+Fri Jun 20 14:52:46 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: Tk interpreter returns TAINTED strings.
+
Fri Jun 20 03:09:21 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* parse.y (new_yield): distinguish "yield 1,2" and "yield [1,2]".
@@ -1410,6 +1701,42 @@ Thu Jun 19 22:51:41 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
lib/drb/invokemethod.rb, lib/drb/observer.rb,
lib/drb/timeridconv.rb, lib/drb/unix.rb: import drb-2.0.4b3
+Thu Jun 19 16:14:43 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c (lib_do_one_event): change default
+ value of the argument
+
+ * ext/tcltklib/tcltklib.c (lib_do_one_event): returns true/false
+
+ * ext/tcltklib/tcltklib.c: add TclTkLib::EventFlag::NONE ( == 0 )
+
+ * ext/tcltklib/tcltklib.c: add set_no_event_wait() and
+ get_no_event_wait()
+
+ * ext/tcltklib/MANUAL.euc: modify
+
+ * ext/tcltklib/README.euc: ditto
+
+ * ext/tk/lib/tk.rb: change default value of TkCore.do_one_event
+ argument
+
+ * ext/tk/lib/tk.rb: add TkCore.set_no_event_wait(wait) and
+ TkCore.get_no_event_wait
+
+ * ext/tk/lib/tk.rb: add Tk.exit ( == destroy root widget )
+
+ * ext/tk/lib/tkafter.rb: rename TkAfter => TkTimer (TkAfter is
+ an alias name)
+
+ * ext/tk/lib/tkafter.rb: set_callback returns self
+
+ * ext/tk/lib/tkafter.rb: continue() raises an exception, if already
+ running or no procedure.
+
+ * ext/tk/lib/tkafter.rb: skip() raises an exception, if not running.
+
+ * ext/tk/sample/tktimer2.rb: new sample for TkTimer class.
+
Thu Jun 19 16:13:54 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* rubytest.rb: add library path to include standard libraries.
@@ -1435,6 +1762,88 @@ Wed Jun 18 23:41:27 2003 Marc Cartright <marc@isri.unlv.edu>
deflate/inflate will return Z_BUF_ERROR, even though another call
is required by the zlib library.
+Wed Jun 18 19:46:21 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb: bug fix
+
+ * ext/tk/lib/tk.rb: rename 'no_create' option to 'without_creating'
+
+ * ext/tk/lib/tk.rb: add TkWindow#pack_in, TkWindow#grid_in,
+ TkWindow#place_in
+
+ * ext/tk/lib/tk.rb: add TkWindow#bind_class and TkWindow#database_class
+
+ * ext/tk/lib/tk.rb: add TkBindTag.new_by_name and TkDatabaseClass
+ for binding to database class
+
+ * ext/tk/lib/tk.rb: check varname whether already exsist or not.
+ (TkVarAccess.new)
+
+ * ext/tk/lib/tk.rb: TkTextWin#bbox returns an array of four numbers
+
+ * ext/tk/lib/tk.rb: autoload TkDialog2, TkWarning2
+
+ * ext/tk/lib/tk.rb: scan event callback arguments and convert
+ to proper type
+
+ * ext/tk/lib/tk.rb: TkBindTag.new accepts a block
+
+ * ext/tk/lib/tk.rb: If given taglist, TkWindow#bindtags(taglist)
+ returns taglist
+
+ * ext/tk/lib/tk.rb: add TkWindow#bindtags=(taglist)
+
+ * ext/tk/lib/tk.rb: Tk.focue and Tk.focus_lastfor return nil
+ if there is no target widget.
+
+ * ext/tk/lib/tk.rb: Tk::Wm.client returns the argument string
+ when setting name
+
+ * ext/tk/lib/tk.rb: TkGrid.columnconfiginfo and rowconfiginfo
+ given a slot return a number.
+
+ * ext/tk/lib/tk.rb: TkWindow.grid_columnconfiginfo and
+ grid_rowconfiginfo --- ditto
+
+ * ext/tk/lib/tk.rb: rename and define alias :: TkOption ==> TkOptionDB
+
+ * ext/tk/lib/tk.rb: define alias :: TkTimer ==> TkAfter
+
+ * ext/tk/lib/tk.rb: some instance methods change from public to private
+
+ * ext/tk/lib/tk.rb: some TkComm methods change to module functions
+
+ * ext/tk/lib/tk.rb: add support for -displayof option to some
+ TkWinfo methods
+
+ * ext/tk/lib/tk.rb: bind, bind_append and bind_remove ---
+ returns the target of event-binding
+
+ * ext/tk/lib/tk.rb: add Tk8.4 features
+
+ * ext/tk/lib/tk.rb: add TkPaneWindow
+
+ * ext/tk/lib/tkdialog.rb: bug fix
+
+ * ext/tk/lib/tkdialog.rb: some methods return self
+
+ * ext/tk/lib/tkdialog.rb: add TkTextMark#+(mod) and TkTextMark#-(mod)
+
+ * ext/tk/lib/tkdialog.rb: add some methods
+
+ * ext/tk/lib/tkcanvas.rb: bug fix and some methods return self
+
+ * ext/tk/lib/tkentry.rb: some methods return self
+
+ * ext/tk/lib/tkentry.rb: TkEntry#bbox returns an array of four numbers
+
+ * ext/tk/lib/tkentry.rb: scan validatecommand arguments and
+ convert to proper type
+
+ * ext/tk/lib/tkbgerror.rb: support to define a error handler by user
+
+ * ext/tcltklib/tcltklib.c: [ruby-talk:60759]
+
Wed Jun 18 13:50:06 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_eval): should dispatch based on ID type.
@@ -1520,6 +1929,27 @@ Fri Jun 13 09:24:39 2003 Shugo Maeda <shugo@ruby-lang.org>
* lib/net/ftp.rb (putbinaryfile): rescue FTPPermError.
+Thu Jun 12 22:13:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb : add 'no_create' option to widget
+ initialize method.
+
+ * ext/tk/MANIFEST : forgot to commit when added tkmacpkg.rb
+ and tkwinpkg.rb
+
+ * ext/tk/lib/README : ditto.
+
+Thu Jun 12 21:14:11 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tk.rb : widget configure returns self (for method
+ call chain)
+
+ * ext/tk/lib/tkmacpkg.rb : Mac resource (not new but not
+ included until now)
+
+ * ext/tk/lib/tkwinpkg.rb : Win DDE and registry (not new but not
+ included until now)
+
Tue Jun 10 14:26:30 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/token.c: preserve newlines prepended to a block.
@@ -1550,6 +1980,14 @@ Mon Jun 9 19:02:33 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* process.c (proc_getgroups, proc_setgroups): raise
NotImplementedError unless available. [ruby-talk:73014]
+Mon Jun 9 18:09:11 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: fixed 100% CPU problem of Tk.mainloop
+
+Mon Jun 9 15:50:24 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: renewal Tk.mainloop
+
Sun Jun 8 13:37:21 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>
* wince/setup.mak: set SUBSYSTEM in each platform.
@@ -7886,6 +8324,11 @@ Thu Jun 6 11:42:15 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* lib/thread.rb (Queue::pop): get rid of race condition.
+Wed Jun 5 01:56:47 2002 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tcltklib/tcltklib.c: Stop the running zombi-eventloop when
+ mainloop_watchdog is killed.
+
Tue Jun 4 23:09:24 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* range.c (range_include): should be based on "<=>", whereas
@@ -7899,6 +8342,31 @@ Tue Jun 4 18:28:37 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/Win32API/extconf.rb: refactoring.
+Tue Jun 4 07:03:33 2002 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkfont.rb: Fix bugs on TkFont.init_widget_font for Tk8.x.
+
+ * ext/tk/lib/tkafter.rb: Add self to 1st argument of interval-
+ and loop-proc
+ TkAfter#current_interval returns an interval (sleep) time value
+ TkAfter#current_args returns an array of arguments
+ TkAfter#return_value returns a return value of last loop-proc
+
+ * ext/tk/lib/tk*.rb: Allow to use Symbols for parameters.
+
+ * ext/tk/lib/tkcanvas.rb: (TkcItem) Add 'coords' parameter to the
+ canvas item constructor (for new notation of constructor).
+
+ * ext/tcltklib/tcltklib.c: New 'mainloop' and 'mainloop_watchdog'.
+
+ * ext/tk/lib/tk.rb: (Tk.restart) Add 'app-name' paramater and
+ 'use' parameter.
+
+ * ext/tk/lib/tk.rb: Add new parameter 'widgetname' to the widget
+ constructor to support effective use of Resource Database.
+
+ * ext/tk/lib/tk.rb: TkOption::get always returns a tainted string.
+
Tue Jun 4 00:45:50 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/addrinfo.h: typo.
diff --git a/ext/tcltklib/MANUAL.euc b/ext/tcltklib/MANUAL.euc
index 30cfd8c107..f04d036c64 100644
--- a/ext/tcltklib/MANUAL.euc
+++ b/ext/tcltklib/MANUAL.euc
@@ -1,5 +1,5 @@
(tof)
- 2003/07/25 Hidetoshi NAGAI
+ 2003/08/07 Hidetoshi NAGAI
本ドキュメントには古い tcltk ライブラリ,tcltklib ライブラリの説明
が含まれていますが,その記述内容は古いものとなっています.
@@ -263,6 +263,12 @@ require "tcltklib" すると, 以下のモジュール, クラスが利用可能です.
: Tk インタープリタ上で例外を発生した際に,イベントループをエ
: ラー停止させるかどうかの設定状態を true/false で得る.
+ num_of_mainwindows
+ : 現在のメインウィンドウ (ルートウィジェット) の数を返す.
+ : メインウィンドウは一つのインタープリタに付き最大一つである
+ : ので,この値は現在 Tk の機能が有効であるインタープリタの総
+ : 数に等しい.
+
クラス TclTkIp
クラスメソッド
@@ -274,6 +280,11 @@ require "tcltklib" すると, 以下のモジュール, クラスが利用可能です.
: 引数として与えるオプションと同様の情報を文字列として与える.
: 与えられた情報は,root widget 生成の際に用いられる.
: ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') )
+ : もし options に敢えて nil または false を与えた場合,Tk ライ
+ : ブラリが導入されていない (つまりは Tcl のみの) インタープリ
+ : タを生成する.この場合は GUI 環境は必要ないため,ウインドウ
+ : システムが存在しない,または使用できない環境でも Tcl インター
+ : プリタを生成し,Tcl やその拡張ライブラリを活用することができる.
インスタンスメソッド
create_slave(name, safe=false)
@@ -331,17 +342,26 @@ require "tcltklib" すると, 以下のモジュール, クラスが利用可能です.
_return_value
: 直前の Tcl/Tk 上での評価の実行結果としての戻り値を返す.
- mainloop : 引数を含めて TclTkLib.mainloop に同じ
- mainloop_watchdog : 引数を含めて TclTkLib.mainloop_watchdog に同じ
- do_one_event : 引数を含めて TclTkLib.do_one_event に同じ
- set_eventloop_tick : 引数を含めて TclTkLib.set_eventloop_tick に同じ
- get_eventloop_tick : 引数を含めて TclTkLib.get_eventloop_tick に同じ
- set_eventloop_weight : 引数を含めて TclTkLib.set_eventloop_weight に同じ
- get_eventloop_weight : 引数を含めて TclTkLib.set_eventloop_weight に同じ
+ mainloop
+ mainloop_watchdog
+ : スレーブ IP の場合にはイベントループを起動せずに nil を返す.
+ : それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
+
+ do_one_event
+ : スレーブ IP の場合には引数のイベントフラグに DONT_WAIT が
+ : 強制的に追加される (イベント待ちでスリープすることは禁止).
+ : それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
+
+ set_eventloop_tick
+ get_eventloop_tick
+ set_no_event_wait
+ get_no_event_wait
+ set_eventloop_weight
+ get_eventloop_weight
mainloop_abort_on_exception
- : 引数を含めて TclTkLib.mainloop_abort_on_exception に同じ
mainloop_abort_on_exception=
- : 引数を含めて TclTkLib.mainloop_abort_on_exception= に同じ
+ : スレーブ IP の場合には値の設定が許されない (無視される).
+ : それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
クラス TkCallbackBreak < StandardError
クラス TkCallbackContinue < StandardError
diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c
index ec00cea217..cb2036296a 100644
--- a/ext/tcltklib/tcltklib.c
+++ b/ext/tcltklib/tcltklib.c
@@ -8,6 +8,13 @@
#include "rubysig.h"
#undef EXTERN /* avoid conflict with tcl.h of tcl8.2 or before */
#include <stdio.h>
+#ifdef HAVE_STDARG_PROTOTYPES
+#include <stdarg.h>
+#define va_init_list(a,b) va_start(a,b)
+#else
+#include <varargs.h>
+#define va_init_list(a,b) va_start(a)
+#endif
#include <string.h>
#include <tcl.h>
#include <tk.h>
@@ -93,6 +100,25 @@ static int ip_ruby _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));
static int ip_ruby _((ClientData, Tcl_Interp *, int, char **));
#endif
+/*---- class TclTkIp ----*/
+struct tcltkip {
+ Tcl_Interp *ip; /* the interpreter */
+ int return_value; /* return value */
+};
+
+static struct tcltkip *
+get_ip(self)
+ VALUE self;
+{
+ struct tcltkip *ptr;
+
+ Data_Get_Struct(self, struct tcltkip, ptr);
+ if (ptr == 0) {
+ rb_raise(rb_eTypeError, "uninitialized TclTkIp");
+ }
+ return ptr;
+}
+
/* Tk_ThreadTimer */
static Tcl_TimerToken timer_token = (Tcl_TimerToken)NULL;
@@ -156,6 +182,27 @@ get_eventloop_tick(self)
}
static VALUE
+ip_set_eventloop_tick(self, tick)
+ VALUE self;
+ VALUE tick;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return get_eventloop_tick(self);
+ }
+ return set_eventloop_tick(self, tick);
+}
+
+static VALUE
+ip_get_eventloop_tick(self)
+ VALUE self;
+{
+ return get_eventloop_tick(self);
+}
+
+static VALUE
set_no_event_wait(self, wait)
VALUE self;
VALUE wait;
@@ -180,6 +227,27 @@ get_no_event_wait(self)
}
static VALUE
+ip_set_no_event_wait(self, wait)
+ VALUE self;
+ VALUE wait;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return get_no_event_wait(self);
+ }
+ return set_no_event_wait(self, wait);
+}
+
+static VALUE
+ip_get_no_event_wait(self)
+ VALUE self;
+{
+ return get_no_event_wait(self);
+}
+
+static VALUE
set_eventloop_weight(self, loop_max, no_event)
VALUE self;
VALUE loop_max;
@@ -206,7 +274,29 @@ get_eventloop_weight(self)
}
static VALUE
-rb_evloop_abort_on_exc(self)
+ip_set_eventloop_weight(self, loop_max, no_event)
+ VALUE self;
+ VALUE loop_max;
+ VALUE no_event;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return get_eventloop_weight(self);
+ }
+ return set_eventloop_weight(self, loop_max, no_event);
+}
+
+static VALUE
+ip_get_eventloop_weight(self)
+ VALUE self;
+{
+ return get_eventloop_weight(self);
+}
+
+static VALUE
+lib_evloop_abort_on_exc(self)
VALUE self;
{
if (event_loop_abort_on_exc > 0) {
@@ -219,7 +309,14 @@ rb_evloop_abort_on_exc(self)
}
static VALUE
-rb_evloop_abort_on_exc_set(self, val)
+ip_evloop_abort_on_exc(self)
+ VALUE self;
+{
+ return lib_evloop_abort_on_exc(self);
+}
+
+static VALUE
+lib_evloop_abort_on_exc_set(self, val)
VALUE self, val;
{
rb_secure(4);
@@ -230,7 +327,27 @@ rb_evloop_abort_on_exc_set(self, val)
} else {
event_loop_abort_on_exc = 0;
}
- return rb_evloop_abort_on_exc(self);
+ return lib_evloop_abort_on_exc(self);
+}
+
+static VALUE
+ip_evloop_abort_on_exc_set(self, val)
+ VALUE self, val;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return lib_evloop_abort_on_exc(self);
+ }
+ return lib_evloop_abort_on_exc_set(self, val);
+}
+
+static VALUE
+lib_num_of_mainwindows(self)
+ VALUE self;
+{
+ return INT2FIX(Tk_GetNumMainWindows());
}
VALUE
@@ -379,6 +496,21 @@ lib_mainloop(argc, argv, self)
return lib_mainloop_launcher(check_rootwidget);
}
+static VALUE
+ip_mainloop(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return Qnil;
+ }
+ return lib_mainloop(argc, argv, self);
+}
+
VALUE
lib_watchdog_core(check_rootwidget)
VALUE check_rootwidget;
@@ -464,10 +596,26 @@ lib_mainloop_watchdog(argc, argv, self)
}
static VALUE
-lib_do_one_event(argc, argv, self)
+ip_mainloop_watchdog(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return Qnil;
+ }
+ return lib_mainloop_watchdog(argc, argv, self);
+}
+
+static VALUE
+lib_do_one_event_core(argc, argv, self, is_ip)
int argc;
VALUE *argv;
VALUE self;
+ int is_ip;
{
VALUE vflags;
int flags;
@@ -479,6 +627,16 @@ lib_do_one_event(argc, argv, self)
Check_Type(vflags, T_FIXNUM);
flags = FIX2INT(vflags);
}
+
+ if (is_ip) {
+ /* check IP */
+ struct tcltkip *ptr = get_ip(self);
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ flags |= TCL_DONT_WAIT;
+ }
+ }
+
ret = Tcl_DoOneEvent(flags);
if (ret) {
return Qtrue;
@@ -487,25 +645,25 @@ lib_do_one_event(argc, argv, self)
}
}
-/*---- class TclTkIp ----*/
-struct tcltkip {
- Tcl_Interp *ip; /* the interpreter */
- int return_value; /* return value */
-};
-
-static struct tcltkip *
-get_ip(self)
+static VALUE
+lib_do_one_event(argc, argv, self)
+ int argc;
+ VALUE *argv;
VALUE self;
{
- struct tcltkip *ptr;
+ return lib_do_one_event_core(argc, argv, self, 0);
+}
- Data_Get_Struct(self, struct tcltkip, ptr);
- if (ptr == 0) {
- rb_raise(rb_eTypeError, "uninitialized TclTkIp");
- }
- return ptr;
+static VALUE
+ip_do_one_event(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ return lib_do_one_event_core(argc, argv, self, 0);
}
+
/* Tcl command `ruby' */
static VALUE
ip_eval_rescue(failed, einfo)
@@ -551,6 +709,19 @@ lib_restart(self)
return Qnil;
}
+static VALUE
+ip_restart(self)
+ VALUE self;
+{
+ struct tcltkip *ptr = get_ip(self);
+
+ if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
+ /* slave IP */
+ return Qnil;
+ }
+ return lib_restart(self);
+}
+
static int
#if TCL_MAJOR_VERSION >= 8
ip_ruby(clientData, interp, argc, argv)
@@ -651,6 +822,7 @@ ip_init(argc, argv, self)
struct tcltkip *ptr; /* tcltkip data struct */
VALUE argv0, opts;
int cnt;
+ int with_tk = 1;
/* create object */
Data_Get_Struct(self, struct tcltkip, ptr);
@@ -675,7 +847,12 @@ ip_init(argc, argv, self)
switch(cnt) {
case 2:
/* options */
- Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), 0);
+ if (opts == Qnil || opts == Qfalse) {
+ /* without Tk */
+ with_tk = 0;
+ } else {
+ Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), 0);
+ }
case 1:
/* argv0 */
if (argv0 != Qnil) {
@@ -687,17 +864,19 @@ ip_init(argc, argv, self)
}
/* from Tcl_AppInit() */
- DUMP1("Tk_Init");
- if (Tk_Init(ptr->ip) == TCL_ERROR) {
- rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
- }
- DUMP1("Tcl_StaticPackage(\"Tk\")");
+ if (with_tk) {
+ DUMP1("Tk_Init");
+ if (Tk_Init(ptr->ip) == TCL_ERROR) {
+ rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
+ }
+ DUMP1("Tcl_StaticPackage(\"Tk\")");
#if TCL_MAJOR_VERSION >= 8
- Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
+ Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
#else
- Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
- (Tcl_PackageInitProc *) NULL);
+ Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
+ (Tcl_PackageInitProc *) NULL);
#endif
+ }
/* add ruby command to the interpreter */
#if TCL_MAJOR_VERSION >= 8
@@ -901,6 +1080,32 @@ ip_fromUTF8(self, str, encodename)
static VALUE
+#ifdef HAVE_STDARG_PROTOTYPES
+create_ip_exc(VALUE interp, VALUE exc, const char *fmt, ...)
+#else
+create_ip_exc(interp, exc, fmt, va_alist)
+ VALUE interp:
+ VALUE exc;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list args;
+ char buf[BUFSIZ];
+ VALUE einfo;
+
+ va_init_list(args,fmt);
+ vsnprintf(buf, BUFSIZ, fmt, args);
+ buf[BUFSIZ - 1] = '\0';
+ va_end(args);
+ einfo = rb_exc_new2(exc, buf);
+ rb_iv_set(einfo, "interp", interp);
+ Tcl_ResetResult(get_ip(interp)->ip);
+ return einfo;
+}
+
+
+static VALUE
ip_invoke_real(argc, argv, obj)
int argc;
VALUE *argv;
@@ -934,7 +1139,9 @@ ip_invoke_real(argc, argv, obj)
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
/* if (event_loop_abort_on_exc || cmd[0] != '.') { */
if (event_loop_abort_on_exc > 0) {
- rb_raise(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,
+ "invalid command name `%s'", cmd);
} else {
if (event_loop_abort_on_exc < 0) {
rb_warning("invalid command name `%s' (ignore)", cmd);
@@ -1021,7 +1228,8 @@ ip_invoke_real(argc, argv, obj)
/* exception on mainloop */
if (ptr->return_value == TCL_ERROR) {
if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) {
- rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
+ /*rb_ip_raise(obj, rb_eRuntimeError, "%s", ptr->ip->result);*/
+ return create_ip_exc(obj, rb_eRuntimeError, "%s", ptr->ip->result);
} else {
if (event_loop_abort_on_exc < 0) {
rb_warning("%s (ignore)", ptr->ip->result);
@@ -1137,6 +1345,9 @@ ip_invoke(argc, argv, obj)
/* get result & free allocated memory */
result = *alloc_result;
+ if (rb_obj_is_kind_of(result, rb_eException)) {
+ rb_exc_raise(result);
+ }
free(alloc_argv);
free(alloc_result);
@@ -1197,6 +1408,10 @@ Init_tcltklib()
rb_define_module_function(lib, "mainloop_watchdog",
lib_mainloop_watchdog, -1);
rb_define_module_function(lib, "do_one_event", lib_do_one_event, -1);
+ rb_define_module_function(lib, "mainloop_abort_on_exception",
+ lib_evloop_abort_on_exc, 0);
+ rb_define_module_function(lib, "mainloop_abort_on_exception=",
+ lib_evloop_abort_on_exc_set, 1);
rb_define_module_function(lib, "set_eventloop_tick",set_eventloop_tick,1);
rb_define_module_function(lib, "get_eventloop_tick",get_eventloop_tick,0);
rb_define_module_function(lib, "set_no_event_wait", set_no_event_wait, 1);
@@ -1205,10 +1420,8 @@ Init_tcltklib()
set_eventloop_weight, 2);
rb_define_module_function(lib, "get_eventloop_weight",
get_eventloop_weight, 0);
- rb_define_module_function(lib, "mainloop_abort_on_exception",
- rb_evloop_abort_on_exc, 0);
- rb_define_module_function(lib, "mainloop_abort_on_exception=",
- rb_evloop_abort_on_exc_set, 1);
+ rb_define_module_function(lib, "num_of_mainwindows",
+ lib_num_of_mainwindows, 0);
rb_define_alloc_func(ip, ip_alloc);
rb_define_method(ip, "initialize", ip_init, -1);
@@ -1222,20 +1435,21 @@ Init_tcltklib()
rb_define_method(ip, "_fromUTF8",ip_fromUTF8,2);
rb_define_method(ip, "_invoke", ip_invoke, -1);
rb_define_method(ip, "_return_value", ip_retval, 0);
- rb_define_method(ip, "mainloop", lib_mainloop, -1);
- rb_define_method(ip, "mainloop_watchdog", lib_mainloop_watchdog, -1);
- rb_define_method(ip, "do_one_event", lib_do_one_event, -1);
+
+ rb_define_method(ip, "mainloop", ip_mainloop, -1);
+ rb_define_method(ip, "mainloop_watchdog", ip_mainloop_watchdog, -1);
+ rb_define_method(ip, "do_one_event", ip_do_one_event, -1);
rb_define_method(ip, "mainloop_abort_on_exception",
- rb_evloop_abort_on_exc, 0);
+ ip_evloop_abort_on_exc, 0);
rb_define_method(ip, "mainloop_abort_on_exception=",
- rb_evloop_abort_on_exc_set, 1);
- rb_define_method(ip, "set_eventloop_tick", set_eventloop_tick, 1);
- rb_define_method(ip, "get_eventloop_tick", get_eventloop_tick, 0);
- rb_define_method(ip, "set_no_event_wait", set_no_event_wait, 1);
- rb_define_method(ip, "get_no_event_wait", get_no_event_wait, 0);
- rb_define_method(ip, "set_eventloop_weight", set_eventloop_weight, 2);
- rb_define_method(ip, "get_eventloop_weight", get_eventloop_weight, 0);
- rb_define_method(ip, "restart", lib_restart, 0);
+ ip_evloop_abort_on_exc_set, 1);
+ rb_define_method(ip, "set_eventloop_tick", ip_set_eventloop_tick, 1);
+ rb_define_method(ip, "get_eventloop_tick", ip_get_eventloop_tick, 0);
+ rb_define_method(ip, "set_no_event_wait", ip_set_no_event_wait, 1);
+ rb_define_method(ip, "get_no_event_wait", ip_get_no_event_wait, 0);
+ rb_define_method(ip, "set_eventloop_weight", ip_set_eventloop_weight, 2);
+ rb_define_method(ip, "get_eventloop_weight", ip_get_eventloop_weight, 0);
+ rb_define_method(ip, "restart", ip_restart, 0);
eventloop_thread = 0;
watchdog_thread = 0;
diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb
index d1bf21164a..12ed7aceff 100644
--- a/ext/tk/lib/multi-tk.rb
+++ b/ext/tk/lib/multi-tk.rb
@@ -6,10 +6,12 @@ require 'tcltklib'
require 'thread'
################################################
-# ignore exception on the mainloop
+# ignore exception on the mainloop?
+TclTkLib.mainloop_abort_on_exception = true
# TclTkLib.mainloop_abort_on_exception = false
-TclTkLib.mainloop_abort_on_exception = nil
+# TclTkLib.mainloop_abort_on_exception = nil
+
################################################
@@ -71,9 +73,16 @@ class MultiTkIp
end
private :_keys2opts
- def _check_and_return(thread, exception, wait=3)
- # wait to stop the caller thread
+ def _check_and_return(thread, exception, wait=0)
return nil unless thread
+
+ if wait == 0
+ # no wait
+ thread.raise exception
+ return thread
+ end
+
+ # wait to stop the caller thread
wait.times{
if thread.stop?
# ready to send exception
@@ -104,22 +113,36 @@ class MultiTkIp
def _create_receiver_and_watchdog()
# command-procedures receiver
receiver = Thread.new{
+ safe_level = $SAFE
loop do
thread, cmd, *args = @cmd_queue.deq
if thread == @system
+ # control command
case cmd
when 'set_safe_level'
begin
- $SAFE = args[0]
+ safe_level = args[0] if safe_level < args[0]
rescue Exception
nil
end
else
# ignore
end
+
else
+ # procedure
begin
- ret = cmd.call(*args)
+ ret = proc{$SAFE = safe_level; cmd.call(*args)}.call
+ rescue SystemExit
+ # delete IP
+ unless @interp.deleted?
+ if @interp._invoke('info', 'command', '.') != ""
+ @interp._invoke('destroy', '.')
+ end
+ @interp.delete
+ end
+ _check_and_return(thread, MultiTkIp_OK.new(nil))
+ break
rescue Exception => e
# raise exception
_check_and_return(thread, e)
@@ -134,7 +157,10 @@ class MultiTkIp
# watchdog of receiver
watchdog = Thread.new{
begin
- receiver.join
+ loop do
+ sleep 1
+ break unless receiver.alive?
+ end
rescue Exception
# ignore all kind of Exception
end
@@ -621,7 +647,9 @@ end
# instance methods to treat tables
class MultiTkIp
def _tk_cmd_tbl
- MultiTkIp.tk_cmd_tbl.collect{|ent| ent.ip == self }
+ tbl = {}
+ MultiTkIp.tk_cmd_tbl.each{|id, ent| tbl[id] = ent if ent.ip == self }
+ tbl
end
def _tk_windows
@@ -632,6 +660,10 @@ class MultiTkIp
@tk_table_list
end
+ def _add_new_tables
+ (@@TK_TABLE_LIST.size - @tk_table_list.size).times{ @tk_table_list << {} }
+ end
+
def _init_ip_env(script)
script.call(self)
end
@@ -669,10 +701,10 @@ class MultiTkIp
__getip._tk_table_list[id]
end
def self.create_table
+ if __getip.slave?
+ raise SecurityError, "slave-IP has no permission creating a new table"
+ end
id = @@TK_TABLE_LIST.size
- @@IP_TABLE.each{|tg, ip|
- ip.instance_eval{@tk_table_list << {}}
- }
obj = Object.new
@@TK_TABLE_LIST << obj
obj.instance_eval <<-EOD
@@ -681,6 +713,7 @@ class MultiTkIp
end
EOD
obj.freeze
+ @@IP_TABLE.each{|tg, ip| ip._add_new_tables }
return obj
end
@@ -719,33 +752,62 @@ end
# evaluate a procedure on the proper interpreter
class MultiTkIp
# instance method
- def eval_proc_core(req_val=true, cmd = Proc.new, *args)
+ def eval_proc_core(req_val, cmd, *args)
# cmd string ==> proc
if cmd.kind_of?(String)
- cmd = proc{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }
+ xcmd = cmd
+ xargs = args
+ cmd = proc{ TkComm._get_eval_string(TkUtil.eval_cmd(xcmd, *xargs)) }
args = []
end
+ # check
+ unless cmd.kind_of?(Proc)
+ raise RuntimeError, "A Proc object is expected for the 'cmd' argument"
+ end
+
# on IP thread
if (@cmd_receiver == Thread.current)
- return cmd.call(*args)
+ begin
+ ret = cmd.call(*args)
+ rescue SystemExit
+ # exit IP
+ warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG
+ self.delete
+ ret = nil
+ rescue Exception => e
+ warn("Warning: " + e.class.inspect +
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
+ " on " + self.inspect)
+ ret = nil
+ end
+ return ret
end
# send cmd to the proc-queue
- if req_val
- @cmd_queue.enq([Thread.current, cmd, *args])
- else
+ unless req_val
@cmd_queue.enq([nil, cmd, *args])
return nil
end
- # wait and get return value by exception
+ # send and get return value by exception
begin
+ @cmd_queue.enq([Thread.current, cmd, *args])
Thread.stop
rescue MultiTkIp_OK => ret
# return value
return ret.value
+ rescue SystemExit
+ # exit IP
+ warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
+ self.delete
+ rescue Exception => e
+ # others --> warning
+ warn("Warning: " + e.class.inspect +
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
+ " on " + self.inspect)
end
+ return nil
end
private :eval_proc_core
@@ -757,48 +819,57 @@ class MultiTkIp
eval_proc_core(true, cmd, *args)
end
alias call eval_proc
-
+ alias eval_string eval_proc
+end
+class << MultiTkIp
# class method
- def self.eval_proc(cmd = Proc.new, *args)
+ def eval_proc(cmd = Proc.new, *args)
# class ==> interp object
__getip.eval_proc(cmd, *args)
end
+ alias call eval_proc
+ alias eval_string eval_proc
end
-# depend on TclTkLib
+# event loop
# all master/slave IPs are controled by only one event-loop
class << MultiTkIp
def mainloop(check_root = true)
- TclTkLib.mainloop(check_root)
+ __getip.mainloop(check_root)
end
def mainloop_watchdog(check_root = true)
- TclTkLib.mainloop_watchdog(check_root)
+ __getip.mainloop_watchdog(check_root)
end
def do_one_event(flag = TclTkLib::EventFlag::ALL)
- TclTkLib.do_one_event(flag)
+ __getip.do_one_event(flag)
+ end
+ def mainloop_abort_on_exception
+ __getip.mainloop_abort_on_exception
+ end
+ def mainloop_abort_on_exception=(mode)
+ __getip.mainloop_abort_on_exception=(mode)
end
def set_eventloop_tick(tick)
- TclTkLib.set_eventloop_tick(tick)
+ __getip.set_eventloop_tick(tick)
end
def get_eventloop_tick
- TclTkLib.get_eventloop_tick
+ __getip.get_eventloop_tick
end
def set_no_event_wait(tick)
- TclTkLib.set_no_event_wait(tick)
+ __getip.set_no_event_wait(tick)
end
def get_no_event_wait
- TclTkLib.get_no_event_wait
+ __getip.get_no_event_wait
end
def set_eventloop_weight(loop_max, no_event_tick)
- TclTkLib.set_eventloop_weight(loop_max, no_event_tick)
+ __getip.set_eventloop_weight(loop_max, no_event_tick)
end
def get_eventloop_weight
- TclTkLib.get_eventloop_weight
+ __getip.get_eventloop_weight
end
end
-
# class methods to delegate to TclTkIp
class << MultiTkIp
def method_missing(id, *args)
@@ -839,32 +910,76 @@ class << MultiTkIp
end
+# wrap methods on TclTkLib : not permit calling TclTkLib module methods
+class << TclTkLib
+ def mainloop(check_root = true)
+ MultiTkIp.mainloop(check_root)
+ end
+ def mainloop_watchdog(check_root = true)
+ MultiTkIp.mainloop_watchdog(check_root)
+ end
+ def do_one_event(flag = TclTkLib::EventFlag::ALL)
+ MultiTkIp.do_one_event(flag)
+ end
+ def mainloop_abort_on_exception
+ MultiTkIp.mainloop_abort_on_exception
+ end
+ def mainloop_abort_on_exception=(mode)
+ MultiTkIp.mainloop_abort_on_exception=(mode)
+ end
+ def set_eventloop_tick(tick)
+ MultiTkIp.set_eventloop_tick(tick)
+ end
+ def get_eventloop_tick
+ MultiTkIp.get_eventloop_tick
+ end
+ def set_no_event_wait(tick)
+ MultiTkIp.set_no_event_wait(tick)
+ end
+ def get_no_event_wait
+ MultiTkIp.get_no_event_wait
+ end
+ def set_eventloop_weight(loop_max, no_event_tick)
+ MultiTkIp.set_eventloop_weight(loop_max, no_event_tick)
+ end
+ def get_eventloop_weight
+ MultiTkIp.get_eventloop_weight
+ end
+ def restart
+ MultiTkIp.restart
+ end
+end
+
+
# depend on TclTkIp
class MultiTkIp
def mainloop(check_root = true, restart_on_dead = true)
+ return self if self.slave?
unless restart_on_dead
@interp.mainloop(check_root)
else
begin
loop do
- @interp.mainloop(check_root)
+ break unless self.alive?
if check_root
begin
- break if @interp._invoke('winfo', 'exists?', '.') == "1"
+ break if TclTkLib.num_of_mainwindows == 0
rescue Exception
break
end
end
+ @interp.mainloop(check_root)
end
rescue StandardError
if TclTkLib.mainloop_abort_on_exception != nil
- STDERR.print("warning: Tk mainloop on ", @interp.inspect,
+ STDERR.print("Warning: Tk mainloop on ", @interp.inspect,
" receives ", $!.class.inspect,
" exception (ignore) : ", $!.message, "\n");
end
retry
end
end
+ self
end
def make_safe
@@ -1187,10 +1302,19 @@ class MultiTkIp
end
-# end of MultiTkIp definition
+# remove methods for security
+class MultiTkIp
+ undef_method :instance_eval
+ undef_method :instance_variable_get
+ undef_method :instance_variable_set
+end
-MultiTkIp.freeze # defend against modification
+# end of MultiTkIp definition
+
+# defend against modification
+MultiTkIp.freeze
+TclTkLib.freeze
########################################
# start Tk which depends on MultiTkIp
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index 0941635716..a03e6823bb 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -14,6 +14,7 @@ module TkComm
def None.to_s
'None'
end
+ None.freeze
#Tk_CMDTBL = {}
#Tk_WINDOWS = {}
@@ -24,10 +25,16 @@ module TkComm
def Tk_CMDTBL.method_missing(id, *args)
TkCore::INTERP.tk_cmd_tbl.send(id, *args)
end
+ Tk_CMDTBL.freeze
Tk_WINDOWS = Object.new
def Tk_WINDOWS.method_missing(id, *args)
TkCore::INTERP.tk_windows.send(id, *args)
end
+ Tk_WINDOWS.freeze
+
+ self.instance_eval{
+ @cmdtbl = []
+ }
def error_at
frames = caller()
@@ -894,30 +901,8 @@ module TkCore
tk_call('info', *args)
end
- def mainloop(check_root = true, restart_on_dead = true)
- unless restart_on_dead
- TclTkLib.mainloop(check_root)
- else
- begin
- loop do
- TclTkLib.mainloop(check_root)
- if check_root
- begin
- break if TkWinfo.exist?('.')
- rescue Exception
- break
- end
- end
- end
- rescue StandardError
- if TclTkLib.mainloop_abort_on_exception != nil
- STDERR.print("warning: Tk mainloop on ", TkCore::INTERP.inspect,
- " receives ", $!.class.inspect,
- " exception (ignore) : ", $!.message, "\n");
- end
- retry
- end
- end
+ def mainloop(check_root = true)
+ TclTkLib.mainloop(check_root)
end
def mainloop_watchdog(check_root = true)
@@ -1020,15 +1005,15 @@ module TkCore
print "=> ", args.join(" ").inspect, "\n" if $DEBUG
begin
# res = INTERP._invoke(*args).taint
- res = INTERP._invoke(*args) # _invoke returns a TAITED string
- rescue NameError
- err = $!
+ res = INTERP._invoke(*args) # _invoke returns a TAINTED string
+ rescue NameError => err
+# err = $!
begin
args.unshift "unknown"
#res = INTERP._invoke(*args).taint
- res = INTERP._invoke(*args) # _invoke returns a TAITED string
- rescue
- fail unless /^invalid command/ =~ $!
+ res = INTERP._invoke(*args) # _invoke returns a TAINTED string
+ rescue StandardError => err2
+ fail err2 unless /^invalid command/ =~ err2
fail err
end
end
@@ -1136,7 +1121,7 @@ module Tk
TkRoot.new
end
- def bell(nice = false)
+ def Tk.bell(nice = false)
if nice
tk_call 'bell', '-nice'
else
@@ -1144,7 +1129,7 @@ module Tk
end
end
- def bell_on_display(win, nice = false)
+ def Tk.bell_on_display(win, nice = false)
if nice
tk_call('bell', '-displayof', win, '-nice')
else
@@ -1720,6 +1705,8 @@ class TkVariable
include Tk
extend TkCore
+ include Comparable
+
TkCommandNames = ['tkwait'.freeze].freeze
#TkVar_CB_TBL = {}
@@ -1749,13 +1736,16 @@ class TkVariable
@trace_elem = nil
@trace_opts = nil
+=begin
if val == []
- INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
- @id, @id, @id))
+ # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
+ # @id, @id, @id))
elsif val.kind_of?(Array)
a = []
- val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
- s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
+ # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
+ # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
+ val.each_with_index{|e,i| a.push(i); a.push(e)}
+ s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
elsif val.kind_of?(Hash)
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
@@ -1765,6 +1755,15 @@ class TkVariable
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end
+=end
+ if val.kind_of?(Hash)
+ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
+ .gsub(/[\[\]$"]/, '\\\\\&') + '"'
+ INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
+ else
+ s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
+ INTERP._eval(format('global %s; set %s %s', @id, @id, s))
+ end
end
def wait
@@ -1782,8 +1781,9 @@ class TkVariable
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
fail
else
- Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
- @id, @id)))]
+ Hash[*tk_split_simplelist(INTERP.
+ _eval(format('global %s; array get %s',
+ @id, @id)))]
end
end
end
@@ -1827,6 +1827,20 @@ class TkVariable
_get_eval_string(index), _get_eval_string(val)))
end
+ def numeric
+ number(value)
+ end
+ def numeric=(val)
+ case val
+ when Numeric
+ self.value=(val)
+ when TkVariable
+ self.value=(val.numeric)
+ else
+ raise ArgumentError, "Numeric is expected"
+ end
+ end
+
def to_i
number(value).to_i
end
@@ -1843,10 +1857,104 @@ class TkVariable
value.intern
end
+ def list
+ tk_split_list(value)
+ end
+ alias to_a list
+
+ def list=(val)
+ case val
+ when Array
+ self.value=(val)
+ when TkVariable
+ self.value=(val.list)
+ else
+ raise ArgumentError, "Array is expected"
+ end
+ end
+
def inspect
format "#<TkVariable: %s>", @id
end
+ def coerce(other)
+ case other
+ when TkVariable
+ [other.value, self.value]
+ when String
+ [other, self.to_s]
+ when Symbol
+ [other, self.to_sym]
+ when Integer
+ [other, self.to_i]
+ when Float
+ [other, self.to_f]
+ when Array
+ [other, self.to_a]
+ else
+ [other, self.value]
+ end
+ end
+
+ def &(other)
+ if other.kind_of?(Array)
+ self.to_a & other.to_a
+ else
+ self.to_i & other.to_i
+ end
+ end
+ def |(other)
+ if other.kind_of?(Array)
+ self.to_a | other.to_a
+ else
+ self.to_i | other.to_i
+ end
+ end
+ def +(other)
+ case other
+ when Array
+ self.to_a + other
+ when String
+ self.value + other
+ else
+ begin
+ number(self.value) + other
+ rescue
+ self.value + other.to_s
+ end
+ end
+ end
+ def -(other)
+ if other.kind_of?(Array)
+ self.to_a - other
+ else
+ number(self.value) - other
+ end
+ end
+ def *(other)
+ begin
+ number(self.value) * other
+ rescue
+ self.value * other
+ end
+ end
+ def /(other)
+ number(self.value) / other
+ end
+ def %(other)
+ begin
+ number(self.value) % other
+ rescue
+ self.value % other
+ end
+ end
+ def **(other)
+ number(self.value) ** other
+ end
+ def =~(other)
+ self.value =~ other
+ end
+
def ==(other)
case other
when TkVariable
@@ -1861,13 +1969,38 @@ class TkVariable
self.to_f == other
when Array
self.to_a == other
+ when Hash
+ self.value == other
else
false
end
end
- def to_a
- list(value)
+ def zero?
+ numeric.zero?
+ end
+ def nonzero?
+ !(numeric.zero?)
+ end
+
+ def <=>(other)
+ if other.kind_of?(TkVariable)
+ begin
+ val = other.numeric
+ other = val
+ rescue
+ other = other.value
+ end
+ end
+ if other.kind_of?(Numeric)
+ begin
+ return self.numeric <=> other
+ rescue
+ return self.value <=> other.to_s
+ end
+ else
+ return self.value <=> other
+ end
end
def to_eval
@@ -3082,9 +3215,16 @@ TkOption = TkOptionDB
TkResourceDB = TkOptionDB
module TkTreatFont
- def font_configinfo
+ def font_configinfo(name = nil)
ret = TkFont.used_on(self.path)
if ret == nil
+=begin
+ if name
+ ret = name
+ else
+ ret = TkFont.init_widget_font(self.path, self.path, 'configure')
+ end
+=end
ret = TkFont.init_widget_font(self.path, self.path, 'configure')
end
ret
@@ -3097,7 +3237,10 @@ module TkTreatFont
if fnt.kind_of? TkFont
return fnt.call_font_configure(self.path, self.path,'configure',slot)
else
- latinfont_configure(fnt) if fnt
+ if fnt
+ latinfont_configure(fnt)
+ kanjifont_configure(fnt)
+ end
end
end
if (ltn = slot.delete('latinfont'))
@@ -3192,10 +3335,18 @@ module TkTreatItemFont
end
private :__conf_cmd, :__item_pathname
- def tagfont_configinfo(tagOrId)
+ def tagfont_configinfo(tagOrId, name = nil)
pathname = __item_pathname(tagOrId)
ret = TkFont.used_on(pathname)
if ret == nil
+=begin
+ if name
+ ret = name
+ else
+ ret = TkFont.init_widget_font(pathname, self.path,
+ __conf_cmd(0), __conf_cmd(1), tagOrId)
+ end
+=end
ret = TkFont.init_widget_font(pathname, self.path,
__conf_cmd(0), __conf_cmd(1), tagOrId)
end
@@ -3212,7 +3363,10 @@ module TkTreatItemFont
__conf_cmd(0), __conf_cmd(1),
tagOrId, slot)
else
- latintagfont_configure(tagOrId, fnt) if fnt
+ if fnt
+ latintagfont_configure(tagOrId, fnt)
+ kanjitagfont_configure(tagOrId, fnt)
+ end
end
end
if (ltn = slot.delete('latinfont'))
@@ -3358,6 +3512,12 @@ class TkObject<TkKernel
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call path, 'cget', "-#{slot}"
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_call(path, 'cget', "-#{slot}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = fontobj(fnt)
+ end
+ fnt
else
tk_tcl2ruby tk_call(path, 'cget', "-#{slot}")
end
@@ -3398,7 +3558,10 @@ class TkObject<TkKernel
def configinfo(slot = nil)
if slot == 'font' || slot == :font ||
slot == 'kanjifont' || slot == :kanjifont
- fontobj
+ conf = tk_split_simplelist(tk_send('configure', "-#{slot}") )
+ conf[0] = conf[0][1..-1]
+ conf[4] = fontobj(conf[4])
+ conf
else
if slot
case slot.to_s
@@ -3436,7 +3599,7 @@ class TkObject<TkKernel
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
- fontconf[4] = fontobj
+ fontconf[4] = fontobj(fontconf[4])
ret.push(fontconf)
else
ret
@@ -4367,6 +4530,7 @@ class TkPanedWindow<TkWindow
end
self
end
+ alias pane_config paneconfigure
def paneconfiginfo(win, key=nil)
if key
@@ -4395,6 +4559,7 @@ class TkPanedWindow<TkWindow
}
end
end
+ alias pane_configinfo paneconfiginfo
def panes
list(tk_send('panes'))
@@ -4717,6 +4882,12 @@ class TkListbox<TkTextWin
case key.to_s
when 'text', 'label', 'show'
tk_send('itemcget', index, "-#{key}")
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_send('itemcget', index, "-#{key}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(index, fnt)
+ end
+ fnt
else
tk_tcl2ruby(tk_send('itemcget', index, "-#{key}"))
end
@@ -4750,13 +4921,17 @@ class TkListbox<TkTextWin
case key.to_s
when 'text', 'label', 'show'
conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}"))
+ when 'font', 'kanjifont'
+ conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}") )
+ conf[4] = tagfont_configinfo(index, conf[4])
else
conf = tk_split_list(tk_send('itemconfigure',index,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
- tk_split_simplelist(tk_send('itemconfigure', index)).collect{|conflist|
+ ret = tk_split_simplelist(tk_send('itemconfigure',
+ index)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@@ -4779,6 +4954,14 @@ class TkListbox<TkTextWin
end
conf
}
+ fontconf = ret.assoc('font')
+ if fontconf
+ ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
+ fontconf[4] = tagfont_configinfo(index, fontconf[4])
+ ret.push(fontconf)
+ else
+ ret
+ end
end
end
end
@@ -4881,8 +5064,14 @@ class TkMenu<TkWindow
case key.to_s
when 'text', 'label', 'show'
tk_send 'entrycget', index, "-#{key}"
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_send('entrycget', index, "-#{key}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(index, fnt)
+ end
+ fnt
else
- tk_tcl2ruby tk_send('entrycget', index, "-#{key}")
+ tk_tcl2ruby(tk_send('entrycget', index, "-#{key}"))
end
end
def entryconfigure(index, key, val=None)
@@ -4914,13 +5103,17 @@ class TkMenu<TkWindow
case key.to_s
when 'text', 'label', 'show'
conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}"))
+ when 'font', 'kanjifont'
+ conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}"))
+ conf[4] = tagfont_configinfo(index, conf[4])
else
conf = tk_split_list(tk_send('entryconfigure',index,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
- tk_split_simplelist(tk_send('entryconfigure', index)).collect{|conflist|
+ ret = tk_split_simplelist(tk_send('entryconfigure',
+ index)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@@ -4943,6 +5136,13 @@ class TkMenu<TkWindow
end
conf
}
+ if fontconf
+ ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
+ fontconf[4] = tagfont_configinfo(index, fontconf[4])
+ ret.push(fontconf)
+ else
+ ret
+ end
end
end
end
@@ -5246,6 +5446,16 @@ TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|xpath|
end
}, 'x%W')
+# freeze core modules
+TclTkLib.freeze
+TclTkIp.freeze
+TkUtil.freeze
+TkKernel.freeze
+TkComm.freeze
+TkComm::Event.freeze
+TkCore.freeze
+Tk.freeze
+
# autoload
autoload :TkCanvas, 'tkcanvas'
autoload :TkImage, 'tkcanvas'
diff --git a/ext/tk/lib/tkcanvas.rb b/ext/tk/lib/tkcanvas.rb
index a899c9caaf..9e386ee50d 100644
--- a/ext/tk/lib/tkcanvas.rb
+++ b/ext/tk/lib/tkcanvas.rb
@@ -211,6 +211,12 @@ class TkCanvas<TkWindow
end
when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
tk_send 'itemcget', tagid(tagOrId), "-#{option}"
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), "-#{option}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(tagid(tagOrId), fnt)
+ end
+ fnt
else
tk_tcl2ruby tk_send('itemcget', tagid(tagOrId), "-#{option}")
end
@@ -264,6 +270,10 @@ class TkCanvas<TkWindow
when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
conf = tk_split_simplelist(tk_send('itemconfigure',
tagid(tagOrId), "-#{key}"))
+ when 'font', 'kanjifont'
+ conf = tk_split_simplelist(tk_send('itemconfigure',
+ tagid(tagOrId),"-#{key}") )
+ conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])
else
conf = tk_split_list(tk_send('itemconfigure',
tagid(tagOrId), "-#{key}"))
@@ -271,8 +281,8 @@ class TkCanvas<TkWindow
conf[0] = conf[0][1..-1]
conf
else
- tk_split_simplelist(tk_send('itemconfigure',
- tagid(tagOrId))).collect{|conflist|
+ ret = tk_split_simplelist(tk_send('itemconfigure',
+ tagid(tagOrId))).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@@ -302,6 +312,14 @@ class TkCanvas<TkWindow
end
conf
}
+ fontconf = ret.assoc('font')
+ if fontconf
+ ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
+ fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4])
+ ret.push(fontconf)
+ else
+ ret
+ end
end
end
diff --git a/ext/tk/lib/tkfont.rb b/ext/tk/lib/tkfont.rb
index eb21b1fabf..f0c88e432d 100644
--- a/ext/tk/lib/tkfont.rb
+++ b/ext/tk/lib/tkfont.rb
@@ -34,19 +34,21 @@ class TkFont
# Tcl/Tk-JP for Windows
ltn = 'defaultgui'
knj = 'defaultgui'
- when /Mincho:Helvetica-12/
+ when /Mincho:Helvetica-Bold-12/
# Tcl/Tk-JP for UNIX/X
ltn, knj = tk_split_simplelist(tk_call('font', 'configure',
- 'Mincho:Helvetica-12',
+ 'Mincho:Helvetica-Bold-12',
'-compound'))
else
# unknown Tcl/Tk-JP
platform = tk_call('set', 'tcl_platform(platform)')
case platform
when 'unix'
- ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12}
- knj = 'k14'
+ ltn = {'family'=>'Helvetica'.freeze,
+ 'size'=>-12, 'weight'=>'bold'.freeze}
+ #knj = 'k14'
#knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'
+ knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'
when 'windows'
ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
knj = 'mincho'
@@ -68,9 +70,11 @@ class TkFont
platform = tk_call('set', 'tcl_platform(platform)')
case platform
when 'unix'
- ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12}
- knj = 'k14'
+ ltn = {'family'=>'Helvetica'.freeze,
+ 'size'=>-12, 'weight'=>'bold'.freeze}
+ #knj = 'k14'
#knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'
+ knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'
when 'windows'
ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
knj = 'mincho'
@@ -133,7 +137,7 @@ class TkFont
end
def TkFont.create_copy(font)
- fail 'source-font need to be TkFont' unless font.kind_of? TkFont
+ fail 'source-font must be a TkFont object' unless font.kind_of? TkFont
keys = {}
font.configinfo.each{|key,value| keys[key] = value }
TkFont.new(font.latin_font, font.kanji_font, keys)
@@ -220,11 +224,46 @@ class TkFont
###################################
private
###################################
- def initialize(ltn=DEFAULT_LATIN_FONT_NAME, knj=nil, keys=nil)
+ def initialize(ltn=nil, knj=nil, keys=nil)
@id = Tk_FontID.join
Tk_FontID[1].succ!
Tk_FontNameTBL[@id] = self
- knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj
+
+ if knj.kind_of?(Hash) && !keys
+ keys = knj
+ knj = nil
+ end
+
+ # compound font check
+ if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK
+ begin
+ compound = tk_split_simplelist(tk_call('font', 'configure',
+ ltn, '-compound'))
+ if knj == nil
+ if compound != []
+ ltn, knj = compound
+ end
+ else
+ if compound != []
+ ltn = compound[0]
+ end
+ compound = tk_split_simplelist(tk_call('font', 'configure',
+ knj, '-compound'))
+ if compound != []
+ knj = compound[1]
+ end
+ end
+ rescue
+ end
+ end
+
+ if ltn
+ knj = ltn if JAPANIZED_TK && !knj
+ else
+ ltn = DEFAULT_LATIN_FONT_NAME
+ knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj
+ end
+
create_compoundfont(ltn, knj, keys)
end
@@ -457,8 +496,48 @@ class TkFont
@compoundfont = @id + 'c'
if JAPANIZED_TK
@fontslot = {'font'=>@compoundfont}
- tk_call('font', 'create', @compoundfont,
- '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ begin
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ rescue RuntimeError => e
+ if ltn == knj
+ if e.message =~ /kanji font .* specified/
+ tk_call('font', 'delete', @latinfont)
+ create_latinfont(DEFAULT_LATIN_FONT_NAME)
+ opts = []
+ Hash[*(tk_split_simplelist(tk_call('font', 'configure',
+ @kanjifont)))].each{|k,v|
+ case k
+ when '-size', '-weight', '-slant', '-underline', '-overstrike'
+ opts << k << v
+ end
+ }
+ tk_call('font', 'configure', @latinfont, *opts)
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+
+ elsif e.message =~ /ascii font .* specified/
+ tk_call('font', 'delete', @kanjifont)
+ create_kanjifont(DEFAULT_KANJI_FONT_NAME)
+ opts = []
+ Hash[*(tk_split_simplelist(tk_call('font', 'configure',
+ @latinfont)))].each{|k,v|
+ case k
+ when '-size', '-weight', '-slant', '-underline', '-overstrike'
+ opts << k << v
+ end
+ }
+ tk_call('font', 'configure', @kanjifont, *opts)
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+
+ else
+ raise e
+ end
+ else
+ raise e
+ end
+ end
else
tk_call('font', 'create', @compoundfont)
@@ -529,7 +608,8 @@ class TkFont
end
def configure_core_tk4x(font, slot, value=None)
- ""
+ #""
+ self
end
def configinfo_core_tk4x(font, option=nil)
@@ -544,11 +624,70 @@ class TkFont
end
def configure_core_tk8x(font, slot, value=None)
+ if JAPANIZED_TK
+ begin
+ padjust = tk_call('font', 'configure', font, '-pointadjust')
+ rescue
+ padjust = nil
+ end
+ else
+ padjust = nil
+ end
if slot.kind_of? Hash
- tk_call 'font', 'configure', font, *hash_kv(slot)
+ if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family))
+ slot = _symbolkey2str(slot)
+ configure_core_tk8x(font, 'family', slot.delete('family'))
+ end
+
+ if ((slot.key?('size') || slot.key?(:size)) &&
+ padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust))
+ tk_call('font', 'configure', font,
+ '-pointadjust', padjust, *hash_kv(slot))
+ else
+ tk_call('font', 'configure', font, *hash_kv(slot))
+ end
+ elsif (slot == 'size' || slot == :size) && padjust != nil
+ tk_call('font', 'configure', font,
+ "-#{slot}", value, '-pointadjust', padjust)
+ elsif JAPANIZED_TK && (slot == 'family' || slot == :family)
+ # coumpund font?
+ begin
+ compound = tk_split_simplelist(tk_call('font', 'configure',
+ font, '-compound'))
+ rescue
+ tk_call('font', 'configure', font, '-family', value)
+ return self
+ end
+ if compound == []
+ tk_call('font', 'configure', font, '-family', value)
+ return self
+ end
+ ltn, knj = compound
+
+ lfnt = tk_call('font', 'create', '-copy', ltn)
+ begin
+ tk_call('font', 'configure', lfnt, '-family', value)
+ latin_replace_core_tk8x(lfnt)
+ rescue RuntimeError => e
+ fail e if $DEBUG
+ ensure
+ tk_call('font', 'delete', lfnt) if lfnt != ''
+ end
+
+ kfnt = tk_call('font', 'create', '-copy', knj)
+ begin
+ tk_call('font', 'configure', kfnt, '-family', value)
+ kanji_replace_core_tk8x(lfnt)
+ rescue RuntimeError => e
+ fail e if $DEBUG
+ ensure
+ tk_call('font', 'delete', kfnt) if kfnt != ''
+ end
+
else
- tk_call 'font', 'configure', font, "-#{slot}", value
+ tk_call('font', 'configure', font, "-#{slot}", value)
end
+ self
end
def configinfo_core_tk8x(font, option=nil)
@@ -659,20 +798,90 @@ class TkFont
end
def latin_replace_core_tk8x(ltn)
+ if JAPANIZED_TK
+ begin
+ tk_call('font', 'delete', '@font_tmp')
+ rescue
+ end
+ begin
+ fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont)
+ rescue
+ fnt_bup = ''
+ end
+ end
+
begin
tk_call('font', 'delete', @latinfont)
rescue
end
create_latinfont(ltn)
+
+ if JAPANIZED_TK
+ keys = self.configinfo
+ tk_call('font', 'delete', @compoundfont)
+ begin
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ rescue RuntimeError => e
+ tk_call('font', 'delete', @latinfont)
+ if fnt_bup != ''
+ tk_call('font', 'create', @latinfont, '-copy', fnt_bup)
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ tk_call('font', 'delete', fnt_bup)
+ end
+ fail e
+ end
+ else
+ latinkeys = {}
+ begin
+ actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
+ rescue
+ latinkeys {}
+ end
+ if latinkeys != {}
+ tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
+ end
+ end
self
end
def kanji_replace_core_tk8x(knj)
+ if JAPANIZED_TK
+ begin
+ tk_call('font', 'delete', '@font_tmp')
+ rescue
+ end
+ begin
+ fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont)
+ rescue
+ fnt_bup = ''
+ end
+ end
+
begin
tk_call('font', 'delete', @kanjifont)
rescue
end
create_kanjifont(knj)
+
+ if JAPANIZED_TK
+ keys = self.configinfo
+ tk_call('font', 'delete', @compoundfont)
+ begin
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ rescue RuntimeError => e
+ tk_call('font', 'delete', @kanjifont)
+ if fnt_bup != ''
+ tk_call('font', 'create', @kanjifont, '-copy', fnt_bup)
+ tk_call('font', 'create', @compoundfont,
+ '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
+ tk_call('font', 'delete', fnt_bup)
+ end
+ fail e
+ end
+ end
self
end
@@ -737,7 +946,7 @@ class TkFont
alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x
- when /^8\.[0123]/
+ when /^8\.[0-4]/
alias create_latinfont create_latinfont_tk8x
alias create_kanjifont create_kanjifont_tk8x
alias create_compoundfont create_compoundfont_tk8x
diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb
index ae40ac8750..9f1ad24665 100644
--- a/ext/tk/lib/tktext.rb
+++ b/ext/tk/lib/tktext.rb
@@ -330,6 +330,12 @@ class TkText<TkTextWin
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call(@path, 'tag', 'cget', tag, "-#{key}")
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(tag, fnt)
+ end
+ fnt
else
tk_tcl2ruby(tk_call(@path, 'tag', 'cget', tag, "-#{key}"))
end
@@ -363,13 +369,17 @@ class TkText<TkTextWin
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}"))
+ when 'font', 'kanjifont'
+ conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}") )
+ conf[4] = tagfont_configinfo(tag, conf[4])
else
conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
- tk_split_simplelist(tk_send('tag', 'configure', tag)).collect{|conflist|
+ ret = tk_split_simplelist(tk_send('tag', 'configure',
+ tag)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@@ -392,6 +402,14 @@ class TkText<TkTextWin
end
conf
}
+ fontconf = ret.assoc('font')
+ if fontconf
+ ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
+ fontconf[4] = tagfont_configinfo(tag, fontconf[4])
+ ret.push(fontconf)
+ else
+ ret
+ end
end
end
@@ -431,6 +449,12 @@ class TkText<TkTextWin
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_send('window', 'cget', index, "-#{slot}")
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(index, fnt)
+ end
+ fnt
else
tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
end
@@ -853,8 +877,14 @@ class TkTextTag<TkObject
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
+ when 'font', 'kanjifont'
+ fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
+ unless fnt.kind_of?(TkFont)
+ fnt = tagfontobj(@id, fnt)
+ end
+ fnt
else
- tk_tcl2ruby tk_call(@t.path, 'tag', 'cget', @id, "-#{key}")
+ tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
end
end
diff --git a/process.c b/process.c
index 0330611aed..b1c1330783 100644
--- a/process.c
+++ b/process.c
@@ -1180,11 +1180,18 @@ proc_setpriority(obj, which, who, prio)
#endif
}
+static int under_uid_switch = 0;
+static int under_gid_switch = 0;
+
static VALUE
p_sys_setuid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETUID
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
if (setuid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1197,6 +1204,10 @@ p_sys_setruid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETRUID
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
if (setruid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1209,6 +1220,10 @@ p_sys_seteuid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETEUID
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
if (seteuid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1221,6 +1236,10 @@ p_sys_setreuid(obj, rid, eid)
VALUE obj, rid, eid;
{
#if defined HAVE_SETREUID
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
if (setreuid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1233,6 +1252,10 @@ p_sys_setresuid(obj, rid, eid, sid)
VALUE obj, rid, eid, sid;
{
#if defined HAVE_SETRESUID
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
if (setresuid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1254,6 +1277,10 @@ proc_setuid(obj, id)
{
int uid = NUM2INT(id);
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
if (setresuid(uid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREUID
@@ -1284,6 +1311,11 @@ p_uid_change_privilege(obj, id)
extern int errno;
int uid;
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
+
uid = NUM2INT(id);
if (geteuid() == 0) { /* root-user */
@@ -1420,6 +1452,10 @@ p_sys_setgid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETGID
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
if (setgid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1432,6 +1468,10 @@ p_sys_setrgid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETRGID
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
if (setrgid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1444,6 +1484,10 @@ p_sys_setegid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETEGID
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
if (setegid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1456,6 +1500,10 @@ p_sys_setregid(obj, rid, eid)
VALUE obj, rid, eid;
{
#if defined HAVE_SETREGID
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
if (setregid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1468,6 +1516,10 @@ p_sys_setresgid(obj, rid, eid, sid)
VALUE obj, rid, eid, sid;
{
#if defined HAVE_SETRESGID
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
if (setresgid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@@ -1505,6 +1557,10 @@ proc_setgid(obj, id)
{
int gid = NUM2INT(id);
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
@@ -1650,6 +1706,11 @@ p_gid_change_privilege(obj, id)
extern int errno;
int gid;
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
+
gid = NUM2INT(id);
if (geteuid() == 0) { /* root-user */
@@ -1794,6 +1855,10 @@ static VALUE
proc_seteuid(obj, euid)
VALUE obj, euid;
{
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
if (setresuid(-1, NUM2INT(euid), -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREUID
@@ -1820,6 +1885,11 @@ rb_seteuid_core(euid)
{
int uid;
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
+
uid = getuid();
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
@@ -1868,6 +1938,9 @@ proc_setegid(obj, egid)
VALUE obj, egid;
{
rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
if (setresgid(-1, NUM2INT(egid), -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
@@ -1894,6 +1967,11 @@ rb_setegid_core(egid)
{
int gid;
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
+
gid = getgid();
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
@@ -1946,6 +2024,11 @@ p_uid_exchange(obj)
{
int uid, euid;
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
+
uid = getuid();
euid = geteuid();
@@ -1979,6 +2062,11 @@ p_gid_exchange(obj)
{
int gid, egid;
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
+
gid = getgid();
egid = getegid();
@@ -2004,6 +2092,16 @@ p_uid_have_saved_id()
#endif
}
+
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
+static VALUE
+p_uid_sw_ensure(id)
+ int id;
+{
+ under_uid_switch = 0;
+ return rb_seteuid_core(id);
+}
+
static VALUE
p_uid_switch(obj)
VALUE obj;
@@ -2011,21 +2109,27 @@ p_uid_switch(obj)
extern int errno;
int uid, euid;
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
+
uid = getuid();
euid = geteuid();
-#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
if (uid != euid) {
proc_seteuid(obj, INT2FIX(uid));
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, rb_seteuid_core, SAVED_USER_ID);
+ under_uid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, SAVED_USER_ID);
} else {
return INT2FIX(euid);
}
} else if (euid != SAVED_USER_ID) {
proc_seteuid(obj, INT2FIX(SAVED_USER_ID));
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, rb_seteuid_core, euid);
+ under_uid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, euid);
} else {
return INT2FIX(uid);
}
@@ -2033,14 +2137,39 @@ p_uid_switch(obj)
errno = EPERM;
rb_sys_fail(0);
}
+
#else
+static VALUE
+p_uid_sw_ensure(obj)
+ VALUE obj;
+{
+ under_uid_switch = 0;
+ return p_uid_exchange(obj);
+}
+
+static VALUE
+p_uid_switch(obj)
+ VALUE obj;
+{
+ extern int errno;
+ int uid, euid;
+
+ rb_secure(2);
+ if (under_uid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
+ }
+
+ uid = getuid();
+ euid = geteuid();
+
if (uid == euid) {
errno = EPERM;
rb_sys_fail(0);
}
- p_uid_switch(obj);
+ p_uid_exchange(obj);
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, p_uid_switch, obj);
+ under_uid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, obj);
} else {
return INT2FIX(euid);
}
@@ -2057,6 +2186,15 @@ p_gid_have_saved_id()
#endif
}
+#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
+static VALUE
+p_gid_sw_ensure(id)
+ int id;
+{
+ under_gid_switch = 0;
+ rb_setegid_core(id);
+}
+
static VALUE
p_gid_switch(obj)
VALUE obj;
@@ -2064,22 +2202,27 @@ p_gid_switch(obj)
extern int errno;
int gid, egid;
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
+
gid = getgid();
egid = getegid();
-#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
if (gid != egid) {
proc_setegid(obj, INT2FIX(gid));
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, proc_setegid,
- INT2FIX(SAVED_GROUP_ID));
+ under_gid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, SAVED_GROUP_ID);
} else {
return INT2FIX(egid);
}
} else if (egid != SAVED_GROUP_ID) {
proc_setegid(obj, INT2FIX(SAVED_GROUP_ID));
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, proc_setegid, INT2FIX(egid));
+ under_gid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, egid);
} else {
return INT2FIX(gid);
}
@@ -2088,13 +2231,36 @@ p_gid_switch(obj)
rb_sys_fail(0);
}
#else
+p_gid_sw_ensure(obj)
+ VALUE obj;
+{
+ under_gid_switch = 0;
+ p_gid_exchange(obj);
+}
+
+static VALUE
+p_gid_switch(obj)
+ VALUE obj;
+{
+ extern int errno;
+ int gid, egid;
+
+ rb_secure(2);
+ if (under_gid_switch) {
+ rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
+ }
+
+ gid = getgid();
+ egid = getegid();
+
if (gid == egid) {
errno = EPERM;
rb_sys_fail(0);
}
- p_gid_switch(obj);
+ p_gid_exchange(obj);
if (rb_block_given_p()) {
- return rb_ensure(rb_yield, Qnil, p_gid_switch, obj);
+ under_gid_switch = 1;
+ return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, obj);
} else {
return INT2FIX(egid);
}