~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tcl/dc/dc/ui-dcthumbnail.tcl

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.