Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
#!/usr/bin/ruby
$KCODE = 'e'
require 'tk'
class Integer
#-----------------------------------------------------------
#
# 序数を返すメソッドを追加
#
def to_s_th
unit = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'][self % 10]
unit = 'th' if(self / 10 % 10 == 1)
self.to_s + unit
end
end
#-------------------------------------------------------------------------------
#
# TkOsziStatus
#
class TkOsziStatus < TkLabel
def initialize
@coupling = ['GND', 'AC', 'DC', '???']
@range = ['1V', '10V', '100V', '???']
@timebase = ['50ns', '100ns', '0.5us', '1us', '5us', '10us', '50us', '0.1ms', '0.5ms', '1ms', '2ms']
@trigger = {0x40 => '+INTERN', 0x20 => '-INTERN', 0x10 => '+EXTERN', 0x08 => '-EXTERN', 0x00 => 'FREE RUN'}
@level = {0x40 => '-0.3', 0x20 => '-0.1', 0x10 => '+0.1', 0x08 => '+0.3', 0x04 => '+0.5', 0x00 => '-0.5'}
super
end
#-----------------------------------------------------------
#
# ステータスセット
#
def set(data)
info = ''
info += @coupling[(data[0] & 0x30) >> 4]
info += @range[(data[0] & 0x0C) >> 2]
info += @timebase[ data[1]]
info += @trigger[ data[2] & 0x78]
info += @level[ data[3]] # if()
self.text(info)
end
end
#-------------------------------------------------------------------------------
#
# TkSignalCanvas
#
class TkSignalCanvas < TkCanvas
attr_reader :vx
attr_reader :vy
attr_reader :vy2
attr_reader :ymax
def initialize
@vx = 5; @vy = 2
@waves = Hash.new
@waveStyles = {
'q' => ['blue', 1],
'w' => ['red', 1],
'e' => ['red', 1],
'r' => ['green', 1],
't' => ['cyan', 1],
'y' => ['yellow', 1],
'u' => ['white', 1],
'i' => ['green', 3],
'o' => ['yellow', 2],
}
@hideData = Array.new
(0..127).each {|i|
@hideData.push(-1)
}
super
end
#-----------------------------------------------------------
#
# スコープ画面の初期化
#
def initScope(vx, vy)
self.width( 127 * (@vx = vx) + 1 + 16) # 描画サイズ決定
self.height(126 * (@vy = vy) + 1 + 16)
@ymax = 63 * (@vy2 = @vy * 2) + 8
self.find_all.each {|item| item.delete} # 全ての描画要素を削除
bg = TkcRectangle.new(self, 0, 0, self.width, self.height) {
fill('#004000')
}
# 目盛り線を設定
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 127].each {|x|
TkcLine.new(self, x * @vx + 8, 8, x * @vx + 8, @ymax) {
width(1)
fill('red')
}
}
[0, 63, 126].each {|y|
TkcLine.new(self, 8, @ymax - (y * @vy), 127 * @vx + 8, @ymax - (y * @vy)) {
width(1)
fill('red')
}
}
# 波形を設定(下準備)
['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o'].each {|key|
@waves[key] = TkcLines.new(self)
@waves[key].fill(@waveStyles[key][0])
@waves[key].width(@waveStyles[key][1])
}
# 米印が回る
end
#-----------------------------------------------------------
#
# 波形を変形
#
def formWave(key, signalData)
@waves[key].form(signalData)
end
#-----------------------------------------------------------
#
# 波形を隠す
#
def hideWave(key)
@waves[key].form(@hideData)
end
end
#-------------------------------------------------------------------------------
#
# TkcLines - 多節点の線分
#
class TkcLines < Array
#-----------------------------------------------------------
#
# 波形の部品を定義する
#
def initialize(canvas)
@canvas = canvas # 各パラメタのみ受け取るよう修正
(0..126).each {|i|
self.push(TkcLine.new(@canvas))
}
# super
end
#-----------------------------------------------------------
#
# 波形を変形する
#
def form(sample)
(0..126).each {|i|
j = i + 1
self[i].coords( i * @canvas.vx + 8, @canvas.ymax - (sample[i] * @canvas.vy2),
j * @canvas.vx + 8, @canvas.ymax - (sample[j] * @canvas.vy2))
# self[i].fill(sprintf('#00%02x00', 255 - (sample[i] - sample[j]).abs))
}
end
#-----------------------------------------------------------
#
# 波形の色を設定する
#
def fill(color)
self.each {|t|
t.fill(color)
}
end
#-----------------------------------------------------------
#
# 波形の太さ設定する
#
def width(width)
self.each {|t|
t.width(width)
}
end
end
#-------------------------------------------------------------------------------
#
# 波形の履歴キュークラス
#
class FormHistory < Array
#-----------------------------------------------------------
#
# コンストラクタ
#
def initialize(size)
@size = size
# super
end
#-----------------------------------------------------------
#
# 過去xxx回分までの波形を履歴キューに溜める
#
def store(samples)
self.push(samples)
self.shift while(self.length > @size)
end
end
#-------------------------------------------------------------------------------
#
# 波形のスナップショットエリアクラス
#
class FormSnap < Array
#-----------------------------------------------------------
#
# 履歴キュー内の波形をスナップエリアにコピー
#
def shot(forms)
self.clear
forms.each {|samples|
self.push(samples)
}
@cursor = self.length - 1 # カーソルを最後の波形に移動
end
#-----------------------------------------------------------
#
# スナップエリア内のカーソル処理
#
def cursorPrev()
@cursor ? (@cursor = (@cursor + self.length - 1) % self.length) : nil
end
def cursorNext()
@cursor ? (@cursor = (@cursor + 1) % self.length) : nil
end
def cursorOn()
@cursor ? @cursor : nil
end
# @cursor ? (@cursor > 0 ? @cursor -= 1 : @cursor) : nil
# @cursor ? (@cursor < (self.length - 1) ? @cursor += 1 : @cursor) : nil
#-----------------------------------------------------------
#
# スナップエリアをファイルに保存 クラス外に出す
#
def writeFile(name)
File.open(name, 'w') {|file|
file.write(sprintf("==AnotherPenScopeSnapshotData==\n"))
self.each {|samples|
file.write(samples.join(',') + "\n")
}
}
end
#-----------------------------------------------------------
#
# スナップエリアをファイルから読む
#
# def readFile(name)
# text = ''
# File.open(name) {|file|
# unless file.readline =~ /^==MasterZapperData=/
# # Ruby/Tk 内では raise が予約語になるので同義の fail を使う
# fail "Signal file format error - #{name}"
# end
# text = file.read
# }
# text.tr!(" \r\n", '')
# @signalData = text.split(',')
# self.draw
# end
end
#-------------------------------------------------------------------------------
#
# 比較参照用の波形クラス
#
class FormRefer < Hash
#-----------------------------------------------------------
#
# キャンバスのインスタンスを受け取っておく
#
def initialize(canvas)
@canvas = canvas
# super
end
#-----------------------------------------------------------
#
# 比較参照用の波形を、強制表示
#
def show(key, samples)
self.delete(key)
self[key] = ['show', samples] # ->登録表示
@canvas.formWave(key, self[key][1])
'force store'
end
#-----------------------------------------------------------
#
# 比較参照用の波形を、強制非表示
#
def hide(key)
if(self[key])
self[key][0] = 'hide' # ->非表示
@canvas.hideWave(key)
'force hide'
end
end
#-----------------------------------------------------------
#
# 比較参照用の波形を、表示中なら更新、非表示中なら無視
#
def indicate(key, samples)
if(self[key])
if(self[key][0] == 'show') # 表示中
self[key] = ['show', samples] # 登録表示
@canvas.formWave(key, self[key][1])
'showin'
elsif(self[key][0] == 'hide') # 非表示中
self[key] = ['hide', samples]
@canvas.hideWave(key)
'hiden'
else
fail "Internal error.\n"
end
else
self[key] = ['show', samples] # 登録表示
@canvas.formWave(key, self[key][1])
'store'
end
end
#-----------------------------------------------------------
#
# 比較参照用の波形を、登録表示->非表示<->再表示
#
def action(key, samples)
if(self[key])
if(self[key][0] == 'show') # ->非表示
self[key][0] = 'hide'
@canvas.hideWave(key)
'hide'
elsif(self[key][0] == 'hide') # ->再表示
self[key][0] = 'show'
@canvas.formWave(key, self[key][1])
'show'
else
fail "Internal error.\n"
end
else
self[key] = ['show', samples] # ->登録表示
@canvas.formWave(key, self[key][1])
self.hide('o') # カーソルは非表示に
'store'
end
end
#-----------------------------------------------------------
#
# 比較参照用の波形を削除
#
def remove(key)
if(self.delete(key))
@canvas.hideWave(key)
'remove'
else
'not registered'
end
end
end
#===============================================================================
#
# Main
#
system "stty 19200 raw -crtscts cs7 -echo < /dev/com1"
rs232c = open("/dev/com1", "r")
root = TkRoot.new {
title('Another PenScope')
}
#-------------------------------------------------------------------------------
#
# Define Canvas for Signal
#
signalCanvas = TkSignalCanvas.new
history = FormHistory.new(100)
snap = FormSnap.new
refer = FormRefer.new(signalCanvas)
#-------------------------------------------------------------------------------
#
# Define StatusBar
#
statusBar = TkLabel.new {
# TkFont.new
# puts *TkFont.names
# puts *TkFont.families
text('Status')
font TkFont.new(['osaka', 10, ['bold']])
relief('sunken')
borderwidth(1)
anchor('w')
}
#-------------------------------------------------------------------------------
#
# Define osziStatusBar
#
osziStatusBar = TkOsziStatus.new {
text('Status')
font TkFont.new(['osaka', 10, ['bold']])
relief('sunken')
borderwidth(1)
anchor('w')
}
#-------------------------------------------------------------------------------
#
# Define AboutBox
#
def aboutBox
Tk.messageBox(
'icon'=>'info',
'type'=>'ok',
'title'=>'About Another PenScope',
'message'=><'Open Another PenScope snapshot file',
'filetypes'=>fileTypes,
'initialfile'=>'*.aps',
'defaultextension'=>'.aps'
)
begin
signalCanvas.readFile(fileName)
statusBar.text(fileName)
rescue
statusBar.text($!)
end unless fileName == ''
}],
'---', # separator
['Save', proc{
fileName = Tk.getSaveFile(
'title'=>'Save Another PenScope snapshot file',
'filetypes'=>fileTypes,
'initialfile'=>'Untitled.aps', # insert current filename
'defaultextension'=>'.aps'
)
begin
snap.writeFile(fileName)
statusBar.text(fileName)
rescue
statusBar.text($!)
end unless fileName == ''
}],
'---',
['Exit', proc{exit}]
],
[['View', 0],
# add with radio
],
[['I/O', 0],
# add with check
],
[['Help', 0],
['About', proc{aboutBox}]
]
]
mainMenu = TkMenubar.new(nil, menu_spec, 'tearoff'=>true)
vx = TkVariable.new(signalCanvas.vx)
[1, 2, 3, 4, 5, 6].each {|v|
mainMenu[1][1].add('radio',
'label' =>['', 'x1','x2','x3','x4','x5','x6'][v],
'command' =>proc{ signalCanvas.initScope(vx.to_i, (vx.to_i) / 2 + 1) },
'variable'=>vx,
'value' =>v)
}
isAutoZap = TkVariable.new(1)
isAutoSave = TkVariable.new(1)
mainMenu[2][1].add('command', {'label'=>'Zap', 'command'=>proc{aboutBox}})
mainMenu[2][1].add('check', {'label'=>'AutoZap', 'variable'=>isAutoZap})
mainMenu[2][1].add('separator')
mainMenu[2][1].add('command', {'label'=>'Master', 'command'=>proc{aboutBox}})
mainMenu[2][1].add('check', {'label'=>'AutoSave', 'variable'=>isAutoSave})
root.bind('F1', proc{ aboutBox }) # aboutダイアログ
root.bind('s', proc{ # 過去xxx波形をスナップ
if(snapCursor = snap.shot(history))
act = refer.show('o', snap[snapCursor])
statusBar.text('Snappshot last ' + snap.length.to_s + ' waves.' + act)
end
})
root.bind('k', proc{ # スナップ内を遡る
if(snapCursor = snap.cursorPrev())
act = refer.show('o', snap[snapCursor])
statusBar.text((snapCursor + 1).to_s_th + '/' + snap.length.to_s + ' wave in snapshot.' + act)
end
})
root.bind('j', proc{ # スナップを進む
if(snapCursor = snap.cursorNext())
act = refer.show('o', snap[snapCursor])
statusBar.text((snapCursor + 1).to_s_th + '/' + snap.length.to_s + ' wave in snapshot.' + act)
end
})
def referAction(key, refer, snap, statusBar)
if(snapCursor = snap.cursorOn())
act = refer.action(key, snap[snapCursor])
statusBar.text(act + ' refer wave to "' + key + '" area.')
end
end
root.bind('q', proc{ referAction('q', refer, snap, statusBar) })
root.bind('w', proc{ referAction('w', refer, snap, statusBar) })
root.bind('e', proc{ referAction('e', refer, snap, statusBar) })
root.bind('r', proc{ referAction('r', refer, snap, statusBar) })
root.bind('t', proc{ referAction('t', refer, snap, statusBar) })
root.bind('y', proc{ referAction('y', refer, snap, statusBar) })
root.bind('u', proc{ referAction('u', refer, snap, statusBar) })
root.bind('i', proc{ referAction('i', refer, snap, statusBar) })
root.bind('o', proc{ referAction('o', refer, snap, statusBar) })
def referRemove(key, refer, statusBar)
act = refer.remove(key)
statusBar.text(act + ' refer wave at "' + key + '" area.')
end
root.bind('Q', proc{ referRemove('q', refer, statusBar) })
root.bind('W', proc{ referRemove('w', refer, statusBar) })
root.bind('E', proc{ referRemove('e', refer, statusBar) })
root.bind('R', proc{ referRemove('r', refer, statusBar) })
root.bind('T', proc{ referRemove('t', refer, statusBar) })
root.bind('Y', proc{ referRemove('y', refer, statusBar) })
root.bind('U', proc{ referRemove('u', refer, statusBar) })
root.bind('I', proc{ referRemove('i', refer, statusBar) })
root.bind('O', proc{ referRemove('o', refer, statusBar) })
#-------------------------------------------------------------------------------
#
# Build Window
#
statusBar.pack('side'=>'bottom', 'fill'=>'x')
mainMenu.pack('side'=>'top', 'fill'=>'x')
osziStatusBar.pack('side'=>'top', 'fill'=>'x')
signalCanvas.pack('fill'=>'both')
if ARGV[0]
begin
signalCanvas.readFile(ARGV[0])
statusBar.text(ARGV[0])
rescue
statusBar.text($!)
end
else
signalCanvas.initScope(5, 2)
end
#-------------------------------------------------------------------------------
#
# 割り込み処理
#
TkAfter.new(10, -1, proc {
samples = Array.new
loop { # パケット切り出し
if(IO.select([rs232c], nil, nil, 5))
c = rs232c.getc
break if(c > 0x6f) # セパレータ発見
samples.push(c)
else
print "Timeout occurred.\n"
break
end
}
if(samples.length == 0) # ダミーパケット
# dummy
elsif(samples.length == 4)
osziStatusBar.set(samples[0, 4])
elsif(samples.length == 133)
history.store(samples[0, 128])
refer.indicate('i', samples[0, 128])
elsif(samples.length == 137)
osziStatusBar.set(samples[0, 4])
history.store(samples[4, 128])
refer.indicate('i', samples[4, 128])
else
print "====protocol error====\n" # パケット長異常
end
}).start
Tk.mainloop