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

Open Mash Cross Reference
mash/tcl/vic/ui-activesourcemgr.tcl

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

  1 # ui-activesourcemgr.tcl --
  2 #
  3 #       ActiveSourceManager is used to dispatch and manage ActiveSource
  4 #       objects.
  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 #  @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/vic/ui-activesourcemgr.tcl,v 1.20 2002/08/12 06:21:19 agu Exp $
 33 
 34 
 35 import Observer ActiveSource UserWindow Configuration
 36 
 37 #
 38 # ActiveSourceManager is used to dispatch and manage ActiveSource
 39 # objects.  It is an Observer of VideoAgent.
 40 #
 41 Class ActiveSourceManager -superclass {Observer} -configuration {
 42         tile 1
 43 }
 44 
 45 #
 46 # Tile out in a grid the video of the ActiveSources followed by the
 47 # provided <i>videoAgent</i>.  If <i>list_direction</i> is "horizontal",
 48 # the <i>tile</i> resource option indicates the initial number of rows
 49 # for the grid.  If <i>list_direction</i> is "vertical", the <i>tile</i>
 50 # resource option indicates the initial number of columns for the grid.
 51 #
 52 ActiveSourceManager public init {ui w videoAgent list_direction localChannel {autoplace 0}} {
 53         $self next
 54 
 55         $self instvar ui_ videoAgent_ localChannel_ autoplace_
 56         set ui_ $ui
 57         set videoAgent_ $videoAgent
 58         set localChannel_ $localChannel
 59         set autoplace_ $autoplace
 60 
 61         $self instvar curcol_ currow_ ncol_ nrow_ list_direction_
 62         set curcol_ 0
 63         set currow_ 0
 64         set list_direction_ $list_direction
 65         set ncol_ [$self get_option tile]
 66         set nrow_ [$self get_option tile]
 67 
 68         # let this ActiveSourceManager be an observer of the VideoAgent so it can catch "trigger_format" and "activate" and "deactivate"
 69         $videoAgent_ attach $self
 70 }
 71 
 72 #
 73 ActiveSourceManager public init_grid {w} {
 74         $self instvar grid_ label_
 75 
 76         frame $w
 77         set grid_ $w.grid
 78         frame $grid_
 79         set label_ $w.label
 80         label $label_ -text "Waiting for video..."
 81 
 82         pack $label_ -anchor c -expand 1 -side left -fill both
 83 }
 84 
 85 #
 86 # The provided ActiveSource, <i>as</i>, is added to the active_() instvar (an array of active senders indexed by <i>src</i>).
 87 # If the array was previously empty, the $label_ is removed and the $grid_ is packed in its place.
 88 #
 89 ActiveSourceManager public add_active { as src } {
 90         $self instvar active_ grid_ label_
 91         set active_($src) $as
 92         if { [array size active_] == 1 } {
 93                 pack forget $label_
 94                 pack $grid_ -expand 1 -fill x -anchor n
 95         }
 96 }
 97 
 98 #
 99 # The specified <i>src</i> is removed from the active_() instvar (an array of active senders indexed by src).
