File: tk.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  class: TclTkIp#15, #2627, #3117
inherits from
  Object ( Builtin-Module )
has properties
alias: _eval_without_enc _eval #17
alias: _invoke_without_enc _invoke #18
method: _ip_id_ #20
method: force_default_encoding= / 1 #2628
method: force_default_encoding? #2632
method: default_encoding= / 1 #2636
method: encoding= / 1 #2643
method: encoding_name #2648
alias: encoding (1/2) encoding_name #2651
alias: default_encoding encoding_name #2652
method: encoding_obj #2654
alias: __toUTF8 _toUTF8 #2662
alias: __fromUTF8 _fromUTF8 #2663
method: _toUTF8 (1/2) / 2 #2671
method: _fromUTF8 (1/2) / 2 #2716
method: _toUTF8 (2/E) / 2 #2745
method: _fromUTF8 (2/E) / 2 #2748
alias: __eval (1/2) _eval #2754
alias: __invoke (1/2) _invoke #2755
method: _eval / 1 #2757
method: _invoke / 1 #2761
alias: _eval_with_enc (1/2) _eval #2765
alias: _invoke_with_enc (1/2) _invoke #2766
attribute: encoding (2/E) [RW] #3118
alias: __eval (2/E) _eval #3120
alias: __invoke (2/E) _invoke #3121
alias: _eval_with_enc (2/E) _eval #3123
alias: _invoke_with_enc (2/E) _invoke #3124
  module: TkComm#27, #901
extends
  TkUtil   
  TkEvent   
includes
  TkUtil   
  TkEvent   
has properties
constant: WidgetClassNames #31
constant: TkExtlibAutoloadModule #32
constant: Tk_IDs #42
method: mutex #45
constant: Tk_CMDTBL #50
constant: Tk_WINDOWS #55
constant: GET_CONFIGINFO_AS_ARRAY #69
constant: GET_CONFIGINFOwoRES_AS_ARRAY #75
method: error_at #80
function: _genobj_for_tkwidget / 1 #89
function: _at / 2 #190
function: tk_tcl2ruby / 3 #199
constant: USE_TCLs_LIST_FUNCTIONS #263
function: tk_split_escstr (1/2) / 3 #271
function: tk_split_sublist (1/2) / 4 #280
function: tk_split_list (1/2) / 4 #300
function: tk_split_simplelist (1/2) / 3 #308
function: array2tk_list (1/2) / 2 #324
function: tk_split_escstr (2/E) / 3 #387
function: tk_split_sublist (2/E) / 4 #408
function: tk_split_list (2/E) / 4 #428
function: tk_split_simplelist (2/E) / 3 #435
function: array2tk_list (2/E) / 2 #461
function: list / 3 #567
function: simplelist / 3 #570
function: window / 1 #573
function: image_obj / 1 #582
function: procedure / 1 #591
method: subst / 2 #610
function: _toUTF8 / 2 #619
function: _fromUTF8 / 2 #622
function: _callback_entry_class? / 1 #628
function: _callback_entry? / 1 #634
function: _curr_cmd_id #763
function: _next_cmd_id #767
module method: install_cmd (1/2) / 2 #778
module method: uninstall_cmd (1/2) / 2 #813
method: install_cmd (2/E) / 1 #831
method: uninstall_cmd (2/E) / 1 #834
method: install_win / 2 #857
method: uninstall_win #882
method: _epath / 1 #888
method: tk_event_sequence / 1 #905
method: _bind_core / 5 #925
method: _bind / 4 #936
method: _bind_append / 4 #940
method: _bind_remove / 2 #944
method: _bindinfo / 2 #948
method: _bind_core_for_event_class / 6 #984
method: _bind_for_event_class / 5 #995
method: _bind_append_for_event_class / 5 #999
method: _bind_remove_for_event_class / 3 #1003
method: _bindinfo_for_event_class / 3 #1007
method: bind / 3 #1021
method: bind_append / 3 #1036
method: bind_remove / 2 #1047
method: bindinfo / 2 #1052
method: bind_all / 2 #1060
method: bind_append_all / 2 #1075
method: bind_remove_all / 1 #1086
method: bindinfo_all / 1 #1091
  module: TkCore#1097
extends
  TkComm   
includes
  TkComm   
has properties
constant: WITH_RUBY_VM #1101
constant: WITH_ENCODING #1102
constant: RUN_EVENTLOOP_ON_MAIN_THREAD #1106
constant: INTERP #1127
constant: INTERP_MUTEX #1129
constant: INTERP_ROOT_CHECK #1130
constant: INTERP_THREAD #1131
module method: inspect (1/2) #1185
module alias: to_s (1/2) inspect #1188
method: initialize / 2 #1191
attribute: ip [R] #1195
attribute: cmd [R] #1195
method: call / 1 #1196
method: inspect (2/E) #1199
alias: to_s (2/E) inspect #1202
constant: WIDGET_DESTROY_HOOK #1282
constant: EventFlag #1367
method: callback_break #1369
method: callback_continue #1373
method: callback_return #1377
module method: callback / 1 #1381
method: load_cmd_on_ip / 1 #1463
method: after / 2 #1467
method: after_idle / 1 #1499
method: after_cancel / 1 #1519
method: windowingsystem #1528
method: scaling / 1 #1532
method: scaling_displayof / 2 #1539
method: inactive #1547
method: inactive_displayof / 1 #1550
method: reset_inactive #1553
method: reset_inactive_displayof / 1 #1556
method: appname / 1 #1560
method: appsend_deny #1564
method: appsend / 3 #1568
method: rb_appsend / 3 #1585
method: appsend_displayof / 4 #1603
method: rb_appsend_displayof / 4 #1621
method: info / 1 #1640
method: mainloop / 1 #1644
method: mainloop_thread? #1668
method: mainloop_exist? #1681
method: is_mainloop? #1685
method: mainloop_watchdog / 1 #1689
method: do_one_event / 1 #1694
method: set_eventloop_tick / 1 #1698
method: get_eventloop_tick #1702
method: set_no_event_wait / 1 #1706
method: get_no_event_wait #1710
method: set_eventloop_weight / 2 #1714
method: get_eventloop_weight #1718
method: restart / 2 #1722
method: event_generate / 3 #1735
method: messageBox / 1 #1750
method: getOpenFile / 1 #1754
method: getMultipleOpenFile / 1 #1757
method: getSaveFile / 1 #1761
method: getMultipleSaveFile / 1 #1764
method: chooseColor / 1 #1768
method: chooseDirectory / 1 #1772
method: _ip_eval_core / 2 #1776
method: ip_eval / 1 #1792
method: ip_eval_without_enc / 1 #1796
method: ip_eval_with_enc / 1 #1800
method: _ip_invoke_core / 2 #1804
method: ip_invoke / 1 #1820
method: ip_invoke_without_enc / 1 #1824
method: ip_invoke_with_enc / 1 #1828
method: _tk_call_core / 2 #1832
method: tk_call / 1 #1866
method: tk_call_without_enc / 1 #1870
method: tk_call_with_enc / 1 #1874
method: _tk_call_to_list_core / 4 #1878
method: tk_call_to_list / 1 #1889
method: tk_call_to_list_without_enc / 1 #1893
method: tk_call_to_list_with_enc / 1 #1897
method: tk_call_to_simplelist / 1 #1901
method: tk_call_to_simplelist_without_enc / 1 #1905
method: tk_call_to_simplelist_with_enc / 1 #1909
  class: Tk_OBJECT_TABLE#1216
inherits from
  Object ( Builtin-Module )
has properties
method: initialize / 1 #1217
method: mutex #1221
method: method_missing / 3 #1224
  module: Tk#1915, #2319, #2342, #3062, #5468
extends
  Encoding ( Unknown-Module )
  Tk   
includes
  TkCore   
has properties
constant: TCL_VERSION #1919
constant: TCL_PATCHLEVEL #1920
constant: TCL_MAJOR_VERSION #1923
constant: TCL_MINOR_VERSION #1924
constant: TK_VERSION #1926
constant: TK_PATCHLEVEL #1927
constant: TK_MAJOR_VERSION #1930
constant: TK_MINOR_VERSION #1931
constant: JAPANIZED_TK #1933
module method: const_missing / 1 #1936
module method: errorInfo #2006
module method: errorCode #2011
module method: has_mainwindow? #2025
method: root #2029
module method: load_tclscript / 2 #2033
module method: load_tcllibrary / 3 #2042
module method: unload_tcllibrary / 1 #2046
module method: pkgconfig_list / 1 #2057
module method: pkgconfig_get / 2 #2076
module method: tcl_pkgconfig_list #2093
module method: tcl_pkgconfig_get / 1 #2098
module method: tk_pkgconfig_list #2103
module method: tk_pkgconfig_get / 1 #2108
module method: bell / 1 #2113
module method: bell_on_display / 2 #2122
module method: destroy / 1 #2131
module method: exit #2142
module method: sleep / 2 #2148
module method: wakeup / 1 #2160
module method: pack / 1 #2167
module method: pack_forget / 1 #2170
module method: unpack / 1 #2173
module method: grid / 1 #2177
module method: grid_forget / 1 #2180
module method: ungrid / 1 #2183
module method: place / 1 #2187
module method: place_forget / 1 #2190
module method: unplace / 1 #2193
module method: update (1/2) / 1 #2197
module method: update_idletasks #2204
method: update (2/E) / 1 #2207
module method: thread_update / 1 #2217
module method: thread_update_idletasks #2224
module method: lower_window / 2 #2228
module method: raise_window / 2 #2232
module method: current_grabs / 1 #2237
module method: focus / 1 #2245
module method: focus_to / 2 #2253
module method: focus_lastfor / 1 #2261
module method: focus_next / 1 #2265
module method: focus_prev / 1 #2269
module method: strictMotif / 1 #2273
module method: show_kinsoku / 1 #2277
module method: add_kinsoku / 2 #2285
module method: delete_kinsoku / 2 #2297
module method: toUTF8 / 2 #2307
module method: fromUTF8 / 2 #2311
module method: subst_utf_backslash / 1 #2320
module method: subst_tk_backslash / 1 #2323
module method: utf_to_backslash_sequence / 1 #2326
module method: utf_to_backslash / 1 #2329
module method: to_backslash_sequence / 1 #2332
constant: RELEASE_DATE #5469
  module: Encoding#2343, #3063
extends
  Encoding ( Tk )
has properties
constant: TkCommandNames #2346
constant: RubyEncoding #2351
constant: BINARY_NAME #2355
constant: UTF8_NAME #2356
constant: DEFAULT_EXTERNAL_NAME #2357
constant: BINARY #2359
constant: UNKNOWN #2360
constant: ENCODING_TABLE #2363
method: force_default_encoding / 1 #2469
method: force_default_encoding? (1/3) #2473
method: default_encoding= (1/3) / 1 #2477
method: encoding= (1/3) / 1 #2481
method: encoding_name (1/2) #2485
method: encoding_obj (1/2) #2488
alias: encoding (1/3) encoding_name #2491
alias: default_encoding (1/3) encoding_name #2492
method: tk_encoding_names (1/2) #2494
method: encoding_names (1/3) #2497
method: encoding_objs (1/2) #2502
method: encoding_system= (1/3) / 1 #2508
method: encoding_system_name (1/2) #2512
method: encoding_system_obj (1/2) #2515
alias: encoding_system (1/3) encoding_system_name #2518
method: force_default_encoding= (1/2) / 1 #2525
method: force_default_encoding? (2/3) #2529
method: default_encoding= (2/3) / 1 #2533
method: encoding= (2/3) / 1 #2537
method: encoding_obj (2/E) #2541
method: encoding_name (2/E) #2544
alias: encoding (2/3) encoding_name #2547
alias: default_encoding (2/3) encoding_name #2548
method: tk_encoding_names (2/E) #2550
method: encoding_objs (2/E) #2553
method: encoding_names (2/3) #2556
method: encoding_system= (2/3) / 1 #2560
method: encoding_system_name (2/E) #2564
method: encoding_system_obj (2/E) #2567
alias: encoding_system (2/3) encoding_system_name #2570
method: encoding_convertfrom (1/2) / 2 #2575
alias: encoding_convert_from (1/2) encoding_convertfrom #2597
method: encoding_convertto (1/2) / 2 #2599
alias: encoding_convert_to (1/2) encoding_convertto #2611
method: encoding_dirs (1/2) #2613
method: encoding_dirs= (1/2) / 1 #2618
method: force_default_encoding= (2/E) / 1 #3066
method: force_default_encoding? (3/E) #3070
method: default_encoding= (3/E) / 1 #3074
method: default_encoding (3/E) #3077
method: encoding= (3/E) / 1 #3081
method: encoding (3/E) #3084
method: encoding_names (3/E) #3087
method: encoding_system (3/E) #3090
method: encoding_system= (3/E) / 1 #3093
method: encoding_convertfrom (2/E) / 2 #3097
alias: encoding_convert_from (2/E) encoding_convertfrom #3100
method: encoding_convertto (2/E) / 2 #3102
alias: encoding_convert_to (2/E) encoding_convertto #3105
method: encoding_dirs (2/E) #3106
method: encoding_dirs= (2/E) / 1 #3109
  module: TclTkLib#2871
has properties
module method: force_default_encoding= / 1 #2873
module method: force_default_encoding? #2877
module method: default_encoding= / 1 #2881
module alias: _encoding encoding #2885
module alias: _encoding= encoding #2886
module method: encoding= / 1 #2887
module method: encoding_name #2892
module alias: encoding encoding_name #2895
module alias: default_encoding encoding_name #2896
module method: encoding_obj #2898
  module: TkBindCore#3129
has properties
method: bind / 2 #3133
method: bind_append / 2 #3146
method: bind_remove / 1 #3156
method: bindinfo / 1 #3160
  module: TkTreatFont#3166
has properties
method: __font_optkeys #3167
method: __pathname #3172
method: font_configinfo / 1 #3179
alias: fontobj font_configinfo #3207
method: font_configure / 1 #3209
method: latinfont_configure / 2 #3282
alias: asciifont_configure latinfont_configure #3340
method: kanjifont_configure / 2 #3342
method: font_copy / 4 #3401
method: latinfont_copy / 4 #3424
alias: asciifont_copy latinfont_copy #3447
method: kanjifont_copy / 4 #3449
  module: TkConfigMethod#3475
includes
  TkUtil   
  TkTreatFont   
has properties
module method: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ #3479
module method: __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! / 1 #3482
method: __cget_cmd #3487
method: __config_cmd #3492
method: __confinfo_cmd #3497
method: __configinfo_struct #3502
method: __optkey_aliases #3508
method: __numval_optkeys #3513
method: __numstrval_optkeys #3518
method: __boolval_optkeys #3523
method: __strval_optkeys #3528
method: __listval_optkeys #3539
method: __numlistval_optkeys #3544
method: __tkvariable_optkeys #3549
method: __val2ruby_optkeys #3554
method: __ruby2val_optkeys #3561
method: __methodcall_optkeys #3569
method: __keyonly_optkeys #3576
method: __conv_keyonly_opts / 1 #3581
method: config_hash_kv / 3 #3604
method: [] / 1 #3610
method: []= / 2 #3614
method: __cget_core / 1 #3619
method: cget / 1 #3702
method: cget_strict / 1 #3719
method: __configure_core / 2 #3724
method: __check_available_configure_options / 1 #3801
method: configure / 2 #3815
method: configure_cmd / 2 #3843
method: __configinfo_core / 1 #3847
method: configinfo / 1 #4611
method: current_configinfo / 1 #4623
  class: TkObject#4657
extends
  TkCore   
includes
  Tk   
  TkBindCore   
  TkConfigMethod   
inherits from
  TkKernel   
has properties
method: epath #4668
method: to_eval #4672
method: tk_send / 2 #4676
method: tk_send_without_enc / 2 #4679
method: tk_send_with_enc / 2 #4682
method: tk_send_to_list / 2 #4687
method: tk_send_to_list_without_enc / 2 #4690
method: tk_send_to_list_with_enc / 2 #4693
method: tk_send_to_simplelist / 2 #4696
method: tk_send_to_simplelist_without_enc / 2 #4699
method: tk_send_to_simplelist_with_enc / 2 #4702
method: method_missing / 2 #4706
method: event_generate / 2 #4748
method: tk_trace_variable / 1 #4764
method: destroy #4772
  class: TkWindow#4778
extends
  TkBindCore   
includes
  TkWinfo   
  Wm_for_General ( Tk )
inherits from
  TkObject   
has properties
class method: _widget_inspect_full_? #4784
class method: _widget_inspect_full_= / 1 #4787
constant: TkCommandNames #4791
constant: WidgetClassName #4794
class method: to_eval #4797
method: initialize / 2 #4801
method: create_self / 1 #4882
method: inspect #4925
method: exist? #4934
method: bind_class #4938
method: database_classname (1/2) #4942
method: database_class (1/2) #4945
class method: database_classname (2/E) #4953
class method: database_class (2/E) #4956
method: pack / 1 #4960
method: pack_in / 2 #4970
method: pack_forget #4982
alias: unpack pack_forget #4987
method: pack_config / 2 #4989
alias: pack_configure pack_config #5001
method: pack_info #5003
method: pack_propagate / 1 #5013
method: pack_slaves #5028
method: grid / 1 #5033
method: grid_in / 2 #5043
method: grid_anchor / 1 #5055
method: grid_forget #5064
alias: ungrid grid_forget #5069
method: grid_bbox / 1 #5071
method: grid_config / 2 #5076
alias: grid_configure grid_config #5088
method: grid_columnconfig / 2 #5090
alias: grid_columnconfigure grid_columnconfig #5094
alias: grid_column grid_columnconfig #5095
method: grid_rowconfig / 2 #5097
alias: grid_rowconfigure grid_rowconfig #5101
alias: grid_row grid_rowconfig #5102
method: grid_columnconfiginfo / 2 #5104
method: grid_rowconfiginfo / 2 #5118
method: grid_info #5132
method: grid_location / 2 #5137
method: grid_propagate / 1 #5142
method: grid_remove #5157
method: grid_size #5163
method: grid_slaves / 1 #5168
method: place / 1 #5173
method: place_in / 2 #5179
method: place_forget #5191
alias: unplace place_forget #5196
method: place_config / 2 #5198
alias: place_configure place_config #5206
method: place_configinfo / 1 #5208
method: place_info #5225
method: place_slaves #5235
method: set_focus / 1 #5240
alias: focus set_focus #5248
method: grab / 1 #5250
method: grab_current #5277
alias: current_grab grab_current #5280
method: grab_release #5281
alias: release_grab grab_release #5284
method: grab_set #5285
alias: set_grab grab_set #5288
method: grab_set_global #5289
alias: set_global_grab grab_set_global #5292
method: grab_status #5293
method: lower / 1 #5297
alias: lower_window lower #5303
method: raise / 1 #5304
alias: raise_window raise #5310
method: command / 2 #5312
method: colormodel / 1 #5322
method: caret / 1 #5327
method: destroy #5331
method: wait_visibility / 1 #5362
method: eventloop_wait_visibility #5373
method: thread_wait_visibility #5376
alias: wait wait_visibility #5379
alias: tkwait wait_visibility #5380
alias: eventloop_wait eventloop_wait_visibility #5381
alias: eventloop_tkwait eventloop_wait_visibility #5382
alias: eventloop_tkwait_visibility eventloop_wait_visibility #5383
alias: thread_wait thread_wait_visibility #5384
alias: thread_tkwait thread_wait_visibility #5385
alias: thread_tkwait_visibility thread_wait_visibility #5386
method: wait_destroy / 1 #5388
alias: wait_window wait_destroy #5399
method: eventloop_wait_destroy #5400
alias: eventloop_wait_window eventloop_wait_destroy #5403
method: thread_wait_destroy #5404
alias: thread_wait_window thread_wait_destroy #5407
alias: tkwait_destroy wait_destroy #5409
alias: tkwait_window wait_destroy #5410
alias: eventloop_tkwait_destroy eventloop_wait_destroy #5412
alias: eventloop_tkwait_window eventloop_wait_destroy #5413
alias: thread_tkwait_destroy thread_wait_destroy #5415
alias: thread_tkwait_window thread_wait_destroy #5416
method: bindtags / 1 #5418
method: bindtags= / 1 #5440
method: bindtags_shift #5445
method: bindtags_unshift / 1 #5452

Class Hierarchy

Object ( Builtin-Module )
TkKernel
TkObject#4657
  TkWindow    #4778
TclTkIp#15, #2627, #3117
Tk_OBJECT_TABLE ( TkCore ) — #1216

