~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to ext/tk/lib/tk.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

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