1 # ui-main.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1993-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #
31 # @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/vic/ui-main.tcl,v 1.97 2002/02/28 03:34:04 chema Exp $
32
33
34 import ControlMenu VicHelpWindow HelpWindow Switcher \
35 ActiveSourceManager VicAudioUI AudioPanel UISrcList \
36 CuesReceiver Configuration VisualFrame mashutils CameraManager
37
38 #
39 # The main user interface for the vic application.
40 # <p>
41 # An interface to video streams... <br>
42 # Displays a panel of postage-stamp-sized video sources and their respective network statistics.
43 # By selecting a thumbnail, a resizable toplevel window will appear that can remain dedicated to
44 # displaying the selected source or can be configured to cycle through all the video sources
45 # in a designated manner (voice-switched, timer-switched, etc.).
46 #
47 # <p>
48 # Defaults:
49 # <br> geometry used to be 250x225
50 # <br> vain can be set to true to allow voice-switch to switch to self
51 Class VicUI -superclass Observer -configuration {
52 minwidth 200
53 minheight 100
54 filterGain 0.25
55 geometry {}
56 vain false
57 }
58
59 #
60 # Takes a frame, <i>w</i>, and create and pack within it the vic title
61 # and 3 buttons: <br>
62 # <dd> toggle Settings (<i>controlWindow</i>)
63 # <dd> toggle Help (<i>helpWindow</i>)
64 # <dd> Quit (<i>exitCmd</i>)
65 # <br>
66 # The caller is responsible for instantiating and packing <i>w</i>.
67 #
68 VicUI instproc build_menubar { w controlWindow helpWindow exitCmd } {
69 frame $w -relief ridge -borderwidth 2
70 label $w.title -text "[$self get_option appname] v[version]" -font [$self get_option smallfont] \
71 -relief flat -justify left
72 button $w.quit -text Quit -relief raised \
73 -font [$self get_option smallfont] -command $exitCmd \
74 -highlightthickness 1
75 button $w.menu -text Settings -relief raised \
76 -font [$self get_option smallfont] -highlightthickness 1 \
77 -command "$controlWindow toggle"
78 button $w.help -text Help -relief raised \
79 -font [$self get_option smallfont] -highlightthickness 1 \
80 -command "$helpWindow toggle"
81
82 pack $w.title -side left -fill both -expand 1
83 pack $w.menu $w.help $w.quit -side left -padx 1 -pady 1
84 }
85
86 #
87 # Set the title and iconname of the window "." to <i>prefix name</i>.
88 #
89 VicUI instproc window-title { prefix name } {
90 $self instvar name_ prefix_
91 set name_ $name
92 set prefix_ $prefix
93
94 wm iconname . "$prefix_ $name_"
95 wm title . "$prefix_ $name_"
96
97 #FIXME
98 proc mark_icon mark "$self mark-icon \$mark"
99 }
100
101 #
102 VicUI instproc mark-icon mark {
103 $self instvar name_ prefix_
104 global current_icon_mark
105 if {$mark != $current_icon_mark} {
106 set current_icon_mark $mark
107 append mark $prefix_$name_
108 wm iconname . $mark
109 }
110 }
111
112 #
113 # Build the user-interface.
114 # FIXME Get rid of this "spec" argument...
115 VicUI instproc init { w localChannel globalChannel videoAgent vpipe exitCmd {vspec {}} {scrollbars_on 0} {autoplace 0} {CINDY_HACK_HAVE_VIDEO 1} } {
116 $self next
117
118 $self instvar localChannel_ globalChannel_ videoAgent_ vpipe_ exitCmd_ scrollbars_on_ autoplace_
119 set localChannel_ $localChannel
120 set globalChannel_ $globalChannel
121 set videoAgent_ $videoAgent
122 set vpipe_ $vpipe
123 set exitCmd_ "$exitCmd"
124 set scrollbars_on_ $scrollbars_on
125 set autoplace_ $autoplace
126
127 # FIXME this is a temporary hack while cindy works on decomposing VicUI so that MuiUI doesn't subclass from it...
128 # remove from args above and "$self next" call of MuiU::init
129 if !$CINDY_HACK_HAVE_VIDEO {
130 $self layout_gui $w
131 set conf [$self get_option conferenceName]
132 } else {
133 # let this ui be an observer of the VideoAgent so it can catch "trigger_sdes"
134 $videoAgent attach $self
135
136 $self build_gui $w
137
138 if { $vspec == "" } {
139 set conf "Contacting MeGa..."
140 } else {
141 set conf [$self get_option conferenceName]
142 }
143 }
144
145 # set the window & icon title from the conference name
146 set prefix [$self get_option iconPrefix]
147 $self window-title $prefix $conf
148
149 $self set-geometry
150
151 if [$self yesno transmitOnStartup] {
152 #FIXME
153 [$self set controlMenu_] build_window
154 [$self set controlMenu_] invoke_transmit
155 }
156
157 $self init_keybindings "$exitCmd_"
158 wm protocol . WM_DELETE_WINDOW "$exitCmd_"
159 }
160
161 #
162 VicUI instproc reset {} {
163 $self new_hostspec
164
165 set conf [$self get_option conferenceName]
166 $self window-title [$self get_option iconPrefix] $conf
167 }
168
169 #
170 # Initialize some shortcut keys.
171 #
172 VicUI public init_keybindings { exitCmd } {
173 #
174 # emulate implicit keyboard focus
175 #
176 bind . <Enter> { focus %W }
177 #wm focusmodel . active
178 bind . <q> "$exitCmd"
179 bind . <Control-c> "$exitCmd"
180 bind . <Control-d> "$exitCmd"
181 }
182
183 #
184 # Given widget <i>w</i>, create frame $w.top, initializing its visual and colormap.
185 # Within this frame, a frame ($w.top.f) is created for holding either a label (instvar label_)
186 # or another frame (instvar grid_).
187 # A few keybinbdings are assigned.
188 #
189 VicUI instproc build_gui { w } {
190 $self instvar videoAgent_ userwindows_ path_ vpipe_ asm_ localChannel_ globalChannel_
191
192 $self set_rate_vars [$videoAgent_ set session_]
193
194 $self instvar id_
195 set id_ [after 1000 "$self periodic_update"]
196
197 #
198 # Configure the Switcher class to ignore attempts to switch
199 # to the local source, since this is not interesting (unless
200 # we set the "vain" configuration option to true).
201 #
202 if { ![$self yesno vain] && [$videoAgent_ have_network] } {
203 Switcher set ignore_([$videoAgent_ local]) 1
204 }
205
206 $self layout_gui $w
207
208 #
209 # Local coordination bus events
210 # - receive a focus speaker message from vat running on the
211 # same machine as this vic
212 #
213 set cb $localChannel_
214 if { $cb != "" } {
215 $cb register FOCUS_SPEAKER "$asm_ focus_speaker"
216 }
217
218 #
219 # Global coordination bus events
220 # - receive a aware {ear,hand,yes,no} message from vat
221 # running on others machine
222 # - receive an unaware of the same types
223 #
224 # CuesReceiver handle these events, this is created only
225 # when the user specified to do so on the command line
226 #
227 set cb $globalChannel_
228 if { [$self yesno useCues] && $cb!="" } {
229 CuesReceiver set_cb $cb
230 }
231
232 # Camera Control
233 if [$self yesno camctrl] {
234 puts "camera controls enabled..."
235 $self instvar camMngr_
236 set camMngr_ [new CameraManager]
237 }
238 }
239
240 #
241 # If the thumbnail container is resized, change the scrollable region
242 # of the canvas to be the larger of the thumbnail container or the vic
243 # window size.
244 #
245 VicUI public rearrange {w h} {
246 $self instvar asm_canvas_ asm_width_ asm_height_ manual_width_ manual_height_ scrollbars_on_
247
248 # Remember the new thumbnail container's size.
249 set asm_width_ $w
250 set asm_height_ $h
251
252 if { $scrollbars_on_ } {
253 # Set the scrollable region to the larger of the thumbnail size and
254 # the vic window size.
255 set w [expr $asm_width_ > $manual_width_ ? $asm_width_ : $manual_width_]
256 set h [expr $asm_height_ > $manual_height_ ? $asm_height_ : $manual_height_]
257 $asm_canvas_ configure -scrollregion "0 0 $w $h"
258 } else {
259 # Resize the entire vic window to match the thumbnail size.
260 $asm_canvas_ configure -width $w -height $h
261 }
262
263 # Re-anchor the thumbnail container if necessary.
264 $self reanchor_asm
265 }
266
267 #
268 # If the vic window is resized, change the scrollable region of the canvas
269 # to be the larger of the thumbnail container or the vic window size.
270 #
271 VicUI public reconfine {w h} {
272 $self instvar asm_canvas_ asm_width_ asm_height_ manual_width_ manual_height_
273
274 # Remember the new vic window size.
275 set manual_width_ $w
276 set manual_height_ $h
277
278 # Set the scrollable region to the larger of the thumbnail size and
279 # the vic window size.
280 set w [expr $manual_width_ > $asm_width_ ? $manual_width_ : $asm_width_]
281 set h [expr $manual_height_ > $asm_height_ ? $manual_height_ : $asm_height_]
282 $asm_canvas_ configure -scrollregion "0 0 $w $h"
283
284 # Re-anchor the thumbnail container if necessary.
285 $self reanchor_asm
286 }
287
288 #
289 # Toggle the thumbnail scrollbars on and off.
290 #
291 VicUI public toggle_scrollbars {} {
292 $self instvar scrollbars_on_
293 if { $scrollbars_on_ } {
294 $self scrollbars_off
295 } else {
296 $self scrollbars_on
297 }
298 }
299
300 VicUI public scrollbars_off {} {
301 $self instvar asm_canvas_ asm_grid_ scrollbars_on_
302
303 if { $scrollbars_on_ } {
304 grid $asm_canvas_ -in $asm_grid_ -padx 1 -pady 1 \
305 -row 0 -column 0 -rowspan 2 -columnspan 2 -sticky news
306 }
307 set scrollbars_on_ 0
308 }
309
310 VicUI public scrollbars_on {} {
311 $self instvar asm_canvas_ asm_grid_ asm_vscroll_ asm_hscroll_ scrollbars_on_
312
313 if { ! $scrollbars_on_ } {
314 grid $asm_canvas_ -in $asm_grid_ -padx 1 -pady 1 \
315 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
316 grid $asm_vscroll_ -in $asm_grid_ -padx 1 -pady 1 \
317 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
318 grid $asm_hscroll_ -in $asm_grid_ -padx 1 -pady 1 \
319 -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
320 }
321 set scrollbars_on_ 1
322 }
323
324 #
325 # Hook to set the scrollbars from outside the main UI using tkvar.
326 #
327 VicUI public set_scrollbars {} {
328 $self tkvar useScrollbars_
329
330 if { $useScrollbars_ } {
331 $self scrollbars_on
332 } else {
333 $self scrollbars_off
334 }
335 }
336
337 #
338 # If the ActiveSourceManager has video streams, anchor it to the NW
339 # corner of the scrolling canvas. If no video streams have ever been
340 # received, then re-center it. This assumes that even if there are
341 # no active streams, the ActiveSourceManager continues to display
342 # thumbnails.
343 #
344 VicUI public reanchor_asm {} {
345 $self instvar asm_ asm_canvas_ asm_window_id_ asm_anchored_ manual_width_ manual_height_
346
347 # Don't do anything if the number of sources hasn't changed from
348 # zero to non-zero.
349 set num_sources [llength [$asm_ active-sources]]
350 if {$asm_anchored_} return
351
352 # If no video streams have ever been received, re-center the
353 # ActiveSourceManager. Otherwise anchor it to the NW corner and
354 # don't do any more reanchoring.
355 if {!$asm_anchored_ && [llength [$asm_ active-sources]] == 0} {
356 $asm_canvas_ delete $asm_window_id_
357 set asm_window_id_ [$asm_canvas_ create window [expr $manual_width_ / 2] [expr $manual_height_ / 2] -anchor center -window $asm_canvas_.top]
358 } else {
359 $asm_canvas_ delete $asm_window_id_
360 set asm_window_id_ [$asm_canvas_ create window 0 0 -anchor nw -window $asm_canvas_.top]
361 set asm_anchored_ 1
362 }
363 }
364
365 #
366 # Create the main vic window.
367 #
368 VicUI public layout_gui {w} {
369 $self instvar asm_ controlMenu_ videoAgent_ vpipe_ vframe_ exitCmd_ localChannel_ asm_canvas_ asm_grid_ asm_width_ asm_height_ manual_width_ manual_height_ scrollbars_on_ asm_vscroll_ asm_hscroll_ asm_window_id_ asm_anchored_ autoplace_
370
371 # Set the default scrolling parameters.
372 set asm_canvas_ $w.asm_canvas
373 set asm_grid_ $w.asm_grid
374 set asm_vscroll_ $w.asm_vscroll
375 set asm_hscroll_ $w.asm_hscroll
376 set asm_width_ 0
377 set asm_height_ 0
378 set manual_width_ 173
379 set manual_height_ 140
380 set asm_anchored_ 0
381
382 # Create a surrounding canvas for the ActiveSourceManager's
383 # enclosing frame to provide scrolling capability.
384 frame $asm_grid_
385 scrollbar $asm_hscroll_ -orient horiz -command "$w.asm_canvas xview"
386 scrollbar $asm_vscroll_ -orient vert -command "$w.asm_canvas yview"
387 canvas $asm_canvas_ -width $manual_width_ -height $manual_height_ \
388 -highlightthickness 0 -scrollregion "0 0 $manual_width_ $manual_height_" \
389 -xscrollcommand "$w.asm_hscroll set" \
390 -yscrollcommand "$w.asm_vscroll set"
391
392 # Layout the scroll canvas and widgets.
393 pack $asm_grid_ -expand yes -fill both -padx 1 -pady 1
394 grid rowconfig $asm_grid_ 0 -weight 1 -minsize 0
395 grid columnconfig $asm_grid_ 0 -weight 1 -minsize 0
396 if { $scrollbars_on_ } {
397 grid $asm_canvas_ -in $asm_grid_ -padx 1 -pady 1 \
398 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
399 grid $asm_vscroll_ -in $asm_grid_ -padx 1 -pady 1 \
400 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
401 grid $asm_hscroll_ -in $asm_grid_ -padx 1 -pady 1 \
402 -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
403 } else {
404 grid $asm_canvas_ -in $asm_grid_ -padx 1 -pady 1 \
405 -row 0 -column 0 -rowspan 2 -columnspan 2 -sticky news
406 }
407
408 # Create the source manager and a vframe to enclose it.
409 set vframe_ [new VisualFrame $asm_canvas_.top]
410 set asm_ [new ActiveSourceManager $self $asm_canvas_.top $videoAgent_ vertical $localChannel_ $autoplace_]
411 $vframe_ attach_observer $asm_
412 $asm_ redecorate 3
413 $asm_ init_grid $asm_canvas_.top.f
414
415 # Pack the thumbnail frames.
416 pack $asm_canvas_.top -expand 1 -fill both
417 pack $asm_canvas_.top.f -expand 1 -fill both -side top
418
419 # Place the thumbnails into the scrollable canvas.
420 set asm_window_id_ [$asm_canvas_ create window [expr $manual_width_ / 2] [expr $manual_height_ / 2] -anchor center -window $asm_canvas_.top]
421
422 # Build the control menu and the vic bottom menubar.
423 set controlMenu_ [new ControlMenu $self $videoAgent_ $vpipe_ $vframe_ $asm_ [new UISrcListWindow $w $videoAgent_]]
424 $self build_menubar $w.asm_bar $controlMenu_ [new VicHelpWindow .help] "$exitCmd_"
425 grid $w.asm_bar -in $asm_grid_ -padx 1 -pady 1 \
426 -row 2 -column 0 -rowspan 1 -columnspan 2 -sticky news
427
428 # Attach some behavior.
429 bind $asm_canvas_.top.f <Configure> "$self rearrange %w %h"
430 bind $asm_canvas_ <Configure> "$self reconfine %w %h"
431 foreach i { 1 2 3 4 5 6 7 8 } {
432 bind . <Key-$i> "$asm_ redecorate $i; $controlMenu_ update_layout $i"
433 }
434 #FIXME a bit dangerous to have this in the GUI
435 bind . <t> "$controlMenu_ build_window ; $controlMenu_ invoke_transmit"
436 bind . <s> "$self toggle_scrollbars; $controlMenu_ toggle_scrollcheck"
437 bind . <a> "$asm_ toggle_autoplace; $controlMenu_ toggle_autocheck"
438 }
439
440 #
441 # An accessor function for a ControlMenu tkvar value.
442 #
443 VicUI public use_hw_decode {} {
444 $self instvar controlMenu_
445 return [$controlMenu_ use-hw]
446 }
447
448 #
449 # An accessor function for a ControlMenu tkvar value.
450 #
451 VicUI public mute_new_sources {} {
452 $self instvar controlMenu_
453 return [$controlMenu_ mute-new-sources]
454 }
455
456 #VicUI instproc cb_switcher msg {
457 # $self instvar videoAgent_
458 # foreach s [$videoAgent_ active_list] {
459 # #
460 # # look up the site by cname. (for backward compat
461 # # with old vat's, try the IP address too)
462 # #
463 # if { [$s addr] == $msg || [$s sdes cname] == $msg } {
464 # Switcher focus $s
465 # return
466 # }
467 # }
468 #}
469
470 #
471 # Size the "." window using values from the resource database:
472 # <i>minwidth</i>, <i>minheight</i>, and <i>geometry</i> (all in
473 # pixels). Specify <i>geometry</i> in the form wXh or set it to empty
474 # string, {}, to cancel the existing user-specified geometry and revert
475 # to the size requested internally by its widgets.
476 #
477 VicUI instproc set-geometry {} {
478 #
479 # Withdraw window so that user-placement is deferred
480 # until after initial geometry is computed
481 #
482 global mash
483 if { ![info exists mash(environ)] || $mash(environ)!="mplug" } {
484 wm withdraw .
485 }
486 wm geometry . [$self get_option geometry]
487 update idletasks
488 set minwidth [winfo reqwidth .]
489 set minheight [winfo reqheight .]
490 #FIXME
491 if { $minwidth < [$self get_option minwidth] } {
492 set minwidth [$self get_option minwidth]
493 }
494 if { $minheight < [$self get_option minheight] } {
495 set minheight [$self get_option minheight]
496 }
497 wm minsize . $minwidth $minheight
498 if { ![info exists mash(environ)] || $mash(environ)!="mplug" } {
499 wm deiconify .
500 }
501 }
502
503 #
504 # Every second, update rate variables.
505 #
506 VicUI instproc periodic_update { } {
507 $self instvar videoAgent_ vpipe_ id_
508 if [$vpipe_ running] {
509 update_rate [$videoAgent_ set session_]
510 }
511 update idletasks
512 set id_ [after 1000 "$self periodic_update"]
513 }
514
515 #
516 VicUI instproc clean_timers { } {
517 $self cancel_periodic_update
518 }
519
520 #
521 # Cancels the periodic_update.
522 #
523 VicUI instproc cancel_periodic_update { } {
524 $self instvar id_
525 if [info exists id_] {
526 after cancel $id_
527 unset id_
528 }
529 }
530
531 #
532 # For the video source, <i>src</i>, set the rate variables.
533 #
534 VicUI instproc set_rate_vars {src} {
535 global fpshat bpshat lhat shat
536 if [info exists fpshat($src)] {
537 unset fpshat($src)
538 unset bpshat($src)
539 unset lhat($src)
540 unset shat($src)
541 }
542 set gain [$self get_option filterGain]
543 set fpshat($src) 0
544 rate_variable fpshat($src) $gain
545 set bpshat($src) 0
546 rate_variable bpshat($src) $gain
547 set lhat($src) 0
548 rate_variable lhat($src) $gain
549 set shat($src) 0
550 rate_variable shat($src) $gain
551
552 #FIXME set guys in stat window too!
553 }
554
555 #
556 VicUI instproc new_hostspec {} {
557 $self instvar controlMenu_
558 if [info exists controlMenu_] {
559 $controlMenu_ new_hostspec
560 }
561 }
562
563 #
564 # Update the source description by updating the element of the global
565 # arrays src_info(), src_nickname(), and src_name() indexed by the
566 # specified <i>src</i>. If the src_name() is changed, then this is
567 # reflected in the UserWindows in which this src appears.
568 #
569 VicUI instproc trigger_sdes src {
570 $self instvar asm_
571
572 global src_info src_nickname src_name
573 #
574 # Figure out best presentation from available information.
575 #
576 set name [$src sdes name]
577 set cname [$src sdes cname]
578 set addr [$src addr]
579 if { $name == "" } {
580 if { $cname == "" } {
581 set src_nickname($src) $addr
582 set info $addr/[$src format_name]
583
584 } else {
585 set src_nickname($src) $cname
586 set info "$addr/[$src format_name]"
587 }
588 } elseif [cname_redundant $name $cname] {
589 set src_nickname($src) $name
590 set info $addr/[$src format_name]
591 } else {
592 set src_nickname($src) $name
593 set info $cname/[$src format_name]
594 }
595 set msg [$src sdes note]
596 if { $msg != "" } {
597 set info $msg
598 }
599 set src_info($src) $info
600
601 # only call change_name when name really changes
602 if { ![info exists src_name($src)] || "$src_name($src)" != "$name" } {
603 set src_name($src) $name
604 $asm_ change_name $src
605 }
606 }
607
608 #
609 VicUI instproc trigger_media src {}
610
611 #
612 # For the source specified by <i>src</i>, update its rate variables and its source description.
613 #
614 VicUI instproc update_decoder src {
615 $self set_rate_vars $src
616 $self trigger_sdes $src
617 }
618
619 VicUI instproc scuba_session {} {
620 $self instvar scuba_sess_
621 if [info exists scuba_sess_] { return $scuba_sess_ } else {return "" }
622 }
623
624 #
625 # switch the VideoAgent object in charge of the M/C session.
626 #
627 VicUI instproc switch-agent {spec} {
628 $self instvar videoAgent_
629 $self instvar vpipe_
630 $self instvar asm_ controlMenu_
631
632 # create the new agent (this has to be done before deleting the old one
633 # to avoid problems due to an encoder trying to give a packet to a
634 # non-existent VideoAgent)
635 if {[catch {new VideoAgent $self $spec} new_agent]} {
636 error $new_agent
637 }
638
639
640 # set the local output BufferPool (VideoPipeline::bufferPool_) right
641 if {[$vpipe_ info vars bufferPool_] == "bufferPool_"} {
642 [$vpipe_ set bufferPool_] srcid [$new_agent get_local_srcid]
643 }
644
645
646 # fix the local output encoder's target
647 # $videoAgent attach $self; # XXXX
648 if {[$vpipe_ info vars encoder_] == "encoder_"} {
649 [$vpipe_ set encoder_] target [$new_agent get_transmitter]
650 }
651
652
653 # fix the VideoAgent handler at the VideoPipeline
654 $vpipe_ set session_ $new_agent
655
656
657 # transfer all the objects attached to the old VideoAgent to the new one
658 foreach observer [$videoAgent_ set observers_] {
659 $new_agent attach $observer
660 }
661
662
663 # configure the Switcher class to ignore attempts to switch
664 # to the local source, since this is not interesting (unless
665 # we set the "vain" configuration option to true).
666 #
667 if { ![$self yesno vain] && [$new_agent have_network] } {
668 Switcher set ignore_([$new_agent local]) 1
669 }
670
671 # report the new VideoAgent to all the UI components
672 $asm_ switch-agent $new_agent
673 $controlMenu_ switch-agent $new_agent
674
675
676 # report the new VideoAgent to the VicApplication object
677 # Note: it's a little tricky to get the VicApplication object by querying for
678 # objects of this type, but the fact is that currently the UI doesn't keep a
679 # handler to the VicApplication
680 if {[llength [VicApplication info instances]] > 0} {
681 [lindex [VicApplication info instances] 0] set agent_ $new_agent
682 }
683
684 # destroy the old VideoAgent and link the ControlMenu to the new one
685 $videoAgent_ destroy
686 set videoAgent_ $new_agent
687
688 }
689
690
691 #
692 # Using the specified video source, <i>src</i>, as an index, update the
693 # global arrays bpshat(), fpshat(), shat(), lhat(), ltext(), ftext(), btext().
694 #
695 proc update_rate src {
696 global ftext btext ltext fpshat bpshat lhat shat V
697
698 set key $src
699 if [string match Session/* [$src info class]] {
700 set bpshat($key) [expr 8 * [$src set nb_]]
701 set fpshat($key) [$src set nf_]
702 } else {
703 # only compute loss statistic for network side
704 set p [$src layer-stat np_]
705 set s [$src ns]
706 set shat($key) $s
707 set lhat($key) [expr $s-$p]
708 if {$shat($key) <= 0.} {
709 set loss 0
710 } else {
711 set loss [expr 100*$lhat($key)/$shat($key)]
712 }
713 if {$loss < .1} {
714 set ltext($key) (0%)
715 } elseif {$loss < 9.9} {
716 set ltext($key) [format "(%.1f%%)" $loss]
717 } else {
718 set ltext($key) [format "(%.0f%%)" $loss]
719 }
720 set bpshat($key) [expr 8 * [$src layer-stat nb_]]
721 set fpshat($key) [$src layer-stat nf_]
722 }
723
724 set fps $fpshat($key)
725 set bps $bpshat($key)
726
727 if { $fps < .1 } {
728 set fps "0 f/s"
729 } elseif { $fps < 10 } {
730 set fps [format "%.1f f/s" $fps]
731 } else {
732 set fps [format "%2.0f f/s" $fps]
733 }
734 if { $bps < 1 } {
735 set bps "0 bps"
736 } elseif { $bps < 1000 } {
737 set bps [format "%3.0f bps" $bps]
738 } elseif { $bps < 1000000 } {
739 set bps [format "%3.0f kb/s" [expr $bps / 1000]]
740 } else {
741 set bps [format "%.1f Mb/s" [expr $bps / 1000000]]
742 }
743 set ftext($key) $fps
744 set btext($key) $bps
745 }
746
747 #
748 # A toggle-able dismissable toplevel window for displaying a bulleted list of tips to help the vic user.
749 #
750 Class VicHelpWindow -superclass HelpWindow
751
752 #
753 # Instantiate, but do not yet display or iconify, a dismissable toplevel
754 # window using the provided widgetpath, <i>w</i>. Within <i>w</i>,
755 # create a bulleted list of tips to help the vic user. (This method is
756 # called when the user toggles this window for the first time.)
757 #
758 VicHelpWindow instproc build w {
759
760 $self create-window $w "Help" {
761
762 "Transmit video by clicking on the ``Transmit'' button \
763 in the ``Menu'' window. You need video capture hardware to do this."
764
765 "Incoming video streams appear in the main vic window. \
766 If you see the message ``Waiting for video...'', then no one is transmitting \
767 video to the conference address you're running on. Otherwise, you'll \
768 see a thumbnail sized image and accompanying information for each source. \
769 Click on the thumbnail to open a larger viewing window. You can tile the \
770 thumbnails in multiple columns using the ``Tile'' menu in the ``Menu'' window."
771 "Clicking on the ``mute'' button for a given source will \
772 turn off decoding. It is usually a good idea to do \
773 this for your own, looped-back transmission."
774
775 "The transmission rate is controlled with the bit-rate \
776 and frame-rate sliders in the ``Transmission'' panel of the ``Menu'' window. \
777 The more restrictive setting limits the transmission rate."
778
779 "The video windows need not be fixed to a given source. \
780 The ``Mode...'' menu attached to a viewing window allows you to specify \
781 voice-switched and/or timer-switched modes. In timer-switched mode, the \
782 window automatically cycles through (unmuted) sources, while in \
783 oice-switched mode, the window switches to whomever is talking \
784 (using cues from vat). You can have more than one voice-switched window, \
785 which results in a simple LRU allocation of the windows to most recent \
786 speakers. See the man page for more details."
787
788 "If the user interface looks peculiar, you might \
789 have X resources that conflict with tk. A common problem is \
790 defining ``*background'' and/or ``*foreground''."
791
792 "Bugs and suggestions to openmash-users@openmash.org. Thanks."
793 }
794 }
795
796 #
797 # Build the audio user-interface for the AudioAgent, <i>agent</i>.
798 #
799 VicUI instproc create-audio-ui agent {
800 $self instvar audioUI_ path_
801 set audioUI_ [new VicAudioUI $path_.top.f $self $agent]
802 }
803
804 #
805 # Don't use this class. It will be obsoleted soon.
806 #
807 Class VicAudioUI
808
809 #
810 VicAudioUI instproc init { w mainUI agent } {
811 $self instvar mainUI_ panel_
812 set mainUI_ $mainUI
813
814 set panel_ [new AudioPanel $w $agent]
815
816 #FIXME
817 global meterDisable
818 set meterDisable 0
819 $panel_ install_meters
820
821 #FIXME mute mike
822 $panel_ ptt-release
823 $agent select_format PCM 2
824 }
825
826 #
827 VicAudioUI instproc destroy {} {
828 $self instvar panel_
829 delete $panel_
830 # FIXME: check that next'ing here doesn't break anything
831 #$self next
832 }
833
834 #
835 VicAudioUI instproc register src {
836 puts "VicAudioUI::register [$src getid]"
837 }
838
839 #
840 VicAudioUI instproc activate src {
841 puts "ACTIVATE: [$src getid]"
842 }
843
844 #
845 VicAudioUI instproc trigger_media src {
846 puts "AUDIO-FROM: [$src getid]"
847 }
848
849 #
850 VicAudioUI instproc trigger_idle src {
851 puts "IDLE: [$src getid] [$src lost]"
852 }
853
854 #
855 VicAudioUI instproc trigger_sdes src {
856 puts "SDES: [$src getid]"
857 }
858
859
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.