Code

   1  #
   2  #               tk.rb - Tk interface module using tcltklib
   3  #                       by Yukihiro Matsumoto <matz@netlab.jp>
   4 
   5  # use Shigehiro's tcltklib
   6  require 'tcltklib'
   7  require 'tkutil'
   8 
   9  # autoload
  10  require 'tk/autoload'
  11 
  12  # for Mutex
  13  require 'thread'
  14 
  15  class TclTkIp
  16    # backup original (without encoding) _eval and _invoke
  17    alias _eval_without_enc _eval
  18    alias _invoke_without_enc _invoke
  19 
  20    def _ip_id_
  21      # for RemoteTkIp
  22      ''
  23    end
  24  end
  25 
  26  # define TkComm module (step 1: basic functions)
  27  module TkComm
  28    include TkUtil
  29    extend TkUtil
  30 
  31    WidgetClassNames = {}.taint
  32    TkExtlibAutoloadModule = [].taint
  33 
  34    # None = Object.new  ### --> definition is moved to TkUtil module
  35    # def None.to_s
  36    #   'None'
  37    # end
  38    # None.freeze
  39 
  40    #Tk_CMDTBL = {}
  41    #Tk_WINDOWS = {}
  42    Tk_IDs = ["00000".taint, "00000".taint]  # [0]-cmdid, [1]-winid
  43    Tk_IDs.instance_eval{
  44      @mutex = Mutex.new
  45      def mutex; @mutex; end
  46      freeze
  47    }
  48 
  49    # for backward compatibility
  50    Tk_CMDTBL = Object.new
  51    def Tk_CMDTBL.method_missing(id, *args)
  52      TkCore::INTERP.tk_cmd_tbl.__send__(id, *args)
  53    end
  54    Tk_CMDTBL.freeze
  55    Tk_WINDOWS = Object.new
  56    def Tk_WINDOWS.method_missing(id, *args)
  57      TkCore::INTERP.tk_windows.__send__(id, *args)
  58    end
  59    Tk_WINDOWS.freeze
  60 
  61    self.instance_eval{
  62      @cmdtbl = [].taint
  63    }
  64 
  65    unless const_defined?(:GET_CONFIGINFO_AS_ARRAY)
  66      # GET_CONFIGINFO_AS_ARRAY = false => returns a Hash { opt =>val, ... }
  67      #                           true  => returns an Array [[opt,val], ... ]
  68      # val is a list which includes resource info. 
  69      GET_CONFIGINFO_AS_ARRAY = true
  70    end
  71    unless const_defined?(:GET_CONFIGINFOwoRES_AS_ARRAY)
  72      # for configinfo without resource info; list of [opt, value] pair
  73      #           false => returns a Hash { opt=>val, ... }
  74      #           true  => returns an Array [[opt,val], ... ]
  75      GET_CONFIGINFOwoRES_AS_ARRAY = true
  76    end
  77    #  *** ATTENTION ***
  78    # 'current_configinfo' method always returns a Hash under all cases of above.
  79 
  80    def error_at
  81      frames = caller()
  82      frames.delete_if do |c|
  83        c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+!
  84      end
  85      frames
  86    end
  87    private :error_at
  88 
  89    def _genobj_for_tkwidget(path)
  90      return TkRoot.new if path == '.'
  91 
  92      begin
  93        #tk_class = TkCore::INTERP._invoke('winfo', 'class', path)
  94        tk_class = Tk.ip_invoke_without_enc('winfo', 'class', path)
  95      rescue
  96        return path
  97      end
  98 
  99      if ruby_class = WidgetClassNames[tk_class]
 100        ruby_class_name = ruby_class.name
 101        # gen_class_name = ruby_class_name + 'GeneratedOnTk'
 102        gen_class_name = ruby_class_name
 103        classname_def = ''
 104      else # ruby_class == nil
 105        mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
 106        mods.each{|mod|
 107          begin
 108            mod.const_get(tk_class)  # auto_load
 109            break if (ruby_class = WidgetClassNames[tk_class])
 110          rescue LoadError
 111            # ignore load error
 112          end
 113        }
 114 
 115        unless ruby_class
 116          std_class = 'Tk' << tk_class
 117          if Object.const_defined?(std_class)
 118            Object.const_get(std_class)  # auto_load
 119            ruby_class = WidgetClassNames[tk_class]
 120          end
 121        end
 122 
 123        if ruby_class
 124          # found
 125          ruby_class_name = ruby_class.name
 126          gen_class_name = ruby_class_name
 127          classname_def = ''
 128        else
 129          # unknown
 130          ruby_class_name = 'TkWindow'
 131          gen_class_name = 'TkWidget_' + tk_class
 132          classname_def = "WidgetClassName = '#{tk_class}'.freeze"
 133        end
 134      end
 135 
 136  ###################################
 137  =begin
 138      if ruby_class = WidgetClassNames[tk_class]
 139        ruby_class_name = ruby_class.name
 140        # gen_class_name = ruby_class_name + 'GeneratedOnTk'
 141        gen_class_name = ruby_class_name
 142        classname_def = ''
 143      else
 144        mod = TkExtlibAutoloadModule.find{|m| m.const_defined?(tk_class)}
 145        if mod
 146          ruby_class_name = mod.name + '::' + tk_class
 147          gen_class_name = ruby_class_name
 148          classname_def = ''
 149        elsif Object.const_defined?('Tk' + tk_class)
 150          ruby_class_name = 'Tk' + tk_class
 151          # gen_class_name = ruby_class_name + 'GeneratedOnTk'
 152          gen_class_name = ruby_class_name
 153          classname_def = ''
 154        else
 155          ruby_class_name = 'TkWindow'
 156          # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk'
 157          gen_class_name = 'TkWidget_' + tk_class
 158          classname_def = "WidgetClassName = '#{tk_class}'.freeze"
 159        end
 160      end
 161  =end
 162 
 163  =begin
 164      unless Object.const_defined? gen_class_name
 165        Object.class_eval "class #{gen_class_name}<#{ruby_class_name}
 166                             #{classname_def}
 167                           end"
 168      end
 169      Object.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', 
 170                                               'without_creating'=>true)"
 171  =end
 172      base = Object
 173      gen_class_name.split('::').each{|klass|
 174        next if klass == ''
 175        if base.const_defined?(klass)
 176          base = base.class_eval klass
 177        else
 178          base = base.class_eval "class #{klass}<#{ruby_class_name}
 179                                    #{classname_def}
 180                                  end
 181                                  #{klass}"
 182        end
 183      }
 184      base.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', 
 185                                             'without_creating'=>true)"
 186    end
 187    private :_genobj_for_tkwidget
 188    module_function :_genobj_for_tkwidget
 189 
 190    def _at(x,y=nil)
 191      if y
 192        "@#{Integer(x)},#{Integer(y)}"
 193      else
 194        "@#{Integer(x)}"
 195      end
 196    end
 197    module_function :_at
 198 
 199    def tk_tcl2ruby(val, enc_mode = false, listobj = true)
 200  =begin
 201      if val =~ /^rb_out\S* (c(_\d+_)?\d+)/
 202        #return Tk_CMDTBL[$1]
 203        return TkCore::INTERP.tk_cmd_tbl[$1]
 204        #cmd_obj = TkCore::INTERP.tk_cmd_tbl[$1]
 205        #if cmd_obj.kind_of?(Proc) || cmd_obj.kind_of?(Method)
 206        #  cmd_obj
 207        #else
 208        #  cmd_obj.cmd
 209        #end
 210      end
 211  =end
 212      if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
 213        return TkCore::INTERP.tk_cmd_tbl[$4]
 214      end
 215      #if val.include? ?\s
 216      #  return val.split.collect{|v| tk_tcl2ruby(v)}
 217      #end
 218      case val
 219      when /\A@font\S+\z/
 220        TkFont.get_obj(val)
 221      when /\A-?\d+\z/
 222        val.to_i
 223      when /\A\.\S*\z/
 224        #Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)
 225        TkCore::INTERP.tk_windows[val]? 
 226             TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val)
 227      when /\Ai(_\d+_)?\d+\z/
 228        TkImage::Tk_IMGTBL.mutex.synchronize{
 229          TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val
 230        }
 231      when /\A-?\d+\.?\d*(e[-+]?\d+)?\z/
 232        val.to_f
 233      when /\\ /
 234        val.gsub(/\\ /, ' ')
 235      when /[^\\] /
 236        if listobj
 237          #tk_split_escstr(val).collect{|elt|
 238          #  tk_tcl2ruby(elt, enc_mode, listobj)
 239          #}
 240          val = _toUTF8(val) unless enc_mode
 241          tk_split_escstr(val, false, false).collect{|elt|
 242            tk_tcl2ruby(elt, true, listobj)
 243          }
 244        elsif enc_mode
 245          _fromUTF8(val)
 246        else
 247          val
 248        end
 249      else
 250        if enc_mode
 251          _fromUTF8(val)
 252        else
 253          val
 254        end
 255      end
 256    end
 257 
 258    private :tk_tcl2ruby
 259    module_function :tk_tcl2ruby
 260    #private_class_method :tk_tcl2ruby
 261 
 262  unless const_defined?(:USE_TCLs_LIST_FUNCTIONS)
 263    USE_TCLs_LIST_FUNCTIONS = true
 264  end
 265 
 266  if USE_TCLs_LIST_FUNCTIONS
 267    ###########################################################################
 268    # use Tcl function version of split_list
 269    ###########################################################################
 270 
 271    def tk_split_escstr(str, src_enc=true, dst_enc=true)
 272      str = _toUTF8(str) if src_enc
 273      if dst_enc
 274        TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)}
 275      else
 276        TkCore::INTERP._split_tklist(str)
 277      end
 278    end
 279 
 280    def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true)
 281      # return [] if str == ""
 282      # list = TkCore::INTERP._split_tklist(str)
 283      str = _toUTF8(str) if src_enc
 284 
 285      if depth == 0
 286        return "" if str == ""
 287        list = [str]
 288      else
 289        return [] if str == ""
 290        list = TkCore::INTERP._split_tklist(str)
 291      end
 292      if list.size == 1
 293        # tk_tcl2ruby(list[0], nil, false)
 294        tk_tcl2ruby(list[0], dst_enc, false)
 295      else
 296        list.collect{|token| tk_split_sublist(token, depth - 1, false, dst_enc)}
 297      end
 298    end
 299 
 300    def tk_split_list(str, depth=0, src_enc=true, dst_enc=true)
 301      return [] if str == ""
 302      str = _toUTF8(str) if src_enc
 303      TkCore::INTERP._split_tklist(str).map!{|token|
 304        tk_split_sublist(token, depth - 1, false, dst_enc)
 305      }
 306    end
 307 
 308    def tk_split_simplelist(str, src_enc=true, dst_enc=true)
 309      #lst = TkCore::INTERP._split_tklist(str)
 310      #if (lst.size == 1 && lst =~ /^\{.*\}$/)
 311      #  TkCore::INTERP._split_tklist(str[1..-2])
 312      #else
 313      #  lst
 314      #end
 315 
 316      str = _toUTF8(str) if src_enc
 317      if dst_enc
 318        TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)}
 319      else
 320        TkCore::INTERP._split_tklist(str)
 321      end
 322    end
 323 
 324    def array2tk_list(ary, enc=nil)
 325      return "" if ary.size == 0
 326 
 327      sys_enc = TkCore::INTERP.encoding
 328      sys_enc = TclTkLib.encoding_system unless sys_enc
 329 
 330      dst_enc = (enc == nil)? sys_enc: enc
 331 
 332      dst = ary.collect{|e|
 333        if e.kind_of? Array
 334          s = array2tk_list(e, enc)
 335        elsif e.kind_of? Hash
 336          tmp_ary = []
 337          #e.each{|k,v| tmp_ary << k << v }
 338          e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v }
 339          s = array2tk_list(tmp_ary, enc)
 340        else
 341          s = _get_eval_string(e, enc)
 342        end
 343 
 344        if dst_enc != true && dst_enc != false
 345          if (s_enc = s.instance_variable_get(:@encoding))
 346            s_enc = s_enc.to_s
 347          elsif TkCore::WITH_ENCODING
 348            s_enc = s.encoding.name
 349          else
 350            s_enc = sys_enc
 351          end
 352          dst_enc = true if s_enc != dst_enc
 353        end
 354 
 355        s
 356      }
 357 
 358      if sys_enc && dst_enc
 359        dst.map!{|s| _toUTF8(s)}
 360        ret = TkCore::INTERP._merge_tklist(*dst)
 361        if TkCore::WITH_ENCODING
 362          if dst_enc.kind_of?(String)
 363            ret = _fromUTF8(ret, dst_enc)
 364            ret.force_encoding(dst_enc)
 365          else
 366            ret.force_encoding('utf-8')
 367          end
 368        else # without encoding
 369          if dst_enc.kind_of?(String)
 370            ret = _fromUTF8(ret, dst_enc)
 371            ret.instance_variable_set(:@encoding, dst_enc)
 372          else
 373            ret.instance_variable_set(:@encoding, 'utf-8')
 374          end
 375        end
 376        ret
 377      else
 378        TkCore::INTERP._merge_tklist(*dst)
 379      end
 380    end
 381 
 382  else
 383    ###########################################################################
 384    # use Ruby script version of split_list (traditional methods)
 385    ###########################################################################
 386 
 387    def tk_split_escstr(str, src_enc=true, dst_enc=true)
 388      return [] if str == ""
 389      list = []
 390      token = nil
 391      escape = false
 392      brace = 0
 393      str.split('').each {|c|
 394        brace += 1 if c == '{' && !escape
 395        brace -= 1 if c == '}' && !escape
 396        if brace == 0 && c == ' ' && !escape
 397          list << token.gsub(/^\{(.*)\}$/, '\1') if token
 398          token = nil
 399        else
 400          token = (token || "") << c
 401        end
 402        escape = (c == '\\' && !escape)
 403      }
 404      list << token.gsub(/^\{(.*)\}$/, '\1') if token
 405      list
 406    end
 407 
 408    def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true)
 409      #return [] if str == ""
 410      #return [tk_split_sublist(str[1..-2])] if str =~ /^\{.*\}$/
 411      #list = tk_split_escstr(str)
 412      if depth == 0
 413        return "" if str == ""
 414        str = str[1..-2] if str =~ /^\{.*\}$/
 415        list = [str]
 416      else
 417        return [] if str == []
 418        return [tk_split_sublist(str[1..-2], depth - 1)] if str =~ /^\{.*\}$/
 419        list = tk_split_escstr(str)
 420      end
 421      if list.size == 1
 422        tk_tcl2ruby(list[0], nil, false)
 423      else
 424        list.collect{|token| tk_split_sublist(token, depth - 1)}
 425      end
 426    end
 427 
 428    def tk_split_list(str, depth=0, src_enc=true, dst_enc=true)
 429      return [] if str == ""
 430      tk_split_escstr(str).collect{|token| 
 431        tk_split_sublist(token, depth - 1)
 432      }
 433    end
 434 
 435    def tk_split_simplelist(str, src_enc=true, dst_enc=true)
 436      return [] if str == ""
 437      list = []
 438      token = nil
 439      escape = false
 440      brace = 0
 441      str.split('').each {|c|
 442        if c == '\\' && !escape
 443          escape = true
 444          token = (token || "") << c if brace > 0
 445          next
 446        end
 447        brace += 1 if c == '{' && !escape
 448        brace -= 1 if c == '}' && !escape
 449        if brace == 0 && c == ' ' && !escape
 450          list << token.gsub(/^\{(.*)\}$/, '\1') if token
 451          token = nil
 452        else
 453          token = (token || "") << c
 454        end
 455        escape = false
 456      }
 457      list << token.gsub(/^\{(.*)\}$/, '\1') if token
 458      list
 459    end
 460 
 461    def array2tk_list(ary, enc=nil)
 462      ary.collect{|e|
 463        if e.kind_of? Array
 464          "{#{array2tk_list(e, enc)}}"
 465        elsif e.kind_of? Hash
 466          # "{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}"
 467          e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v }
 468          array2tk_list(tmp_ary, enc)
 469        else
 470          s = _get_eval_string(e, enc)
 471          (s.index(/\s/) || s.size == 0)? "{#{s}}": s
 472        end
 473      }.join(" ")
 474    end
 475  end
 476 
 477    private :tk_split_escstr, :tk_split_sublist
 478    private :tk_split_list, :tk_split_simplelist
 479    private :array2tk_list
 480 
 481    module_function :tk_split_escstr, :tk_split_sublist
 482    module_function :tk_split_list, :tk_split_simplelist
 483    module_function :array2tk_list
 484 
 485    private_class_method :tk_split_escstr, :tk_split_sublist
 486    private_class_method :tk_split_list, :tk_split_simplelist
 487  #  private_class_method :array2tk_list
 488 
 489  =begin
 490    ### --> definition is moved to TkUtil module
 491    def _symbolkey2str(keys)
 492      h = {}
 493      keys.each{|key,value| h[key.to_s] = value}
 494      h
 495    end
 496    private :_symbolkey2str
 497    module_function :_symbolkey2str
 498  =end
 499 
 500  =begin
 501    ### --> definition is moved to TkUtil module
 502    # def hash_kv(keys, enc_mode = nil, conf = [], flat = false)
 503    def hash_kv(keys, enc_mode = nil, conf = nil)
 504      # Hash {key=>val, key=>val, ... } or Array [ [key, val], [key, val], ... ]
 505      #     ==> Array ['-key', val, '-key', val, ... ]
 506      dst = []
 507      if keys and keys != None
 508        keys.each{|k, v|
 509          #dst.push("-#{k}")
 510          dst.push('-' + k.to_s)
 511          if v != None
 512            # v = _get_eval_string(v, enc_mode) if (enc_mode || flat)
 513            v = _get_eval_string(v, enc_mode) if enc_mode
 514            dst.push(v)
 515          end
 516        }
 517      end
 518      if conf
 519        conf + dst
 520      else
 521        dst
 522      end
 523    end
 524    private :hash_kv
 525    module_function :hash_kv
 526  =end
 527 
 528  =begin
 529    ### --> definition is moved to TkUtil module
 530    def bool(val)
 531      case val
 532      when "1", 1, 'yes', 'true'
 533        true
 534      else
 535        false
 536      end
 537    end
 538 
 539    def number(val)
 540      case val
 541      when /^-?\d+$/
 542        val.to_i
 543      when /^-?\d+\.?\d*(e[-+]?\d+)?$/
 544        val.to_f
 545      else
 546        fail(ArgumentError, "invalid value for Number:'#{val}'")
 547      end
 548    end
 549    def string(val)
 550      if val == "{}"
 551        ''
 552      elsif val[0] == ?{ && val[-1] == ?}
 553        val[1..-2]
 554      else
 555        val
 556      end
 557    end
 558    def num_or_str(val)
 559      begin
 560        number(val)
 561      rescue ArgumentError
 562        string(val)
 563      end
 564    end
 565  =end
 566 
 567    def list(val, depth=0, enc=true)
 568      tk_split_list(val, depth, enc, enc)
 569    end
 570    def simplelist(val, src_enc=true, dst_enc=true)
 571      tk_split_simplelist(val, src_enc, dst_enc)
 572    end
 573    def window(val)
 574      if val =~ /^\./
 575        #Tk_WINDOWS[val]? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)
 576        TkCore::INTERP.tk_windows[val]? 
 577             TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val)
 578      else
 579        nil
 580      end
 581    end
 582    def image_obj(val)
 583      if val =~ /^i(_\d+_)?\d+$/
 584        TkImage::Tk_IMGTBL.mutex.synchronize{
 585          TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val
 586        }
 587      else
 588        val
 589      end
 590    end
 591    def procedure(val)
 592  =begin
 593      if val =~ /^rb_out\S* (c(_\d+_)?\d+)/
 594        #Tk_CMDTBL[$1]
 595        #TkCore::INTERP.tk_cmd_tbl[$1]
 596        TkCore::INTERP.tk_cmd_tbl[$1].cmd
 597  =end
 598      if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
 599        return TkCore::INTERP.tk_cmd_tbl[$4].cmd
 600      else
 601        #nil
 602        val
 603      end
 604    end
 605    private :bool, :number, :string, :num_or_str
 606    private :list, :simplelist, :window, :procedure
 607    module_function :bool, :number, :num_or_str, :string
 608    module_function :list, :simplelist, :window, :image_obj, :procedure
 609 
 610    def subst(str, *opts)
 611      # opts := :nobackslashes | :nocommands | novariables
 612      tk_call('subst', 
 613              *(opts.collect{|opt|
 614                  opt = opt.to_s
 615                  (opt[0] == ?-)? opt: '-' << opt
 616                } << str))
 617    end
 618 
 619    def _toUTF8(str, encoding = nil)
 620      TkCore::INTERP._toUTF8(str, encoding)
 621    end
 622    def _fromUTF8(str, encoding = nil)
 623      TkCore::INTERP._fromUTF8(str, encoding)
 624    end
 625    private :_toUTF8, :_fromUTF8
 626    module_function :_toUTF8, :_fromUTF8
 627 
 628    def _callback_entry_class?(cls)
 629      cls <= Proc || cls <= Method || cls <= TkCallbackEntry
 630    end
 631    private :_callback_entry_class?
 632    module_function :_callback_entry_class?
 633 
 634    def _callback_entry?(obj)
 635      obj.kind_of?(Proc) || obj.kind_of?(Method) || obj.kind_of?(TkCallbackEntry)
 636    end
 637    private :_callback_entry?
 638    module_function :_callback_entry?
 639 
 640  =begin
 641    ### --> definition is moved to TkUtil module
 642    def _get_eval_string(str, enc_mode = nil)
 643      return nil if str == None
 644      if str.kind_of?(TkObject)
 645        str = str.path
 646      elsif str.kind_of?(String)
 647        str = _toUTF8(str) if enc_mode
 648      elsif str.kind_of?(Symbol)
 649        str = str.id2name
 650        str = _toUTF8(str) if enc_mode
 651      elsif str.kind_of?(Hash)
 652        str = hash_kv(str, enc_mode).join(" ")
 653      elsif str.kind_of?(Array)
 654        str = array2tk_list(str)
 655        str = _toUTF8(str) if enc_mode
 656      elsif str.kind_of?(Proc)
 657        str = install_cmd(str)
 658      elsif str == nil
 659        str = ""
 660      elsif str == false
 661        str = "0"
 662      elsif str == true
 663        str = "1"
 664      elsif (str.respond_to?(:to_eval))
 665        str = str.to_eval()
 666        str = _toUTF8(str) if enc_mode
 667      else
 668        str = str.to_s() || ''
 669        unless str.kind_of? String
 670          fail RuntimeError, "fail to convert the object to a string" 
 671        end
 672        str = _toUTF8(str) if enc_mode
 673      end
 674      return str
 675    end
 676  =end
 677  =begin
 678    def _get_eval_string(obj, enc_mode = nil)
 679      case obj
 680      when Numeric
 681        obj.to_s
 682      when String
 683        (enc_mode)? _toUTF8(obj): obj
 684      when Symbol
 685        (enc_mode)? _toUTF8(obj.id2name): obj.id2name
 686      when TkObject
 687        obj.path
 688      when Hash
 689        hash_kv(obj, enc_mode).join(' ')
 690      when Array
 691        (enc_mode)? _toUTF8(array2tk_list(obj)): array2tk_list(obj)
 692      when Proc, Method, TkCallbackEntry
 693        install_cmd(obj)
 694      when false
 695        '0'
 696      when true
 697        '1'
 698      when nil
 699        ''
 700      when None
 701        nil
 702      else
 703        if (obj.respond_to?(:to_eval))
 704          (enc_mode)? _toUTF8(obj.to_eval): obj.to_eval
 705        else
 706          begin
 707            obj = obj.to_s || ''
 708          rescue
 709            fail RuntimeError, "fail to convert object '#{obj}' to string" 
 710          end
 711          (enc_mode)? _toUTF8(obj): obj
 712        end
 713      end
 714    end
 715    private :_get_eval_string
 716    module_function :_get_eval_string
 717  =end
 718 
 719  =begin
 720    ### --> definition is moved to TkUtil module
 721    def _get_eval_enc_str(obj)
 722      return obj if obj == None
 723      _get_eval_string(obj, true)
 724    end
 725    private :_get_eval_enc_str
 726    module_function :_get_eval_enc_str
 727  =end
 728 
 729  =begin
 730    ### --> obsolete
 731    def ruby2tcl(v, enc_mode = nil)
 732      if v.kind_of?(Hash)
 733        v = hash_kv(v)
 734        v.flatten!
 735        v.collect{|e|ruby2tcl(e, enc_mode)}
 736      else
 737        _get_eval_string(v, enc_mode)
 738      end
 739    end
 740    private :ruby2tcl
 741  =end
 742 
 743  =begin
 744    ### --> definition is moved to TkUtil module
 745    def _conv_args(args, enc_mode, *src_args)
 746      conv_args = []
 747      src_args.each{|arg|
 748        conv_args << _get_eval_string(arg, enc_mode) unless arg == None
 749        # if arg.kind_of?(Hash)
 750        # arg.each{|k, v|
 751        #   args << '-' + k.to_s
 752        #   args << _get_eval_string(v, enc_mode)
 753        # }
 754        # elsif arg != None
 755        #   args << _get_eval_string(arg, enc_mode)
 756        # end
 757      }
 758      args + conv_args
 759    end
 760    private :_conv_args
 761  =end
 762 
 763    def _curr_cmd_id
 764      #id = format("c%.4d", Tk_IDs[0])
 765      id = "c" + TkCore::INTERP._ip_id_ + TkComm::Tk_IDs[0]
 766    end
 767    def _next_cmd_id
 768      TkComm::Tk_IDs.mutex.synchronize{
 769        id = _curr_cmd_id
 770        #Tk_IDs[0] += 1
 771        TkComm::Tk_IDs[0].succ!
 772        id
 773      }
 774    end
 775    private :_curr_cmd_id, :_next_cmd_id
 776    module_function :_curr_cmd_id, :_next_cmd_id
 777 
 778    def TkComm.install_cmd(cmd, local_cmdtbl=nil)
 779      return '' if cmd == ''
 780      begin
 781        ns = TkCore::INTERP._invoke_without_enc('namespace', 'current')
 782        ns = nil if ns == '::' # for backward compatibility
 783      rescue
 784        # probably, Tcl7.6
 785        ns = nil
 786      end
 787      id = _next_cmd_id
 788      #Tk_CMDTBL[id] = cmd
 789      if cmd.kind_of?(TkCallbackEntry)
 790        TkCore::INTERP.tk_cmd_tbl[id] = cmd
 791      else
 792        TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)
 793      end
 794      @cmdtbl = [] unless defined? @cmdtbl
 795      @cmdtbl.taint unless @cmdtbl.tainted?
 796      @cmdtbl.push id
 797 
 798      if local_cmdtbl && local_cmdtbl.kind_of?(Array)
 799        begin
 800          local_cmdtbl << id
 801        rescue Exception
 802          # ignore
 803        end
 804      end
 805 
 806      #return Kernel.format("rb_out %s", id);
 807      if ns
 808        'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id
 809      else
 810        'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id
 811      end
 812    end
 813    def TkComm.uninstall_cmd(id, local_cmdtbl=nil)
 814      #id = $1 if /rb_out\S* (c(_\d+_)?\d+)/ =~ id
 815      id = $4 if id =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
 816 
 817      if local_cmdtbl && local_cmdtbl.kind_of?(Array)
 818        begin
 819          local_cmdtbl.delete(id)
 820        rescue Exception
 821          # ignore
 822        end
 823      end
 824      @cmdtbl.delete(id)
 825 
 826      #Tk_CMDTBL.delete(id)
 827      TkCore::INTERP.tk_cmd_tbl.delete(id)
 828    end
 829    # private :install_cmd, :uninstall_cmd
 830    # module_function :install_cmd, :uninstall_cmd
 831    def install_cmd(cmd)
 832      TkComm.install_cmd(cmd, @cmdtbl)
 833    end
 834    def uninstall_cmd(id)
 835      TkComm.uninstall_cmd(id, @cmdtbl)
 836    end
 837 
 838  =begin
 839    def install_win(ppath,name=nil)
 840      if !name or name == ''
 841        #name = format("w%.4d", Tk_IDs[1])
 842        #Tk_IDs[1] += 1
 843        name = "w" + Tk_IDs[1]
 844        Tk_IDs[1].succ!
 845      end
 846      if name[0] == ?.
 847        @path = name.dup
 848      elsif !ppath or ppath == "."
 849        @path = Kernel.format(".%s", name);
 850      else
 851        @path = Kernel.format("%s.%s", ppath, name)
 852      end
 853      #Tk_WINDOWS[@path] = self
 854      TkCore::INTERP.tk_windows[@path] = self
 855    end
 856  =end
 857    def install_win(ppath,name=nil)
 858      if name
 859        if name == ''
 860          raise ArgumentError, "invalid wiget-name '#{name}'"
 861        end
 862        if name[0] == ?.
 863          @path = '' + name
 864          @path.freeze
 865          return TkCore::INTERP.tk_windows[@path] = self
 866        end
 867      else
 868        Tk_IDs.mutex.synchronize{
 869          name = "w" + TkCore::INTERP._ip_id_ + Tk_IDs[1]
 870          Tk_IDs[1].succ!
 871        }
 872      end
 873      if !ppath or ppath == '.'
 874        @path = '.' + name
 875      else
 876        @path = ppath + '.' + name
 877      end
 878      @path.freeze
 879      TkCore::INTERP.tk_windows[@path] = self
 880    end
 881 
 882    def uninstall_win()
 883      #Tk_WINDOWS.delete(@path)
 884      TkCore::INTERP.tk_windows.delete(@path)
 885    end
 886    private :install_win, :uninstall_win
 887 
 888    def _epath(win)
 889      if win.kind_of?(TkObject)
 890        win.epath
 891      elsif win.respond_to?(:epath)
 892        win.epath
 893      else
 894        win
 895      end
 896    end
 897    private :_epath
 898  end
 899 
 900  # define TkComm module (step 2: event binding)
 901  module TkComm
 902    include TkEvent
 903    extend TkEvent
 904 
 905    def tk_event_sequence(context)
 906      if context.kind_of? TkVirtualEvent
 907        context = context.path
 908      end
 909      if context.kind_of? Array
 910        context = context.collect{|ev|
 911          if ev.kind_of? TkVirtualEvent
 912            ev.path
 913          else
 914            ev
 915          end
 916        }.join("><")
 917      end
 918      if /,/ =~ context
 919        context = context.split(/\s*,\s*/).join("><")
 920      else
 921        context
 922      end
 923    end
 924 
 925    def _bind_core(mode, what, context, cmd, *args)
 926      id = install_bind(cmd, *args) if cmd
 927      begin
 928        tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", 
 929                                mode + id]))
 930      rescue
 931        uninstall_cmd(id) if cmd
 932        fail
 933      end
 934    end
 935 
 936    def _bind(what, context, cmd, *args)
 937      _bind_core('', what, context, cmd, *args)
 938    end
 939 
 940    def _bind_append(what, context, cmd, *args)
 941      _bind_core('+', what, context, cmd, *args)
 942    end
 943 
 944    def _bind_remove(what, context)
 945      tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", '']))
 946    end
 947 
 948    def _bindinfo(what, context=nil)
 949      if context
 950        if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!
 951          enum_obj = tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"]).each_line
 952        else
 953          enum_obj = tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"])
 954        end
 955        enum_obj.collect {|cmdline|
 956  =begin
 957          if cmdline =~ /^rb_out\S* (c(?:_\d+_)?\d+)\s+(.*)$/
 958            #[Tk_CMDTBL[$1], $2]
 959            [TkCore::INTERP.tk_cmd_tbl[$1], $2]
 960  =end
 961          if cmdline =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
 962            [TkCore::INTERP.tk_cmd_tbl[$4], $5]
 963          else
 964            cmdline
 965          end
 966        }
 967      else
 968        tk_split_simplelist(tk_call_without_enc(*what)).collect!{|seq|
 969          l = seq.scan(/<*[^<>]+>*/).collect!{|subseq|
 970            case (subseq)
 971            when /^<<[^<>]+>>$/
 972              TkVirtualEvent.getobj(subseq[1..-2])
 973            when /^<[^<>]+>$/
 974              subseq[1..-2]
 975            else
 976              subseq.split('')
 977            end
 978          }.flatten
 979          (l.size == 1) ? l[0] : l
 980        }
 981      end
 982    end
 983 
 984    def _bind_core_for_event_class(klass, mode, what, context, cmd, *args)
 985      id = install_bind_for_event_class(klass, cmd, *args) if cmd
 986      begin
 987        tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", 
 988                                mode + id]))
 989      rescue
 990        uninstall_cmd(id) if cmd
 991        fail
 992      end
 993    end
 994 
 995    def _bind_for_event_class(klass, what, context, cmd, *args)
 996      _bind_core_for_event_class(klass, '', what, context, cmd, *args)
 997    end
 998 
 999    def _bind_append_for_event_class(klass, what, context, cmd, *args)
