nam.tcl.tk
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:21k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. # Copyright (c) 1993-1994 Regents of the University of California.
  3. # All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions
  7. # are met:
  8. # 1. Redistributions of source code must retain the above copyright
  9. #    notice, this list of conditions and the following disclaimer.
  10. # 2. Redistributions in binary form must reproduce the above copyright
  11. #    notice, this list of conditions and the following disclaimer in the
  12. #    documentation and/or other materials provided with the distribution.
  13. # 3. All advertising materials mentioning features or use of this software
  14. #    must display the following acknowledgement:
  15. # This product includes software developed by the Computer Systems
  16. # Engineering Group at Lawrence Berkeley Laboratory.
  17. # 4. Neither the name of the University nor of the Laboratory may be used
  18. #    to endorse or promote products derived from this software without
  19. #    specific prior written permission.
  20. #
  21. # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. # SUCH DAMAGE.
  32. #
  33. # @(#) $Header: /cvsroot/nsnam/nam-1/nam.tcl.tk,v 1.1.1.1 1997/06/16 22:40:30 mjh Exp $ (LBL)
  34. #
  35. source canvas.tcl
  36. set tk_strictMotif 0
  37. set uscale(m) 1e-3
  38. set uscale(u) 1e-6
  39. set uscale(k) 1e3
  40. set uscale(M) 1e6
  41. proc time2real v {
  42. global uscale
  43. foreach u [array names uscale] {
  44. set k [string first $u $v]
  45. if { $k >= 0 } {
  46. set scale $uscale($u)
  47. break
  48. }
  49. }
  50. if { $k > 0 } {
  51. set v [string range $v 0 [expr $k - 1]]
  52. set v [expr $scale * $v]
  53. }
  54. return $v
  55. }
  56. #XXX
  57. proc bw2real v {
  58. return [time2real $v]
  59. }
  60. #XXX
  61. proc mapf s { return $s }
  62. option add Nam.foundry adobe startupFile
  63. set ff [option get . foundry Nam]
  64. set helv10 [mapf "-$ff-helvetica-medium-r-normal--*-100-75-75-*-*-*-*"]
  65. set helv10b [mapf "-$ff-helvetica-bold-r-normal--*-100-75-75-*-*-*-*"]
  66. set helv10o [mapf "-$ff-helvetica-bold-o-normal--*-100-75-75-*-*-*-*"]
  67. set helv12 [mapf "-$ff-helvetica-medium-r-normal--*-120-75-75-*-*-*-*"]
  68. set helv12b [mapf "-$ff-helvetica-bold-r-normal--*-120-75-75-*-*-*-*"]
  69. set helv14 [mapf "-$ff-helvetica-medium-r-normal--*-140-75-75-*-*-*-*"]
  70. set helv14b [mapf "-$ff-helvetica-bold-r-normal--*-140-75-75-*-*-*-*"]
  71. set times14 [mapf  "-$ff-times-medium-r-normal--*-140-75-75-*-*-*-*"]
  72. option add Nam.viewBackground gray80 startupFile
  73. option add *font $helv12b startupFile
  74. option add *Font $helv12b startupFile
  75. option add Nam.disablefont $helv10o startupFile
  76. option add Nam.smallfont $helv10b startupFile
  77. option add Nam.medfont $helv12b  startupFile
  78. option add Nam.helpFont $times14 startupFile
  79. option add Nam.entryFont $helv10 startupFile
  80. option add *Radiobutton.relief flat startupFile
  81. option add Nam.rate 2ms startupFile
  82. option add Nam.movie 0 startupFile
  83. option add Nam.granularity 40 startupFile
  84. option add Nam.pause 1 startupFile
  85. #
  86. # use 2 pixels of padding by default
  87. #
  88. option add *padX 2 startupFile
  89. option add *padY 2 startupFile
  90. #
  91. # don't put tearoffs in pull-down menus
  92. #
  93. option add *tearOff 0 startupFile
  94. proc smallfont { } {
  95. return [option get . smallfont Nam]
  96. }
  97. proc mediumfont { } {
  98. return [option get . medfont Nam]
  99. }
  100. proc toggle_window w {
  101. if ![winfo exists $w] { build$w }
  102. global created$w
  103. if ![info exists created$w] {
  104. set created$w 1
  105. wm transient $w .
  106. update idletasks
  107. set x [winfo rootx .]
  108. set y [winfo rooty .]
  109. incr y [winfo height .]
  110. incr y -[winfo reqheight $w]
  111. incr y -20
  112.   # adjust for virtual desktops
  113. incr x [winfo vrootx .]
  114. incr y [winfo vrooty .]
  115. if { $y < 0 } { set y 0 }
  116. if { $x < 0 } {
  117. set x 0
  118. } else {
  119. set right [expr [winfo screenwidth .] - 
  120.    [winfo reqwidth $w]]
  121. if { $x > $right } {
  122. set x $right
  123. }
  124. }
  125. wm geometry $w +$x+$y
  126. wm deiconify $w
  127. } elseif [winfo ismapped $w] {
  128. wm withdraw $w
  129. } else {
  130. wm deiconify $w
  131. }
  132. }
  133. proc backFrame { } {
  134. global now timeStep
  135. settime [expr $now - $timeStep]
  136. }
  137. proc nextFrame { } {
  138. global now timeStep
  139. settime [expr $now + $timeStep]
  140. }
  141. proc net_settime t {}
  142. #
  143. # Set time slider to a tick value between 0 and 100.
  144. #
  145. set sliderPressed 0
  146. proc settime t {
  147. #XXX
  148. net_settime $t    
  149.         global sliderPressed range mintime timeSlider trace now nowDisp 
  150. maxtime graphName
  151.         if { $t > $maxtime } {
  152. stop 1
  153. return
  154. } elseif { $t < $mintime } {
  155.         set t $mintime
  156. }
  157. set now $t
  158. set nowDisp [format %.6f $now]
  159. if { $sliderPressed == 0 } {
  160.         $timeSlider set [expr int(100. * ($now - $mintime) / $range)]
  161. }
  162. set event [$trace settime $now $sliderPressed]
  163. if { [string length $graphName] > 0 } {
  164. if { [string length $event] > 0 } {
  165. graph_update $event
  166. }
  167. }
  168. }
  169. proc draw_data_pnt { tim id } {
  170. global prevAckId prevPktId clearDataCmd clearAckCmd lastDrawCmd 
  171.        graphName
  172. if { $prevAckId != 0 } {
  173. tkgraph_cmd 0 $clearAckCmd
  174. set prevAckId 0
  175. } elseif { $prevPktId != 0 } {
  176. tkgraph_cmd 0 $clearDataCmd
  177. }
  178. set lastDrawCmd "draw_point $graphName $tim $id"
  179. tkgraph_cmd 1 $lastDrawCmd
  180. set clearDataCmd "clear_point $graphName $tim $id"
  181. set prevPktId $id
  182. }
  183. proc draw_ack_pnt { tim id } {
  184. global prevAckId prevPktId delay01 graphName lastDrawCmd clearAckCmd 
  185.        clearDataCmd
  186. if { $prevAckId != 0 } {
  187. tkgraph_cmd 0 $clearAckCmd
  188. } elseif { $prevPktId != 0 } {
  189. tkgraph_cmd 0 $clearDataCmd
  190. set prevPktId 0
  191. }
  192. set prevAckId $id
  193. set arriv [expr $tim + $delay01]
  194. set lastDrawCmd "draw_point $graphName $arriv $id"
  195. tkgraph_cmd 1 $lastDrawCmd
  196. set clearAckCmd "clear_point $graphName $arriv $id"
  197. }
  198. proc graph_update_interval tim {
  199. global intervalStart intervalEnd mintime maxtime lastDrawCmd 
  200.        interval graphName
  201. # Update graph interval as needed.
  202. set overlap [expr 0.2 * $interval]
  203. if { $tim > $intervalStart && $tim < $intervalEnd } {
  204. return
  205. }
  206. if { $tim > $maxtime } {
  207. stop 1
  208. return
  209. }
  210. if { $tim >= [expr $intervalEnd - $overlap] } {
  211. set intervalStart [expr $intervalEnd - $overlap]
  212. } elseif { $tim < $intervalStart } {
  213. set intervalStart [expr $tim - 0.5 * $interval]
  214. }
  215. set intervalEnd [expr $intervalStart + $interval]
  216. # Check if going beyond max x or min x and update interval
  217. # accordingly.
  218. if { $intervalEnd > $maxtime } {
  219. set intervalEnd [expr $maxtime + $overlap]
  220. set intervalStart [expr $intervalEnd - $interval]
  221. } elseif { $intervalStart <= $mintime } {
  222. set intervalStart 0.0
  223. set intervalEnd [expr $intervalStart + $interval]
  224. }
  225. set cmd [format "update_graph %s %.17g %.17g" 
  226.  $graphName $intervalStart $intervalEnd]
  227. tkgraph_cmd 1 $cmd
  228. # Redraw last point drawn.
  229. tkgraph_cmd 1 $lastDrawCmd
  230. }
  231. proc graph_update events {
  232. set el [split $events /]
  233. foreach e $el {
  234. scan $e "%d %d %g %g" src dst tim id
  235. # Draw and/or clear any points as needed.
  236. if { $src == 0 } {
  237. # data packet leaving node 0
  238. draw_data_pnt $tim $id
  239. } elseif { $dst == 0 } {
  240. # Ack packet leaving node 1 (to 0).  Just need to save
  241. # ack id. Point for ack will be drawn later when the
  242. # first data packet sent as a result of this ack leaves
  243. # node 0.
  244. draw_ack_pnt $tim $id
  245. }
  246. graph_update_interval $tim
  247. }
  248. }
  249. proc slidetime { tick remote } {
  250. global now range mintime trace
  251. set now [expr ($tick * $range) / 100. + $mintime]
  252. settime $now
  253. if { $remote } {
  254. peer_cmd 1 "slidetime $tick 0"
  255. }
  256. }
  257. proc bumpstepper { amt remote } {
  258. set v [.right.rate get]
  259. incr v [expr - $amt]
  260. if { $v > 100 } {
  261. .right.rate set 100
  262. } {
  263. if { $v < 0 } {
  264. .right.rate set 0
  265. } {
  266. .right.rate set $v
  267. }
  268. }
  269. if { $remote } {
  270. peer_cmd 1 "bumpstepper $amt 0"
  271. }
  272. }
  273. proc renderFrame { } {
  274. global running sliderPressed granularity
  275. if { $running && !$sliderPressed } {
  276. nextFrame
  277. update idletasks
  278. after $granularity renderFrame
  279. }
  280. }
  281. proc remote_play t {
  282.         global timeSlider
  283.         settime $t
  284.         play 0
  285. }
  286. proc play remote {
  287. global running now
  288. set running 1
  289. after 0 renderFrame
  290. if { $remote } {
  291. peer_cmd 1 "remote_play $now"
  292. }
  293. }
  294. proc remote_stop t {
  295.         stop 0
  296.         settime $t
  297. }
  298. proc stop remote {
  299. global running now
  300. set running 0
  301. if { $remote } {
  302. peer_cmd 1 "remote_stop $now"
  303. }
  304. }
  305. proc remote_set_time t {
  306.         global timeSlider
  307.         settime $t
  308. }
  309. proc reset { } {
  310. settime 0.
  311. peer_cmd 1 "remote_set_time 0."
  312. }
  313. proc rewind { } {
  314. global now timeStep
  315. set t [expr $now - $timeStep*25.0]
  316. settime $t
  317. peer_cmd 1 "remote_set_time $t"
  318. # settime 0.
  319. # peer_cmd 1 "remote_set_time 0."
  320. }
  321. proc fast_fwd { } {
  322. global now timeStep
  323.         set t [expr $now + $timeStep*25.0]
  324.         settime $t
  325. peer_cmd 1 "remote_set_time $t"
  326. }
  327. proc next_event { } {
  328. global trace running
  329. set t [$trace nxtevent]
  330. settime $t
  331. peer_cmd 1 "remote_set_time $t"
  332. if { !$running } {
  333. nextFrame
  334. peer_cmd 1 nextFrame
  335. }
  336. }
  337. proc step_format t {
  338. if { $t < 1e-3 } {
  339. return [format "%.1f" [expr $t * 1e6]]us
  340. } elseif { $t < 1. } {
  341. return [format "%.1f" [expr $t * 1e3]]ms
  342. }
  343. return [format "%.1f" $t]s
  344. }
  345. proc set_rate { v remote } {
  346. global timeStep stepDisp rateSlider currRate
  347. set timeStep [expr pow(10, $v / 10.)]
  348. set stepDisp [step_format $timeStep]
  349.         if { [$rateSlider get] != $v } { $rateSlider set $v }
  350. set currRate $v
  351. if { $remote } {
  352. peer_cmd 1 "set_rate $v 0"
  353. }
  354. }
  355. # Set time to its previous value (before it was changed by
  356. # pressing mouse button 1 on the time slider).
  357. proc time_undo { } {
  358.         global timeSlider prevTime now
  359.         set currTime $now
  360.         settime $prevTime
  361. peer_cmd 1 "settime $prevTime"
  362.         set prevTime $currTime
  363. }
  364. # Set rate to its previous value (before it was changed by
  365. # pressing mouse button 1 on the rate slider).
  366. proc rate_undo { } {
  367.         global prevRate rateSlider
  368.         set tmpRate [$rateSlider get]
  369.         set_rate $prevRate 1
  370.         $rateSlider set $prevRate
  371.         set prevRate $tmpRate
  372. }
  373. proc button_release_1 t {
  374.         global timeSlider
  375. slidetime $t 1
  376.         $timeSlider set $t
  377. global sliderPressed
  378. set sliderPressed 0
  379. }
  380. proc button_press_1 s {
  381. global sliderPressed prevTime
  382. set sliderPressed 1
  383.         set prevTime $s
  384. }
  385. proc build.p0 w {
  386. scale $w.slider -orient horizontal -width 7p 
  387. -from 0 -to 100 -showvalue false -relief groove 
  388. -borderwidth 1
  389. #
  390. # We want slightly different semantics.  Instead of tracking
  391. # the time slider continuously, we just update it when the
  392. # button is released.
  393. # E.g., it takes too long to do a fast-forward each time.
  394. #
  395. global timeSlider 
  396. set timeSlider $w.slider
  397. bind $timeSlider <ButtonRelease-1> {
  398.         set t [%W get]
  399. slidetime $t 1
  400. global sliderPressed running
  401. set sliderPressed 0
  402. peer_cmd 1 "button_release_1 $t"
  403. if $running {
  404. renderFrame
  405. }
  406. }
  407. bind $timeSlider <ButtonPress-1> {
  408. global sliderPressed prevTime
  409. set sliderPressed 1
  410.         set prevTime $now
  411. peer_cmd 1 "button_press_1 $prevTime"
  412. }
  413. bind $timeSlider <B1-Motion> {
  414. global range mintime trace nowDisp
  415. set tick [%W get]
  416. set now [expr ($tick * $range) / 100. + $mintime]
  417. set nowDisp [format %%.6f $now]
  418. }
  419. # button $w.rew -bitmap rewind 
  420. # -command rewind -anchor center -relief ridge
  421. # button $w.stop -bitmap stop 
  422. # -command stop -anchor center -relief ridge
  423. # button $w.idle -bitmap play 
  424. # -command play -anchor center -relief ridge
  425. # button $w.ff -bitmap "ff" 
  426. # -command fast_fwd -anchor center -relief ridge
  427. pack $w.slider -side left -fill x -expand 1
  428. # pack $w.rew $w.stop $w.idle $w.ff -side left
  429. }
  430. proc build.p1 w {
  431. set f [smallfont]
  432. frame $w.bar -relief ridge -borderwidth 2
  433. label $w.bar.title -text "   LBL Network Animator v[version]" 
  434. -anchor w -font $f -borderwidth 1
  435. # label $w.bar.timer -text Time: -font $f -borderwidth 1
  436. label $w.bar.timerVal -textvariable nowDisp -width 10 -anchor w -font $f 
  437. -borderwidth 1 -relief groove -anchor e
  438. # label $v.step -text "  Step:" -font $f -borderwidth 1
  439. label $w.bar.stepVal -textvariable stepDisp -width 8 -anchor w -font $f 
  440. -borderwidth 1 -relief groove -anchor e
  441. pack $w.bar.title -side left -fill x -expand 1
  442. pack $w.bar.timerVal $w.bar.stepVal -side left -pady 1 
  443. -ipady 1 -padx 1 -padx 1
  444. # button $w.help -text Help -borderwidth 2 -relief raised 
  445. # -font $f -command "toggle_window .help" -width 5
  446. checkbutton $w.bar.run -text Run -borderwidth 1 -relief raised 
  447. -highlightthickness 1 -font $f -variable running 
  448. -command renderFrame
  449. button $w.bar.rew -text Rew -borderwidth 1 -relief raised 
  450. -highlightthickness 1 -font $f -command rewind
  451. button $w.bar.quit -text Quit -borderwidth 1 -relief raised 
  452. -highlightthickness 1 -font $f -command done
  453. pack $w.bar.run $w.bar.rew $w.bar.quit -side left 
  454. -padx 1 -pady 1 -ipadx 2
  455. # pack $w.bar.run -side left -padx 1 -pady 1
  456. pack $w.bar -fill x
  457. }
  458. proc back_step { } {
  459.         global running
  460.         if $running { stop 1 }
  461. backFrame
  462. peer_cmd 1 backFrame
  463. }
  464. proc toggle_pause { } {
  465.         global running
  466.         if $running {
  467. stop 1
  468. } else {
  469. play 1
  470. }
  471. }
  472. proc single_step { } {
  473.         global running
  474.         if $running { stop 1 }
  475.         nextFrame
  476. peer_cmd 1 nextFrame
  477. }
  478. proc dead name {
  479. global peers
  480. set i [lsearch -exact $peers $name]
  481. set peers [lreplace $peers $i $i]
  482. }
  483. proc done { } {
  484.         peer_cmd 1 "dead "[winfo name .]""
  485. # peer_cmd 1 "destroy ."
  486. # tkgraph_cmd 1 "destroy ."
  487.         destroy .
  488. }
  489. proc all_done { } {
  490. peer_cmd 1 "destroy ."
  491. tkgraph_cmd 1 "destroy ."
  492. destroy .
  493. }
  494. proc remote_change_rate r {
  495.         global timeStep stepDisp
  496.         set timeStep $r
  497.         set stepDisp [step_format $r]
  498. }
  499. proc change_rate inc {
  500.         global timeStep stepDisp
  501.         if $inc {
  502.         set timeStep [expr $timeStep + $timeStep*0.05]
  503. } else {
  504.         set timeStep [expr $timeStep - $timeStep*0.05]
  505. }     
  506.         set stepDisp [step_format $timeStep]
  507. peer_cmd 1 "remote_change_rate $timeStep"
  508. }
  509. proc start_info { x y } {
  510. global running resume nowDisp netView
  511. if $running {
  512.         set resume 1 
  513.         } else {
  514.         set resume 0
  515. }
  516. stop 1
  517. set text [$netView info $nowDisp]
  518. if { [string length $text] > 0 } {
  519. message $netView.msg -width 8c -text $text
  520. place $netView.msg -x $x -y $y
  521. }
  522. }
  523. proc end_info {} { 
  524.         global resume netView
  525. catch { destroy $netView.msg }
  526.         if $resume { play 1 }
  527. }
  528. proc graph_init graphInput {
  529. global prevAckId prevPktId interval intervalStart intervalEnd range 
  530.        clearDataCmd graphName delay01 graphTool
  531. set prevAckId 0
  532. set prevPktId 0
  533. set delay01 0
  534. set clearDataCmd ""
  535. set intervalStart 0.0
  536. set intervalEnd [expr $intervalStart + $interval]
  537. exec tkgraph $graphInput &
  538. after 1000
  539. set interps [winfo interps]
  540. foreach i $interps {
  541. if [regexp ^tkgraph* $i] {
  542. after 1000
  543. set graphTool $i
  544. set graphName [send $i {graph_name}]
  545. tkgraph_cmd 0 
  546.   "update_graph $graphName $intervalStart $intervalEnd"
  547. break
  548. }
  549. }
  550. }
  551. proc tkgraph_cmd { async cmd } {
  552. global graphName graphTool
  553. if { [string length $graphName] > 0 } {
  554. remote_cmd $async $graphTool $cmd
  555. }
  556. }
  557. proc remote_cmd { async interp cmd } {
  558. if $async {
  559. set rcmd "send -async "$interp" {$cmd}"
  560. } else {
  561. set rcmd "send "$interp" {$cmd}"
  562. }
  563. eval $rcmd
  564. }
  565. #proc master_cmd { async cmd } {
  566. # global master
  567. # if { [llength $master] > 0 } {
  568. # remote_cmd $async $master $cmd
  569. # }
  570. #}
  571. proc peer_cmd { async cmd } {
  572. global peers
  573. foreach s $peers {
  574. remote_cmd $async $s $cmd
  575. }
  576. }
  577. proc peer_init name {
  578. peer $name 0
  579. peer_cmd 0 "peer "[winfo name .]" 1"
  580. }
  581. proc peer { name remote } {
  582. global peers
  583. if { $remote } {
  584. peer_cmd 1 "peer "$name" 0"
  585. foreach s $peers {
  586. remote_cmd 1 $name "peer "$s" 0"
  587. }
  588. }
  589. lappend peers $name
  590. }
  591. # nam_init trace-name [g=graph-input] [i=graph-interval]
  592. # where trace-name is the nam trace input file
  593. #       graph-input is the input tcl file to tkgraph (optional)
  594. #       graph-interval is the graph interval to be used (optional)
  595. #                      and is only meaningful when a graph input file
  596. #                      is provided
  597. proc nam_init { tracefile args } {
  598. . configure -background [option get . background Nam]
  599. global trace now mintime range maxtime timeStep prevTime prevRate 
  600.                rateSlider netView netModel currRate graphName 
  601.        interval running peers peerName granularity
  602. set netModel [new NetworkModel]
  603. set trace [new Trace $tracefile]
  604. set now [$trace mintime]
  605. set mintime $now
  606.         set maxtime [expr [$trace maxtime] + .05]
  607. set range [expr $maxtime - $mintime]
  608.         set prevTime $mintime
  609. $trace connect $netModel
  610.         canvas .view2 -width 400 -height 150 -background white
  611.         global canv
  612.         set canv .view2
  613. frame .view
  614. nam_config $netModel
  615. $netModel layout
  616. $netModel view .view.net
  617.         set netView .view.net
  618. set running 0
  619. set interval [expr $range / 7.]
  620. set graphName ""
  621. set graphInput ""
  622. set peerName ""
  623. set peers ""
  624. set i 0
  625. foreach a $args {
  626. set x [lindex $args [expr $i+1]]
  627. set aa [split $a "="]
  628. set pn [format "%s %s" [lindex $aa 1] $x]
  629. switch [lindex $aa 0] {
  630. g {set graphInput [lindex $aa 1]}
  631. i {set interval [lindex $aa 1]}
  632. p {
  633. if {[string length $x] > 0} {
  634. set peerName $pn
  635. } else {
  636. set peerName [lindex $aa 1]
  637. }
  638. }
  639. }
  640. incr i
  641. }
  642. if { [llength $graphInput] > 0 } {
  643. graph_init $graphInput
  644. }
  645. if { [llength $peerName] > 0 } {
  646. peer_init $peerName
  647. }
  648. scale .view.rate -orient vertical -width 7p 
  649. -from 1 -to -60 -showvalue false 
  650. -relief groove
  651.         set rateSlider .view.rate
  652. set granularity [option get . granularity Nam]
  653. set timeStep [time2real [option get . rate Nam]]
  654.         set currRate [expr 10*log10($timeStep)]
  655.         set prevRate $currRate
  656. $rateSlider set $currRate
  657. pack .view.net -side left -expand 1 -fill both
  658. pack .view.rate -side left -fill y
  659.         bind $rateSlider <ButtonRelease-1> { 
  660. set v [%W get]
  661. set_rate $v 1
  662. }
  663. bind $rateSlider <ButtonPress-1> {
  664. global currRate prevRate
  665. set prevRate $currRate
  666. }
  667. bind $rateSlider <B1-Motion> {
  668. global timeStep stepDisp
  669. set v [%W get]
  670. set timeStep [expr pow(10, $v / 10.)]
  671. set stepDisp [step_format $timeStep]
  672. }
  673. frame .ctrl -relief flat -borderwidth 0
  674. frame .ctrl.p0 -relief flat -borderwidth 0
  675. build.p0 .ctrl.p0
  676. frame .ctrl.p1 -relief flat -borderwidth 0
  677. build.p1 .ctrl.p1
  678. pack .ctrl.p0 .ctrl.p1 -side top -fill x
  679. pack .view -fill both -expand 1
  680. pack .view2 -side top -expand 1
  681. pack .ctrl -fill x
  682. wm minsize . 200 200
  683. settime $now
  684. set_rate $currRate 1
  685.         bind . <q> { done }
  686. bind . <Q> { all_done }
  687. bind . <Control-c> { done }
  688. bind . <Control-d> { done }
  689. bind . <space> { toggle_pause }
  690. bind . <Return> { single_step }
  691.         bind . <b> { back_step }
  692.         bind . <B> { back_step }
  693. bind . <BackSpace> { back_step }
  694. bind . <Delete> { back_step }
  695. bind .view.net <ButtonPress-3> { start_info %x %y }
  696. bind .view.net <ButtonRelease-3> { end_info }
  697. bind . <0> { reset }
  698. bind . <c> { play 1 }
  699. bind . <C> { play 1 }
  700. bind . <f> { fast_fwd }
  701. bind . <F> { fast_fwd }
  702. bind . <n> { next_event }
  703. bind . <N> { next_event }
  704. bind . <p> { stop 1 }
  705. bind . <P> { stop 1 }
  706. bind . <r> { rewind }
  707. bind . <R> { rewind }
  708. bind . <u> { time_undo }
  709. bind . <U> { time_undo }
  710. bind . <x> { rate_undo }
  711. bind . <X> { rate_undo }
  712. bind . <period> { change_rate 1 }
  713. bind . <greater> { change_rate 1 }
  714. bind . <comma> { change_rate 0 }
  715. bind . <less> { change_rate 0 }
  716. }
  717. set helpno 0
  718. proc helpitem { w text } {
  719. global helpno
  720. set f [option get . helpFont Nam]
  721. set h $w.h$helpno
  722. incr helpno
  723. frame $h
  724. canvas $h.bullet -width 12 -height 12 
  725. $h.bullet create oval 6 3 12 9 -fill black
  726. message $h.msg -justify left -anchor w -font $f -width 460 -text $text
  727. pack $h.bullet -side left -anchor ne -pady 5
  728. pack $h.msg -side left -expand 1 -fill x -anchor nw
  729. pack $h -expand 1 -fill both
  730. }
  731. proc build.help { } {
  732. set w .help
  733. if [winfo exists $w] { return }
  734. toplevel $w
  735. bind $w <Enter> "focus $w"
  736. wm withdraw $w
  737. wm iconname $w "nam help"
  738. wm title $w "nam help"
  739. frame $w.frame -borderwidth 2 -relief raised
  740. set p $w.frame
  741. helpitem $p "Sorry, nothing here yet."
  742. button $w.frame.ok -text " Dismiss " -borderwidth 2 -relief raised 
  743. -command "wm withdraw $w" -font [mediumfont] 
  744. pack $w.frame.ok -pady 6 -padx 6 -anchor e
  745. pack $w.frame -expand 1 -fill both
  746. }
  747. #
  748. # helper functions
  749. #
  750. proc nam_angle { v } {
  751. switch $v {
  752. up-right -
  753. right-up { return 0.25 }
  754. up { return 0.5 }
  755. up-left -
  756. left-up { return 0.75 }
  757. left { return 1. }
  758. left-down -
  759. down-left { return 1.25 }
  760. down { return 1.5 }
  761. down-right -
  762. right-down { return 1.75 }
  763. default { return 0.0 }
  764. }
  765. }
  766. proc mklink { net n0 n1 bandwidth delay angle } {
  767. global delay01
  768. set th [nam_angle $angle]
  769. set result [$net link $n0 $n1 
  770. [bw2real $bandwidth]  [time2real $delay] $th]
  771. $net link $n1 $n0 
  772. [bw2real $bandwidth] [time2real $delay] [expr $th + 1]
  773. if { $n0 == 0 && $n1 == 1 } {
  774. set delay01 $result
  775. }
  776. }
  777. proc mklinkq { net n0 n1 bandwidth delay angle } {
  778. mklink $net $n0 $n1 $bandwidth $delay $angle
  779. $net queue $n0 $n1 0.5
  780. $net queue $n1 $n0 0.5
  781. }
  782. proc ncolor {n0 color} {
  783. global netModel
  784. $netModel ncolor $n0 $color
  785. }
  786. proc ecolor {n0 n1 color} {
  787. global netModel
  788. $netModel ecolor $n0 $n1 $color
  789. $netModel ecolor $n1 $n0 $color
  790. }