1 # ui-dcthumbnail.tcl --
2 #
3 # Stuff for thumbnail frame, including video thumbnails as well as
4 # other services.
5 #
6 # Copyright (c) 2000-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 Observer
33 import DragNDrop
34
35 # this is a hack to fix the circular dependency
36 # ie - don't move this lower then to imports below
37 Class CDcUIThumbnail
38
39 import CDcUIThumbnail/Service/Replay
40 import CDcUIThumbnail/Video
41
42 Class CDcUIThumbnailFrame -superclass Observer
43
44 CDcUIThumbnailFrame instproc init { appDc uiMain winFrame } {
45 $self instvar m_appDc
46 $self instvar m_uiMain
47 $self instvar m_winFrame
48 $self instvar m_iFrameCounter
49 $self instvar m_aVideoThumbnail
50 $self instvar m_aWaitingService
51 $self instvar m_aWaitingSource
52
53 $self next
54
55 # initialize member variables
56 set m_iFrameCounter 0
57 set m_aWaitingSerivce("") ""
58 set m_aWaitingSource("") ""
59 $self instvar m_thumbnailsInfo
60 set m_thumbnailsInfo(windows) [list]
61
62 # copy arguments to member variables
63 set m_appDc $appDc
64 set m_uiMain $uiMain
65 set m_winFrame $winFrame
66
67 # lets attach this object to the dc agent
68 set studioAgent [$m_appDc get_studio_agent]
69 $studioAgent attach $self
70
71 # link the service session so that it'll call this function
72 # when something new happens
73 # get the service object
74 set serviceSession [$m_appDc get_sds_session]
75 $serviceSession UpdateInfo "$self BuildMenu"
76
77 $self instvar m_font
78 set m_font [$self get_option smallfont]
79
80 # build the ui
81 $self BuildUI
82 }
83
84 CDcUIThumbnailFrame instproc BuildUI {} {
85 $self instvar m_winFrame m_font
86
87
88 # the layout of this frame goes like this:
89 # Inside the main frame, there are four frames
90 # the top frame has a label in it
91 # the middle frames has a column of thumbnails
92 # the bottom frame has a row of menu buttons
93
94 # the top frame
95 label $m_winFrame.title -text "Sources" -relief ridge -font $m_font
96 pack $m_winFrame.title -side top -fill x
97
98
99 # the middle frames
100 frame $m_winFrame.video -relief ridge
101 pack $m_winFrame.video -side top -fill both
102
103 # the frame for the bottom
104 frame $m_winFrame.menubar -relief ridge
105 pack $m_winFrame.menubar -side bottom -fill x
106
107 # the frame for the services
108 frame $m_winFrame.service -relief ridge
109 pack $m_winFrame.service -side bottom -fill both
110
111 # the button in the bottom frame
112 menubutton $m_winFrame.menubar.button -text "Service" \
113 -menu $m_winFrame.menubar.button.menu -relief raised -font $m_font
114 pack $m_winFrame.menubar.button -fill x -expand 1
115
116 # the menu from which entries will be deleted and added
117 menu $m_winFrame.menubar.button.menu
118
119 $self BuildMenu
120 }
121
122 CDcUIThumbnailFrame instproc BuildMenu { } {
123 $self instvar m_appDc
124 $self instvar m_winFrame
125 $self instvar m_font
126
127 # first get the data from the service session object
128 set serviceSession [$m_appDc get_sds_session]
129 set data [$serviceSession set m_data]
130
131 # now let's parse the data
132 set lTree [$self ParseData $data]
133
134 # destroy the old menu
135 destroy $m_winFrame.menubar.button.menu
136
137 # construct the new menu
138 menu $m_winFrame.menubar.button.menu -font $m_font
139 $self AddMenuEntry $m_winFrame.menubar.button.menu $lTree root
140 }
141
142 CDcUIThumbnailFrame instproc AddMenuEntry { menuCurrent lTree parent } {
143 array set aTree $lTree
144 $self instvar m_font
145
146 set iCount 0
147 set children $aTree($parent)
148 set f $m_font
149 foreach child $children {
150 if { [info exists aTree($child)] } {
151 $menuCurrent add cascade -label $child -menu $menuCurrent.$iCount
152 menu $menuCurrent.$iCount -font $m_font
153 $self AddMenuEntry $menuCurrent.$iCount $lTree $child
154 } else {
155 $menuCurrent add command -label $child \
156 -command "$self StartService [list $child]"
157 }
158 set iCount [expr "$iCount + 1"]
159 }
160 }
161
162 CDcUIThumbnailFrame instproc ParseData { data } {
163 set aTree(root) ""
164
165 # iterate through each pair of contact info and properties
166 foreach { contactInfo properties } $data {
167
168 # iterate through all the prperties
169 foreach property $properties {
170
171 # get which property it is. ie which attribute
172 set attribute [lindex $property 0]
173
174 # it's a location property and construct a tree with location
175 # information
176 if { $attribute == "LOCATION:" } {
177 set parent root
178 foreach node [lindex $property 1] {
179
180 if { [info exists aTree($parent)] } {
181 set children $aTree($parent)
182 } else {
183 set children ""
184 }
185
186 if { ![string match $node $children] } {
187 set aTree($parent) [concat [list $node] $children]
188 }
189
190 set parent $node
191 }
192 set lastNode $parent
193 }
194
195 # save the type information for the leaf node of the location tree
196 if { $attribute == "TYPE:" } {
197 set infoType [lindex $property 1]
198 }
199 }
200
201 # construct the leaf node
202 if { [info exists aTree($lastNode)] } {
203 set children $aTree($lastNode)
204 } else {
205 set children {}
206 }
207 set node "$infoType : $contactInfo"
208 set aTree($lastNode) [concat [list $node] $children]
209 }
210
211 puts "tree = [array get aTree]"
212 return [array get aTree]
213 }
214
215 #
216 # This is called when someone selects a service from the "Service" button in
217 # DC.
218 #
219 CDcUIThumbnailFrame instproc StartService { menuEntry } {
220 # first of all I need to parse the service entry
221 # the format shoube be "type:contact info"
222 set lEntry [split $menuEntry :]
223
224 set strType [lindex $lEntry 0]
225 set lContactInfo [lindex $lEntry 1]
226 set inetAddr [lindex $lContactInfo 0]
227 set iPort [lindex $lContactInfo 1]
228
229 # get some needed member variables
230 $self instvar m_appDc
231 $self instvar m_uiMain
232 $self instvar m_winFrame
233 $self instvar m_iFrameCounter
234
235 # create the new thumbnail object
236 # puts "strType = $strType;"
237
238 switch -exact -- $strType {
239 "Video Capture Device " {
240 # so the idea here is that we want to connect temporarily to send
241 # the start message and then the rvc will initiate another service
242 # with the appropriate video source id. Once the service is gotten
243 # the thunmbnailframe will hook up the correct service to the
244 # thumbnail
245
246 # get the service manager and create a new service
247 set service [$m_appDc new_service $inetAddr $iPort]
248
249 # get options to give to the video service
250 set options [$m_appDc options]
251 set inetMStudioAddr [$options get_option optMStudioAddress]
252 set iMStudioPort [$options get_option optMStudioPort]
253 set spec [$m_appDc get_service_spec]
254 set inetClientAddr [lindex $spec 0]
255 set iClientPort [lindex $spec 1]
256 set arguments [list $inetMStudioAddr $iMStudioPort \
257 $inetClientAddr $iClientPort]
258
259 if {$service != ""} {
260 $service Send "SYN_START" $arguments
261 delete $service
262 } else {
263 # Something is wrong in new_service.
264 }
265 }
266
267 "Archive Replay " {
268 # we have to create the frame
269 set winFrame [frame $m_winFrame.service.$m_iFrameCounter]
270 pack $winFrame -side bottom -fill x
271
272 # increment the frame counter
273 set m_iFrameCounter [expr "$m_iFrameCounter + 1"]
274
275 # create the new thumbnail object
276 set uiThumbnail [new CDcUIThumbnail/Service/Replay $m_appDc \
277 $m_uiMain $winFrame]
278
279 # get the service manager and create a new service
280 set service [$m_appDc new_service $inetAddr $iPort]
281
282 if {$service != ""} {
283 $uiThumbnail StartService $service
284 }
285 }
286
287 "Special FX " {
288 # we have to create the frame
289 set winFrame [frame $m_winFrame.service.$m_iFrameCounter]
290 pack $winFrame -side bottom -fill x
291
292 # increment the frame counter
293 set m_iFrameCounter [expr "$m_iFrameCounter + 1"]
294
295 # create the new thumbnail object
296 set uiThumbnail [new CDcUIThumbnail/Service/SpecialFx $m_appDc \
297 $m_uiMain $winFrame]
298
299 # get the service manager and create a new service
300 set service [$m_appDc new_service $inetAddr $iPort]
301
302 if {$service != ""} {
303 $uiThumbnail StartService $service
304 }
305 }
306
307 "405 Room Control " -
308 "Real Networks Switcher " {
309 # we have to create the frame
310 set winFrame [frame $m_winFrame.service.$m_iFrameCounter]
311 pack $winFrame -side bottom -fill x
312
313 # increment the frame counter
314 set m_iFrameCounter [expr "$m_iFrameCounter + 1"]
315
316 # create the new thumbnail object
317 set uiThumbnail [new CDcUIThumbnail/Service $m_appDc \
318 $m_uiMain $winFrame]
319
320 # get the service manager and create a new service
321 set service [$m_appDc new_service $inetAddr $iPort]
322
323 if {$service != ""} {
324 $uiThumbnail StartService $service
325 }
326 }
327 }
328 }
329
330 CDcUIThumbnailFrame instproc activate {source} {
331 #
332 # As noted in vic/ui-activesourcemgr.tcl,
333 # we need to wait until the decoder is created.
334 # This needs to be fixed when mash is fixed??
335 #
336 after idle "$self ReallyActivate $source"
337 }
338
339 CDcUIThumbnailFrame instproc ReallyActivate {source} {
340 $self instvar m_aVideoThumbnail
341 $self instvar m_aWaitingService
342 $self instvar m_aWaitingSource
343
344 set iSourceId [$source srcid]
345
346 # so the first thing is to find if a service already exists waiting
347 # for this incoming source. So search through the table of waiting
348 # services
349 if { [info exists m_aWaitingService($iSourceId)] } {
350 # create the new video thumbnail
351 set uiThumbnail [$self NewVideoThumbnail $source \
352 $m_aWaitingService($iSourceId)]
353 set m_aVideoThumbnail($iSourceId) $uiThumbnail
354
355 # remove this entry from the list
356 unset m_aWaitingService($iSourceId)
357
358 return
359 }
360
361 # otherwise we have to wait for a while to let the incomming
362 # service come in. After the wait just start the source without
363 # a service
364
365 set m_aWaitingSource($iSourceId) $source
366 after 5000 "$self ServiceTimeout $source"
367 }
368
369
370 CDcUIThumbnailFrame instproc deactivate {source} {
371 $self DeleteVideoThumbnail $source
372 }
373
374
375 ##############################################################################
376 #
377 # CDcUIThumbnailFrame public ServiceTimeout { source } {
378 #
379 # Input:
380 # source - the source that is waiting for the service to come in but it never
381 # did so a timeout occured
382 #
383 # Output:
384 # none
385 #
386 # Description:
387 # This is called some time after the source comes in. If no service connects
388 # between that time then this source goes out as a serverless thumbnail.
389 #
390 ##############################################################################
391 CDcUIThumbnailFrame public ServiceTimeout { source } {
392 $self instvar m_aWaitingSource
393 $self instvar m_aVideoThumbnail
394
395 set iSourceId [$source srcid]
396
397 # check if the waiting source has be taken
398 if { ![info exists m_aWaitingSource($iSourceId)] } {
399 return
400 }
401
402 # otherwise we need to create a new thumbnail without the service
403
404 # create the new video thumbnail
405 set uiThumbnail [$self NewVideoThumbnail $source]
406 set m_aVideoThumbnail($iSourceId) $uiThumbnail
407
408 # remove this entry from the list
409 unset m_aWaitingSource($iSourceId)
410 }
411
412
413 ##############################################################################
414 #
415 # CDcUIThumbnailFrame public NewConnection { service }
416 #
417 # Input:
418 # service - the newly connected service object
419 #
420 # Output:
421 # none
422 #
423 # Description:
424 # This is called by the dc application object when a service of the correct
425 # type has arrived. We take this service object and try to match it to one
426 # of the waiting sources. If none are waiting then we put them into
427 # a waiting list so that the thumbnails can get them when the source is
428 # activated
429 #
430 ##############################################################################
431 CDcUIThumbnailFrame public NewConnection { service } {
432 $self instvar m_aVideoThumbnail
433 $self instvar m_aWaitingSource
434 $self instvar m_aWaitingService
435
436 # first check that the service is of type VideoService
437 if { [$service set m_szType] != "VideoService" } {
438 return
439 }
440
441 set iSourceId [$service set m_szAttribute]
442
443 # check if the source is waiting at the moment
444 if { [info exists m_aWaitingSource($iSourceId)] } {
445 # create the new video thumbnail
446 set uiThumbnail [$self NewVideoThumbnail \
447 $m_aWaitingSource($iSourceId) $service]
448 set m_aVideoThumbnail($iSourceId) $uiThumbnail
449
450 # remove this entry from the list
451 unset m_aWaitingSource($iSourceId)
452
453 return
454 }
455
456 # otherwise we have to wait until a source comes in
457 set m_aWaitingService($iSourceId) $service
458 }
459
460 ##############################################################################
461 #
462 # CDcUIThumbnailFrame public NewVideoThumbnail { source {service 0} }
463 #
464 # Input:
465 # source - the source object of the video stream
466 # service - the service object - defaulted to 0
467 #
468 # Output:
469 # CDcUIThumbnail/Video object that is created
470 #
471 # Description:
472 # will
473 #
474 ##############################################################################
475 CDcUIThumbnailFrame public NewVideoThumbnail { source {service 0} } {
476 $self instvar m_appDc
477 $self instvar m_uiMain
478 $self instvar m_winFrame
479 $self instvar m_iFrameCounter
480
481 # we have to create the frame
482 set winFrame [frame $m_winFrame.video.$m_iFrameCounter]
483 pack $m_winFrame.video.$m_iFrameCounter -side top
484
485 # increment the frame counter
486 set m_iFrameCounter [expr "$m_iFrameCounter + 1"]
487
488 # create the new thumbnail object
489 set uiThumbnail [new CDcUIThumbnail/Video $m_appDc $m_uiMain $winFrame]
490
491 set inetAddr [$source addr]
492 set hostname [lookup_host_name $inetAddr]
493 set hostname [string tolower $hostname]
494 $self instvar m_thumbnailsInfo
495 # FIXME - need to deal with this case better
496 if {[info exists m_thumbnailsInfo($hostname,addr)]} {
497 puts stdout "warning, service from $inetAddr already exists!!!"
498 }
499 lappend m_thumbnailsInfo(windows) $uiThumbnail
500 set m_thumbnailsInfo($uiThumbnail,hostname) $hostname
501 set m_thumbnailsInfo($uiThumbnail,addr) $inetAddr
502
503
504 # start the video
505 $uiThumbnail StartVideo $source
506
507 # start the service if we have one
508 if { $service != 0 } {
509 $uiThumbnail StartService $service
510 }
511
512 return $uiThumbnail
513 }
514
515
516 #---------------------------------------------------------------------------
517 #
518 # CDcUIThumbnailFrame public DeleteVideoThumbnail { source }
519 #
520 # Input:
521 # source - the source object of the video stream whose thumbnail we
522 # are going to delete
523 #
524 #---------------------------------------------------------------------------
525 CDcUIThumbnailFrame public DeleteVideoThumbnail { source } {
526
527 #
528 # Retrieve the associated thumbnail
529 #
530 $self instvar m_aVideoThumbnail
531 set srcid [$source srcid]
532 if ![info exists m_aVideoThumbnail($srcid)] {
533 puts "WARNING: no video thumbnail exists for $srcid"
534 return
535 }
536 set thumbnail $m_aVideoThumbnail($srcid)
537
538 #
539 # Cleanup thumbnails info
540 #
541 $self instvar m_thumbnailsInfo
542 set pos [lsearch m_thumbnailsInfo(windows) $thumbnail]
543 if {$pos > 0} {
544 lreplace m_thumbnailsInfo(windows) $pos $pos
545 }
546 unset m_thumbnailsInfo($thumbnail,hostname)
547 unset m_thumbnailsInfo($thumbnail,addr)
548
549 $thumbnail StopVideo
550
551 #
552 # Cleanup UI stuffs
553 #
554 set winFrame [$thumbnail GetWinFrame]
555 destroy $winFrame
556
557 delete $thumbnail
558 }
559
560
561 #---------------------------------------------------------------------------
562 #
563 # CDcUIThumbnailFrame public GetSourceIDs { }
564 #
565 # Purpose:
566 # Return a list of source ids for all thumbnails managed by this frame.
567 #
568 #---------------------------------------------------------------------------
569 CDcUIThumbnailFrame public GetSourceIDs { } {
570 $self instvat m_aVideoThumbnail
571 if {[info exists m_aVideoThumbnail]} {
572 return [array names $m_aVideoThumbnail]
573 } else {
574 return ""
575 }
576 }
577
578
579 #
580 # Return the CDcUIPreview object containing the source
581 #
582 CDcUIThumbnailFrame public GetUIVideoWithSource { source } {
583 $self instvar m_thumbnailsInfo
584 foreach v $m_thumbnailsInfo(windows) {
585 if {[$v GetSource] == $source} {
586 return $v
587 }
588 }
589 return ""
590 }
591
592
593
594 # Class declaration at the top
595 CDcUIThumbnail public init { appDc uiMain winFrame } {
596 $self instvar m_appDc m_uiMain m_winFrame
597
598 # store away input
599 set m_appDc $appDc
600 set m_uiMain $uiMain
601 set m_winFrame $winFrame
602 }
603
604
605 CDcUIThumbnail public GetWinFrame { } {
606 return [$self set m_winFrame]
607 }
608
609
610 CDcUIThumbnailFrame public getThumbnailInfo {} {
611 $self instvar m_thumbnailsInfo
612
613 set retList [array get m_thumbnailsInfo]
614 return $retList
615 }
616
617
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.