1000      _bind_core_for_event_class(klass, '+', what, context, cmd, *args)
1001    end
1002 
1003    def _bind_remove_for_event_class(klass, what, context)
1004      _bind_remove(what, context)
1005    end
1006 
1007    def _bindinfo_for_event_class(klass, what, context=nil)
1008      _bindinfo(what, context)
1009    end
1010 
1011    private :tk_event_sequence
1012    private :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo
1013    private :_bind_core_for_event_class, :_bind_for_event_class, 
1014            :_bind_append_for_event_class, :_bind_remove_for_event_class, 
1015            :_bindinfo_for_event_class
1016 
1017    #def bind(tagOrClass, context, cmd=Proc.new, *args)
1018    #  _bind(["bind", tagOrClass], context, cmd, *args)
1019    #  tagOrClass
1020    #end
1021    def bind(tagOrClass, context, *args)
1022      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
1023      if TkComm._callback_entry?(args[0]) || !block_given?
1024        cmd = args.shift
1025      else
1026        cmd = Proc.new
1027      end
1028      _bind(["bind", tagOrClass], context, cmd, *args)
1029      tagOrClass
1030    end
1031 
1032    #def bind_append(tagOrClass, context, cmd=Proc.new, *args)
1033    #  _bind_append(["bind", tagOrClass], context, cmd, *args)
1034    #  tagOrClass
1035    #end
1036    def bind_append(tagOrClass, context, *args)
1037      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
1038      if TkComm._callback_entry?(args[0]) || !block_given?
1039        cmd = args.shift
1040      else
1041        cmd = Proc.new
1042      end
1043      _bind_append(["bind", tagOrClass], context, cmd, *args)
1044      tagOrClass
1045    end
1046 
1047    def bind_remove(tagOrClass, context)
1048      _bind_remove(['bind', tagOrClass], context)
1049      tagOrClass
1050    end
1051 
1052    def bindinfo(tagOrClass, context=nil)
1053      _bindinfo(['bind', tagOrClass], context)
1054    end
1055 
1056    #def bind_all(context, cmd=Proc.new, *args)
1057    #  _bind(['bind', 'all'], context, cmd, *args)
1058    #  TkBindTag::ALL
1059    #end
1060    def bind_all(context, *args)
1061      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
1062      if TkComm._callback_entry?(args[0]) || !block_given?
1063        cmd = args.shift
1064      else
1065        cmd = Proc.new
1066      end
1067      _bind(['bind', 'all'], context, cmd, *args)
1068      TkBindTag::ALL
1069    end
1070 
1071    #def bind_append_all(context, cmd=Proc.new, *args)
1072    #  _bind_append(['bind', 'all'], context, cmd, *args)
1073    #  TkBindTag::ALL
1074    #end
1075    def bind_append_all(context, *args)
1076      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
1077      if TkComm._callback_entry?(args[0]) || !block_given?
1078        cmd = args.shift
1079      else
1080        cmd = Proc.new
1081      end
1082      _bind_append(['bind', 'all'], context, cmd, *args)
1083      TkBindTag::ALL
1084    end
1085 
1086    def bind_remove_all(context)
1087      _bind_remove(['bind', 'all'], context)
1088      TkBindTag::ALL
1089    end
1090 
1091    def bindinfo_all(context=nil)
1092      _bindinfo(['bind', 'all'], context)
1093    end
1094  end
1095 
1096 
1097  module TkCore
1098    include TkComm
1099    extend TkComm
1100 
1101    WITH_RUBY_VM  = Object.const_defined?(:VM) && ::VM.class == Class
1102    WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
1103 
1104    unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
1105      ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!
1106      RUN_EVENTLOOP_ON_MAIN_THREAD = false
1107    end
1108 
1109    unless self.const_defined? :INTERP
1110      if self.const_defined? :IP_NAME
1111        name = IP_NAME.to_s
1112      else
1113        #name = nil
1114        name = $0
1115      end
1116      if self.const_defined? :IP_OPTS
1117        if IP_OPTS.kind_of?(Hash)
1118          opts = hash_kv(IP_OPTS).join(' ')
1119        else
1120          opts = IP_OPTS.to_s
1121        end
1122      else
1123        opts = ''
1124      end
1125 
1126      if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
1127        INTERP = TclTkIp.new(name, opts)
1128      else
1129        INTERP_MUTEX = Mutex.new
1130        INTERP_ROOT_CHECK = ConditionVariable.new
1131        INTERP_THREAD = Thread.new{
1132          begin
1133            Thread.current[:interp] = interp = TclTkIp.new(name, opts)
1134          rescue => e
1135            Thread.current[:interp] = e
1136            raise e
1137          end
1138          Thread.current[:status] = nil
1139          #sleep
1140 
1141          begin
1142            Thread.current[:status] = TclTkLib.mainloop(true)
1143          rescue Exception=>e
1144            Thread.current[:status] = e
1145          ensure
1146            INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
1147          end
1148          Thread.current[:status] = TclTkLib.mainloop(false)
1149        }
1150 
1151        until INTERP_THREAD[:interp]
1152          Thread.pass
1153        end
1154        # INTERP_THREAD.run
1155        raise INTERP_THREAD[:interp] if INTERP_THREAD[:interp].kind_of? Exception
1156 
1157        INTERP = INTERP_THREAD[:interp]
1158      end
1159 
1160      def INTERP.__getip
1161        self
1162      end
1163 
1164      INTERP.instance_eval{
1165        # @tk_cmd_tbl = {}.taint
1166        @tk_cmd_tbl = Hash.new{|hash, key|
1167          fail IndexError, "unknown command ID '#{key}'"
1168        }.taint
1169        def @tk_cmd_tbl.[]=(idx,val)
1170          if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default
1171            fail SecurityError,"cannot change the entried command"
1172          end
1173          super(idx,val)
1174        end
1175 
1176        @tk_windows = {}.taint
1177 
1178        @tk_table_list = [].taint
1179 
1180        @init_ip_env  = [].taint  # table of Procs
1181        @add_tk_procs = [].taint  # table of [name, args, body]
1182 
1183        @cb_entry_class = Class.new(TkCallbackEntry){
1184          class << self
1185            def inspect
1186              sprintf("#<Class(TkCallbackEntry):%0x>", self.__id__)
1187            end
1188            alias to_s inspect
1189          end
1190 
1191          def initialize(ip, cmd)
1192            @ip = ip
1193            @cmd = cmd
1194          end
1195          attr_reader :ip, :cmd
1196          def call(*args)
1197            @ip.cb_eval(@cmd, *args)
1198          end
1199          def inspect
1200            sprintf("#<cb_entry:%0x>", self.__id__)
1201          end
1202          alias to_s inspect
1203        }.freeze
1204      }
1205 
1206      def INTERP.cb_entry_class
1207        @cb_entry_class
1208      end
1209      def INTERP.tk_cmd_tbl
1210        @tk_cmd_tbl
1211      end
1212      def INTERP.tk_windows
1213        @tk_windows
1214      end
1215 
1216      class Tk_OBJECT_TABLE
1217        def initialize(id)
1218          @id = id
1219          @mutex = Mutex.new
1220        end
1221        def mutex
1222          @mutex
1223        end
1224        def method_missing(m, *args, &b)
1225          TkCore::INTERP.tk_object_table(@id).__send__(m, *args, &b)
1226        end
1227      end
1228 
1229      def INTERP.tk_object_table(id)
1230        @tk_table_list[id]
1231      end
1232      def INTERP.create_table
1233        id = @tk_table_list.size
1234        (tbl = {}).tainted? || tbl.taint
1235        @tk_table_list << tbl
1236  #      obj = Object.new
1237  #      obj.instance_eval <<-EOD
1238  #        def self.method_missing(m, *args)
1239  #         TkCore::INTERP.tk_object_table(#{id}).send(m, *args)
1240  #        end
1241  #      EOD
1242  #      return obj
1243        Tk_OBJECT_TABLE.new(id)
1244      end
1245 
1246      def INTERP.get_cb_entry(cmd)
1247        @cb_entry_class.new(__getip, cmd).freeze
1248      end
1249      def INTERP.cb_eval(cmd, *args)
1250        TkUtil._get_eval_string(TkUtil.eval_cmd(cmd, *args))
1251      end
1252 
1253      def INTERP.init_ip_env(script = Proc.new)
1254        @init_ip_env << script
1255        script.call(self)
1256      end
1257      def INTERP.add_tk_procs(name, args = nil, body = nil)
1258        if name.kind_of?(Array)
1259          name.each{|param| self.add_tk_procs(*param)}
1260        else
1261          name = name.to_s
1262          @add_tk_procs << [name, args, body]
1263          self._invoke('proc', name, args, body) if args && body
1264        end
1265      end
1266      def INTERP.remove_tk_procs(*names)
1267        names.each{|name|
1268          name = name.to_s
1269          @add_tk_procs.delete_if{|elem| 
1270            elem.kind_of?(Array) && elem[0].to_s == name
1271          }
1272          self._invoke('rename', name, '')
1273        }
1274      end
1275      def INTERP.init_ip_internal
1276        ip = self
1277        @init_ip_env.each{|script| script.call(ip)}
1278        @add_tk_procs.each{|name,args,body| ip._invoke('proc',name,args,body)}
1279      end
1280    end
1281 
1282    WIDGET_DESTROY_HOOK = '<WIDGET_DESTROY_HOOK>'
1283    INTERP._invoke_without_enc('event', 'add', 
1284                               "<#{WIDGET_DESTROY_HOOK}>", '<Destroy>')
1285    INTERP._invoke_without_enc('bind', 'all', "<#{WIDGET_DESTROY_HOOK}>",
1286                               install_cmd(proc{|path|
1287                                  unless TkCore::INTERP.deleted?
1288                                    begin
1289                                      if (widget=TkCore::INTERP.tk_windows[path])
1290                                        if widget.respond_to?(:__destroy_hook__)
1291                                          widget.__destroy_hook__
1292                                        end
1293                                      end
1294                                    rescue Exception=>e
1295                                        p e if $DEBUG
1296                                    end
1297                                  end
1298                               }) << ' %W')
1299 
1300    INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', 
1301                        "catch { bind all <#{WIDGET_DESTROY_HOOK}> {} }")
1302 
1303    INTERP.add_tk_procs('rb_out', 'ns args', <<-'EOL')
1304      if [regexp {^::} $ns] {
1305        set cmd {namespace eval $ns {ruby_cmd TkCore callback} $args}
1306      } else {
1307        set cmd {eval {ruby_cmd TkCore callback} $ns $args}
1308      }
1309      if {[set st [catch $cmd ret]] != 0} {
1310         #return -code $st $ret
1311         set idx [string first "\n\n" $ret]
1312         if {$idx > 0} {
1313            return -code $st \
1314                   -errorinfo [string range $ret [expr $idx + 2] \
1315                                                 [string length $ret]] \
1316                   [string range $ret 0 [expr $idx - 1]]
1317         } else {
1318            return -code $st $ret
1319         }
1320      } else {
1321          return $ret
1322      }
1323    EOL
1324  =begin
1325    INTERP.add_tk_procs('rb_out', 'args', <<-'EOL')
1326      if {[set st [catch {eval {ruby_cmd TkCore callback} $args} ret]] != 0} {
1327         #return -code $st $ret
1328         set idx [string first "\n\n" $ret]
1329         if {$idx > 0} {
1330            return -code $st \
1331                   -errorinfo [string range $ret [expr $idx + 2] \
1332                                                 [string length $ret]] \
1333                   [string range $ret 0 [expr $idx - 1]]
1334         } else {
1335            return -code $st $ret
1336         }
1337      } else {
1338          return $ret
1339      }
1340    EOL
1341  =end
1342  =begin
1343    INTERP.add_tk_procs('rb_out', 'args', <<-'EOL')
1344      #regsub -all {\\} $args {\\\\} args
1345      #regsub -all {!} $args {\\!} args
1346      #regsub -all "{" $args "\\{" args
1347      regsub -all {(\\|!|\{|\})} $args {\\\1} args
1348      if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {
1349         #return -code $st $ret
1350         set idx [string first "\n\n" $ret]
1351         if {$idx > 0} {
1352            return -code $st \
1353                   -errorinfo [string range $ret [expr $idx + 2] \
1354                                                 [string length $ret]] \
1355                   [string range $ret 0 [expr $idx - 1]]
1356         } else {
1357            return -code $st $ret
1358         }
1359      } else {
1360          return $ret
1361      }
1362    EOL
1363  =end
1364 
1365    at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) }
1366 
1367    EventFlag = TclTkLib::EventFlag
1368 
1369    def callback_break
1370      fail TkCallbackBreak, "Tk callback returns 'break' status"
1371    end
1372 
1373    def callback_continue
1374      fail TkCallbackContinue, "Tk callback returns 'continue' status"
1375    end
1376 
1377    def callback_return
1378      fail TkCallbackReturn, "Tk callback returns 'return' status"
1379    end
1380 
1381    def TkCore.callback(*arg)
1382      begin
1383        if TkCore::INTERP.tk_cmd_tbl.kind_of?(Hash)
1384          #TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)
1385          normal_ret = false
1386          ret = catch(:IRB_EXIT) do  # IRB hack
1387            retval = TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)
1388            normal_ret = true
1389            retval
1390          end
1391          unless normal_ret
1392            # catch IRB_EXIT
1393            exit(ret)
1394          end
1395          ret
1396        end
1397      rescue SystemExit=>e
1398        exit(e.status)
1399      rescue Interrupt=>e
1400        fail(e)
1401      rescue Exception => e
1402        begin
1403          msg = _toUTF8(e.class.inspect) + ': ' + 
1404                _toUTF8(e.message) + "\n" + 
1405                "\n---< backtrace of Ruby side >-----\n" + 
1406                _toUTF8(e.backtrace.join("\n")) + 
1407                "\n---< backtrace of Tk side >-------"
1408          if TkCore::WITH_ENCODING
1409            msg.force_encoding('utf-8')
1410          else
1411            msg.instance_variable_set(:@encoding, 'utf-8')
1412          end
1413        rescue Exception
1414          msg = e.class.inspect + ': ' + e.message + "\n" + 
1415                "\n---< backtrace of Ruby side >-----\n" + 
1416                e.backtrace.join("\n") + 
1417                "\n---< backtrace of Tk side >-------"
1418        end
1419        # TkCore::INTERP._set_global_var('errorInfo', msg)
1420        # fail(e)
1421        fail(e, msg)
1422      end
1423    end
1424  =begin
1425    def TkCore.callback(arg_str)
1426      # arg = tk_split_list(arg_str)
1427      arg = tk_split_simplelist(arg_str)
1428      #_get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg))
1429      #_get_eval_string(TkUtil.eval_cmd(TkCore::INTERP.tk_cmd_tbl[arg.shift], 
1430      #                        *arg))
1431      # TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)
1432      begin
1433        TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)
1434      rescue Exception => e
1435        raise(e, e.class.inspect + ': ' + e.message + "\n" + 
1436                 "\n---< backtrace of Ruby side >-----\n" + 
1437                 e.backtrace.join("\n") + 
1438                 "\n---< backtrace of Tk side >-------")
1439      end
1440  #=begin
1441  #    cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift]
1442  #    unless $DEBUG
1443  #      cb_obj.call(*arg)
1444  #    else
1445  #      begin
1446  #       raise 'check backtrace'
1447  #      rescue
1448  #       # ignore backtrace before 'callback'
1449  #       pos = -($!.backtrace.size)
1450  #      end
1451  #      begin
1452  #       cb_obj.call(*arg)
1453  #      rescue
1454  #       trace = $!.backtrace
1455  #       raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + 
1456  #                 "\tfrom #{trace[1..pos].join("\n\tfrom ")}"
1457  #      end
1458  #    end
1459  #=end
1460    end
1461  =end
1462 
1463    def load_cmd_on_ip(tk_cmd)
1464      bool(tk_call('auto_load', tk_cmd))
1465    end
1466 
1467    def after(ms, cmd=Proc.new)
1468      cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
1469      after_id = tk_call_without_enc("after",ms,cmdid)
1470      after_id.instance_variable_set('@cmdid', cmdid)
1471      after_id
1472    end
1473  =begin
1474    def after(ms, cmd=Proc.new)
1475      crit_bup = Thread.critical
1476      Thread.critical = true
1477 
1478      myid = _curr_cmd_id
1479      cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret})
1480 
1481      Thread.critical = crit_bup
1482 
1483      tk_call_without_enc("after",ms,cmdid)  # return id
1484  #    return
1485  #    if false #defined? Thread
1486  #      Thread.start do
1487  #       ms = Float(ms)/1000
1488  #       ms = 10 if ms == 0
1489  #       sleep ms/1000
1490  #       cmd.call
1491  #      end
1492  #    else
1493  #      cmdid = install_cmd(cmd)
1494  #      tk_call("after",ms,cmdid)
1495  #    end
1496    end
1497  =end
1498 
1499    def after_idle(cmd=Proc.new)
1500      cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
1501      after_id = tk_call_without_enc('after','idle',cmdid)
1502      after_id.instance_variable_set('@cmdid', cmdid)
1503      after_id
1504    end
1505  =begin
1506    def after_idle(cmd=Proc.new)
1507      crit_bup = Thread.critical
1508      Thread.critical = true
1509 
1510      myid = _curr_cmd_id
1511      cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret})
1512 
1513      Thread.critical = crit_bup
1514 
1515      tk_call_without_enc('after','idle',cmdid)
1516    end
1517  =end
1518 
1519    def after_cancel(afterId)
1520      tk_call_without_enc('after','cancel',afterId)
1521      if (cmdid = afterId.instance_variable_get('@cmdid'))
1522        afterId.instance_variable_set('@cmdid', nil)
1523        uninstall_cmd(cmdid)
1524      end
1525      afterId
1526    end
1527 
1528    def windowingsystem
1529      tk_call_without_enc('tk', 'windowingsystem')
1530    end
1531 
1532    def scaling(scale=nil)
1533      if scale
1534        tk_call_without_enc('tk', 'scaling', scale)
1535      else
1536        Float(number(tk_call_without_enc('tk', 'scaling')))
1537      end
1538    end
1539    def scaling_displayof(win, scale=nil)
1540      if scale
1541        tk_call_without_enc('tk', 'scaling', '-displayof', win, scale)
1542      else
1543        Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling')))
1544      end
1545    end
1546 
1547    def inactive
1548      Integer(tk_call_without_enc('tk', 'inactive'))
1549    end
1550    def inactive_displayof(win)
1551      Integer(tk_call_without_enc('tk', 'inactive', '-displayof', win))
1552    end
1553    def reset_inactive
1554      tk_call_without_enc('tk', 'inactive', 'reset')
1555    end
1556    def reset_inactive_displayof(win)
1557      tk_call_without_enc('tk', 'inactive', '-displayof', win, 'reset')
1558    end
1559 
1560    def appname(name=None)
1561      tk_call('tk', 'appname', name)
1562    end
1563 
1564    def appsend_deny
1565      tk_call('rename', 'send', '')
1566    end
1567 
1568    def appsend(interp, async, *args)
1569      if $SAFE >= 4
1570        fail SecurityError, "cannot send Tk commands at level 4"
1571      elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}
1572        fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}"
1573      end
1574      if async != true && async != false && async != nil
1575        args.unshift(async)
1576        async = false
1577      end
1578      if async
1579        tk_call('send', '-async', '--', interp, *args)
1580      else
1581        tk_call('send', '--', interp, *args)
1582      end
1583    end
1584 
1585    def rb_appsend(interp, async, *args)
1586      if $SAFE >= 4
1587        fail SecurityError, "cannot send Ruby commands at level 4"
1588      elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}
1589        fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}"
1590      end
1591      if async != true && async != false && async != nil
1592        args.unshift(async)
1593        async = false
1594      end
1595      #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')}
1596      args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')}
1597      # args.push(').to_s"')
1598      # appsend(interp, async, 'ruby "(', *args)
1599      args.push('}.call)"')
1600      appsend(interp, async, 'ruby "TkComm._get_eval_string(proc{', *args)
1601    end
1602 
1603    def appsend_displayof(interp, win, async, *args)
1604      if $SAFE >= 4
1605        fail SecurityError, "cannot send Tk commands at level 4"
1606      elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}
1607        fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}"
1608      end
1609      win = '.' if win == nil
1610      if async != true && async != false && async != nil
1611        args.unshift(async)
1612        async = false
1613      end
1614      if async
1615        tk_call('send', '-async', '-displayof', win, '--', interp, *args)
1616      else
1617        tk_call('send', '-displayor', win, '--', interp, *args)
1618      end
1619    end
1620 
1621    def rb_appsend_displayof(interp, win, async, *args)
1622      if $SAFE >= 4
1623        fail SecurityError, "cannot send Ruby commands at level 4"
1624      elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}
1625        fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}"
1626      end
1627      win = '.' if win == nil
1628      if async != true && async != false && async != nil
1629        args.unshift(async)
1630        async = false
1631      end
1632      #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')}
1633      args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')}
1634      # args.push(').to_s"')
1635      # appsend_displayof(interp, win, async, 'ruby "(', *args)
1636      args.push('}.call)"')
1637      appsend(interp, win, async, 'ruby "TkComm._get_eval_string(proc{', *args)
1638    end
1639 
1640    def info(*args)
1641      tk_call('info', *args)
1642    end
1643 
1644    def mainloop(check_root = true)
1645      if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
1646        TclTkLib.mainloop(check_root)
1647      else ### Ruby 1.9 !!!!!
1648        begin
1649          TclTkLib.set_eventloop_window_mode(true)
1650          if check_root
1651            INTERP_MUTEX.synchronize{
1652              INTERP_ROOT_CHECK.wait(INTERP_MUTEX)
1653              status = INTERP_THREAD[:status]
1654              if status
1655                INTERP_THREAD[:status] = nil
1656                raise status if status.kind_of?(Exception)
1657              end
1658            }
1659          else
1660            INTERP_THREAD.value
1661          end
1662        ensure
1663          TclTkLib.set_eventloop_window_mode(false)
1664        end
1665      end
1666    end
1667 
1668    def mainloop_thread?
1669      # true  : current thread is mainloop
1670      # nil   : there is no mainloop
1671      # false : mainloop is running on the other thread
1672      #         ( At then, it is dangerous to call Tk interpreter directly. )
1673      if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
1674        ### Ruby 1.9 !!!!!!!!!!!
1675        TclTkLib.mainloop_thread?
1676      else
1677        Thread.current == INTERP_THREAD
1678      end
1679    end
1680 
1681    def mainloop_exist?
1682      TclTkLib.mainloop_thread? != nil
1683    end
1684 
1685    def is_mainloop?
1686      TclTkLib.mainloop_thread? == true
1687    end
1688 
1689    def mainloop_watchdog(check_root = true)
1690      # watchdog restarts mainloop when mainloop is dead
1691      TclTkLib.mainloop_watchdog(check_root)
1692    end
1693 
1694    def do_one_event(flag = TclTkLib::EventFlag::ALL)
1695      TclTkLib.do_one_event(flag)
1696    end
1697 
1698    def set_eventloop_tick(timer_tick)
1699      TclTkLib.set_eventloop_tick(timer_tick)
1700    end
1701 
1702    def get_eventloop_tick()
1703      TclTkLib.get_eventloop_tick
1704    end
1705 
1706    def set_no_event_wait(wait)
1707      TclTkLib.set_no_even_wait(wait)
1708    end
1709 
1710    def get_no_event_wait()
1711      TclTkLib.get_no_eventloop_wait
1712    end
1713 
1714    def set_eventloop_weight(loop_max, no_event_tick)
1715      TclTkLib.set_eventloop_weight(loop_max, no_event_tick)
1716    end
1717 
1718    def get_eventloop_weight()
1719      TclTkLib.get_eventloop_weight
1720    end
1721 
1722    def restart(app_name = nil, keys = {})
1723      TkCore::INTERP.init_ip_internal
1724 
1725      tk_call('set', 'argv0', app_name) if app_name
1726      if keys.kind_of?(Hash)
1727        # tk_call('set', 'argc', keys.size * 2)
1728        tk_call('set', 'argv', hash_kv(keys).join(' '))
1729      end
1730 
1731      INTERP.restart
1732      nil
1733    end
1734 
1735    def event_generate(win, context, keys=nil)
1736      #win = win.path if win.kind_of?(TkObject)
1737      if context.kind_of?(TkEvent::Event)
1738        context.generate(win, ((keys)? keys: {}))
1739      elsif keys
1740        tk_call_without_enc('event', 'generate', win, 
1741                            "<#{tk_event_sequence(context)}>", 
1742                            *hash_kv(keys, true))
1743      else
1744        tk_call_without_enc('event', 'generate', win, 
1745                            "<#{tk_event_sequence(context)}>")
1746      end
1747      nil
1748    end
1749 
1750    def messageBox(keys)
1751      tk_call('tk_messageBox', *hash_kv(keys))
1752    end
1753 
1754    def getOpenFile(keys = nil)
1755      tk_call('tk_getOpenFile', *hash_kv(keys))
1756    end
1757    def getMultipleOpenFile(keys = nil)
1758      simplelist(tk_call('tk_getOpenFile', '-multiple', '1', *hash_kv(keys)))
1759    end
1760 
1761    def getSaveFile(keys = nil)
1762      tk_call('tk_getSaveFile', *hash_kv(keys))
1763    end
1764    def getMultipleSaveFile(keys = nil)
1765      simplelist(tk_call('tk_getSaveFile', '-multiple', '1', *hash_kv(keys)))
1766    end
1767 
1768    def chooseColor(keys = nil)
1769      tk_call('tk_chooseColor', *hash_kv(keys))
1770    end
1771 
1772    def chooseDirectory(keys = nil)
1773      tk_call('tk_chooseDirectory', *hash_kv(keys))
1774    end
1775 
1776    def _ip_eval_core(enc_mode, cmd_string)
1777      case enc_mode
1778      when nil
1779        res = INTERP._eval(cmd_string)
1780      when false
1781        res = INTERP._eval_without_enc(cmd_string)
1782      when true
1783        res = INTERP._eval_with_enc(cmd_string)
1784      end
1785      if  INTERP._return_value() != 0
1786        fail RuntimeError, res, error_at
1787      end
1788      return res
1789    end
1790    private :_ip_eval_core
1791 
1792    def ip_eval(cmd_string)
1793      _ip_eval_core(nil, cmd_string)
1794    end
1795 
1796    def ip_eval_without_enc(cmd_string)
1797      _ip_eval_core(false, cmd_string)
1798    end
1799 
1800    def ip_eval_with_enc(cmd_string)
1801      _ip_eval_core(true, cmd_string)
1802    end
1803 
1804    def _ip_invoke_core(enc_mode, *args)
1805      case enc_mode
1806      when false
1807        res = INTERP._invoke_without_enc(*args)
1808      when nil
1809        res = INTERP._invoke(*args)
1810      when true
1811        res = INTERP._invoke_with_enc(*args)
1812      end
1813      if  INTERP._return_value() != 0
1814        fail RuntimeError, res, error_at
1815      end
1816      return res
1817    end
1818    private :_ip_invoke_core
1819 
1820    def ip_invoke(*args)
1821      _ip_invoke_core(nil, *args)
1822    end
1823 
1824    def ip_invoke_without_enc(*args)
1825      _ip_invoke_core(false, *args)
1826    end
1827 
1828    def ip_invoke_with_enc(*args)
1829      _ip_invoke_core(true, *args)
1830    end
1831 
1832    def _tk_call_core(enc_mode, *args)
1833      ### puts args.inspect if $DEBUG
1834      #args.collect! {|x|ruby2tcl(x, enc_mode)}
1835      #args.compact!
1836      #args.flatten!
1837      args = _conv_args([], enc_mode, *args)
1838      puts 'invoke args => ' + args.inspect if $DEBUG
1839      ### print "=> ", args.join(" ").inspect, "\n" if $DEBUG
1840      begin
1841        # res = INTERP._invoke(*args).taint
1842        # res = INTERP._invoke(enc_mode, *args)
1843        res = _ip_invoke_core(enc_mode, *args)
1844        # >>>>>  _invoke returns a TAINTED string  <<<<<
1845      rescue NameError => err
1846        # err = $!
1847        begin
1848          args.unshift "unknown"
1849          #res = INTERP._invoke(*args).taint 
1850          #res = INTERP._invoke(enc_mode, *args) 
1851          res = _ip_invoke_core(enc_mode, *args) 
1852          # >>>>>  _invoke returns a TAINTED string  <<<<<
1853        rescue StandardError => err2
1854          fail err2 unless /^invalid command/ =~ err2.message
1855          fail err
1856        end
1857      end
1858      if  INTERP._return_value() != 0
1859        fail RuntimeError, res, error_at
1860      end
1861      ### print "==> ", res.inspect, "\n" if $DEBUG
1862      return res
1863    end
1864    private :_tk_call_core
1865 
1866    def tk_call(*args)
1867      _tk_call_core(nil, *args)
1868    end
1869 
1870    def tk_call_without_enc(*args)
1871      _tk_call_core(false, *args)
1872    end
1873 
1874    def tk_call_with_enc(*args)
1875      _tk_call_core(true, *args)
1876    end
1877 
1878    def _tk_call_to_list_core(depth, arg_enc, val_enc, *args)
1879      args = _conv_args([], arg_enc, *args)
1880      val = _tk_call_core(false, *args)
1881      if !depth.kind_of?(Integer) || depth == 0
1882        tk_split_simplelist(val, false, val_enc)
1883      else
1884        tk_split_list(val, depth, false, val_enc)
1885      end
1886    end
1887    #private :_tk_call_to_list_core
1888 
1889    def tk_call_to_list(*args)
1890      _tk_call_to_list_core(-1, nil, true, *args)
1891    end
1892 
1893    def tk_call_to_list_without_enc(*args)
1894      _tk_call_to_list_core(-1, false, false, *args)
1895    end
1896 
1897    def tk_call_to_list_with_enc(*args)
1898      _tk_call_to_list_core(-1, true, true, *args)
1899    end
1900 
1901    def tk_call_to_simplelist(*args)
1902      _tk_call_to_list_core(0, nil, true, *args)
1903    end
1904 
1905    def tk_call_to_simplelist_without_enc(*args)
1906      _tk_call_to_list_core(0, false, false, *args)
1907    end
1908 
1909    def tk_call_to_simplelist_with_enc(*args)
1910      _tk_call_to_list_core(0, true, true, *args)
1911    end
1912  end
1913 
1914 
1915  module Tk
1916    include TkCore
1917    extend Tk
1918 
1919    TCL_VERSION = INTERP._invoke_without_enc("info", "tclversion").freeze
1920    TCL_PATCHLEVEL = INTERP._invoke_without_enc("info", "patchlevel").freeze
1921 
1922    major, minor = TCL_VERSION.split('.')
1923    TCL_MAJOR_VERSION = major.to_i
1924    TCL_MINOR_VERSION = minor.to_i
1925 
1926    TK_VERSION  = INTERP._invoke_without_enc("set", "tk_version").freeze
1927    TK_PATCHLEVEL  = INTERP._invoke_without_enc("set", "tk_patchLevel").freeze
1928 
1929    major, minor = TK_VERSION.split('.')
1930    TK_MAJOR_VERSION = major.to_i
1931    TK_MINOR_VERSION = minor.to_i
1932 
1933    JAPANIZED_TK = (INTERP._invoke_without_enc("info", "commands", 
1934                                               "kanji") != "").freeze
1935 
1936    def Tk.const_missing(sym)
1937      case(sym)
1938      when :TCL_LIBRARY
1939        INTERP._invoke_without_enc('global', 'tcl_library')
1940        INTERP._invoke("set", "tcl_library").freeze
1941 
1942      when :TK_LIBRARY
1943        INTERP._invoke_without_enc('global', 'tk_library')
1944        INTERP._invoke("set", "tk_library").freeze
1945 
1946      when :LIBRARY
1947        INTERP._invoke("info", "library").freeze
1948 
1949      #when :PKG_PATH, :PACKAGE_PATH, :TCL_PACKAGE_PATH
1950      #  INTERP._invoke_without_enc('global', 'tcl_pkgPath')
1951      #  tk_split_simplelist(INTERP._invoke('set', 'tcl_pkgPath'))
1952 
1953      #when :LIB_PATH, :LIBRARY_PATH, :TCL_LIBRARY_PATH
1954      #  INTERP._invoke_without_enc('global', 'tcl_libPath')
1955      #  tk_split_simplelist(INTERP._invoke('set', 'tcl_libPath'))
1956 
1957      when :PLATFORM, :TCL_PLATFORM
1958        if $SAFE >= 4
1959          fail SecurityError, "can't get #{sym} when $SAFE >= 4"
1960        end
1961        INTERP._invoke_without_enc('global', 'tcl_platform')
1962        Hash[*tk_split_simplelist(INTERP._invoke_without_enc('array', 'get', 
1963                                                             'tcl_platform'))]
1964 
1965      when :ENV
1966        INTERP._invoke_without_enc('global', 'env')
1967        Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'env'))]
1968 
1969      #when :AUTO_PATH   #<=== 
1970      #  tk_split_simplelist(INTERP._invoke('set', 'auto_path'))
1971 
1972      #when :AUTO_OLDPATH
1973      #  tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath'))
1974 
1975      when :AUTO_INDEX
1976        INTERP._invoke_without_enc('global', 'auto_index')
1977        Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'auto_index'))]
1978 
1979      when :PRIV, :PRIVATE, :TK_PRIV
1980        priv = {}
1981        if INTERP._invoke_without_enc('info', 'vars', 'tk::Priv') != ""
1982          var_nam = 'tk::Priv'
1983        else
1984          var_nam = 'tkPriv'
1985        end
1986        INTERP._invoke_without_enc('global', var_nam)
1987        Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 
1988                                                 var_nam))].each{|k,v|
1989          k.freeze
1990          case v
1991          when /^-?\d+$/
1992            priv[k] = v.to_i
1993          when /^-?\d+\.?\d*(e[-+]?\d+)?$/
1994            priv[k] = v.to_f
1995          else
1996            priv[k] = v.freeze
1997          end
1998        }
1999        priv
2000 
2001      else
2002        raise NameError, 'uninitialized constant Tk::' + sym.id2name
2003      end
2004    end
2005 
2006    def Tk.errorInfo
2007      INTERP._invoke_without_enc('global', 'errorInfo')
2008      INTERP._invoke_without_enc('set', 'errorInfo')
2009    end
2010 
2011    def Tk.errorCode
2012      INTERP._invoke_without_enc('global', 'errorCode')
2013      code = tk_split_simplelist(INTERP._invoke_without_enc('set', 'errorCode'))
2014      case code[0]
2015      when 'CHILDKILLED', 'CHILDSTATUS', 'CHILDSUSP'
2016        begin
2017          pid = Integer(code[1])
2018          code[1] = pid
2019        rescue
2020        end
2021      end
2022      code
2023    end
2024 
2025    def Tk.has_mainwindow?
2026      INTERP.has_mainwindow?
2027    end
2028 
2029    def root
2030      Tk::Root.new
2031    end
2032 
2033    def Tk.load_tclscript(file, enc=nil)
2034      if enc
2035        # TCL_VERSION >= 8.5
2036        tk_call('source', '-encoding', enc, file)
2037      else
2038        tk_call('source', file)
2039      end
2040    end
2041 
2042    def Tk.load_tcllibrary(file, pkg_name=None, interp=None)
2043      tk_call('load', file, pkg_name, interp)
2044    end
2045 
2046    def Tk.unload_tcllibrary(*args)
2047      if args[-1].kind_of?(Hash)
2048        keys = _symbolkey2str(args.pop)
2049        nocomp = (keys['nocomplain'])? '-nocomplain': None
2050        keeplib = (keys['keeplibrary'])? '-keeplibrary': None
2051        tk_call('unload', nocomp, keeplib, '--', *args)
2052      else
2053        tk_call('unload', *args)
2054      end
2055    end
2056 
2057    def Tk.pkgconfig_list(mod)
2058      # Tk8.5 feature
2059      if mod.kind_of?(Module)
2060        if mod.respond_to?(:package_name)
2061          pkgname = mod.package_name
2062        elsif mod.const_defined?(:PACKAGE_NAME)
2063          pkgname = mod::PACKAGE_NAME
2064        else
2065          fail NotImplementedError, 'may not be a module for a Tcl extension'
2066        end
2067      else
2068        pkgname = mod.to_s
2069      end
2070 
2071      pkgname = '::' << pkgname unless pkgname =~ /^::/
2072 
2073      tk_split_list(tk_call(pkgname + '::pkgconfig', 'list'))
2074    end
2075 
2076    def Tk.pkgconfig_get(mod, key)
2077      # Tk8.5 feature
2078      if mod.kind_of?(Module)
2079        if mod.respond_to?(:package_name)
2080          pkgname = mod.package_name
2081        else
2082          fail NotImplementedError, 'may not be a module for a Tcl extension'
2083        end
2084      else
2085        pkgname = mod.to_s
2086      end
2087 
2088      pkgname = '::' << pkgname unless pkgname =~ /^::/
2089 
2090      tk_call(pkgname + '::pkgconfig', 'get', key)
2091    end
2092 
2093    def Tk.tcl_pkgconfig_list
2094      # Tk8.5 feature
2095      Tk.pkgconfig_list('::tcl')
2096    end
2097 
2098    def Tk.tcl_pkgconfig_get(key)
2099      # Tk8.5 feature
2100      Tk.pkgconfig_get('::tcl', key)
2101    end
2102 
2103    def Tk.tk_pkgconfig_list
2104      # Tk8.5 feature
2105      Tk.pkgconfig_list('::tk')
2106    end
2107 
2108    def Tk.tk_pkgconfig_get(key)
2109      # Tk8.5 feature
2110      Tk.pkgconfig_get('::tk', key)
2111    end
2112 
2113    def Tk.bell(nice = false)
2114      if nice
2115        tk_call_without_enc('bell', '-nice')
2116      else
2117        tk_call_without_enc('bell')
2118      end
2119      nil
2120    end
2121 
2122    def Tk.bell_on_display(win, nice = false)
2123      if nice
2124        tk_call_without_enc('bell', '-displayof', win, '-nice')
2125      else
2126        tk_call_without_enc('bell', '-displayof', win)
2127      end
2128      nil
2129    end
2130 
2131    def Tk.destroy(*wins)
2132      #tk_call_without_enc('destroy', *wins)
2133      tk_call_without_enc('destroy', *(wins.collect{|win|
2134                                         if win.kind_of?(TkWindow)
2135                                           win.epath
2136                                         else
2137                                           win
2138                                         end
2139                                       }))
2140    end
2141 
2142    def Tk.exit
2143      tk_call_without_enc('destroy', '.')
2144    end
2145 
2146    ################################################
2147 
2148    def Tk.sleep(ms = nil, id = nil)
2149      if id
2150        var = (id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s)
2151      else
2152        var = TkVariable.new
2153      end
2154 
2155      var.value = tk_call_without_enc('after', ms, proc{ var.value = 0 }) if ms
2156      var.thread_wait
2157      ms
2158    end
2159 
2160    def Tk.wakeup(id)
2161      ((id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s)).value = 0
2162      nil
2163    end
2164 
2165    ################################################
2166 
2167    def Tk.pack(*args)
2168      TkPack.configure(*args)
2169    end
2170    def Tk.pack_forget(*args)
2171      TkPack.forget(*args)
2172    end
2173    def Tk.unpack(*args)
2174      TkPack.forget(*args)
2175    end
2176 
2177    def Tk.grid(*args)
2178      TkGrid.configure(*args)
2179    end
2180    def Tk.grid_forget(*args)
2181      TkGrid.forget(*args)
2182    end
2183    def Tk.ungrid(*args)
2184      TkGrid.forget(*args)
2185    end
2186 
2187    def Tk.place(*args)
2188      TkPlace.configure(*args)
2189    end
2190    def Tk.place_forget(*args)
2191      TkPlace.forget(*args)
2192    end
2193    def Tk.unplace(*args)
2194      TkPlace.forget(*args)
2195    end
2196 
2197    def Tk.update(idle=nil)
2198      if idle
2199        tk_call_without_enc('update', 'idletasks')
2200      else
2201        tk_call_without_enc('update')
2202      end
2203    end
2204    def Tk.update_idletasks
2205      update(true)
2206    end
2207    def update(idle=nil)
2208      # only for backward compatibility (This never be recommended to use)
2209      Tk.update(idle)
2210      self
2211    end
2212 
2213    # NOTE::
2214    #   If no eventloop-thread is running, "thread_update" method is same 
2215    #   to "update" method. Else, "thread_update" method waits to complete 
2216    #   idletask operation on the eventloop-thread. 
2217    def Tk.thread_update(idle=nil)
2218      if idle
2219        tk_call_without_enc('thread_update', 'idletasks')
2220      else
2221        tk_call_without_enc('thread_update')
2222      end
2223    end
2224    def Tk.thread_update_idletasks
2225      thread_update(true)
2226    end
2227 
2228    def Tk.lower_window(win, below=None)
2229      tk_call('lower', _epath(win), _epath(below))
2230      nil
2231    end
2232    def Tk.raise_window(win, above=None)
2233      tk_call('raise', _epath(win), _epath(above))
2234      nil
2235    end
2236 
2237    def Tk.current_grabs(win = nil)
2238      if win
2239        window(tk_call_without_enc('grab', 'current', win))
2240      else
2241        tk_split_list(tk_call_without_enc('grab', 'current'))
2242      end
2243    end
2244 
2245    def Tk.focus(display=nil)
2246      if display == nil
2247        window(tk_call_without_enc('focus'))
2248      else
2249        window(tk_call_without_enc('focus', '-displayof', display))
2250      end
2251    end
2252 
2253    def Tk.focus_to(win, force=false)
2254      if force
2255        tk_call_without_enc('focus', '-force', win)
2256      else
2257        tk_call_without_enc('focus', win)
2258      end
2259    end
2260 
2261    def Tk.focus_lastfor(win)
2262      window(tk_call_without_enc('focus', '-lastfor', win))
2263    end
2264 
2265    def Tk.focus_next(win)
2266      TkManageFocus.next(win)
2267    end
2268 
2269    def Tk.focus_prev(win)
2270      TkManageFocus.prev(win)
2271    end
2272 
2273    def Tk.strictMotif(mode=None)
2274      bool(tk_call_without_enc('set', 'tk_strictMotif', mode))
2275    end
2276 
2277    def Tk.show_kinsoku(mode='both')
2278      begin
2279        if /^8\.*/ === TK_VERSION  && JAPANIZED_TK
2280          tk_split_simplelist(tk_call('kinsoku', 'show', mode))
2281        end
2282      rescue
2283      end
2284    end
2285    def Tk.add_kinsoku(chars, mode='both')
2286      begin
2287        if /^8\.*/ === TK_VERSION  && JAPANIZED_TK
2288          tk_split_simplelist(tk_call('kinsoku', 'add', mode, 
2289                                      *(chars.split(''))))
2290        else
2291          []
2292        end
2293      rescue
2294        []
2295      end
2296    end
2297    def Tk.delete_kinsoku(chars, mode='both')
2298      begin
2299        if /^8\.*/ === TK_VERSION  && JAPANIZED_TK
2300          tk_split_simplelist(tk_call('kinsoku', 'delete', mode, 
2301                              *(chars.split(''))))
2302        end
2303      rescue
2304      end
2305    end
2306 
2307    def Tk.toUTF8(str, encoding = nil)
2308      _toUTF8(str, encoding)
2309    end
2310    
2311    def Tk.fromUTF8(str, encoding = nil)
2312      _fromUTF8(str, encoding)
2313    end
2314  end
2315 
2316  ###########################################
2317  #  string with Tcl's encoding
2318  ###########################################
2319  module Tk
2320    def Tk.subst_utf_backslash(str)
2321      Tk::EncodedString.subst_utf_backslash(str)
2322    end
2323    def Tk.subst_tk_backslash(str)
2324      Tk::EncodedString.subst_tk_backslash(str)
2325    end
2326    def Tk.utf_to_backslash_sequence(str)
2327      Tk::EncodedString.utf_to_backslash_sequence(str)
2328    end
2329    def Tk.utf_to_backslash(str)
2330      Tk::EncodedString.utf_to_backslash_sequence(str)
2331    end
2332    def Tk.to_backslash_sequence(str)
2333      Tk::EncodedString.to_backslash_sequence(str)
2334    end
2335  end
2336 
2337 
2338  ###########################################
2339  #  convert kanji string to/from utf-8
2340  ###########################################
2341  if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
2342    module Tk
2343      module Encoding
2344        extend Encoding
2345 
2346        TkCommandNames = ['encoding'.freeze].freeze
2347 
2348        #############################################
2349 
2350        if TkCore::WITH_ENCODING ### Ruby 1.9
2351          RubyEncoding = ::Encoding
2352 
2353          # for saving GC cost
2354          #ENCNAMES_CMD = ['encoding'.freeze, 'names'.freeze]
2355          BINARY_NAME  = 'binary'.freeze
2356          UTF8_NAME    = 'utf-8'.freeze
2357          DEFAULT_EXTERNAL_NAME = RubyEncoding.default_external.name.freeze
2358 
2359          BINARY  = RubyEncoding.find(BINARY_NAME)
2360          UNKNOWN = RubyEncoding.find('ASCII-8BIT')
2361 
2362          ### start of creating ENCODING_TABLE
2363          ENCODING_TABLE = TkCore::INTERP.encoding_table
2364  =begin
2365          ENCODING_TABLE = {
2366            'binary'       => BINARY, 
2367            # 'UNKNOWN-8BIT' => UNKNOWN, 
2368          }
2369 
2370          list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 
2371                                                    ENCNAMES_CMD[1])
2372          TkCore::INTERP._split_tklist(list).each{|name|
2373            begin
2374              enc = RubyEncoding.find(name)
2375            rescue ArgumentError
2376              case name
2377              when 'identity'
2378                enc = BINARY
2379              when 'shiftjis'
2380                enc = RubyEncoding.find('Shift_JIS')
2381              when 'unicode'
2382                enc = RubyEncoding.find('UTF-8')
2383                #if Tk.tk_call('set', 'tcl_platform(byteOrder)') =='littleEndian'
2384                #  enc = RubyEncoding.find('UTF-16LE')
2385                #else
2386                #  enc = RubyEncoding.find('UTF-16BE')
2387                #end
2388              when 'symbol'
2389                # single byte data
2390                enc = RubyEncoding.find('ASCII-8BIT') ### ???
2391              else
2392                # unsupported on Ruby, but supported on Tk
2393                enc = TkCore::INTERP.create_dummy_encoding_for_tk(name)
2394              end
2395            end
2396            ENCODING_TABLE[name.freeze] = enc
2397          }
2398  =end
2399  =begin
2400          def ENCODING_TABLE.get_name(enc)
2401            orig_enc = enc
2402 
2403            # unles enc, use system default
2404            #  1st: Ruby/Tk default encoding
2405            #  2nd: Tcl/Tk default encoding
2406            #  3rd: Ruby's default_external
2407            enc ||= TkCore::INTERP.encoding
2408            enc ||= TclTkLib.encoding_system
2409            enc ||= DEFAULT_EXTERNAL_NAME
2410 
2411            if enc.kind_of?(RubyEncoding)
2412              # Ruby's Encoding object
2413              if (name = self.key(enc))
2414                return name
2415              end
2416 
2417              # Is it new ?
2418              list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 
2419                                                        ENCNAMES_CMD[1])
2420              TkComm.simplelist(list).each{|name|
2421                if ((enc == RubyEncoding.find(name)) rescue false)
2422                  # new relation!! update table
2423                  self[name.freeze] = enc
2424                  return name
2425                end
2426              }
2427            else
2428              # String or Symbol ?
2429              if self[name = enc.to_s]
2430                return name
2431              end
2432 
2433              # Is it new ?
2434              if (enc_obj = (RubyEncoding.find(name) rescue false))
2435                list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 
2436                                                          ENCNAMES_CMD[1])
2437                if TkComm.simplelist(list).index(name)
2438                  # Tk's encoding name ?
2439                  self[name.freeze] = enc_obj  # new relation!! update table
2440                  return name
2441                else
2442                  # Ruby's encoding name ?
2443                  if (name = self.key(enc_obj))
2444                    return name
2445                  end
2446                end
2447              end
2448            end
2449 
2450            fail ArgumentError, "unsupported Tk encoding '#{orig_enc}'"
2451          end
2452 
2453          def ENCODING_TABLE.get_obj(enc)
2454            # returns the encoding object.
2455            # If 'enc' is the encoding name on Tk only, it returns nil.
2456            ((obj = self[self.get_name(enc)]).kind_of?(RubyEncoding))? obj: nil
2457          end
2458  =end
2459          ### end of creating ENCODING_TABLE
2460 
2461        end
2462 
2463        #############################################
2464 
2465        if TkCore::WITH_ENCODING
2466          ################################
2467          ### Ruby 1.9
2468          ################################
2469          def force_default_encoding(mode)
2470            TkCore::INTERP.force_default_encoding = mode
2471          end
2472 
2473          def force_default_encoding?
2474            TkCore::INTERP.force_default_encoding?
2475          end
2476 
2477          def default_encoding=(enc)
2478            TkCore::INTERP.default_encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc)
2479          end
2480 
2481          def encoding=(enc)
2482            TkCore::INTERP.encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc)
2483          end
2484 
2485          def encoding_name
2486            Tk::Encoding::ENCODING_TABLE.get_name(TkCore::INTERP.encoding)
2487          end
2488          def encoding_obj
2489            Tk::Encoding::ENCODING_TABLE.get_obj(TkCore::INTERP.encoding)
2490          end
2491          alias encoding encoding_name
2492          alias default_encoding encoding_name
2493 
2494          def tk_encoding_names
2495            TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1]))
2496         end
2497          def encoding_names
2498            self.tk_encoding_names.find_all{|name|
2499              Tk::Encoding::ENCODING_TABLE.get_name(name) rescue false
2500            }
2501          end
2502          def encoding_objs
2503            self.tk_encoding_names.map!{|name|
2504              Tk::Encoding::ENCODING_TABLE.get_obj(name) rescue nil
2505            }.compact
2506          end
2507 
2508          def encoding_system=(enc)
2509            TclTkLib.encoding_system = Tk::Encoding::ENCODING_TABLE.get_name(enc)
2510          end
2511 
2512          def encoding_system_name
2513            Tk::Encoding::ENCODING_TABLE.get_name(TclTkLib.encoding_system)
2514          end
2515          def encoding_system_obj
2516            Tk::Encoding::ENCODING_TABLE.get_obj(TclTkLib.encoding_system)
2517          end
2518          alias encoding_system encoding_system_name
2519 
2520          ################################
2521        else
2522          ################################
2523          ### Ruby 1.8-
2524          ################################
2525          def force_default_encoding=(mode)
2526            true
2527          end
2528 
2529          def force_default_encoding?
2530            true
2531          end
2532 
2533          def default_encoding=(enc)
2534            TkCore::INTERP.default_encoding = enc
2535          end
2536 
2537          def encoding=(enc)
2538            TkCore::INTERP.encoding = enc
2539          end
2540 
2541          def encoding_obj
2542            TkCore::INTERP.encoding
2543          end
2544          def encoding_name
2545            TkCore::INTERP.encoding
2546          end
2547          alias encoding encoding_name
2548          alias default_encoding encoding_name
2549 
2550          def tk_encoding_names
2551            TkComm.simplelist(Tk.tk_call('encoding', 'names'))
2552          end
2553          def encoding_objs
2554            self.tk_encoding_names
2555          end
2556          def encoding_names
2557            self.tk_encoding_names
2558          end
2559 
2560          def encoding_system=(enc)
2561            TclTkLib.encoding_system = enc
2562          end
2563 
2564          def encoding_system_name
2565            TclTkLib.encoding_system
2566          end
2567          def encoding_system_obj
2568            TclTkLib.encoding_system
2569          end
2570          alias encoding_system encoding_system_name
2571 
2572          ################################
2573        end
2574 
2575        def encoding_convertfrom(str, enc=nil)
2576          enc = encoding_system_name unless enc
2577          str = str.dup
2578          if TkCore::WITH_ENCODING
2579            if str.kind_of?(Tk::EncodedString)
2580              str.__instance_variable_set('@encoding', nil)
2581            else
2582              str.instance_variable_set('@encoding', nil)
2583            end
2584            str.force_encoding('binary')
2585          else
2586            str.instance_variable_set('@encoding', 'binary')
2587          end
2588          ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertfrom', 
2589                                                   enc, str)
2590          if TkCore::WITH_ENCODING
2591            ret.force_encoding('utf-8')
2592          else
2593            Tk::UTF8_String.new(ret)
2594          end
2595          ret
2596        end
2597        alias encoding_convert_from encoding_convertfrom
2598 
2599        def encoding_convertto(str, enc=nil)
2600          # str must be a UTF-8 string
2601          enc = encoding_system_name unless enc
2602          ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertto', 
2603                                                   enc, str)
2604          #ret.instance_variable_set('@encoding', 'binary')
2605          if TkCore::WITH_ENCODING
2606            #ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj('binary'))
2607            ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc))
2608          end
2609          ret
2610        end
2611        alias encoding_convert_to encoding_convertto
2612 
2613        def encoding_dirs
2614          # Tcl8.5 feature
2615          TkComm.simplelist(Tk.tk_call_without_enc('encoding', 'dirs'))
2616        end
2617 
2618        def encoding_dirs=(dir_list) # an array or a Tcl's list string
2619          # Tcl8.5 feature
2620          Tk.tk_call_without_enc('encoding', 'dirs', dir_list)
2621        end
2622      end
2623 
2624      extend Encoding
2625    end
2626 
2627    class TclTkIp
2628      def force_default_encoding=(mode)
2629        @force_default_encoding = (mode)? true: false
2630      end
2631 
2632      def force_default_encoding?
2633        @force_default_encoding ||= false
2634      end
2635 
2636      def default_encoding=(name)
2637        name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING
2638        @encoding = name
2639      end
2640 
2641      # from tkencoding.rb by ttate@jaist.ac.jp
2642      #attr_accessor :encoding
2643      def encoding=(name)
2644        self.force_default_encoding = true  # for comaptibility
2645        self.default_encoding = name
2646      end
2647 
2648      def encoding_name
2649        (@encoding)? @encoding.dup: nil
2650      end
2651      alias encoding encoding_name
2652      alias default_encoding encoding_name
2653 
2654      def encoding_obj
2655        if Tk::WITH_ENCODING
2656          Tk::Encoding.tcl2rb_encoding(@encoding)
2657        else
2658          (@encoding)? @encoding.dup: nil
2659        end
2660      end
2661 
2662      alias __toUTF8 _toUTF8
2663      alias __fromUTF8 _fromUTF8
2664 
2665      if Object.const_defined?(:Encoding) && ::Encoding.class == Class
2666        # with Encoding (Ruby 1.9+)
2667        #
2668        # use functions on Tcl as default.
2669        # but when unsupported encoding on Tcl, use methods on Ruby.
2670        #
2671        def _toUTF8(str, enc = nil)
2672          if enc
2673            # use given encoding
2674            begin
2675              enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc)
2676            rescue
2677              # unknown encoding for Tk -> try to convert encoding on Ruby
2678              str = str.dup.force_encoding(enc)
2679              str.encode!(Tk::Encoding::UTF8_NAME) # modify self !!
2680              return str  # if no error, probably succeed converting
2681            end
2682          end
2683 
2684          enc_name ||= str.instance_variable_get(:@encoding)
2685 
2686          enc_name ||= 
2687            Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil
2688 
2689          unless enc_name
2690            # str.encoding isn't supported by Tk -> try to convert on Ruby
2691            begin
2692              return str.encode(Tk::Encoding::UTF8_NAME) # new string
2693            rescue
2694              # error -> ignore, try to use default encoding of Ruby/Tk
2695            end
2696          end
2697 
2698          #enc_name ||= 
2699          #  Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding) rescue nil
2700          enc_name ||= Tk::Encoding::ENCODING_TABLE.get_name(nil)
2701 
2702          # is 'binary' encoding?
2703          if enc_name == Tk::Encoding::BINARY_NAME
2704            return str.dup.force_encoding(Tk::Encoding::BINARY_NAME)
2705          end
2706 
2707          # force default encoding?
2708          if ! str.kind_of?(Tk::EncodedString) && self.force_default_encoding?
2709            enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.default_encoding)
2710          end
2711 
2712          encstr = __toUTF8(str, enc_name)
2713          encstr.force_encoding(Tk::Encoding::UTF8_NAME)
2714          encstr
2715        end
2716        def _fromUTF8(str, enc = nil)
2717          # str must be UTF-8 or binary.
2718          enc_name = str.instance_variable_get(:@encoding)
2719          enc_name ||= 
2720            Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil
2721 
2722          # is 'binary' encoding?
2723          if enc_name == Tk::Encoding::BINARY_NAME
2724            return str.dup.force_encoding(Tk::Encoding::BINARY_NAME)
2725          end
2726 
2727          # get target encoding name (if enc == nil, use default encoding)
2728          begin
2729            enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc)
2730          rescue
2731            # then, enc != nil
2732            # unknown encoding for Tk -> try to convert encoding on Ruby
2733            str = str.dup.force_encoding(Tk::Encoding::UTF8_NAME)
2734            str.encode!(enc) # modify self !!
2735            return str  # if no error, probably succeed converting
2736          end
2737 
2738          encstr = __fromUTF8(str, enc_name)
2739          encstr.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc_name))
2740          encstr
2741        end
2742        ###
2743      else
2744        # without Encoding (Ruby 1.8)
2745        def _toUTF8(str, encoding = nil)
2746          __toUTF8(str, encoding)
2747        end
2748        def _fromUTF8(str, encoding = nil)
2749          __fromUTF8(str, encoding)
2750        end
2751        ###
2752      end
2753 
2754      alias __eval _eval
2755      alias __invoke _invoke
2756 
2757      def _eval(cmd)
2758        _fromUTF8(__eval(_toUTF8(cmd)))
2759      end
2760 
2761      def _invoke(*cmds)
2762        _fromUTF8(__invoke(*(cmds.collect{|cmd| _toUTF8(cmd)})))
2763      end
2764 
2765      alias _eval_with_enc _eval
2766      alias _invoke_with_enc _invoke
2767 
2768  =begin
2769      #### --> definition is moved to TclTkIp module
2770 
2771      def _toUTF8(str, encoding = nil)
2772        # decide encoding
2773        if encoding
2774          encoding = encoding.to_s
2775        elsif str.kind_of?(Tk::EncodedString) && str.encoding != nil
2776          encoding = str.encoding.to_s
2777        elsif str.instance_variable_get(:@encoding)
2778          encoding = str.instance_variable_get(:@encoding).to_s
2779        elsif defined?(@encoding) && @encoding != nil
2780          encoding = @encoding.to_s
2781        else
2782          encoding = __invoke('encoding', 'system')
2783        end
2784 
2785        # convert
2786        case encoding
2787        when 'utf-8', 'binary'
2788          str
2789        else
2790          __toUTF8(str, encoding)
2791        end
2792      end
2793 
2794      def _fromUTF8(str, encoding = nil)
2795        unless encoding
2796          if defined?(@encoding) && @encoding != nil
2797            encoding = @encoding.to_s
2798          else
2799            encoding = __invoke('encoding', 'system')
2800          end
2801        end
2802 
2803        if str.kind_of?(Tk::EncodedString)
2804          if str.encoding == 'binary'
2805            str
2806          else
2807            __fromUTF8(str, encoding)
2808          end
2809        elsif str.instance_variable_get(:@encoding).to_s == 'binary'
2810          str
2811        else
2812          __fromUTF8(str, encoding)
2813        end
2814      end
2815  =end
2816 
2817  =begin
2818      def _eval(cmd)
2819        if defined?(@encoding) && @encoding != 'utf-8'
2820          ret = if cmd.kind_of?(Tk::EncodedString)
2821                  case cmd.encoding
2822                  when 'utf-8', 'binary'
2823                    __eval(cmd)
2824                  else
2825                    __eval(_toUTF8(cmd, cmd.encoding))
2826                  end
2827                elsif cmd.instance_variable_get(:@encoding) == 'binary'
2828                  __eval(cmd)
2829                else
2830                  __eval(_toUTF8(cmd, @encoding))
2831                end
2832          if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary'
2833            ret
2834          else
2835            _fromUTF8(ret, @encoding)
2836          end
2837        else
2838          __eval(cmd)
2839        end
2840      end
2841 
2842      def _invoke(*cmds)
2843        if defined?(@encoding) && @encoding != 'utf-8'
2844          cmds = cmds.collect{|cmd|
2845            if cmd.kind_of?(Tk::EncodedString)
2846              case cmd.encoding
2847              when 'utf-8', 'binary'
2848                cmd
2849              else
2850                _toUTF8(cmd, cmd.encoding)
2851              end
2852            elsif cmd.instance_variable_get(:@encoding) == 'binary'
2853              cmd
2854            else
2855              _toUTF8(cmd, @encoding)
2856            end
2857          }
2858          ret = __invoke(*cmds)
2859          if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary'
2860            ret
2861          else
2862            _fromUTF8(ret, @encoding)
2863          end
2864        else
2865          __invoke(*cmds)
2866          end
2867      end
2868  =end
2869    end
2870 
2871    module TclTkLib
2872      class << self
2873        def force_default_encoding=(mode)
2874          TkCore::INTERP.force_default_encoding = mode
2875        end
2876 
2877        def force_default_encoding?
2878          TkCore::INTERP.force_default_encoding?
2879        end
2880 
2881        def default_encoding=(name)
2882          TkCore::INTERP.default_encoding = name
2883        end
2884 
2885        alias _encoding encoding
2886        alias _encoding= encoding=
2887        def encoding=(name)
2888          name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING
2889          TkCore::INTERP.encoding = name
2890        end
2891 
2892        def encoding_name
2893          TkCore::INTERP.encoding
2894        end
2895        alias encoding encoding_name
2896        alias default_encoding encoding_name
2897 
2898        def encoding_obj
2899          if Tk::WITH_ENCODING
2900            Tk::Encoding.tcl2rb_encoding(TkCore::INTERP.encoding)
2901          else
2902            TkCore::INTERP.encoding
2903          end
2904        end
2905      end
2906    end
2907 
2908    # estimate encoding
2909    unless TkCore::WITH_ENCODING 
2910      case $KCODE
2911      when /^e/i  # EUC
2912        Tk.encoding = 'euc-jp'
2913        Tk.encoding_system = 'euc-jp'
2914      when /^s/i  # SJIS
2915        begin
2916          if Tk.encoding_system == 'cp932'
2917            Tk.encoding = 'cp932'
2918          else
2919            Tk.encoding = 'shiftjis'
2920            Tk.encoding_system = 'shiftjis'
2921          end
2922        rescue StandardError, NameError
2923          Tk.encoding = 'shiftjis'
2924          Tk.encoding_system = 'shiftjis'
2925        end
2926      when /^u/i  # UTF8
2927        Tk.encoding = 'utf-8'
2928        Tk.encoding_system = 'utf-8'
2929      else        # NONE
2930        if defined? DEFAULT_TK_ENCODING
2931          Tk.encoding_system = DEFAULT_TK_ENCODING
2932        end
2933        begin
2934          Tk.encoding = Tk.encoding_system
2935        rescue StandardError, NameError
2936          Tk.encoding = 'utf-8'
2937          Tk.encoding_system = 'utf-8'
2938        end
2939      end
2940 
2941    else ### Ruby 1.9 !!!!!!!!!!!!
2942      loc_enc_obj = ::Encoding.find(::Encoding.locale_charmap)
2943      ext_enc_obj = ::Encoding.default_external
2944      tksys_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding_system)
2945      # p [Tk.encoding, Tk.encoding_system, loc_enc_obj, ext_enc_obj]
2946 
2947  =begin
2948      if ext_enc_obj == Tk::Encoding::UNKNOWN
2949        if defind? DEFAULT_TK_ENCODING
2950          if DEFAULT_TK_ENCODING.kind_of?(::Encoding)
2951            tk_enc_name    = DEFAULT_TK_ENCODING.name
2952            tksys_enc_name = DEFAULT_TK_ENCODING.name
2953          else
2954            tk_enc_name    = DEFAULT_TK_ENCODING
2955            tksys_enc_name = DEFAULT_TK_ENCODING
2956          end
2957        else
2958          tk_enc_name    = loc_enc_obj.name
2959          tksys_enc_name = loc_enc_obj.name
2960        end
2961      else
2962        tk_enc_name    = ext_enc_obj.name
2963        tksys_enc_name = ext_enc_obj.name
2964      end
2965 
2966      # Tk.encoding = tk_enc_name
2967      Tk.default_encoding = tk_enc_name
2968      Tk.encoding_system = tksys_enc_name
2969  =end
2970 
2971      if ext_enc_obj == Tk::Encoding::UNKNOWN
2972        if loc_enc_obj == Tk::Encoding::UNKNOWN
2973          # use Tk.encoding_system
2974        else
2975          # use locale_charmap
2976          begin
2977            loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj)
2978            if loc_enc_name && loc_enc_name != tksys_enc_name
2979              # use locale_charmap
2980              Tk.encoding_system = loc_enc_name
2981            else
2982              # use Tk.encoding_system
2983            end
2984          rescue ArgumentError
2985            # unsupported encoding on Tk -> use Tk.encoding_system
2986          end
2987        end
2988      else
2989        begin
2990          ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)
2991          if ext_enc_name && ext_enc_name != tksys_enc_name
2992            # use default_external
2993            Tk.encoding_system = ext_enc_name
2994          else
2995            # use Tk.encoding_system
2996          end
2997        rescue ArgumentError
2998          # unsupported encoding on Tk -> use Tk.encoding_system
2999        end
3000      end
3001 
3002      # setup Tk.encoding
3003      enc_name = nil
3004 
3005      begin
3006        default_def = DEFAULT_TK_ENCODING
3007        if ::Encoding.find(default_def.to_s) != Tk::Encoding::UNKNOWN
3008          enc_name = Tk::Encoding::ENCODING_TABLE.get_name(default_def)
3009        end
3010      rescue NameError
3011        # ignore
3012        enc_name = nil
3013      rescue ArgumentError
3014        enc_name = nil
3015        fail ArgumentError, 
3016             "DEFAULT_TK_ENCODING has an unknown encoding #{default_def}"
3017      end
3018 
3019      unless enc_name
3020        if ext_enc_obj == Tk::Encoding::UNKNOWN
3021          if loc_enc_obj == Tk::Encoding::UNKNOWN
3022            # use Tk.encoding_system
3023            enc_name = tksys_enc_name
3024          else
3025            # use locale_charmap
3026            begin
3027              loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj)
3028              if loc_enc_name && loc_enc_name != tksys_enc_name
3029                # use locale_charmap
3030                enc_name = loc_enc_name
3031              else
3032                # use Tk.encoding_system
3033                enc_name = tksys_enc_name
3034              end
3035            rescue ArgumentError
3036              # unsupported encoding on Tk -> use Tk.encoding_system
3037              enc_name = tksys_enc_name
3038            end
3039          end
3040        else
3041          begin
3042            ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)
3043            if ext_enc_name && ext_enc_name != tksys_enc_name
3044              # use default_external
3045              enc_name = ext_enc_name
3046            else
3047              # use Tk.encoding_system
3048              enc_name = tksys_enc_name
3049            end
3050          rescue ArgumentError
3051            # unsupported encoding on Tk -> use Tk.encoding_system
3052            enc_name = tksys_enc_name
3053          end
3054        end
3055      end
3056 
3057      Tk.default_encoding = (enc_name)? enc_name: tksys_enc_name
3058    end
3059 
3060  else
3061    # dummy methods
3062    module Tk
3063      module Encoding
3064        extend Encoding
3065 
3066        def force_default_encoding=(mode)
3067          nil
3068        end
3069 
3070        def force_default_encoding?
3071          nil
3072        end
3073 
3074        def default_encoding=(enc)
3075          nil
3076        end
3077        def default_encoding
3078          nil
3079        end
3080 
3081        def encoding=(name)
3082          nil
3083        end
3084        def encoding
3085          nil
3086        end
3087        def encoding_names
3088          nil
3089        end
3090        def encoding_system
3091          nil
3092        end
3093        def encoding_system=(enc)
3094          nil
3095        end
3096 
3097        def encoding_convertfrom(str, enc=None)
3098          str
3099        end
3100        alias encoding_convert_from encoding_convertfrom
3101 
3102        def encoding_convertto(str, enc=None)
3103          str
3104        end
3105        alias encoding_convert_to encoding_convertto
3106        def encoding_dirs
3107          nil
3108        end
3109        def encoding_dirs=(dir_array)
3110          nil
3111        end
3112      end
3113 
3114      extend Encoding
3115    end
3116 
3117    class TclTkIp
3118      attr_accessor :encoding
3119 
3120      alias __eval _eval
3121      alias __invoke _invoke
3122 
3123      alias _eval_with_enc _eval
3124      alias _invoke_with_enc _invoke
3125    end
3126  end
3127 
3128 
3129  module TkBindCore
3130    #def bind(context, cmd=Proc.new, *args)
3131    #  Tk.bind(self, context, cmd, *args)
3132    #end
3133    def bind(context, *args)
3134      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
3135      if TkComm._callback_entry?(args[0]) || !block_given?
3136        cmd = args.shift
3137      else
3138        cmd = Proc.new
3139      end
3140      Tk.bind(self, context, cmd, *args)
3141    end
3142 
3143    #def bind_append(context, cmd=Proc.new, *args)
3144    #  Tk.bind_append(self, context, cmd, *args)
3145    #end
3146    def bind_append(context, *args)
3147      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
3148      if TkComm._callback_entry?(args[0]) || !block_given?
3149        cmd = args.shift
3150      else
3151        cmd = Proc.new
3152      end
3153      Tk.bind_append(self, context, cmd, *args)
3154    end
3155 
3156    def bind_remove(context)
3157      Tk.bind_remove(self, context)
3158    end
3159 
3160    def bindinfo(context=nil)
3161      Tk.bindinfo(self, context)
3162    end
3163  end
3164 
3165 
3166  module TkTreatFont
3167    def __font_optkeys
3168      ['font']
3169    end
3170    private :__font_optkeys
3171 
3172    def __pathname
3173      self.path
3174    end
3175    private :__pathname
3176 
3177    ################################
3178 
3179    def font_configinfo(key = nil)
3180      optkeys = __font_optkeys
3181      if key && !optkeys.find{|opt| opt.to_s == key.to_s}
3182        fail ArgumentError, "unknown font option name `#{key}'"
3183      end
3184 
3185      win, tag = __pathname.split(':')
3186 
3187      if key
3188        pathname = [win, tag, key].join(';')
3189        TkFont.used_on(pathname) || 
3190          TkFont.init_widget_font(pathname, *__confinfo_cmd)
3191      elsif optkeys.size == 1
3192        pathname = [win, tag, optkeys[0]].join(';')
3193        TkFont.used_on(pathname) || 
3194          TkFont.init_widget_font(pathname, *__confinfo_cmd)
3195      else
3196        fonts = {}
3197        optkeys.each{|key|
3198          key = key.to_s
3199          pathname = [win, tag, key].join(';')
3200          fonts[key] = 
3201            TkFont.used_on(pathname) || 
3202            TkFont.init_widget_font(pathname, *__confinfo_cmd)
3203        }
3204        fonts
3205      end
3206    end
3207    alias fontobj font_configinfo
3208 
3209    def font_configure(slot)
3210      pathname = __pathname
3211 
3212      slot = _symbolkey2str(slot)
3213 
3214      __font_optkeys.each{|optkey|
3215        optkey = optkey.to_s
3216        l_optkey = 'latin' << optkey
3217        a_optkey = 'ascii' << optkey
3218        k_optkey = 'kanji' << optkey
3219 
3220        if slot.key?(optkey)
3221          fnt = slot.delete(optkey)
3222          if fnt.kind_of?(TkFont)
3223            slot.delete(l_optkey)
3224            slot.delete(a_optkey)
3225            slot.delete(k_optkey)
3226 
3227            fnt.call_font_configure([pathname, optkey], *(__config_cmd << {}))
3228            next
3229          else
3230            if fnt
3231              if (slot.key?(l_optkey) || 
3232                  slot.key?(a_optkey) || 
3233                  slot.key?(k_optkey))
3234                fnt = TkFont.new(fnt)
3235 
3236                lfnt = slot.delete(l_optkey)
3237                lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)
3238                kfnt = slot.delete(k_optkey)
3239 
3240                fnt.latin_replace(lfnt) if lfnt
3241                fnt.kanji_replace(kfnt) if kfnt
3242 
3243                fnt.call_font_configure([pathname, optkey], 
3244                                        *(__config_cmd << {}))
3245                next
3246              else
3247                fnt = hash_kv(fnt) if fnt.kind_of?(Hash)
3248                unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3249                  tk_call(*(__config_cmd << "-#{optkey}" << fnt))
3250                else
3251                  begin
3252                    tk_call(*(__config_cmd << "-#{optkey}" << fnt))
3253                  rescue
3254                    # ignore
3255                  end
3256                end
3257              end
3258            end
3259            next
3260          end
3261        end
3262 
3263        lfnt = slot.delete(l_optkey)
3264        lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)
3265        kfnt = slot.delete(k_optkey)
3266 
3267        if lfnt && kfnt
3268          TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], 
3269                                                     *(__config_cmd << {}))
3270        elsif lfnt
3271          latinfont_configure([lfnt, optkey])
3272        elsif kfnt
3273          kanjifont_configure([kfnt, optkey])
3274        end
3275      }
3276 
3277      # configure other (without font) options
3278      tk_call(*(__config_cmd.concat(hash_kv(slot)))) if slot != {}
3279      self
3280    end
3281 
3282    def latinfont_configure(ltn, keys=nil)
3283      if ltn.kind_of?(Array)
3284        key = ltn[1]
3285        ltn = ltn[0]
3286      else
3287        key = nil
3288      end
3289 
3290      optkeys = __font_optkeys
3291      if key && !optkeys.find{|opt| opt.to_s == key.to_s}
3292        fail ArgumentError, "unknown font option name `#{key}'"
3293      end
3294 
3295      win, tag = __pathname.split(':')
3296 
3297      optkeys = [key] if key
3298 
3299      optkeys.each{|optkey|
3300        optkey = optkey.to_s
3301 
3302        pathname = [win, tag, optkey].join(';')
3303 
3304        if (fobj = TkFont.used_on(pathname))
3305          fobj = TkFont.new(fobj) # create a new TkFont object
3306        elsif Tk::JAPANIZED_TK
3307          fobj = fontobj          # create a new TkFont object
3308        else
3309          ltn = hash_kv(ltn) if ltn.kind_of?(Hash)
3310          unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3311            tk_call(*(__config_cmd << "-#{optkey}" << ltn))
3312          else
3313            begin
3314              tk_call(*(__config_cmd << "-#{optkey}" << ltn))
3315            rescue => e
3316              # ignore
3317            end
3318          end
3319          next
3320        end
3321 
3322        if fobj.kind_of?(TkFont)
3323          if ltn.kind_of?(TkFont)
3324            conf = {}
3325            ltn.latin_configinfo.each{|key,val| conf[key] = val}
3326            if keys
3327              fobj.latin_configure(conf.update(keys))
3328            else
3329              fobj.latin_configure(conf)
3330            end
3331          else
3332            fobj.latin_replace(ltn)
3333          end
3334        end
3335 
3336        fobj.call_font_configure([pathname, optkey], *(__config_cmd << {}))
3337      }
3338      self
3339    end
3340    alias asciifont_configure latinfont_configure
3341 
3342    def kanjifont_configure(knj, keys=nil)
3343      if knj.kind_of?(Array)
3344        key = knj[1]
3345        knj = knj[0]
3346      else
3347        key = nil
3348      end
3349 
3350      optkeys = __font_optkeys
3351      if key && !optkeys.find{|opt| opt.to_s == key.to_s}
3352        fail ArgumentError, "unknown font option name `#{key}'"
3353      end
3354 
3355      win, tag = __pathname.split(':')
3356 
3357      optkeys = [key] if key
3358 
3359      optkeys.each{|optkey|
3360        optkey = optkey.to_s
3361 
3362        pathname = [win, tag, optkey].join(';')
3363 
3364        if (fobj = TkFont.used_on(pathname))
3365          fobj = TkFont.new(fobj) # create a new TkFont object
3366        elsif Tk::JAPANIZED_TK
3367          fobj = fontobj          # create a new TkFont object
3368        else
3369          knj = hash_kv(knj) if knj.kind_of?(Hash)
3370          unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3371            tk_call(*(__config_cmd << "-#{optkey}" << knj))
3372          else
3373            begin
3374              tk_call(*(__config_cmd << "-#{optkey}" << knj))
3375            rescue => e
3376              # ignore
3377            end
3378          end
3379          next
3380        end
3381 
3382        if fobj.kind_of?(TkFont)
3383          if knj.kind_of?(TkFont)
3384            conf = {}
3385            knj.kanji_configinfo.each{|key,val| conf[key] = val}
3386            if keys
3387              fobj.kanji_configure(conf.update(keys))
3388            else
3389              fobj.kanji_configure(conf)
3390            end
3391          else
3392            fobj.kanji_replace(knj)
3393          end
3394        end
3395 
3396        fobj.call_font_configure([pathname, optkey], *(__config_cmd << {}))
3397      }
3398      self
3399    end
3400 
3401    def font_copy(win, wintag=nil, winkey=nil, targetkey=nil)
3402      if wintag
3403        if winkey
3404          fnt = win.tagfontobj(wintag, winkey).dup
3405        else
3406          fnt = win.tagfontobj(wintag).dup
3407        end
3408      else
3409        if winkey
3410          fnt = win.fontobj(winkey).dup
3411        else
3412          fnt = win.fontobj.dup
3413        end
3414      end
3415 
3416      if targetkey
3417        fnt.call_font_configure([__pathname, targetkey], *(__config_cmd << {}))
3418      else
3419        fnt.call_font_configure(__pathname, *(__config_cmd << {}))
3420      end
3421      self
3422    end
3423 
3424    def latinfont_copy(win, wintag=nil, winkey=nil, targetkey=nil)
3425      if targetkey
3426        fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], 
3427                                                   *(__config_cmd << {}))
3428      else
3429        fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {}))
3430      end
3431 
3432      if wintag
3433        if winkey
3434          fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id)
3435        else
3436          fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id)
3437        end
3438      else
3439        if winkey
3440          fontobj.latin_replace(win.fontobj(winkey).latin_font_id)
3441        else
3442          fontobj.latin_replace(win.fontobj.latin_font_id)
3443        end
3444      end
3445      self
3446    end
3447    alias asciifont_copy latinfont_copy
3448 
3449    def kanjifont_copy(win, wintag=nil, winkey=nil, targetkey=nil)
3450      if targetkey
3451        fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], 
3452                                                   *(__config_cmd << {}))
3453      else
3454          fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {}))
3455      end
3456 
3457      if wintag
3458        if winkey
3459          fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id)
3460        else
3461          fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id)
3462        end
3463      else
3464        if winkey
3465          fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id)
3466        else
3467          fontobj.kanji_replace(win.fontobj.kanji_font_id)
3468        end
3469      end
3470      self
3471    end
3472  end
3473 
3474 
3475  module TkConfigMethod
3476    include TkUtil
3477    include TkTreatFont
3478 
3479    def TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3480      @mode || false
3481    end
3482    def TkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode)
3483      fail SecurityError, "can't change the mode" if $SAFE>=4
3484      @mode = (mode)? true: false
3485    end
3486 
3487    def __cget_cmd
3488      [self.path, 'cget']
3489    end
3490    private :__cget_cmd
3491 
3492    def __config_cmd
3493      [self.path, 'configure']
3494    end
3495    private :__config_cmd
3496 
3497    def __confinfo_cmd
3498      __config_cmd
3499    end
3500    private :__confinfo_cmd
3501 
3502    def __configinfo_struct
3503      {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, 
3504        :default_value=>3, :current_value=>4}
3505    end
3506    private :__configinfo_struct
3507 
3508    def __optkey_aliases
3509      {}
3510    end
3511    private :__optkey_aliases
3512 
3513    def __numval_optkeys
3514      []
3515    end
3516    private :__numval_optkeys
3517 
3518    def __numstrval_optkeys
3519      []
3520    end
3521    private :__numstrval_optkeys
3522 
3523    def __boolval_optkeys
3524      ['exportselection', 'jump', 'setgrid', 'takefocus']
3525    end
3526    private :__boolval_optkeys
3527 
3528    def __strval_optkeys
3529      [
3530        'text', 'label', 'show', 'data', 'file', 
3531        'activebackground', 'activeforeground', 'background', 
3532        'disabledforeground', 'disabledbackground', 'foreground', 
3533        'highlightbackground', 'highlightcolor', 'insertbackground', 
3534        'selectbackground', 'selectforeground', 'troughcolor'
3535      ]
3536    end
3537    private :__strval_optkeys
3538 
3539    def __listval_optkeys
3540      []
3541    end
3542    private :__listval_optkeys
3543 
3544    def __numlistval_optkeys
3545      []
3546    end
3547    private :__numlistval_optkeys
3548 
3549    def __tkvariable_optkeys
3550      ['variable', 'textvariable']
3551    end
3552    private :__tkvariable_optkeys
3553 
3554    def __val2ruby_optkeys  # { key=>proc, ... }
3555      # The method is used to convert a opt-value to a ruby's object.
3556      # When get the value of the option "key", "proc.call(value)" is called.
3557      {}
3558    end
3559    private :__val2ruby_optkeys
3560 
3561    def __ruby2val_optkeys  # { key=>proc, ... }
3562      # The method is used to convert a ruby's object to a opt-value.
3563      # When set the value of the option "key", "proc.call(value)" is called.
3564      # That is, "-#{key} #{proc.call(value)}".
3565      {}
3566    end
3567    private :__ruby2val_optkeys
3568 
3569    def __methodcall_optkeys  # { key=>method, ... }
3570      # The method is used to both of get and set.
3571      # Usually, the 'key' will not be a widget option.
3572      {}
3573    end
3574    private :__methodcall_optkeys
3575 
3576    def __keyonly_optkeys  # { def_key=>undef_key or nil, ... }
3577      {}
3578    end
3579    private :__keyonly_optkeys
3580 
3581    def __conv_keyonly_opts(keys)
3582      return keys unless keys.kind_of?(Hash)
3583      keyonly = __keyonly_optkeys
3584      keys2 = {}
3585      keys.each{|k, v|
3586        optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s}
3587        if optkey
3588          defkey, undefkey = optkey
3589          if v
3590            keys2[defkey.to_s] = None
3591          elsif undefkey
3592            keys2[undefkey.to_s] = None
3593          else
3594            # remove key
3595          end
3596        else
3597          keys2[k.to_s] = v
3598        end
3599      }
3600      keys2
3601    end
3602    private :__conv_keyonly_opts
3603 
3604    def config_hash_kv(keys, enc_mode = nil, conf = nil)
3605      hash_kv(__conv_keyonly_opts(keys), enc_mode, conf)
3606    end
3607 
3608    ################################
3609 
3610    def [](id)
3611      cget(id)
3612    end
3613 
3614    def []=(id, val)
3615      configure(id, val)
3616      val
3617    end
3618 
3619    def __cget_core(slot)
3620      orig_slot = slot
3621      slot = slot.to_s
3622   
3623     if slot.length == 0
3624        fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
3625      end
3626 
3627      alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
3628      if real_name
3629        slot = real_name.to_s
3630      end
3631 
3632      if ( method = _symbolkey2str(__val2ruby_optkeys())[slot] )
3633        optval = tk_call_without_enc(*(__cget_cmd << "-#{slot}"))
3634        begin
3635          return method.call(optval)
3636        rescue => e
3637          warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
3638          return optval
3639        end
3640      end
3641 
3642      if ( method = _symbolkey2str(__methodcall_optkeys)[slot] )
3643        return self.__send__(method)
3644      end
3645 
3646      case slot
3647      when /^(#{__numval_optkeys.join('|')})$/
3648        begin
3649          number(tk_call_without_enc(*(__cget_cmd << "-#{slot}")))
3650        rescue
3651          nil
3652        end
3653 
3654      when /^(#{__numstrval_optkeys.join('|')})$/
3655        num_or_str(tk_call_without_enc(*(__cget_cmd << "-#{slot}")))
3656 
3657      when /^(#{__boolval_optkeys.join('|')})$/
3658        begin
3659          bool(tk_call_without_enc(*(__cget_cmd << "-#{slot}")))
3660        rescue
3661          nil
3662        end
3663 
3664      when /^(#{__listval_optkeys.join('|')})$/
3665        simplelist(tk_call_without_enc(*(__cget_cmd << "-#{slot}")))
3666 
3667      when /^(#{__numlistval_optkeys.join('|')})$/
3668        conf = tk_call_without_enc(*(__cget_cmd << "-#{slot}"))
3669        if conf =~ /^[0-9+-]/
3670          list(conf)
3671        else
3672          conf
3673        end
3674 
3675      when /^(#{__strval_optkeys.join('|')})$/
3676        _fromUTF8(tk_call_without_enc(*(__cget_cmd << "-#{slot}")))
3677 
3678      when /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/
3679        fontcode = $1
3680        fontkey  = $2
3681        fnt = tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{fontkey}")), true)
3682        unless fnt.kind_of?(TkFont)
3683          fnt = fontobj(fontkey)
3684        end
3685        if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
3686          # obsolete; just for compatibility
3687          fnt.kanji_font
3688        else
3689          fnt
3690        end
3691 
3692      when /^(#{__tkvariable_optkeys.join('|')})$/
3693        v = tk_call_without_enc(*(__cget_cmd << "-#{slot}"))
3694        (v.empty?)? nil: TkVarAccess.new(v)
3695 
3696      else
3697        tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{slot}")), true)
3698      end
3699    end
3700    private :__cget_core
3701 
3702    def cget(slot)
3703      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3704        __cget_core(slot)
3705      else
3706        begin
3707          __cget_core(slot)
3708        rescue => e
3709          if current_configinfo.has_key?(slot.to_s)
3710            # error on known option
3711            fail e
3712          else
3713            # unknown option
3714            nil
3715          end
3716        end
3717      end
3718    end
3719    def cget_strict(slot)
3720      # never use TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3721      __cget_core(slot)
3722    end
3723 
3724    def __configure_core(slot, value=None)
3725      if slot.kind_of? Hash
3726        slot = _symbolkey2str(slot)
3727 
3728        __optkey_aliases.each{|alias_name, real_name|
3729          alias_name = alias_name.to_s
3730          if slot.has_key?(alias_name)
3731            slot[real_name.to_s] = slot.delete(alias_name)
3732          end
3733        }
3734 
3735        __methodcall_optkeys.each{|key, method|
3736          value = slot.delete(key.to_s)
3737          self.__send__(method, value) if value
3738        }
3739 
3740        __ruby2val_optkeys.each{|key, method|
3741          key = key.to_s
3742          slot[key] = method.call(slot[key]) if slot.has_key?(key)
3743        }
3744 
3745        __keyonly_optkeys.each{|defkey, undefkey|
3746          conf = slot.find{|kk, vv| kk == defkey.to_s}
3747          if conf
3748            k, v = conf
3749            if v
3750              slot[k] = None
3751            else
3752              slot[undefkey.to_s] = None if undefkey
3753              slot.delete(k)
3754            end
3755          end
3756        }
3757 
3758        if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/})
3759          font_configure(slot)
3760        elsif slot.size > 0
3761          tk_call(*(__config_cmd.concat(hash_kv(slot))))
3762        end
3763 
3764      else
3765        orig_slot = slot
3766        slot = slot.to_s
3767        if slot.length == 0
3768          fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
3769        end
3770 
3771        alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
3772        if real_name
3773          slot = real_name.to_s
3774        end
3775 
3776        if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} )
3777          defkey, undefkey = conf
3778          if value
3779            tk_call(*(__config_cmd << "-#{defkey}"))
3780          elsif undefkey
3781            tk_call(*(__config_cmd << "-#{undefkey}"))
3782          end
3783        elsif ( method = _symbolkey2str(__ruby2val_optkeys)[slot] )
3784          tk_call(*(__config_cmd << "-#{slot}" << method.call(value)))
3785        elsif ( method = _symbolkey2str(__methodcall_optkeys)[slot] )
3786          self.__send__(method, value)
3787        elsif (slot =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)
3788          if value == None
3789            fontobj($2)
3790          else
3791            font_configure({slot=>value})
3792          end
3793        else
3794          tk_call(*(__config_cmd << "-#{slot}" << value))
3795        end
3796      end
3797      self
3798    end
3799    private :__configure_core
3800 
3801    def __check_available_configure_options(keys)
3802      availables = self.current_configinfo.keys
3803 
3804      # add non-standard keys
3805      availables |= __font_optkeys.map{|k|
3806        [k.to_s, "latin#{k}", "ascii#{k}", "kanji#{k}"]
3807      }.flatten
3808      availables |= __methodcall_optkeys.keys.map{|k| k.to_s}
3809      availables |= __keyonly_optkeys.keys.map{|k| k.to_s}
3810 
3811      keys = _symbolkey2str(keys)
3812      keys.delete_if{|k, v| !(availables.include?(k))}
3813    end
3814 
3815    def configure(slot, value=None)
3816      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
3817        __configure_core(slot, value)
3818      else
3819        if slot.kind_of?(Hash)
3820          begin
3821            __configure_core(slot)
3822          rescue
3823            slot = __check_available_configure_options(slot)
3824            __configure_core(slot) unless slot.empty?
3825          end
3826        else
3827          begin
3828            __configure_core(slot, value)
3829          rescue => e
3830            if current_configinfo.has_key?(slot.to_s)
3831              # error on known option
3832              fail e
3833            else
3834              # unknown option
3835              nil
3836            end
3837          end
3838        end
3839      end
3840      self
3841    end
3842 
3843    def configure_cmd(slot, value)
3844      configure(slot, install_cmd(value))
3845    end
3846 
3847    def __configinfo_core(slot = nil)
3848      if TkComm::GET_CONFIGINFO_AS_ARRAY
3849        if (slot && 
3850            slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)
3851          fontkey  = $2
3852          # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}"))))
3853          conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true)
3854          conf[__configinfo_struct[:key]] = 
3855            conf[__configinfo_struct[:key]][1..-1]
3856          if ( ! __configinfo_struct[:alias] \
3857              || conf.size > __configinfo_struct[:alias] + 1 )
3858            fnt = conf[__configinfo_struct[:default_value]]
3859            if TkFont.is_system_font?(fnt)
3860              conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt)
3861            end
3862            conf[__configinfo_struct[:current_value]] = fontobj(fontkey)
3863          elsif ( __configinfo_struct[:alias] \
3864                 && conf.size == __configinfo_struct[:alias] + 1 \
3865                 && conf[__configinfo_struct[:alias]][0] == ?- )
3866            conf[__configinfo_struct[:alias]] = 
3867              conf[__configinfo_struct[:alias]][1..-1]
3868          end
3869          conf
3870        else
3871          if slot
3872            slot = slot.to_s
3873 
3874            alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
3875            if real_name
3876              slot = real_name.to_s
3877            end
3878 
3879            case slot
3880            when /^(#{__val2ruby_optkeys().keys.join('|')})$/
3881              method = _symbolkey2str(__val2ruby_optkeys())[slot]
3882              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd() << "-#{slot}")), false, true)
3883              if ( __configinfo_struct[:default_value] \
3884                  && conf[__configinfo_struct[:default_value]] )
3885                optval = conf[__configinfo_struct[:default_value]]
3886                begin
3887                  val = method.call(optval)
3888                rescue => e
3889                  warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
3890                  val = optval
3891                end
3892                conf[__configinfo_struct[:default_value]] = val
3893              end
3894              if ( conf[__configinfo_struct[:current_value]] )
3895                optval = conf[__configinfo_struct[:current_value]]
3896                begin
3897                  val = method.call(optval)
3898                rescue => e
3899                  warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
3900                  val = optval
3901                end
3902                conf[__configinfo_struct[:current_value]] = val
3903              end
3904 
3905            when /^(#{__methodcall_optkeys.keys.join('|')})$/
3906              method = _symbolkey2str(__methodcall_optkeys)[slot]
3907              return [slot, '', '', '', self.__send__(method)]
3908 
3909            when /^(#{__numval_optkeys.join('|')})$/
3910              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3911              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
3912 
3913              if ( __configinfo_struct[:default_value] \
3914                  && conf[__configinfo_struct[:default_value]])
3915                begin
3916                  conf[__configinfo_struct[:default_value]] = 
3917                    number(conf[__configinfo_struct[:default_value]])
3918                rescue
3919                  conf[__configinfo_struct[:default_value]] = nil
3920                end
3921              end
3922              if ( conf[__configinfo_struct[:current_value]] )
3923                begin
3924                  conf[__configinfo_struct[:current_value]] = 
3925                    number(conf[__configinfo_struct[:current_value]])
3926                rescue
3927                  conf[__configinfo_struct[:current_value]] = nil
3928                end
3929              end
3930 
3931            when /^(#{__numstrval_optkeys.join('|')})$/
3932              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3933              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
3934 
3935              if ( __configinfo_struct[:default_value] \
3936                  && conf[__configinfo_struct[:default_value]])
3937                conf[__configinfo_struct[:default_value]] = 
3938                  num_or_str(conf[__configinfo_struct[:default_value]])
3939              end
3940              if ( conf[__configinfo_struct[:current_value]] )
3941                conf[__configinfo_struct[:current_value]] = 
3942                  num_or_str(conf[__configinfo_struct[:current_value]])
3943              end
3944 
3945            when /^(#{__boolval_optkeys.join('|')})$/
3946              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3947              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
3948 
3949              if ( __configinfo_struct[:default_value] \
3950                  && conf[__configinfo_struct[:default_value]])
3951                begin
3952                  conf[__configinfo_struct[:default_value]] = 
3953                    bool(conf[__configinfo_struct[:default_value]])
3954                rescue
3955                  conf[__configinfo_struct[:default_value]] = nil
3956                end
3957              end
3958              if ( conf[__configinfo_struct[:current_value]] )
3959                begin
3960                  conf[__configinfo_struct[:current_value]] = 
3961                    bool(conf[__configinfo_struct[:current_value]])
3962                rescue
3963                  conf[__configinfo_struct[:current_value]] = nil
3964                end
3965              end
3966 
3967            when /^(#{__listval_optkeys.join('|')})$/
3968              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3969              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
3970 
3971              if ( __configinfo_struct[:default_value] \
3972                  && conf[__configinfo_struct[:default_value]])
3973                conf[__configinfo_struct[:default_value]] = 
3974                  simplelist(conf[__configinfo_struct[:default_value]])
3975              end
3976              if ( conf[__configinfo_struct[:current_value]] )
3977                conf[__configinfo_struct[:current_value]] = 
3978                  simplelist(conf[__configinfo_struct[:current_value]])
3979              end
3980 
3981            when /^(#{__numlistval_optkeys.join('|')})$/
3982              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3983              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
3984 
3985              if ( __configinfo_struct[:default_value] \
3986                  && conf[__configinfo_struct[:default_value]] \
3987                  && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )
3988                conf[__configinfo_struct[:default_value]] = 
3989                  list(conf[__configinfo_struct[:default_value]])
3990              end
3991              if ( conf[__configinfo_struct[:current_value]] \
3992                  && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )
3993                conf[__configinfo_struct[:current_value]] = 
3994                  list(conf[__configinfo_struct[:current_value]])
3995              end
3996 
3997            when /^(#{__strval_optkeys.join('|')})$/
3998              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
3999              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4000 
4001            when /^(#{__tkvariable_optkeys.join('|')})$/
4002              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4003 
4004              if ( __configinfo_struct[:default_value] \
4005                  && conf[__configinfo_struct[:default_value]])
4006                v = conf[__configinfo_struct[:default_value]]
4007                if v.empty?
4008                  conf[__configinfo_struct[:default_value]] = nil
4009                else
4010                  conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)
4011                end
4012              end
4013              if ( conf[__configinfo_struct[:current_value]] )
4014                v = conf[__configinfo_struct[:current_value]]
4015                if v.empty?
4016                  conf[__configinfo_struct[:current_value]] = nil
4017                else
4018                  conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)
4019                end
4020              end
4021 
4022            else
4023              # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4024              conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
4025            end
4026            conf[__configinfo_struct[:key]] = 
4027              conf[__configinfo_struct[:key]][1..-1]
4028 
4029            if ( __configinfo_struct[:alias] \
4030                && conf.size == __configinfo_struct[:alias] + 1 \
4031                && conf[__configinfo_struct[:alias]][0] == ?- )
4032              conf[__configinfo_struct[:alias]] = 
4033                conf[__configinfo_struct[:alias]][1..-1]
4034            end
4035 
4036            conf
4037 
4038          else
4039            # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).collect{|conflist|
4040            #  conf = tk_split_simplelist(conflist)
4041            ret = tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).collect{|conflist|
4042              conf = tk_split_simplelist(conflist, false, true)
4043              conf[__configinfo_struct[:key]] = 
4044                conf[__configinfo_struct[:key]][1..-1]
4045 
4046              optkey = conf[__configinfo_struct[:key]]
4047              case optkey
4048              when /^(#{__val2ruby_optkeys().keys.join('|')})$/
4049                method = _symbolkey2str(__val2ruby_optkeys())[optkey]
4050                if ( __configinfo_struct[:default_value] \
4051                    && conf[__configinfo_struct[:default_value]] )
4052                  optval = conf[__configinfo_struct[:default_value]]
4053                  begin
4054                    val = method.call(optval)
4055                  rescue => e
4056                    warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4057                    val = optval
4058                  end
4059                  conf[__configinfo_struct[:default_value]] = val
4060                end
4061                if ( conf[__configinfo_struct[:current_value]] )
4062                  optval = conf[__configinfo_struct[:current_value]]
4063                  begin
4064                    val = method.call(optval)
4065                  rescue => e
4066                    warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4067                    val = optval
4068                  end
4069                  conf[__configinfo_struct[:current_value]] = val
4070                end
4071 
4072              when /^(#{__strval_optkeys.join('|')})$/
4073                # do nothing
4074 
4075              when /^(#{__numval_optkeys.join('|')})$/
4076                if ( __configinfo_struct[:default_value] \
4077                    && conf[__configinfo_struct[:default_value]] )
4078                  begin
4079                    conf[__configinfo_struct[:default_value]] = 
4080                      number(conf[__configinfo_struct[:default_value]])
4081                  rescue
4082                    conf[__configinfo_struct[:default_value]] = nil
4083                  end
4084                end
4085                if ( conf[__configinfo_struct[:current_value]] )
4086                  begin
4087                    conf[__configinfo_struct[:current_value]] = 
4088                      number(conf[__configinfo_struct[:current_value]])
4089                  rescue
4090                    conf[__configinfo_struct[:current_value]] = nil
4091                  end
4092                end
4093 
4094              when /^(#{__numstrval_optkeys.join('|')})$/
4095                if ( __configinfo_struct[:default_value] \
4096                    && conf[__configinfo_struct[:default_value]] )
4097                  conf[__configinfo_struct[:default_value]] = 
4098                    num_or_str(conf[__configinfo_struct[:default_value]])
4099                end
4100                if ( conf[__configinfo_struct[:current_value]] )
4101                  conf[__configinfo_struct[:current_value]] = 
4102                    num_or_str(conf[__configinfo_struct[:current_value]])
4103                end
4104 
4105              when /^(#{__boolval_optkeys.join('|')})$/
4106                if ( __configinfo_struct[:default_value] \
4107                    && conf[__configinfo_struct[:default_value]] )
4108                  begin
4109                    conf[__configinfo_struct[:default_value]] = 
4110                      bool(conf[__configinfo_struct[:default_value]])
4111                  rescue
4112                    conf[__configinfo_struct[:default_value]] = nil
4113                  end
4114                end
4115                if ( conf[__configinfo_struct[:current_value]] )
4116                  begin
4117                    conf[__configinfo_struct[:current_value]] = 
4118                      bool(conf[__configinfo_struct[:current_value]])
4119                  rescue
4120                    conf[__configinfo_struct[:current_value]] = nil
4121                  end
4122                end
4123 
4124              when /^(#{__listval_optkeys.join('|')})$/
4125                if ( __configinfo_struct[:default_value] \
4126                    && conf[__configinfo_struct[:default_value]] )
4127                  conf[__configinfo_struct[:default_value]] = 
4128                    simplelist(conf[__configinfo_struct[:default_value]])
4129                end
4130                if ( conf[__configinfo_struct[:current_value]] )
4131                  conf[__configinfo_struct[:current_value]] = 
4132                    simplelist(conf[__configinfo_struct[:current_value]])
4133                end
4134 
4135              when /^(#{__numlistval_optkeys.join('|')})$/
4136                if ( __configinfo_struct[:default_value] \
4137                    && conf[__configinfo_struct[:default_value]] \
4138                    && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )
4139                  conf[__configinfo_struct[:default_value]] = 
4140                    list(conf[__configinfo_struct[:default_value]])
4141                end
4142                if ( conf[__configinfo_struct[:current_value]] \
4143                    && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )
4144                  conf[__configinfo_struct[:current_value]] = 
4145                    list(conf[__configinfo_struct[:current_value]])
4146                end
4147 
4148              when /^(#{__tkvariable_optkeys.join('|')})$/
4149                if ( __configinfo_struct[:default_value] \
4150                    && conf[__configinfo_struct[:default_value]] )
4151                  v = conf[__configinfo_struct[:default_value]]
4152                  if v.empty?
4153                    conf[__configinfo_struct[:default_value]] = nil
4154                  else
4155                    conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)
4156                  end
4157                end
4158                if ( conf[__configinfo_struct[:current_value]] )
4159                  v = conf[__configinfo_struct[:current_value]]
4160                  if v.empty?
4161                    conf[__configinfo_struct[:current_value]] = nil
4162                  else
4163                    conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)
4164                  end
4165                end
4166 
4167              else
4168                if ( __configinfo_struct[:default_value] \
4169                    && conf[__configinfo_struct[:default_value]] )
4170                  if conf[__configinfo_struct[:default_value]].index('{')
4171                    conf[__configinfo_struct[:default_value]] = 
4172                      tk_split_list(conf[__configinfo_struct[:default_value]]) 
4173                  else
4174                    conf[__configinfo_struct[:default_value]] = 
4175                      tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) 
4176                  end
4177                end
4178                if conf[__configinfo_struct[:current_value]]
4179                  if conf[__configinfo_struct[:current_value]].index('{')
4180                    conf[__configinfo_struct[:current_value]] = 
4181                      tk_split_list(conf[__configinfo_struct[:current_value]]) 
4182                  else
4183                    conf[__configinfo_struct[:current_value]] = 
4184                      tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) 
4185                  end
4186                end
4187              end
4188 
4189              if ( __configinfo_struct[:alias] \
4190                  && conf.size == __configinfo_struct[:alias] + 1 \
4191                  && conf[__configinfo_struct[:alias]][0] == ?- )
4192                conf[__configinfo_struct[:alias]] = 
4193                  conf[__configinfo_struct[:alias]][1..-1]
4194              end
4195 
4196              conf
4197            }
4198 
4199            __font_optkeys.each{|optkey|
4200              optkey = optkey.to_s
4201              fontconf = ret.assoc(optkey)
4202              if fontconf && fontconf.size > 2
4203                ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}
4204                fnt = fontconf[__configinfo_struct[:default_value]]
4205                if TkFont.is_system_font?(fnt)
4206                  fontconf[__configinfo_struct[:default_value]] \
4207                    = TkNamedFont.new(fnt)
4208                end
4209                fontconf[__configinfo_struct[:current_value]] = fontobj(optkey)
4210                ret.push(fontconf)
4211              end
4212            }
4213 
4214            __methodcall_optkeys.each{|optkey, method|
4215              ret << [optkey.to_s, '', '', '', self.__send__(method)]
4216            }
4217 
4218            ret
4219          end
4220        end
4221 
4222      else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
4223        if (slot && 
4224            slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)
4225          fontkey  = $2
4226          # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}"))))
4227          conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true)
4228          conf[__configinfo_struct[:key]] = 
4229            conf[__configinfo_struct[:key]][1..-1]
4230 
4231          if ( ! __configinfo_struct[:alias] \
4232              || conf.size > __configinfo_struct[:alias] + 1 )
4233            fnt = conf[__configinfo_struct[:default_value]]
4234            if TkFont.is_system_font?(fnt)
4235              conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt)
4236            end
4237            conf[__configinfo_struct[:current_value]] = fontobj(fontkey)
4238            { conf.shift => conf }
4239          elsif ( __configinfo_struct[:alias] \
4240                 && conf.size == __configinfo_struct[:alias] + 1 )
4241            if conf[__configinfo_struct[:alias]][0] == ?-
4242              conf[__configinfo_struct[:alias]] = 
4243                conf[__configinfo_struct[:alias]][1..-1]
4244            end
4245            { conf[0] => conf[1] }
4246          else
4247            { conf.shift => conf }
4248          end
4249        else
4250          if slot
4251            slot = slot.to_s
4252 
4253            alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
4254            if real_name
4255              slot = real_name.to_s
4256            end
4257 
4258            case slot
4259            when /^(#{__val2ruby_optkeys().keys.join('|')})$/
4260              method = _symbolkey2str(__val2ruby_optkeys())[slot]
4261              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4262              if ( __configinfo_struct[:default_value] \
4263                  && conf[__configinfo_struct[:default_value]] )
4264                optval = conf[__configinfo_struct[:default_value]]
4265                begin
4266                  val = method.call(optval)
4267                rescue => e
4268                  warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4269                  val = optval
4270                end
4271                conf[__configinfo_struct[:default_value]] = val
4272              end
4273              if ( conf[__configinfo_struct[:current_value]] )
4274                optval = conf[__configinfo_struct[:current_value]]
4275                begin
4276                  val = method.call(optval)
4277                rescue => e
4278                  warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4279                  val = optval
4280                end
4281                conf[__configinfo_struct[:current_value]] = val
4282              end
4283 
4284            when /^(#{__methodcall_optkeys.keys.join('|')})$/
4285              method = _symbolkey2str(__methodcall_optkeys)[slot]
4286              return {slot => ['', '', '', self.__send__(method)]}
4287 
4288            when /^(#{__numval_optkeys.join('|')})$/
4289              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4290              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4291 
4292              if ( __configinfo_struct[:default_value] \
4293                  && conf[__configinfo_struct[:default_value]] )
4294                begin
4295                  conf[__configinfo_struct[:default_value]] = 
4296                    number(conf[__configinfo_struct[:default_value]])
4297                rescue
4298                  conf[__configinfo_struct[:default_value]] = nil
4299                end
4300              end
4301              if ( conf[__configinfo_struct[:current_value]] )
4302                begin
4303                  conf[__configinfo_struct[:current_value]] = 
4304                    number(conf[__configinfo_struct[:current_value]])
4305                rescue
4306                  conf[__configinfo_struct[:current_value]] = nil
4307                end
4308              end
4309 
4310            when /^(#{__numstrval_optkeys.join('|')})$/
4311              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4312              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4313 
4314              if ( __configinfo_struct[:default_value] \
4315                  && conf[__configinfo_struct[:default_value]] )
4316                conf[__configinfo_struct[:default_value]] = 
4317                  num_or_str(conf[__configinfo_struct[:default_value]])
4318              end
4319              if ( conf[__configinfo_struct[:current_value]] )
4320                conf[__configinfo_struct[:current_value]] = 
4321                  num_or_str(conf[__configinfo_struct[:current_value]])
4322              end
4323 
4324            when /^(#{__boolval_optkeys.join('|')})$/
4325              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4326              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4327 
4328              if ( __configinfo_struct[:default_value] \
4329                  && conf[__configinfo_struct[:default_value]] )
4330                begin
4331                  conf[__configinfo_struct[:default_value]] = 
4332                    bool(conf[__configinfo_struct[:default_value]])
4333                rescue
4334                  conf[__configinfo_struct[:default_value]] = nil
4335                end
4336              end
4337              if ( conf[__configinfo_struct[:current_value]] )
4338                begin
4339                  conf[__configinfo_struct[:current_value]] = 
4340                    bool(conf[__configinfo_struct[:current_value]])
4341                rescue
4342                  conf[__configinfo_struct[:current_value]] = nil
4343                end
4344              end
4345 
4346            when /^(#{__listval_optkeys.join('|')})$/
4347              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4348              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4349 
4350              if ( __configinfo_struct[:default_value] \
4351                  && conf[__configinfo_struct[:default_value]] )
4352                conf[__configinfo_struct[:default_value]] = 
4353                  simplelist(conf[__configinfo_struct[:default_value]])
4354              end
4355              if ( conf[__configinfo_struct[:current_value]] )
4356                conf[__configinfo_struct[:current_value]] = 
4357                  simplelist(conf[__configinfo_struct[:current_value]])
4358              end
4359 
4360            when /^(#{__numlistval_optkeys.join('|')})$/
4361              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4362              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4363 
4364              if ( __configinfo_struct[:default_value] \
4365                  && conf[__configinfo_struct[:default_value]] \
4366                  && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )
4367                conf[__configinfo_struct[:default_value]] = 
4368                  list(conf[__configinfo_struct[:default_value]])
4369              end
4370              if ( conf[__configinfo_struct[:current_value]] \
4371                  && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )
4372                conf[__configinfo_struct[:current_value]] = 
4373                  list(conf[__configinfo_struct[:current_value]])
4374              end
4375 
4376            when /^(#{__tkvariable_optkeys.join('|')})$/
4377              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4378 
4379              if ( __configinfo_struct[:default_value] \
4380                  && conf[__configinfo_struct[:default_value]] )
4381                v = conf[__configinfo_struct[:default_value]]
4382                if v.empty?
4383                  conf[__configinfo_struct[:default_value]] = nil
4384                else
4385                  conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)
4386                end
4387              end
4388              if ( conf[__configinfo_struct[:current_value]] )
4389                v = conf[__configinfo_struct[:current_value]]
4390                if v.empty?
4391                  conf[__configinfo_struct[:current_value]] = nil
4392                else
4393                  conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)
4394                end
4395              end
4396 
4397            when /^(#{__strval_optkeys.join('|')})$/
4398              # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4399              conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true)
4400            else
4401              # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
4402              conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
4403            end
4404            conf[__configinfo_struct[:key]] = 
4405              conf[__configinfo_struct[:key]][1..-1]
4406 
4407            if ( __configinfo_struct[:alias] \
4408                && conf.size == __configinfo_struct[:alias] + 1 )
4409              if conf[__configinfo_struct[:alias]][0] == ?-
4410                conf[__configinfo_struct[:alias]] = 
4411                  conf[__configinfo_struct[:alias]][1..-1]
4412              end
4413              { conf[0] => conf[1] }
4414            else
4415              { conf.shift => conf }
4416            end
4417 
4418          else
4419            ret = {}
4420            # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).each{|conflist|
4421            #  conf = tk_split_simplelist(conflist)
4422            tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).each{|conflist|
4423              conf = tk_split_simplelist(conflist, false, true)
4424              conf[__configinfo_struct[:key]] = 
4425                conf[__configinfo_struct[:key]][1..-1]
4426 
4427              optkey = conf[__configinfo_struct[:key]]
4428              case optkey
4429              when /^(#{__val2ruby_optkeys().keys.join('|')})$/
4430                method = _symbolkey2str(__val2ruby_optkeys())[optkey]
4431                if ( __configinfo_struct[:default_value] \
4432                    && conf[__configinfo_struct[:default_value]] )
4433                  optval = conf[__configinfo_struct[:default_value]]
4434                  begin
4435                    val = method.call(optval)
4436                  rescue => e
4437                    warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4438                    val = optval
4439                  end
4440                  conf[__configinfo_struct[:default_value]] = val
4441                end
4442                if ( conf[__configinfo_struct[:current_value]] )
4443                  optval = conf[__configinfo_struct[:current_value]]
4444                  begin
4445                    val = method.call(optval)
4446                  rescue => e
4447                    warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG
4448                    val = optval
4449                  end
4450                  conf[__configinfo_struct[:current_value]] = val
4451                end
4452 
4453              when /^(#{__strval_optkeys.join('|')})$/
4454                # do nothing
4455 
4456              when /^(#{__numval_optkeys.join('|')})$/
4457                if ( __configinfo_struct[:default_value] \
4458                    && conf[__configinfo_struct[:default_value]] )
4459                  begin
4460                    conf[__configinfo_struct[:default_value]] = 
4461                      number(conf[__configinfo_struct[:default_value]])
4462                  rescue
4463                    conf[__configinfo_struct[:default_value]] = nil
4464                  end
4465                end
4466                if ( conf[__configinfo_struct[:current_value]] )
4467                  begin
4468                    conf[__configinfo_struct[:current_value]] = 
4469                      number(conf[__configinfo_struct[:current_value]])
4470                  rescue
4471                    conf[__configinfo_struct[:current_value]] = nil
4472                  end
4473                end
4474 
4475              when /^(#{__numstrval_optkeys.join('|')})$/
4476                if ( __configinfo_struct[:default_value] \
4477                    && conf[__configinfo_struct[:default_value]] )
4478                  conf[__configinfo_struct[:default_value]] = 
4479                    num_or_str(conf[__configinfo_struct[:default_value]])
4480                end
4481                if ( conf[__configinfo_struct[:current_value]] )
4482                  conf[__configinfo_struct[:current_value]] = 
4483                    num_or_str(conf[__configinfo_struct[:current_value]])
4484                end
4485 
4486              when /^(#{__boolval_optkeys.join('|')})$/
4487                if ( __configinfo_struct[:default_value] \
4488                    && conf[__configinfo_struct[:default_value]] )
4489                  begin
4490                    conf[__configinfo_struct[:default_value]] = 
4491                      bool(conf[__configinfo_struct[:default_value]])
4492                  rescue
4493                    conf[__configinfo_struct[:default_value]] = nil
4494                  end
4495                end
4496                if ( conf[__configinfo_struct[:current_value]] )
4497                  begin
4498                    conf[__configinfo_struct[:current_value]] = 
4499                      bool(conf[__configinfo_struct[:current_value]])
4500                  rescue
4501                    conf[__configinfo_struct[:current_value]] = nil
4502                  end
4503                end
4504 
4505              when /^(#{__listval_optkeys.join('|')})$/
4506                if ( __configinfo_struct[:default_value] \
4507                    && conf[__configinfo_struct[:default_value]] )
4508                  conf[__configinfo_struct[:default_value]] = 
4509                    simplelist(conf[__configinfo_struct[:default_value]])
4510                end
4511                if ( conf[__configinfo_struct[:current_value]] )
4512                  conf[__configinfo_struct[:current_value]] = 
4513                    simplelist(conf[__configinfo_struct[:current_value]])
4514                end
4515 
4516              when /^(#{__numlistval_optkeys.join('|')})$/
4517                if ( __configinfo_struct[:default_value] \
4518                    && conf[__configinfo_struct[:default_value]] \
4519                    && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )
4520                  conf[__configinfo_struct[:default_value]] = 
4521                    list(conf[__configinfo_struct[:default_value]])
4522                end
4523                if ( conf[__configinfo_struct[:current_value]] \
4524                    && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )
4525                  conf[__configinfo_struct[:current_value]] = 
4526                    list(conf[__configinfo_struct[:current_value]])
4527                end
4528 
4529              when /^(#{__tkvariable_optkeys.join('|')})$/
4530                if ( __configinfo_struct[:default_value] \
4531                    && conf[__configinfo_struct[:default_value]] )
4532                  v = conf[__configinfo_struct[:default_value]]
4533                  if v.empty?
4534                    conf[__configinfo_struct[:default_value]] = nil
4535                  else
4536                    conf[__configinfo_struct[:default_value]] = TkVarAccess.new
4537                  end
4538                end
4539                if ( conf[__configinfo_struct[:current_value]] )
4540                  v = conf[__configinfo_struct[:current_value]]
4541                  if v.empty?
4542                    conf[__configinfo_struct[:current_value]] = nil
4543                  else
4544                    conf[__configinfo_struct[:current_value]] = TkVarAccess.new
4545                  end
4546                end
4547 
4548              else
4549                if ( __configinfo_struct[:default_value] \
4550                    && conf[__configinfo_struct[:default_value]] )
4551                  if conf[__configinfo_struct[:default_value]].index('{')
4552                    conf[__configinfo_struct[:default_value]] = 
4553                      tk_split_list(conf[__configinfo_struct[:default_value]]) 
4554                  else
4555                    conf[__configinfo_struct[:default_value]] = 
4556                      tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) 
4557                  end
4558                end
4559                if conf[__configinfo_struct[:current_value]]
4560                  if conf[__configinfo_struct[:current_value]].index('{')
4561                    conf[__configinfo_struct[:current_value]] = 
4562                      tk_split_list(conf[__configinfo_struct[:current_value]]) 
4563                  else
4564                    conf[__configinfo_struct[:current_value]] = 
4565                      tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) 
4566                  end
4567                end
4568              end
4569 
4570              if ( __configinfo_struct[:alias] \
4571                  && conf.size == __configinfo_struct[:alias] + 1 )
4572                if conf[__configinfo_struct[:alias]][0] == ?-
4573                  conf[__configinfo_struct[:alias]] = 
4574                    conf[__configinfo_struct[:alias]][1..-1]
4575                end
4576                ret[conf[0]] = conf[1]
4577              else
4578                ret[conf.shift] = conf
4579              end
4580            }
4581 
4582            __font_optkeys.each{|optkey|
4583              optkey = optkey.to_s
4584              fontconf = ret[optkey]
4585              if fontconf.kind_of?(Array)
4586                ret.delete(optkey)
4587                ret.delete('latin' << optkey)
4588                ret.delete('ascii' << optkey)
4589                ret.delete('kanji' << optkey)
4590                fnt = fontconf[__configinfo_struct[:default_value]]
4591                if TkFont.is_system_font?(fnt)
4592                  fontconf[__configinfo_struct[:default_value]] \
4593                    = TkNamedFont.new(fnt)
4594                end
4595                fontconf[__configinfo_struct[:current_value]] = fontobj(optkey)
4596                ret[optkey] = fontconf
4597              end
4598            }
4599 
4600            __methodcall_optkeys.each{|optkey, method|
4601              ret[optkey.to_s] = ['', '', '', self.__send__(method)]
4602            }
4603 
4604            ret
4605          end
4606        end
4607      end
4608    end
4609    private :__configinfo_core
4610 
4611    def configinfo(slot = nil)
4612      if slot && TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
4613        begin
4614          __configinfo_core(slot)
4615        rescue
4616          Array.new(__configinfo_struct.values.max).unshift(slot.to_s)
4617        end
4618      else
4619        __configinfo_core(slot)
4620      end
4621    end
4622 
4623    def current_configinfo(slot = nil)
4624      if TkComm::GET_CONFIGINFO_AS_ARRAY
4625        if slot
4626          org_slot = slot
4627          begin
4628            conf = configinfo(slot)
4629            if ( ! __configinfo_struct[:alias] \
4630                || conf.size > __configinfo_struct[:alias] + 1 )
4631              return {conf[0] => conf[-1]}
4632            end
4633            slot = conf[__configinfo_struct[:alias]]
4634          end while(org_slot != slot)
4635          fail RuntimeError, 
4636            "there is a configure alias loop about '#{org_slot}'"
4637        else
4638          ret = {}
4639          configinfo().each{|conf|
4640            if ( ! __configinfo_struct[:alias] \
4641                || conf.size > __configinfo_struct[:alias] + 1 )
4642              ret[conf[0]] = conf[-1]
4643            end
4644          }
4645          ret
4646        end
4647      else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
4648        ret = {}
4649        configinfo(slot).each{|key, conf| 
4650          ret[key] = conf[-1] if conf.kind_of?(Array)
4651        }
4652        ret
4653      end
4654    end
4655  end
4656 
4657  class TkObject<TkKernel
4658    extend  TkCore
4659    include Tk
4660    include TkConfigMethod
4661    include TkBindCore
4662 
4663  ### --> definition is moved to TkUtil module
4664  #  def path
4665  #    @path
4666  #  end
4667 
4668    def epath
4669      @path
4670    end
4671 
4672    def to_eval
4673      @path
4674    end
4675 
4676    def tk_send(cmd, *rest)
4677      tk_call(path, cmd, *rest)
4678    end
4679    def tk_send_without_enc(cmd, *rest)
4680      tk_call_without_enc(path, cmd, *rest)
4681    end
4682    def tk_send_with_enc(cmd, *rest)
4683      tk_call_with_enc(path, cmd, *rest)
4684    end
4685    # private :tk_send, :tk_send_without_enc, :tk_send_with_enc
4686 
4687    def tk_send_to_list(cmd, *rest)
4688      tk_call_to_list(path, cmd, *rest)
4689    end
4690    def tk_send_to_list_without_enc(cmd, *rest)
4691      tk_call_to_list_without_enc(path, cmd, *rest)
4692    end
4693    def tk_send_to_list_with_enc(cmd, *rest)
4694      tk_call_to_list_with_enc(path, cmd, *rest)
4695    end
4696    def tk_send_to_simplelist(cmd, *rest)
4697      tk_call_to_simplelist(path, cmd, *rest)
4698    end
4699    def tk_send_to_simplelist_without_enc(cmd, *rest)
4700      tk_call_to_simplelist_without_enc(path, cmd, *rest)
4701    end
4702    def tk_send_to_simplelist_with_enc(cmd, *rest)
4703      tk_call_to_simplelist_with_enc(path, cmd, *rest)
4704    end
4705 
4706    def method_missing(id, *args)
4707      name = id.id2name
4708      case args.length
4709      when 1
4710        if name[-1] == ?=
4711          configure name[0..-2], args[0]
4712          args[0]
4713        else
4714          configure name, args[0]
4715          self
4716        end
4717      when 0
4718        begin
4719          cget(name)
4720        rescue
4721          if self.kind_of?(TkWindow)
4722            fail NameError, 
4723                 "unknown option '#{id}' for #{self.inspect} (deleted widget?)"
4724          else
4725            super(id, *args)
4726          end
4727  #        fail NameError, 
4728  #             "undefined local variable or method `#{name}' for #{self.to_s}", 
4729  #             error_at
4730        end
4731      else
4732        super(id, *args)
4733  #      fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at
4734      end
4735    end
4736 
4737  =begin
4738    def [](id)
4739      cget(id)
4740    end
4741 
4742    def []=(id, val)
4743      configure(id, val)
4744      val
4745    end
4746  =end
4747 
4748    def event_generate(context, keys=nil)
4749      if context.kind_of?(TkEvent::Event)
4750        context.generate(self, ((keys)? keys: {}))
4751      elsif keys
4752        #tk_call('event', 'generate', path, 
4753        #       "<#{tk_event_sequence(context)}>", *hash_kv(keys))
4754        tk_call_without_enc('event', 'generate', path, 
4755                            "<#{tk_event_sequence(context)}>", 
4756                            *hash_kv(keys, true))
4757      else
4758        #tk_call('event', 'generate', path, "<#{tk_event_sequence(context)}>")
4759        tk_call_without_enc('event', 'generate', path, 
4760                            "<#{tk_event_sequence(context)}>")
4761      end
4762    end
4763 
4764    def tk_trace_variable(v)
4765      #unless v.kind_of?(TkVariable)
4766      #  fail(ArgumentError, "type error (#{v.class}); must be TkVariable object")
4767      #end
4768      v
4769    end
4770    private :tk_trace_variable
4771 
4772    def destroy
4773      #tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id
4774    end
4775  end
4776 
4777 
4778  class TkWindow<TkObject
4779    include TkWinfo
4780    extend TkBindCore
4781    include Tk::Wm_for_General
4782 
4783    @@WIDGET_INSPECT_FULL = false
4784    def TkWindow._widget_inspect_full_?
4785      @@WIDGET_INSPECT_FULL
4786    end
4787    def TkWindow._widget_inspect_full_=(mode)
4788      @@WIDGET_INSPECT_FULL = (mode && true) || false
4789    end
4790 
4791    TkCommandNames = [].freeze
4792    ## ==> If TkCommandNames[0] is a string (not a null string), 
4793    ##     assume the string is a Tcl/Tk's create command of the widget class. 
4794    WidgetClassName = ''.freeze
4795    # WidgetClassNames[WidgetClassName] = self  
4796    ## ==> If self is a widget class, entry to the WidgetClassNames table.
4797    def self.to_eval
4798      self::WidgetClassName
4799    end
4800 
4801    def initialize(parent=nil, keys=nil)
4802      if parent.kind_of? Hash
4803        keys = _symbolkey2str(parent)
4804        parent = keys.delete('parent')
4805        widgetname = keys.delete('widgetname')
4806        install_win(if parent then parent.path end, widgetname)
4807        without_creating = keys.delete('without_creating')
4808        # if without_creating && !widgetname 
4809        #   fail ArgumentError, 
4810        #        "if set 'without_creating' to true, need to define 'widgetname'"
4811        # end
4812      elsif keys
4813        keys = _symbolkey2str(keys)
4814        widgetname = keys.delete('widgetname')
4815        install_win(if parent then parent.path end, widgetname)
4816        without_creating = keys.delete('without_creating')
4817        # if without_creating && !widgetname 
4818        #   fail ArgumentError, 
4819        #        "if set 'without_creating' to true, need to define 'widgetname'"
4820        # end
4821      else
4822        install_win(if parent then parent.path end)
4823      end
4824      if self.method(:create_self).arity == 0
4825        p 'create_self has no arg' if $DEBUG
4826        create_self unless without_creating
4827        if keys
4828          # tk_call @path, 'configure', *hash_kv(keys)
4829          configure(keys)
4830        end
4831      else
4832        p 'create_self has args' if $DEBUG
4833        fontkeys = {}
4834        methodkeys = {}
4835        if keys
4836          #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|
4837          #  fontkeys[key] = keys.delete(key) if keys.key?(key)
4838          #}
4839          __font_optkeys.each{|key|
4840            fkey = key.to_s
4841            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
4842 
4843            fkey = "kanji#{key}"
4844            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
4845 
4846            fkey = "latin#{key}"
4847            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
4848 
4849            fkey = "ascii#{key}"
4850            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
4851          }
4852 
4853          __optkey_aliases.each{|alias_name, real_name|
4854            alias_name = alias_name.to_s
4855            if keys.has_key?(alias_name)
4856              keys[real_name.to_s] = keys.delete(alias_name)
4857            end
4858          }
4859 
4860          __methodcall_optkeys.each{|key|
4861            key = key.to_s
4862            methodkeys[key] = keys.delete(key) if keys.key?(key)
4863          }
4864 
4865          __ruby2val_optkeys.each{|key, method|
4866            key = key.to_s
4867            keys[key] = method.call(keys[key]) if keys.has_key?(key)
4868          }
4869        end
4870        if without_creating && keys
4871          #configure(keys)
4872          configure(__conv_keyonly_opts(keys))
4873        else
4874          #create_self(keys)
4875          create_self(__conv_keyonly_opts(keys))
4876        end
4877        font_configure(fontkeys) unless fontkeys.empty?
4878        configure(methodkeys) unless methodkeys.empty?
4879      end
4880    end
4881 
4882    def create_self(keys)
4883      # may need to override
4884      begin
4885        cmd = self.class::TkCommandNames[0]
4886        fail unless (cmd.kind_of?(String) && cmd.length > 0)
4887      rescue
4888        fail RuntimeError, "class #{self.class} may be an abstract class"
4889      end
4890 
4891      if keys and keys != None
4892        unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
4893          tk_call_without_enc(cmd, @path, *hash_kv(keys, true))
4894        else
4895          begin
4896            tk_call_without_enc(cmd, @path, *hash_kv(keys, true))
4897          rescue => e
4898            tk_call_without_enc(cmd, @path)
4899            keys = __check_available_configure_options(keys)
4900            unless keys.empty?
4901              begin
4902                # try to configure
4903                configure(keys)
4904              rescue
4905                # fail => includes options adaptable when creattion only?
4906                begin
4907                  tk_call_without_enc('destroy', @path)
4908                rescue
4909                  # cannot rescue options error
4910                  fail e 
4911                else
4912                  # re-create widget
4913                  tk_call_without_enc(cmd, @path, *hash_kv(keys, true))
4914                end
4915              end
4916            end
4917          end
4918        end
4919      else
4920        tk_call_without_enc(cmd, @path)
4921      end
4922    end
4923    private :create_self
4924 
4925    def inspect
4926      if @@WIDGET_INSPECT_FULL
4927        super
4928      else
4929        str = super
4930        str[0..(str.index(' '))] << '@path=' << @path.inspect << '>'
4931      end
4932    end
4933 
4934    def exist?
4935      TkWinfo.exist?(self)
4936    end
4937 
4938    def bind_class
4939      @db_class || self.class()
4940    end
4941 
4942    def database_classname
4943      TkWinfo.classname(self)
4944    end
4945    def database_class
4946      name = database_classname()
4947      if WidgetClassNames[name]
4948        WidgetClassNames[name]
4949      else
4950        TkDatabaseClass.new(name)
4951      end
4952    end
4953    def self.database_classname
4954      self::WidgetClassName
4955    end
4956    def self.database_class
4957      WidgetClassNames[self::WidgetClassName]
4958    end
4959 
4960    def pack(keys = nil)
4961      #tk_call_without_enc('pack', epath, *hash_kv(keys, true))
4962      if keys
4963        TkPack.configure(self, keys)
4964      else
4965        TkPack.configure(self)
4966      end
4967      self
4968    end
4969 
4970    def pack_in(target, keys = nil)
4971      if keys
4972        keys = keys.dup
4973        keys['in'] = target
4974      else
4975        keys = {'in'=>target}
4976      end
4977      #tk_call 'pack', epath, *hash_kv(keys)
4978      TkPack.configure(self, keys)
4979      self
4980    end
4981 
4982    def pack_forget
4983      #tk_call_without_enc('pack', 'forget', epath)
4984      TkPack.forget(self)
4985      self
4986    end
4987    alias unpack pack_forget
4988 
4989    def pack_config(slot, value=None)
4990      #if slot.kind_of? Hash
4991      #  tk_call 'pack', 'configure', epath, *hash_kv(slot)
4992      #else
4993      #  tk_call 'pack', 'configure', epath, "-#{slot}", value
4994      #end
4995      if slot.kind_of? Hash
4996        TkPack.configure(self, slot)
4997      else
4998        TkPack.configure(self, slot=>value)
4999      end
5000    end
5001    alias pack_configure pack_config
5002 
5003    def pack_info()
5004      #ilist = list(tk_call('pack', 'info', epath))
5005      #info = {}
5006      #while key = ilist.shift
5007      #  info[key[1..-1]] = ilist.shift
5008      #end
5009      #return info
5010      TkPack.info(self)
5011    end
5012 
5013    def pack_propagate(mode=None)
5014      #if mode == None
5015      #  bool(tk_call('pack', 'propagate', epath))
5016      #else
5017      #  tk_call('pack', 'propagate', epath, mode)
5018      #  self
5019      #end
5020      if mode == None
5021        TkPack.propagate(self)
5022      else
5023        TkPack.propagate(self, mode)
5024        self
5025      end
5026    end
5027 
5028    def pack_slaves()
5029      #list(tk_call('pack', 'slaves', epath))
5030      TkPack.slaves(self)
5031    end
5032 
5033    def grid(keys = nil)
5034      #tk_call 'grid', epath, *hash_kv(keys)
5035      if keys
5036        TkGrid.configure(self, keys)
5037      else
5038        TkGrid.configure(self)
5039      end
5040      self
5041    end
5042 
5043    def grid_in(target, keys = nil)
5044      if keys
5045        keys = keys.dup
5046        keys['in'] = target
5047      else
5048        keys = {'in'=>target}
5049      end
5050      #tk_call 'grid', epath, *hash_kv(keys)
5051      TkGrid.configure(self, keys)
5052      self
5053    end
5054 
5055    def grid_anchor(anchor=None)
5056      if anchor == None
5057        TkGrid.anchor(self)
5058      else
5059        TkGrid.anchor(self, anchor)
5060        self
5061      end
5062    end
5063 
5064    def grid_forget
5065      #tk_call('grid', 'forget', epath)
5066      TkGrid.forget(self)
5067      self
5068    end
5069    alias ungrid grid_forget
5070 
5071    def grid_bbox(*args)
5072      #list(tk_call('grid', 'bbox', epath, *args))
5073      TkGrid.bbox(self, *args)
5074    end
5075 
5076    def grid_config(slot, value=None)
5077      #if slot.kind_of? Hash
5078      #  tk_call 'grid', 'configure', epath, *hash_kv(slot)
5079      #else
5080      #  tk_call 'grid', 'configure', epath, "-#{slot}", value
5081      #end
5082      if slot.kind_of? Hash
5083        TkGrid.configure(self, slot)
5084      else
5085        TkGrid.configure(self, slot=>value)
5086      end
5087    end
5088    alias grid_configure grid_config
5089 
5090    def grid_columnconfig(index, keys)
5091      #tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys))
5092      TkGrid.columnconfigure(self, index, keys)
5093    end
5094    alias grid_columnconfigure grid_columnconfig
5095    alias grid_column grid_columnconfig
5096 
5097    def grid_rowconfig(index, keys)
5098      #tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys))
5099      TkGrid.rowconfigure(self, index, keys)
5100    end
5101    alias grid_rowconfigure grid_rowconfig
5102    alias grid_row grid_rowconfig
5103 
5104    def grid_columnconfiginfo(index, slot=nil)
5105      #if slot
5106      #  tk_call('grid', 'columnconfigure', epath, index, "-#{slot}").to_i
5107      #else
5108      #  ilist = list(tk_call('grid', 'columnconfigure', epath, index))
5109      #  info = {}
5110      #  while key = ilist.shift
5111      #   info[key[1..-1]] = ilist.shift
5112      #  end
5113      #  info
5114      #end
5115      TkGrid.columnconfiginfo(self, index, slot)
5116    end
5117 
5118    def grid_rowconfiginfo(index, slot=nil)
5119      #if slot
5120      #  tk_call('grid', 'rowconfigure', epath, index, "-#{slot}").to_i
5121      #else
5122      #  ilist = list(tk_call('grid', 'rowconfigure', epath, index))
5123      #  info = {}
5124      #  while key = ilist.shift
5125      #   info[key[1..-1]] = ilist.shift
5126      #  end
5127      #  info
5128      #end
5129      TkGrid.rowconfiginfo(self, index, slot)
5130    end
5131 
5132    def grid_info()
5133      #list(tk_call('grid', 'info', epath))
5134      TkGrid.info(self)
5135    end
5136 
5137    def grid_location(x, y)
5138      #list(tk_call('grid', 'location', epath, x, y))
5139      TkGrid.location(self, x, y)
5140    end
5141 
5142    def grid_propagate(mode=None)
5143      #if mode == None
5144      #  bool(tk_call('grid', 'propagate', epath))
5145      #else
5146      #  tk_call('grid', 'propagate', epath, mode)
5147      #  self
5148      #end
5149      if mode == None
5150        TkGrid.propagate(self)
5151      else
5152        TkGrid.propagate(self, mode)
5153        self
5154      end
5155    end
5156 
5157    def grid_remove()
5158      #tk_call 'grid', 'remove', epath
5159      TkGrid.remove(self)
5160      self
5161    end
5162 
5163    def grid_size()
5164      #list(tk_call('grid', 'size', epath))
5165      TkGrid.size(self)
5166    end
5167 
5168    def grid_slaves(args)
5169      #list(tk_call('grid', 'slaves', epath, *hash_kv(args)))
5170      TkGrid.slaves(self, args)
5171    end
5172 
5173    def place(keys)
5174      #tk_call 'place', epath, *hash_kv(keys)
5175      TkPlace.configure(self, keys)
5176      self
5177    end
5178 
5179    def place_in(target, keys = nil)
5180      if keys
5181        keys = keys.dup
5182        keys['in'] = target
5183      else
5184        keys = {'in'=>target}
5185      end
5186      #tk_call 'place', epath, *hash_kv(keys)
5187      TkPlace.configure(self, keys)
5188      self
5189    end
5190 
5191    def  place_forget
5192      #tk_call 'place', 'forget', epath
5193      TkPlace.forget(self)
5194      self
5195    end
5196    alias unplace place_forget
5197 
5198    def place_config(slot, value=None)
5199      #if slot.kind_of? Hash
5200      #  tk_call 'place', 'configure', epath, *hash_kv(slot)
5201      #else
5202      #  tk_call 'place', 'configure', epath, "-#{slot}", value
5203      #end
5204      TkPlace.configure(self, slot, value)
5205    end
5206    alias place_configure place_config
5207 
5208    def place_configinfo(slot = nil)
5209      # for >= Tk8.4a2 ?
5210      #if slot
5211      #  conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") )
5212      #  conf[0] = conf[0][1..-1]
5213      #  conf
5214      #else
5215      #  tk_split_simplelist(tk_call('place', 
5216      #                             'configure', epath)).collect{|conflist|
5217      #   conf = tk_split_simplelist(conflist)
5218      #   conf[0] = conf[0][1..-1]
5219      #   conf
5220      #  }
5221      #end
5222      TkPlace.configinfo(self, slot)
5223    end
5224 
5225    def place_info()
5226      #ilist = list(tk_call('place', 'info', epath))
5227      #info = {}
5228      #while key = ilist.shift
5229      #  info[key[1..-1]] = ilist.shift
5230      #end
5231      #return info
5232      TkPlace.info(self)
5233    end
5234 
5235    def place_slaves()
5236      #list(tk_call('place', 'slaves', epath))
5237      TkPlace.slaves(self)
5238    end
5239 
5240    def set_focus(force=false)
5241      if force
5242        tk_call_without_enc('focus', '-force', path)
5243      else
5244        tk_call_without_enc('focus', path)
5245      end
5246      self
5247    end
5248    alias focus set_focus
5249 
5250    def grab(opt = nil)
5251      unless opt
5252        tk_call_without_enc('grab', 'set', path)
5253        return self
5254      end
5255 
5256      case opt
5257      when 'set', :set
5258        tk_call_without_enc('grab', 'set', path)
5259        return self
5260      when 'global', :global
5261        #return(tk_call('grab', 'set', '-global', path))
5262        tk_call_without_enc('grab', 'set', '-global', path)
5263        return self
5264      when 'release', :release
5265        #return tk_call('grab', 'release', path)
5266        tk_call_without_enc('grab', 'release', path)
5267        return self
5268      when 'current', :current
5269        return window(tk_call_without_enc('grab', 'current', path))
5270      when 'status', :status
5271        return tk_call_without_enc('grab', 'status', path)
5272      else
5273        return tk_call_without_enc('grab', opt, path)
5274      end
5275    end
5276 
5277    def grab_current
5278      grab('current')
5279    end
5280    alias current_grab grab_current
5281    def grab_release
5282      grab('release')
5283    end
5284    alias release_grab grab_release
5285    def grab_set
5286      grab('set')
5287    end
5288    alias set_grab grab_set
5289    def grab_set_global
5290      grab('global')
5291    end
5292    alias set_global_grab grab_set_global
5293    def grab_status
5294      grab('status')
5295    end
5296 
5297    def lower(below=None)
5298      # below = below.epath if below.kind_of?(TkObject)
5299      below = _epath(below)
5300      tk_call 'lower', epath, below
5301      self
5302    end
5303    alias lower_window lower
5304    def raise(above=None)
5305      #above = above.epath if above.kind_of?(TkObject)
5306      above = _epath(above)
5307      tk_call 'raise', epath, above
5308      self
5309    end
5310    alias raise_window raise
5311 
5312    def command(cmd=nil, &b)
5313      if cmd
5314        configure_cmd('command', cmd)
5315      elsif b
5316        configure_cmd('command', Proc.new(&b))
5317      else
5318        cget('command')
5319      end
5320    end
5321 
5322    def colormodel(model=None)
5323      tk_call('tk', 'colormodel', path, model)
5324      self
5325    end
5326 
5327    def caret(keys=nil)
5328      TkXIM.caret(path, keys)
5329    end
5330 
5331    def destroy
5332      super
5333      children = []
5334      rexp = /^#{self.path}\.[^.]+$/
5335      TkCore::INTERP.tk_windows.each{|path, obj|
5336        children << [path, obj] if path =~ rexp
5337      }
5338      if defined?(@cmdtbl)
5339        for id in @cmdtbl
5340          uninstall_cmd id
5341        end
5342      end
5343 
5344      children.each{|path, obj|
5345        obj.instance_eval{
5346          if defined?(@cmdtbl)
5347            for id in @cmdtbl
5348              uninstall_cmd id
5349            end
5350          end
5351        }
5352        TkCore::INTERP.tk_windows.delete(path)
5353      }
5354 
5355      begin
5356        tk_call_without_enc('destroy', epath)
5357      rescue
5358      end
5359      uninstall_win
5360    end
5361 
5362    def wait_visibility(on_thread = true)
5363      if $SAFE >= 4
5364        fail SecurityError, "can't wait visibility at $SAFE >= 4"
5365      end
5366      on_thread &= (Thread.list.size != 1)
5367      if on_thread
5368        INTERP._thread_tkwait('visibility', path)
5369      else
5370        INTERP._invoke('tkwait', 'visibility', path)
5371      end
5372    end
5373    def eventloop_wait_visibility
5374      wait_visibility(false)
5375    end
5376    def thread_wait_visibility
5377      wait_visibility(true)
5378    end
5379    alias wait wait_visibility
5380    alias tkwait wait_visibility
5381    alias eventloop_wait eventloop_wait_visibility
5382    alias eventloop_tkwait eventloop_wait_visibility
5383    alias eventloop_tkwait_visibility eventloop_wait_visibility
5384    alias thread_wait thread_wait_visibility
5385    alias thread_tkwait thread_wait_visibility
5386    alias thread_tkwait_visibility thread_wait_visibility
5387 
5388    def wait_destroy(on_thread = true)
5389      if $SAFE >= 4
5390        fail SecurityError, "can't wait destroy at $SAFE >= 4"
5391      end
5392      on_thread &= (Thread.list.size != 1)
5393      if on_thread
5394        INTERP._thread_tkwait('window', epath)
5395      else
5396        INTERP._invoke('tkwait', 'window', epath)
5397      end
5398    end
5399    alias wait_window wait_destroy
5400    def eventloop_wait_destroy
5401      wait_destroy(false)
5402    end
5403    alias eventloop_wait_window eventloop_wait_destroy
5404    def thread_wait_destroy
5405      wait_destroy(true)
5406    end
5407    alias thread_wait_window thread_wait_destroy
5408 
5409    alias tkwait_destroy wait_destroy
5410    alias tkwait_window wait_destroy
5411 
5412    alias eventloop_tkwait_destroy eventloop_wait_destroy
5413    alias eventloop_tkwait_window eventloop_wait_destroy
5414 
5415    alias thread_tkwait_destroy thread_wait_destroy
5416    alias thread_tkwait_window thread_wait_destroy
5417 
5418    def bindtags(taglist=nil)
5419      if taglist
5420        fail ArgumentError, "taglist must be Array" unless taglist.kind_of? Array
5421        tk_call('bindtags', path, taglist)
5422        taglist
5423      else
5424        list(tk_call('bindtags', path)).collect{|tag|
5425          if tag.kind_of?(String) 
5426            if cls = WidgetClassNames[tag]
5427              cls
5428            elsif btag = TkBindTag.id2obj(tag)
5429              btag
5430            else
5431              tag
5432            end
5433          else
5434            tag
5435          end
5436        }
5437      end
5438    end
5439 
5440    def bindtags=(taglist)
5441      bindtags(taglist)
5442      taglist
5443    end
5444 
5445    def bindtags_shift
5446      taglist = bindtags
5447      tag = taglist.shift
5448      bindtags(taglist)
5449      tag
5450    end
5451 
5452    def bindtags_unshift(tag)
5453      bindtags(bindtags().unshift(tag))
5454    end
5455  end
5456  TkWidget = TkWindow
5457 
5458  # freeze core modules
5459  #TclTkLib.freeze
5460  #TclTkIp.freeze
5461  #TkUtil.freeze
5462  #TkKernel.freeze
5463  #TkComm.freeze
5464  #TkComm::Event.freeze
5465  #TkCore.freeze
5466  #Tk.freeze
5467 
5468  module Tk
5469    RELEASE_DATE = '2008-05-23'.freeze
5470 
5471    autoload :AUTO_PATH,        'tk/variable'
5472    autoload :TCL_PACKAGE_PATH, 'tk/variable'
5473    autoload :PACKAGE_PATH,     'tk/variable'
5474    autoload :TCL_LIBRARY_PATH, 'tk/variable'
5475    autoload :LIBRARY_PATH,     'tk/variable'
5476    autoload :TCL_PRECISION,    'tk/variable'
5477  end
5478 
5479  # call setup script for Tk extension libraries (base configuration)
5480  begin
5481    require 'tkextlib/version.rb'
5482    require 'tkextlib/setup.rb'
5483  rescue LoadError
5484    # ignore
5485  end