100 # If this was the last element of the array, the $grid_ is removed and the $label_ is packed in its place.
101 #
102 ActiveSourceManager public rm_active src {
103         $self instvar active_ grid_ label_
104         unset active_($src)
105         if { [array size active_] == 0 } {
106                 pack forget $grid_
107                 pack $label_ -anchor c -expand 1 -side left
108         }
109 }
110 
111 #
112 # Return a list of the active sources.
113 #
114 ActiveSourceManager public active-sources {} {
115         $self instvar active_
116         return [array names active_]
117 }
118 
119 #
120 # Update the row and column variables to indicate an addition to the
121 # grid of thumbnails of ActiveSources.  If the <i>list_direction_</i> is
122 # "vertical", additions to the grid are placed at the end of the first
123 # non-full column.  When a column becomes full, a new column is begun,
124 # filled from top to bottom.  If the <i>list_direction_</i> is
125 # "horizontal", additions to the grid are placed at the end of the first
126 # non-full row.  When a row becomes full, a new row is begun, filled
127 # from left to right.
128 #
129 ActiveSourceManager public bump { } {
130         $self instvar curcol_ currow_ list_direction_
131 
132         if { $list_direction_ == "vertical" } {
133                 $self instvar ncol_
134                 incr curcol_
135                 if { $curcol_ == $ncol_ } {
136                         set curcol_ 0
137                         incr currow_
138                 }
139         } else {
140                 $self instvar nrow_
141                 incr currow_
142                 if { $currow_ == $nrow_ } {
143                         set currow_ 0
144                         incr curcol_
145                 }
146         }
147 }
148 
149 #
150 # If the <i>list_direction_</i> is "vertical", reformat the grid of
151 # video thumbnails into <i>n</i> columns.  If the <i>list_direction_</i>
152 # is "horizontal", reformat the grid of video thumbnails into <i>n</i>
153 # rows.
154 #
155 ActiveSourceManager public redecorate { {n 0} } {
156         $self instvar curcol_ currow_ list_direction_ active_
157         set curcol_ 0
158         set currow_ 0
159         if { $n != 0 } { 
160             if { $list_direction_ == "vertical" } {
161                 $self instvar ncol_
162                 set ncol_ $n
163             } else {
164                 $self instvar nrow_
165                 set nrow_ $n
166             }
167         }
168 
169         $self instvar grid_
170         if ![info exists grid_] {
171                 return
172         }
173         foreach src [$self active-sources] {
174             if [$active_($src) set hidden_] {
175                 grid forget $grid_.$src
176             } else {
177                 grid $grid_.$src -row $currow_ -column $curcol_ -sticky we
178                 if { $list_direction_ == "vertical" } {
179                     grid columnconfigure $grid_ $curcol_ -weight 1
180                 } else {
181                     grid rowconfigure $grid_ $currow_ -weight 1
182                 }
183                 $self bump
184             }
185         }
186     }
187 
188 
189 #
190 # Add a <i>src</i> to the active senders list.  E.g., make a postage
191 # stamp window appear, stats, etc. so that the user can select
192 # the video stream.
193 #
194 ActiveSourceManager public activate src {
195         #
196         # give the VideoAgent a chance to create and install
197         # a decoder and for that decoder to see a packet so it can
198         # determine the output geometry and color decimation.
199         # we shouldn't have to do this (e.g., resize will
200         # take care of a geometry change), but currently
201         # decoders can't trigger a renderer realloation
202         # when the decimation changes.FIXME fix this
203         # Note that trigger_format allocates the decoder object
204         # is called before the event loop goes idle
205         #
206         after idle "$self really_activate $src"
207 }
208 
209 #
210 # Create an ActiveSource, $as, within the widget, $grid_.$src, out of the provided <i>src</i>.
211 # (This entails dropping a postage-stamp-sized VideoWidget decoding the $src into the $grid_.$src widget.)
212 # The widget, $grid.$src, is subsequently positioned within $grid_ by the grid manager in
213 # the row specified by instvar $currow_ and the column specified by instvar $curcol_.
214 # The column and row variables are updated by the bump method to reflect this addition to the grid.
215 # Add this ActiveSource, $as, to the instvar array active_() (the array of active senders).
216 # Update the decoder for the specified <i>src</i>.
217 #
218 ActiveSourceManager public really_activate src {
219         $self instvar grid_ curcol_ currow_ ui_ list_direction_ localChannel_ autoplace_
220 
221         set as [new ActiveSource $self $ui_ $grid_.$src $src $localChannel_]
222 
223         # If autoplace is active, get the x,y coordinates and scale factor
224         # for the new ActiveSource. After creating the UserWindow, register
225         # it so its movements, etc. can be tracked.
226         if { $autoplace_ } {
227                 set coords_scale [$self autoplace add $as]
228                 $as place [lindex $coords_scale 0] \
229                         [lindex $coords_scale 1] \
230                         [lindex $coords_scale 2]
231         }
232 
233         grid $grid_.$src -row $currow_ -column $curcol_ -sticky we
234 
235         if { $list_direction_ == "vertical" } {
236                 grid columnconfigure $grid_ $curcol_ -weight 1
237         } else {
238                 grid rowconfigure $grid_ $currow_ -weight 1
239         }
240 
241         $ui_ update_decoder $src
242         $self bump
243 
244         #
245         # Someone became activated, so we have to change
246         # the switchable menu to include this participant
247         #
248         Switcher rebuild_switch_list_menu
249 
250         # FIXME this is a temporary hack while cindy works on the VideoBox class...
251         if {[$ui_ info class] == "MuiUI"} {
252                 $ui_ maybe_switch_in $src
253         }
254 }
255 
256 #
257 # Remove a <i>src</i> from the active senders list.
258 #
259 ActiveSourceManager public deactivate {src} {
260         $self instvar active_
261         if [info exists active_($src)] {
262                 set as $active_($src)
263                 set L [$as user-windows]
264                 foreach uw $L {
265                         #FIXME should check if we're voice-switched
266                         # and if so, bump window
267                         delete $uw
268                 }
269                 # detach any we missed by deleting user-windows
270                 $as detach-windows
271                 $as delete-decoder-window
272                 $as destroy
273         }
274 
275         $self instvar grid_
276         set w $grid_.$src
277         if [winfo exists $w] {
278                 grid forget $w
279                 destroy $w
280         }
281         $self rm_active $src
282         $self redecorate
283         $src handler ""
284 
285         #
286         # Someone became de-activated, so we have to change
287         # the switchable menu to un-include this participant
288         #
289         Switcher rebuild_switch_list_menu
290 
291         #FIXME
292         global ftext btext ltext fpshat bpshat lhat shat
293         unset ftext($src)
294         unset btext($src)
295         unset ltext($src)
296         unset fpshat($src)
297         unset bpshat($src)
298         unset lhat($src)
299         unset shat($src)
300 }
301 
302 #
303 # Dispatch focus method on switcher windows.
304 #
305 ActiveSourceManager public focus_speaker { infoname msg } {
306         foreach s [$self active-sources] {
307                 if { [$s sdes cname] == $msg } {
308                         Switcher focus $s
309                 }
310         }
311 }
312 
313 #
314 # Update the name of the <i>src</i> for the UserWindows in which it appears.
315 #
316 ActiveSourceManager public change_name {src} {
317         set name [$src sdes name]
318         # update viewing window names to reflect new name
319         $self instvar active_
320         if [info exists active_($src)] {
321                 set as $active_($src)
322                 foreach uw [$as user-windows] {
323                         if { [$uw attached-source] == "$as" } {
324                                 $uw set-name $name
325                         }
326                 }
327         }
328 
329         # Someone's name has been altered , so we have to change
330         # the switchable menu to include this participant
331         #
332         Switcher rebuild_switch_list_menu
333 }
334 
335 #
336 ActiveSourceManager public trigger_format {src} {
337         $self instvar active_ videoAgent_ ui_
338 
339         if ![info exists active_($src)] {
340                 #
341                 # if we get a change format before really_activate
342                 # was called (i.e., so we don't even have a thumbnail yet),
343                 # don't do anything
344                 #
345                 return
346         }
347 
348         set as $active_($src)
349 
350         set L [$as user-windows]
351         $as detach-windows
352         #FIXME
353         set extoutList [extout_detach_src $src]
354 
355         set d [$videoAgent_ reactivate $src]
356 
357         $ui_ update_decoder $src
358         global colorbutton
359         $d color $colorbutton($src)
360 
361         foreach uw $L {
362                 $as attach-window $uw
363                 [$uw video-widget] redraw
364         }
365         $as attach-thumbnail
366         #FIXME
367         extout_attach_src $src $extoutList
368 }
369 
370 #
371 # Called when the video stream state changes in a way that would
372 # affect the choice of renderer.  For example, when a jpeg stream
373 # changes from type-0 to type-1 we might have to revert from
374 # hardware to software decoding, or we might have to reallocate
375 # a 422 renderer as a 420 renderer.  This never needs to happen
376 # for most stream types (i.e., because the decimation factor is fixed).
377 #
378 ActiveSourceManager public decoder_changed {src} {
379         $self instvar active_
380         if ![info exists active_($src)] {
381                 return
382         }
383         #FIXME redundant with trigger_format
384         set as $active_($src)
385 
386         set L [$as user-windows]
387         $as detach-windows
388         #FIXME
389         set extoutList [extout_detach_src $src]
390         foreach uw $L {
391                 $as attach-window $uw
392                 [$uw video-widget] redraw
393         }
394         #FIXME
395         extout_attach_src $src $extoutList
396         return
397 }
398 
399 
400 ActiveSourceManager public trigger_format_all { } {
401         foreach s [$self active-sources] {
402                 $self trigger_format $s
403         }
404 }
405 
406 
407 ActiveSourceManager public get_activesource src {
408         $self instvar active_
409         if [info exists active_($src)] {
410                 return $active_($src)
411         } else {
412                 return ""
413         }
414 }
415 
416 #
417 # switches the VideoAgent object.
418 # This method should be called always from VicUI::switch-agent
419 #
420 ActiveSourceManager instproc switch-agent {new_agent} {
421         $self instvar videoAgent_
422 
423         # the attachement is already done by VicUI::switch-agent
424         #$new_agent attach $self
425 
426         # set the new videoAgent
427         set videoAgent_ $new_agent
428 }
429 
430 #
431 # Outside hook via tkvar autoplaceNewSources to turn on/off use of the
432 # autoplace function.
433 #
434 ActiveSourceManager instproc set_autoplace {} {
435     $self tkvar autoplaceNewSources
436     if { $autoplaceNewSources } {
437         $self autoplace_on
438     } else {
439         $self autoplace_off
440     }
441 }
442 
443 #
444 # Toggle the autoplace function on and off.
445 #
446 ActiveSourceManager instproc toggle_autoplace {} {
447     $self instvar autoplace_
448     if { $autoplace_ } {
449         $self autoplace_off
450     } else {
451         $self autoplace_on
452     }
453 }
454 
455 #
456 # Turn off autoplace.
457 #
458 ActiveSourceManager instproc autoplace_off {} {
459     $self instvar autoplace_
460     set autoplace_ false
461 }
462 
463 #
464 # Turn on autoplace. Close all windows and replace them.
465 #
466 ActiveSourceManager instproc autoplace_on {} {
467     $self instvar autoplace_ active_
468 
469     # Don't do anything if autoplace is already on.
470     if {$autoplace_} return
471 
472     # Close all windows. We can't just call detach-windows because that
473     # also detaches the thumbnail.
474     foreach src [$self active-sources] {
475         set as $active_($src)
476         foreach uw [$as user-windows] {
477             # We have to check that the user windows this ActiveSource
478             # knows about are actually still attached to this ActiveSource
479             # because voice-switched or browse-mode windows change their
480             # ActiveSources.
481             if {[$uw attached-source] == "$as"} {
482                 $uw destroy
483             }
484         }
485     }
486 
487     # Replace all windows.
488     foreach src [$self active-sources] {
489         set as $active_($src)
490         set coords_scale [$self autoplace add $as]
491         $as place [lindex $coords_scale 0] \
492                 [lindex $coords_scale 1] \
493                 [lindex $coords_scale 2]
494     }
495 
496     # Set new autoplace_ value.
497     set autoplace_ true
498 }
499 
500 #
501 # Default autoplace function.
502 #
503 # {add $as} is called when a new ActiveSource is to be placed. It
504 #           should return virtual screen coordinates and image size
505 #           formatted as "x y scale". If scale is 0, the ActiveSource
506 #           will not be placed.
507 # {remove $as} is called when an ActiveSource's display window is
508 #              destroyed (e.g. user closes the window).
509 # {register $as $uw} is called when the ActiveSource's display window
510 #                    has been created to associate a specific
511 #                    UserWindow with the ActiveSource.
512 ActiveSourceManager instproc autoplace {cmd as {uw false}} {
513     global mutebutton
514     $self instvar asources_ windows_ mon_ xbase_ ybase_ nextx_ nexty_ maxy_ xoffset_ yoffset_ xincr_ yincr_ mon_list_ screen_width_ screen_height_ minx_ miny_ maxx_ maxy_ framesize_ titlebarsize_
515 
516     # Should we place windows across monitors or only within monitors?
517     set cross_monitors 0
518 
519     # Handle add commands.
520     if {$cmd == "add"} {
521         # Get the monitor coordinates.
522         if {![info exists mon_list_]} {
523             # get_monitorinfo returns a list of lists. Each element of the
524             # list is a list formatted as "minx miny maxx maxy". The first
525             # element contains the total virtual screen resolution. All
526             # subsequent elements contain the physical screen resolutions
527             # in the virtual screen coordinate space. e.g. the second
528             # monitor might return "1024 0 1824 600" if its resolution is
529             # 800x600.
530             set mon_list_ [get_monitorinfo]
531             if { $mon_list_ == "" } {
532                 set mon_list_ [list [list 0 0 [winfo screenwidth .] [winfo screenheight .]] [list 0 0 [winfo screenwidth .] [winfo screenheight .]]]
533             }
534 
535             # Grab the virtual screen coordinates.
536             set v_coords [lindex $mon_list_ 0]
537             set minx_ [lindex $v_coords 0]
538             set miny_ [lindex $v_coords 1]
539             set maxx_ [lindex $v_coords 2]
540             set maxy_ [lindex $v_coords 3]
541 
542             # Remove the virtual screen coordinates from the monitor list,
543             # and sort left-most, then top-most.
544             set mon_list_ [lsort [lrange $mon_list_ 1 end]]
545 
546             # Compute the virtual screen width and height.
547             set screen_width_ [expr $maxx_ - $minx_ + 1]
548             set screen_height_ [expr $maxy_ - $miny_ + 1]
549 
550         # Compute the window frame and titlebar sizes.
551         set wm_geom [split [wm geometry .] {+}]
552         set winfo_geom [split [winfo geometry .] {+}]
553         if {[lindex $wm_geom 1] != [lindex $winfo_geom 1] && \
554             [lindex $wm_geom 2] != [lindex $winfo_geom 2]} \
555         {
556             set framesize_ [expr [lindex $winfo_geom 1] - [lindex $wm_geom 1]]
557             set titlebarsize_ [expr [lindex $winfo_geom 2] - [lindex $wm_geom 2]]
558         } else {
559             set framesize_ [expr [winfo rootx .] - [winfo x .]]
560             set titlebarsize_ [expr [winfo rooty .] - [winfo y .]]
561         }
562         }
563 
564         # If there are no ActiveSources placed, initialize values.
565         #
566         # mon_     the list index of the current monitor being populated.
567         # xbase_   the left-most pixel value of the last window placed.
568         # nextx_   the right-most pixel value of the last window placed.
569         # nexty_   the bottom-most pixel value of the last completed row.
570         # maxy_    the bottom-most pixel value of the current row.
571         # xincr_   the pixel amount to increase the xbase by each time.
572         # yincr_   the pixel amount to increase the ybase by each time.
573         # xoffset_ the horizontal pixel spacing between windows.
574         # yoffset_ the vertical pixel spacing between windows.
575         if {![array size asources_]} {
576             set mon_   0
577             set xbase_ [expr $minx_ - $framesize_]
578             set ybase_ [expr $miny_ - $titlebarsize_]
579             set nextx_ $xbase_
580             set nexty_ $ybase_
581             set maxy_ $nexty_
582             set xincr_ 10
583             set yincr_ 20
584             set xoffset_ $framesize_
585             set yoffset_ $titlebarsize_
586         }
587         
588         # Initialize the return values.
589         set retx [expr $nextx_ + $xoffset_]
590         set rety [expr $nexty_ + $yoffset_]
591         set scale 1
592 
593     # If the ActiveSource is muted, just return 0 for the scale.
594     if {$mutebutton([$as source])} {
595         return "$retx $rety 0"
596     }
597 
598         # If the ActiveSource was already placed, just return the previously
599         # calculated coordinates.
600         if {[info exists asources_($as)]} {
601             return $asources_($as)
602         }
603         
604         # Get the video stream dimensions.
605         set src [$as source]
606         set decoder [$src handler]
607         set width [expr int([$decoder width] * $scale)]
608         set height [expr int([$decoder height] * $scale)]
609 
610         # If we're crossing monitors or there is only one monitor, use
611         # a simple left-right, top-down placement. If we run out of room
612         # on the bottom of the virtual screen, jump back to the top.
613         if {$cross_monitors || [llength $mon_list_] == 1} {
614             # If there is no room in the current row, try the next row.
615             if {[expr $retx + $width] >= $screen_width_} {
616                 set retx [expr $xbase_ + $xoffset_]
617                 set rety [expr $maxy_ + $yoffset_]
618                 
619                 # Update nexty_.
620                 set nexty_ $maxy_
621             }
622             
623             # If there is no room for the bottom of the window in this
624             # row, go back to the top-left corner. Increase the base
625             # coordinates so we don't cover up the previous windows.
626             if {[expr $rety + $height] >= $screen_height_} {
627                 set xbase_ [expr $xbase_ + $xincr_]
628                 set ybase_ [expr $ybase_ + $yincr_]
629                 set retx [expr $xbase_ + $xoffset_]
630                 set rety [expr $ybase_ + $yoffset_]
631                 
632                         # Update nexty_ and maxy_.
633                 set nexty_ $ybase_
634                 set maxy_ $ybase_
635             }
636         } else {
637             # If we're not crossing monitors, place on one monitor after
638             # another, looping back to the first monitor if all monitors
639             # have been fully covered. If we're starting on the first
640             # monitor, then there is no need to loop later (set looped to
641             # true).
642             set placed 0
643             set looped [expr $mon_ == 0]
644             while {!$placed} {
645                 # If the current monitor index is less than zero or larger
646                 # than the number of monitors, reset it to zero.
647                 if {$mon_ < 0 || $mon_ >= [llength $mon_list_]} {
648                     set mon_ 0
649                 }
650                 
651                 # Get the virtual space coordinates for the current
652                 # monitor.
653                 set v_coords [lindex $mon_list_ $mon_]
654                 set minx [lindex $v_coords 0]
655                 set miny [lindex $v_coords 1]
656                 set maxx [lindex $v_coords 2]
657                 set maxy [lindex $v_coords 3]
658                 
659                 # Assume that we've placed the window. If it doesn't fit
660                 # on this monitor, then we know it can't be placed.
661                 set placed 1
662                 
663                 # If we're on the last monitor and we've looped here, then
664                 # just use these coordinates.
665                 if {[expr $mon_ + 1] == [llength $mon_list_] && $looped} {
666                     break;
667                 }
668                 
669                 # If there is no room in the current row, try the next row.
670                 if {[expr $retx + $width] >= $maxx} {
671                     set retx [expr $minx + $xbase_ + $xoffset_]
672                     set rety [expr $maxy_ + $yoffset_]
673                     
674                     # Update nexty_.
675                     set nexty_ $maxy_
676                     
677                     # Try the new coordinates.
678                     set placed 0
679                 }
680                 
681                 # If there is no room for the bottom of the window in this
682                 # row, go to the top-left corner of the next monitor.
683                 if {[expr $rety + $height] >= $maxy} {
684                     # If the next monitor would be the first monitor
685                     # (looping around) and we have not already looped
686                     # around, increase the base coordinates so we don't
687                     # cover up the previous windows.
688                     incr mon_
689                     if {$mon_ == [llength $mon_list_]} {
690                         set mon_ 0
691                         set xbase_ [expr $xbase_ + $xincr_]
692                         set ybase_ [expr $ybase_ + $yincr_]
693                         set looped 1
694                     }
695                     
696                     # Set the window coordinates to the top-left corner
697                     # of the next monitor.
698                     set v_coords [lindex $mon_list_ $mon_]
699                     set minx [lindex $v_coords 0]
700                     set miny [lindex $v_coords 1]
701                     set retx [expr $minx + $xbase_ + $xoffset_]
702                     set rety [expr $miny + $ybase_ + $yoffset_]
703                     
704                     # Update nexty_ and maxy_.
705                     set nexty_ [expr $miny + $ybase_]
706                     set maxy_ [expr $miny + $ybase_]
707                     
708                     # Try the new coordinates.
709                     set placed 0
710                 }
711             }
712         }
713     
714         # Update nextx_ and maxy_.
715         set nextx_ [expr $retx + $width]
716         if {[expr $rety + $height] > $maxy_} {
717             set maxy_ [expr $rety + $height]
718         }
719         
720         # Store and return this window's coordinates.
721         set asources_($as) "$retx $rety $scale"
722         return $asources_($as)
723     }
724 
725     # Handle remove commands.
726     if {$cmd == "remove"} {
727         array unset asources_ $as
728         array unset windows_ $as
729     }
730 
731     # Handle register commands.
732     if {$cmd == "register" && $uw != "false"} {
733         set windows_($as) $uw
734     }
735 }
736 
737 
738 
739 

~ [ 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.