1 # ui-mediaedit.tcl --
2 #
3 # Constructs and manages a window that is used to edit the list of
4 # media streams in an SDP session description.
5 #
6 # Copyright (c) 1998-2002 The Regents of the University of California.
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are met:
11 #
12 # A. Redistributions of source code must retain the above copyright notice,
13 # this list of conditions and the following disclaimer.
14 # B. Redistributions in binary form must reproduce the above copyright notice,
15 # this list of conditions and the following disclaimer in the documentation
16 # and/or other materials provided with the distribution.
17 # C. Neither the names of the copyright holders nor the names of its
18 # contributors may be used to endorse or promote products derived from this
19 # software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
22 # AND 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 FOR
25 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 import PopupMenu
33 import RTP/Audio
34 import RTP/Video
35
36 # Constructs and manages a window that is used to edit the list of
37 # media streams in an SDP session description. This window contains
38 # a listbox on the left side that lists all streams current in the
39 # announcement. Streams can be added and deleted from this list.
40 # The right side of the window contains a series of entry widgets
41 # that are used to edit the format/address/port/etc.. of the stream
42 # that is currently selected in the listbox.
43 Class SDPMediaEditWindow
44
45 # Creates the user interface elements needed for this window.
46 # The streams in the SDPMessage object <i>msg</i> will be displayed
47 # initially or defaults will be displayed if <i>msg</i> is an empty
48 # string. The ProgramSource <i>src</i> is queried to find out what
49 # administrative scope zones are available.
50 SDPMediaEditWindow public init {w msg src} {
51 $self set win_ $w
52 $self set msg_ $msg
53 $self set src_ $src
54
55 $self instvar simple_
56 set simple_ [$self yesno simpleInterface]
57 if {$simple_} {
58 $self set simplewin_ [new SDPMediaEditWindow/Simple $self]
59 } else {
60 $self set advancedwin_ [new SDPMediaEditWindow/Advanced $self]
61 }
62 }
63
64 SDPMediaEditWindow public destroy {} {
65 $self instvar simplewin_ advancedwin_ win_
66
67 if [info exists simplewin_] { delete $simplewin_ }
68 if [info exists advancedwin_] { delete $advancedwin_ }
69 destroy $win_
70 }
71
72 SDPMediaEditWindow public build-simple {} {
73 $self instvar simplewin_ advancedwin_ simple_
74
75 if [info exists advancedwin_] {
76 $advancedwin_ hide
77 }
78
79 if [info exists simplewin_] {
80 $simplewin_ show
81 } else {
82 set simplewin_ [new SDPMediaEditWindow/Simple $self]
83 }
84 set simple_ 1
85 }
86
87 SDPMediaEditWindow public build-advanced {} {
88 $self instvar simplewin_ advancedwin_ simple_
89
90 if [info exists simplewin_] {
91 $simplewin_ hide
92 }
93
94 if [info exists advancedwin_] {
95 $advancedwin_ show
96 } else {
97 set advancedwin_ [new SDPMediaEditWindow/Advanced $self]
98 }
99 set simple_ 0
100 }
101
102 SDPMediaEditWindow public buildmsgs {} {
103 $self instvar simple_ simplewin_ advancedwin_
104 if $simple_ {
105 return [list [$simplewin_ buildmsg]]
106 } else {
107 return [$advancedwin_ buildmsgs]
108 }
109 }
110
111 #
112 SDPMediaEditWindow proc is-number {n} {
113 if [catch {expr $n}] {
114 return 0
115 }
116 return 1
117 }
118
119 #
120 SDPMediaEditWindow proc valid-addr {a} {
121 set l [split $a .]
122 if {[llength $l] != 4} { return 1 }
123 foreach i $l {
124 if {![$self is-number $i] || $i<0 || $i>255} { return 1 }
125 }
126 return 0
127 }
128
129 #
130 SDPMediaEditWindow proc valid-port {p} {
131 if {![$self is-number $p] || $p<0 || $p>65535} { return 1}
132 return 0
133 }
134
135
136 #
137 #
138 #
139 Class SDPMediaEditWindow/Advanced
140
141 SDPMediaEditWindow/Advanced public init {parent} {
142 $self instvar win_ parent_ msg_ src_
143
144 set win_ "[$parent set win_].advanced"
145 frame $win_
146
147 set parent_ $parent
148 set msg_ [$parent set msg_]
149 set src_ [$parent set src_]
150
151 $self buildwin
152 $self show
153 }
154
155 SDPMediaEditWindow/Advanced public hide {} {
156 $self instvar win_
157 pack forget $win_
158 }
159
160 SDPMediaEditWindow/Advanced public show {} {
161 $self instvar win_
162 pack $win_ -fill both -expand yes
163 }
164
165 SDPMediaEditWindow/Advanced private buildwin {} {
166 $self instvar win_ msg_ src_ scopes_
167 $self instvar typemenu_ formatmenu_ protomenu_ attrentries_
168
169 set scopes_ [$src_ scopes]
170
171 $self set streams_ {}
172 $self set current_ -1
173
174 set font [$self get_option smallfont]
175
176 frame $win_.list
177 label $win_.list.l -text "Streams"
178 set h [expr ([winfo reqheight $win_.list.l]/2) + 2]
179 frame $win_.list.pad -height $h
180
181 set f $win_.list.f
182 frame $f -relief groove -bd 2
183 frame $f.pad -height $h
184 pack $f.pad -side top
185
186 frame $f.top
187 $self instvar lb_
188 set lb_ [listbox $f.top.lb -width 15 -height 5 \
189 -exportselection no -selectmode single \
190 -yscrollcommand "$f.top.sb set"]
191 bind $f.top.lb <Button-1> "$self streamclick %x %y"
192 pack $f.top.lb -side right -fill both -expand yes
193 scrollbar $f.top.sb -width 10 -command "$f.top.lb yview"
194 pack $f.top.sb -side right -before $f.top.lb -fill y
195 pack $f.top -side top -fill both -expand yes
196
197 frame $f.b
198 button $f.b.add -text "Add" -command "$self add-stream"
199 button $f.b.del -text "Delete" -command "$self delete-stream"
200 pack $f.b.add $f.b.del -side left
201 pack $f.b
202
203 pack $win_.list.pad -side top
204 pack $f -fill both -expand yes -padx 4 -pady 0
205 place $win_.list.l -x 6 -y 2
206 raise $win_.list.l
207 pack $win_.list -side left -fill both -expand no
208
209 frame $win_.prop
210 label $win_.prop.l -text "Properties"
211 set h [expr ([winfo reqheight $win_.prop.l])/2 + 2]
212 frame $win_.prop.pad -height $h
213
214 frame $win_.prop.f -relief groove -bd 2
215 frame $win_.prop.f.pad -height $h
216 pack $win_.prop.f.pad -side top
217 set f $win_.prop.f.f
218 frame $f
219
220 frame $f.left
221
222 label $f.left.typet -text "Type:" -anchor e
223 grid $f.left.typet -row 0 -column 0 -sticky ew
224 set typemenu_ [new PopupMenu $f.left.typem]
225 foreach type [UserApplication media] {
226 $typemenu_ add $type "$self set-type $type"
227 }
228 grid $f.left.typem -row 0 -column 1 -sticky ew
229
230 label $f.left.formatt -text "Format:" -anchor e
231 grid $f.left.formatt -row 1 -column 0 -sticky ew
232 set formatmenu_ [new PopupMenu $f.left.formatm]
233 # menu gets filled in in set-type
234 grid $f.left.formatm -row 1 -column 1 -sticky ew
235
236 label $f.left.protot -text "Protocol:" -anchor e
237 grid $f.left.protot -row 2 -column 0 -sticky ew
238 set protomenu_ [new PopupMenu $f.left.protom]
239 # filled in in set-type
240 grid $f.left.protom -row 2 -column 1 -sticky ew
241
242 # attributes created in set-type
243 set attrentries_ {}
244
245 pack $f.left -side left -fill y -expand yes
246
247 frame $f.right
248
249 $self instvar layeredcb_
250 set layeredcb_ [new CheckButton $f.right.cb -text "Use Layering" \
251 -command "$self toggle-layering"]
252 pack $f.right.cb -side top -fill x
253
254 frame $f.right.addr
255 $self set addrframe_ $f.right.addr
256 $self set addrblocks_ {}
257 pack $f.right.addr -side top -fill both -expand yes
258
259 pack $f.right -fill both -expand yes
260
261 pack $win_.prop.pad -side top -fill both
262 pack $win_.prop.f -fill both -expand yes
263 pack $f -side left -fill both -expand yes -padx 4 -pady 0
264 place $win_.prop.l -x 6 -y 2
265 raise $win_.prop.l
266 pack $win_.prop -side left -fill both -expand yes
267 pack propagate $win_.prop no
268
269 pack $win_ -fill both -expand yes -pady 2
270
271 if {$msg_ == ""} {
272 $self add-stream
273 } else {
274 foreach m [[$msg_ base] set allmedia_] {
275 $self add-stream $m
276 }
277 }
278
279 $self set layered_ 0
280 $self select-stream 0
281 $lb_ selection set 0
282 }
283
284 # Callback when the mouse is clicked in the listbox containing
285 # all streams. Saves the state of the current stream and selects
286 # a new stream.
287 SDPMediaEditWindow/Advanced private streamclick {x y} {
288 $self instvar current_ lb_
289
290 if {$current_ >= 0} {
291 $self save-stream
292 }
293
294 set i [$lb_ nearest $y]
295 $self select-stream $i
296 }
297
298 #
299 SDPMediaEditWindow/Advanced private save-stream {} {
300 $self instvar typemenu_ formatmenu_ protomenu_ \
301 addrblocks_ attrentries_ streams_ current_
302
303 set media [$typemenu_ get]
304 set fmt [$formatmenu_ get]
305 set proto [$protomenu_ get]
306
307 set addrs {}
308 foreach b $addrblocks_ {
309 lappend addrs [$b get]
310 }
311
312 set attrs {}
313 foreach e $attrentries_ {
314 lappend attrs [$e entry-value]
315 }
316
317 if {$proto=={RTP/AVP}} {
318 set lfmt [string tolower $fmt]
319 if {$media=={video}} {
320 set v [new RTP/Video]
321 set fmt [$v rtp_fmt_number $lfmt]
322 delete $v
323 } elseif {$media=={audio}} {
324 set a [new RTP/Audio]
325 set fmt [$a rtp_fmt_number $lfmt]
326 delete $a
327 } else {
328 puts "nsdr: unknown format named $fmt"
329 }
330 }
331
332 set stream [list $media $fmt $proto $addrs $attrs]
333 set streams_ [lreplace $streams_ $current_ $current_ $stream]
334 }
335
336 # Updates the entry widgets on the right side of the window when a
337 # new stream is selected in the listbox.
338 SDPMediaEditWindow/Advanced private select-stream {i {layered -1}} {
339 $self set current_ $i
340
341 #fill in the properties for this stream
342 $self instvar current_ streams_ typemenu_ formatmenu_ \
343 protomenu_ layeredcb_ addrblocks_ attrentries_ layered_
344 set stream [lindex $streams_ $i]
345 set type [lindex $stream 0]
346 set fmt [lindex $stream 1]
347 set proto [lindex $stream 2]
348 set addrs [lindex $stream 3]
349 set attrs [lindex $stream 4]
350
351 $self set-type $type
352 set i [lsearch -exact [UserApplication media] $type]
353 $typemenu_ select $i
354
355 set fmts [UserApplication formats $type]
356 if {($proto == {RTP/AVP}) && ([string is digit $fmt])} {
357 if {$type == {video}} {
358 set fmt [string toupper [RTP/Video set default_ptoa_($fmt)]]
359 } elseif {$type == {audio}} {
360 set fmt [string toupper [RTP/Audio set default_ptoa_($fmt)]]
361 } else {
362 puts "nsdr: unknown format number $fmt"
363 }
364 }
365 set i [lsearch -exact $fmts $fmt]
366 $formatmenu_ select $i
367
368 set protos [UserApplication protos $type]
369 set i [lsearch -exact $protos $proto]
370 $protomenu_ select $i
371
372 if {$layered == -1} {
373 set layered 0
374 if {[llength $addrs] > 1 || [lindex [lindex $addrs 0] 2] > 1} {
375 set layered 1
376 }
377 }
378
379 # kill old addrblocks
380 foreach b $addrblocks_ {
381 delete $b
382 }
383
384 # make sure we have the right ui components
385 if {$layered_ == 0 && $layered == 1} {
386 # not previously layered, now layered
387 $self build-layers
388
389 set layered_ 1
390 $layeredcb_ set-val 1
391 } elseif {$layered_ == 1 && $layered == 0} {
392 # previously layered, not any more
393 $self destroy-layers
394
395 set layered_ 0
396 $layeredcb_ set-val 0
397 }
398
399 # now set the addresses
400 if $layered {
401 foreach a $addrs {
402 set b [$self add-addrblock]
403 $b set $a
404 }
405 } else {
406 $self instvar addrframe_
407 set addrblocks_ [new AddrBlockWindow $addrframe_ 0 $self]
408 $addrblocks_ set-type [lindex $stream 0]
409 $addrblocks_ set [lindex $addrs 0]
410 }
411
412 set i [llength $attrs]
413 while {$i>0} {
414 incr i -1
415 set e [lindex $attrentries_ $i]
416 set v [lindex $attrs $i]
417 $e set-value $v
418 }
419 }
420
421 # Called when the Add button is pressed, adds a new stream to
422 # the list of exisitng streams.
423 SDPMediaEditWindow/Advanced private add-stream {{m ""}} {
424 $self instvar streams_ lb_
425
426 if {$m == ""} {
427 set media [lindex [UserApplication media] 0]
428 set fmt [lindex [UserApplication formats $media] 0]
429 set proto [lindex [UserApplication protos $media] 0]
430 set attrs [UserApplication attrs $media]
431 set addr [list [$self alloc-addrs 1] [$self alloc-port $media] 1]
432 set addrs [list $addr]
433 set new [list $media $fmt $proto $addrs $attrs]
434 } else {
435 set media [$m set mediatype_]
436 set fmt [$m set fmt_]
437 set proto [$m set proto_]
438
439 #FIXME
440 set addr [list [$m set caddr_] [$m set port_] ]
441 set addrs [list $addr]
442
443 #FIXME
444 set attrs ""
445 set new [list $media $fmt $proto $addrs $attrs]
446 }
447 lappend streams_ $new
448
449 $lb_ insert end $media
450 }
451
452 # Deletes the currently selected stream from this announcement.
453 SDPMediaEditWindow/Advanced private delete-stream {} {
454 $self instvar streams_ lb_ current_
455 set streams_ [lreplace $streams_ $current_ $current_]
456 $lb_ delete $current_
457
458 set end [expr [$lb_ index end] -1]
459 if {$current_ > $end} {
460 set new $end
461 } else {
462 set new $current_
463 }
464 $self select-stream $new
465 $lb_ selection set $new
466 }
467
468 Class AddrBlockWindow
469
470 AddrBlockWindow public init {w layered parent} {
471 $self next
472
473 $self instvar win_ layered_ parent_ scope_
474 $self instvar scopemenu_ addrentry_ portentry_ layerentry_
475
476 set win_ $w
477 set layered_ $layered
478 set parent_ $parent
479
480 label $w.sl -text "Address Scope:" -anchor e
481 grid $w.sl -row 0 -column 0 -sticky ew
482
483 set scopemenu_ [new PopupMenu $w.sm]
484 $w.sm config -width 16 -anchor w
485 grid $w.sm -row 0 -column 1 -sticky e
486
487 set i 0
488 foreach s [$parent_ set scopes_] {
489 $scopemenu_ add [$s name] "$self choose-scope $i"
490 incr i
491 }
492 $scopemenu_ select 0
493 set scope_ 0
494
495 label $w.al -text "Address:" -anchor e
496 grid $w.al -row 1 -column 0 -sticky ew
497
498 set addrentry_ [new TextEntry "SDPMediaEditWindow valid-addr" $w.ae ""]
499 $w.ae config -width 16
500 grid $w.ae -row 1 -column 1 -sticky ew
501
502 label $w.pl -text "Port:" -anchor e
503 grid $w.pl -row 2 -column 0 -sticky ew
504
505 set portentry_ [new TextEntry "SDPMediaEditWindow valid-port" $w.pe ""]
506 $w.pe config -width 8
507 grid $w.pe -row 2 -column 1 -sticky ew
508
509 set row 3
510 if {$layered} {
511 label $w.ll -text "Layers:" -anchor e
512 grid $w.ll -row 3 -column 0 -sticky ew
513
514 set layerentry_ [new TextEntry "SDPMediaEditWindow valid-port" \
515 $w.le "1"]
516 $w.le config -width 8
517 grid $w.le -row 3 -column 1 -sticky ew
518 incr row
519 }
520
521 grid rowconfigure $w $row -weight 1
522
523 #FIXME alloc default address/port
524 }
525
526 AddrBlockWindow public destroy {} {
527 $self instvar scopemenu_ addrentry_ portentry_ layerentry_ win_
528 delete $addrentry_
529 delete $portentry_
530 catch {delete $layerentry_}
531
532 foreach w [winfo children $win_] { destroy $w }
533 }
534
535 AddrBlockWindow private choose-scope {i} {
536 $self instvar scope_ addrentry_ layerentry_ parent_
537 if {$i == $scope_} { return }
538
539 set scope_ $i
540
541 # reallocate address
542 set l 1
543 if [info exists layerentry_] {
544 set l [$layerentry_ entry-value]
545 }
546 set addr [$parent_ alloc-addrs $l [lindex [$parent_ set scopes_] $i]]
547
548 $addrentry_ set-value $addr
549 }
550
551 AddrBlockWindow public set-type {type} {
552 $self instvar portentry_ parent_
553
554 set p [$parent_ alloc-port $type]
555 $portentry_ set-value $p
556 }
557
558 AddrBlockWindow public get {} {
559 $self instvar addrentry_ portentry_ layerentry_
560
561 set addr [$addrentry_ entry-value]
562 set port [$portentry_ entry-value]
563 set layers 1
564 if [info exists layerentry_] {
565 set layers [$layerentry_ entry-value]
566 }
567 return [list $addr $port $layers]
568 }
569
570 AddrBlockWindow public set {l} {
571 $self instvar addrentry_ portentry_ layerentry_
572
573 $addrentry_ set-value [lindex $l 0]
574 $portentry_ set-value [lindex $l 1]
575
576 if [info exists layerentry_] {
577 $layerentry_ set-value [lindex $l 2]
578 }
579 }
580
581 SDPMediaEditWindow/Advanced private build-layers {} {
582 $self instvar addrframe_ addrcanvas_ addrblocks_
583
584 set f $addrframe_.top
585 frame $f
586
587 button $addrframe_.add -text "Add Block" -command "$self add-addrblock"
588 pack $addrframe_.add -side bottom
589
590 set addrcanvas_ $f.c
591 set sb $f.sb
592 canvas $addrcanvas_ -yscrollcommand "$sb set"
593 scrollbar $sb -relief groove -bd 2 -width 10 \
594 -command "$addrcanvas_ yview"
595 pack $addrcanvas_ -side right -fill y
596 set addrblocks_ {}
597
598 pack $sb -side right -before $addrcanvas_ -fill y
599 pack $f -side bottom -fill both -expand yes
600 }
601
602 SDPMediaEditWindow/Advanced private destroy-layers {} {
603 $self instvar addrframe_
604 destroy $addrframe_.top $addrframe_.add
605 }
606
607 SDPMediaEditWindow/Advanced private toggle-layering {} {
608 $self instvar streams_ current_ layeredcb_
609
610 $self save-stream
611 set stream [lindex $streams_ $current_]
612 set addrs [lindex $stream 3]
613
614 set stream [lreplace $stream 3 3 $addrs]
615 set streams_ [lreplace $streams_ $current_ $current_ $stream]
616 $self select-stream $current_ [$layeredcb_ get-val]
617 }
618
619 SDPMediaEditWindow/Advanced private add-addrblock {} {
620 $self instvar addrcanvas_ numblocks_ addrblocks_ type_
621
622 if ![info exists numblocks_] {
623 set numblocks_ 0
624 set y 0
625 } else {
626 set bb [$addrcanvas_ bbox all]
627 set y [expr [lindex $bb 3] + 4]
628 }
629
630 set w $addrcanvas_.addr$numblocks_
631 frame $w -relief groove -bd 2
632
633 $addrcanvas_ create window 2 $y -window $w -anchor nw
634 set b [new AddrBlockWindow $w 1 $self]
635 $b set-type $type_
636 lappend addrblocks_ $b
637
638 incr numblocks_
639
640 update
641 set bb [$addrcanvas_ bbox all]
642 $addrcanvas_ config -width [lindex $bb 2]
643 $addrcanvas_ config -scrollregion "0 0 2.5i [lindex $bb 3]"
644
645 return $b
646 }
647
648 # Called when a selection is made in the media type menu. Updates
649 # the formats menu so that the choices are appropriate for the new
650 # media type (for example, if the media type is set to audio, the
651 # format menu should contain audio formats and not video formats...)
652 SDPMediaEditWindow/Advanced private set-type {type} {
653 $self instvar type_ formatmenu_ protomenu_ win_ \
654 current_ lb_ addrblocks_ attrentries_
655
656 set type_ $type
657
658 # update entry in listbox
659 if {$current_ == [$lb_ index end]} {
660 set current_ end
661 }
662 $lb_ delete $current_
663 $lb_ insert $current_ $type
664 $lb_ selection set $current_
665 set current_ [$lb_ index $current_]
666
667 # update format menu for new type
668 $formatmenu_ clear
669 set fmts [UserApplication formats $type]
670 foreach f $fmts {
671 $formatmenu_ add $f
672 }
673 $formatmenu_ select 0
674
675 # update protocol menu
676 $protomenu_ clear
677 foreach proto [UserApplication protos $type] {
678 $protomenu_ add $proto
679 }
680 $protomenu_ select 0
681
682 # reallocate ports
683 foreach b $addrblocks_ {
684 $b set-type $type
685 }
686
687 # attributes
688 set f $win_.prop.f.f.left
689
690 # kill old attribute entries
691 foreach e $attrentries_ {
692 delete $e
693 }
694 set row 3
695 while {[winfo exists $f.l$row]} {
696 destroy $f.l$row
697 catch {destroy $f.e$row} ;#FIXME
698 incr row
699 }
700
701 # create appropriate attribute entries
702 set attrentries_ {}
703 set row 3
704 set attrs [UserApplication attrs $type]
705 foreach attr $attrs {
706 if {[llength $attr] == 1} {
707 set label $attr
708 set value ""
709 } else {
710 set label [lindex $attr 0]
711 set value [lindex $attr 1]
712 }
713 append label :
714 label $f.l$row -text $label -anchor e
715 grid $f.l$row -row $row -column 0 -sticky ew
716 lappend attrentries_ [new TextEntry "" $f.e$row $value]
717 $f.e$row config -width 10
718 grid $f.e$row -row $row -column 1 -sticky ew
719 incr row
720 }
721
722 grid rowconfigure $f $row -weight 1
723 }
724
725 #
726 SDPMediaEditWindow/Advanced private alloc-addrs {n {scope ""}} {
727 if {$scope == ""} {
728 $self instvar scopes_
729 set scope [lindex $scopes_ 0]
730 }
731
732 return [[AddressAllocator instance] alloc $scope $n]
733 }
734
735 #
736 SDPMediaEditWindow/Advanced private alloc-port {media} {
737 switch $media {
738 audio { set base 0x4000 }
739 whiteboard { set base 0x8000 }
740 video - default { set base 0xc000 }
741 }
742 set port [expr ([random]&0x3ffe) + $base]
743 return $port
744 }
745
746 #
747 SDPMediaEditWindow/Advanced private find-scope {addr} {
748 $self instvar scopes_
749 foreach s $scopes_ {
750
751 if [$s contains $addr] {
752 return $s
753 }
754 }
755 return ""
756 }
757
758 #
759 SDPMediaEditWindow/Advanced public buildmsgs {} {
760 $self save-stream
761
762 # first, find all scopes
763 set scopes {}
764 $self instvar streams_
765 foreach s $streams_ {
766 foreach a [lindex $s 3] {
767
768 set scope [$self find-scope [lindex $a 0]]
769 if {$scope == ""} {
770 #FIXME
771
772 $self warn "Can't find scope for address $a"
773 return {}
774 }
775
776 if { [lsearch -exact $scopes $scope] < 0 } {
777 lappend scopes $scope
778 }
779 }
780 }
781
782 # find the "base" scope -- the one that comes first in
783 # scopes_ for which we have layers -- and move it to the
784 # front of the list
785 $self instvar scopes_
786 foreach s $scopes_ {
787 set i [lsearch -exact $scopes $s]
788 if {$i == 0} {
789 break
790 } elseif {$i>0} {
791 set scopes [concat $s [lreplace $scopes $i $i]]
792 break
793 }
794 }
795
796 # build a media message fragment for each scope in which we
797 # have layers
798 set msgs {}
799 foreach scope $scopes {
800 set text ""
801 foreach stream $streams_ {
802 set media [lindex $stream 0]
803 set fmt [lindex $stream 1]
804 set proto [lindex $stream 2]
805 set addrs [lindex $stream 3]
806 set attrs [lindex $stream 4]
807
808 set layer 0
809 foreach a $addrs {
810 set addr [lindex $a 0]
811 set port [lindex $a 1]
812 set layers [lindex $a 2]
813
814 if [$scope contains $addr] {
815
816 #FIXME
817 set ttl 127
818
819 append text "m=$media $port $proto $fmt\n"
820 append text "c=IN IP4 $addr/$ttl/$layers\n"
821 if {$layers > 1 || [llength $addrs] > 1} {
822 if {$layers == 1} {
823 append text "a=layers:$layer"
824 } else {
825 set last [expr $layer + $layers - 1]
826 append text "a=layers:$layer-$last\n"
827 }
828 }
829
830 set i 0
831 set names [UserApplication attrs $media]
832 foreach v $attrs {
833 if {$v != ""} {
834 set name [lindex $names $i]
835 if {[llength $name] > 1} {
836 set name [lindex $name 0]
837 }
838 append text "a=$name:$v\n"
839 incr i
840 }
841 }
842 }
843 incr layer $layers
844 }
845 }
846 lappend msgs $text
847 }
848
849 return $msgs
850 }
851
852
853 #
854 # FIXME needs lots of work
855 #
856 Class SDPMediaEditWindow/Simple
857
858 SDPMediaEditWindow/Simple public init {parent} {
859 $self instvar win_ msg_ src_
860
861 set win_ "[$parent set win_].simple"
862 frame $win_
863
864 set msg_ [$parent set msg_]
865 set src_ [$parent set src_]
866
867 $self buildwin
868 $self show
869 }
870
871 SDPMediaEditWindow/Simple public hide {} {
872 $self instvar win_
873 pack forget $win_
874 }
875
876 SDPMediaEditWindow/Simple public show {} {
877 $self instvar win_
878 pack $win_ -fill both -expand yes
879 }
880
881 SDPMediaEditWindow/Simple private buildwin {} {
882 $self instvar win_ msg_ media_ buttons_ menus_ addrs_ ports_
883
884 set buttons_ {}
885 set menus_ {}
886 set addrs_ {}
887 set ports_ {}
888
889 label $win_.lt -text "Media"
890 grid $win_.lt -row 0 -column 0 -columnspan 2 -sticky ew
891
892 label $win_.ft -text "Format"
893 grid $win_.ft -row 0 -column 2 -sticky ew
894
895 label $win_.addrt -text "Address"
896 grid $win_.addrt -row 0 -column 3 -sticky ew
897
898 label $win_.portt -text "Port"
899 grid $win_.portt -row 0 -column 4 -sticky ew
900
901 set media_ [UserApplication media]
902 set i 1
903 foreach type $media_ {
904 if {$msg_ == ""} {
905 set present 1
906 set addr [$self alloc-addr]
907 set port [$self alloc-port $type]
908 } else {
909 #FIXME set defaults
910 }
911
912 set button [new CheckButton $win_.c$i]
913 $button set-val $present
914 lappend buttons_ $button
915 grid $win_.c$i -row $i -column 0 -padx 2 -pady 2
916
917 label $win_.l$i -text $type -anchor w
918 grid $win_.l$i -row $i -column 1 -sticky ew
919
920 set menu [new PopupMenu $win_.f$i]
921 lappend menus_ $menu
922 foreach fmt [UserApplication formats $type] {
923 $menu add $fmt
924 }
925 grid $win_.f$i -row $i -column 2 -sticky ew
926
927 set entry [new TextEntry "$self valid-addr" $win_.addr$i ""]
928 $win_.addr$i configure -width 16
929 $win_.addr$i insert 0 $addr
930 lappend addrs_ $entry
931 grid $win_.addr$i -row $i -column 3 -sticky ew
932
933 set entry [new TextEntry "$self valid-port" $win_.port$i ""]
934 $win_.port$i configure -width 8
935 $win_.port$i insert 0 $port
936 lappend ports_ $entry
937 grid $win_.port$i -row $i -column 4 -sticky ew
938
939 incr i
940 }
941
942 #FIXME scoping stuff
943 message $win_.m \
944 -text "WARNING: The simple interface really doesn't work yet."
945 grid $win_.m -row $i -column 0 -columnspan 5 -sticky news
946
947 update
948 $win_.m configure -width [winfo width $win_.m]
949 }
950
951 #FIXME
952 SDPMediaEditWindow/Simple private alloc-addr {} { return "224.2.3.4" }
953 SDPMediaEditWindow/Simple private alloc-port {media} { return "1234" }
954 SDPMediaEditWindow/Simple public buildobjs {} { return {} }
955
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.