| # Kernel Object Display Window for Insight. |
| # Copyright (C) 1998, 1999, 2001 Red Hat, Inc. |
| # |
| # This program is free software; you can redistribute it and/or modify it |
| # under the terms of the GNU General Public License (GPL) as published by |
| # the Free Software Foundation; either version 2 of the License, or (at |
| # your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # AUTHOR: Fernando Nasser <fnasser@cygnus.com> |
| # |
| |
| |
| # ------------------------------------------------------------------ |
| # CONSTRUCTOR - create new process window |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::constructor {args} { |
| # |
| # Create a window with the same name as this object |
| # |
| global gdb_kod_cmd |
| |
| # initialize local variables |
| set LevelCmd(0) "info $gdb_kod_cmd " |
| debug "Level 0 kod command is $LevelCmd(0)" |
| |
| gdbtk_busy |
| build_win |
| gdbtk_idle |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: build_win - build the main KOD window |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::build_win {} { |
| # FIXME: rename this variable. |
| global kodActivePane |
| |
| debug "Will build KOD window" |
| |
| cyg::PanedWindow $itk_interior.pw -orient horizontal |
| $itk_interior.pw add titlepane |
| # We would like to use a fixed pane for the buttons. However, |
| # this feature of PanedWindow doesn't work. |
| # $itk_interior.pw add buttonpane -resizable 0 |
| $itk_interior.pw add pane1 |
| $itk_interior.pw add pane2 |
| |
| # Now a frame for what is being listed, headers and list |
| set tp [$itk_interior.pw childsite titlepane] |
| Labelledframe $tp.tf -text "No Kernel Objects Known" \ |
| -anchor nw |
| set titl $tp.tf |
| set lf [$tp.tf get_frame] |
| |
| set p1 [$itk_interior.pw childsite pane1] |
| set p2 [$itk_interior.pw childsite pane2] |
| $p1 configure -height 120 -bd 2 |
| $p2 configure -height 120 -bd 2 |
| Labelledframe $p1.d1 -text "Details" -anchor nw |
| Labelledframe $p2.d2 -text "Details" -anchor nw |
| set d1 [$p1.d1 get_frame] |
| set d2 [$p2.d2 get_frame] |
| pack $p1.d1 $p2.d2 -side top -expand yes -fill both -padx 5 -pady 5 |
| set pl1 $p1.d1 |
| set pl2 $p2.d2 |
| |
| # Setup the button box |
| set bf [frame $tp.bf] |
| set BTop [button $bf.top -height 1 -text Top -command [code $this top]] |
| set BUp [button $bf.up -height 1 -text Up -command [code $this up]] |
| set BClear [button $bf.clear -height 1 -text Clear \ |
| -command [code $this clear]] |
| set BDisplay [button $bf.display -height 1 -text Display \ |
| -command [code $this display]] |
| set kodActivePane pane1 |
| set BPane1 [radiobutton $bf.pane1 -variable kodActivePane \ |
| -height 1 -text "Pane 1" -value pane1] |
| set BPane2 [radiobutton $bf.pane2 -variable kodActivePane \ |
| -height 1 -text "Pane 2" -value pane2] |
| balloon register $bf.top "Return to List of Kernel Objects" |
| balloon register $bf.up "Return to previous List of Objects" |
| balloon register $bf.clear "Clear Object Detail Panes\nand Active setting" |
| balloon register $bf.display \ |
| "Display Object or\nList of Objects of this type" |
| balloon register $bf.pane1 "Make Pane 1 Active" |
| balloon register $bf.pane2 "Make Pane 2 Active" |
| pack $bf.top $bf.up -side left -padx 5 |
| pack $bf.display $bf.clear -side right -padx 5 |
| pack $bf.pane2 $bf.pane1 -side bottom -padx 5 -fill both |
| |
| # The list of objects |
| table $lf.s -titlerows 1 \ |
| -colstretch last -rowstretch last -selectmode single \ |
| -selecttype row -variable $this \ |
| -yscrollcommand "$lf.sb set" -resizeborders none \ |
| -state disabled |
| scrollbar $lf.sb -orient vertical -command "$lf.s yview" |
| bind $lf.s <Double-1> [code $this display] |
| $lf.s tag configure coltag -anchor nw |
| |
| grid $lf.s -row 0 -column 0 -sticky nsew |
| grid $lf.sb -row 0 -column 1 -sticky nsw |
| grid columnconfigure $lf 0 -weight 1 |
| grid rowconfigure $lf 0 -weight 1 |
| |
| # Areas to display object details |
| set t1 [table $d1.t1 -titlerows 1 -colstretch last -rowstretch last \ |
| -selectmode single -selecttype row -variable $this-pane1 \ |
| -yscrollcommand "$d1.s1 set" -resizeborders none \ |
| -rows 1 -cols 1 -state disabled] |
| scrollbar $d1.s1 -orient vertical -command "$d1.t1 yview" |
| set t2 [table $d2.t2 -titlerows 1 -colstretch last -rowstretch last \ |
| -selectmode single -selecttype row -variable $this-pane2 \ |
| -yscrollcommand "$d2.s2 set" -resizeborders none \ |
| -rows 1 -cols 1 -state disabled] |
| scrollbar $d2.s2 -orient vertical -command "$d2.t2 yview" |
| |
| grid $d1.t1 -row 0 -column 0 -sticky nsew |
| grid $d1.s1 -row 0 -column 1 -sticky nsw |
| grid columnconfigure $d1 0 -weight 1 |
| grid rowconfigure $d1 0 -weight 1 |
| grid $d2.t2 -row 0 -column 0 -sticky nsew |
| grid $d2.s2 -row 0 -column 1 -sticky nsw |
| grid columnconfigure $d2 0 -weight 1 |
| grid rowconfigure $d2 0 -weight 1 |
| |
| debug "Will pack KOD window" |
| pack $tp.tf -side top -expand yes -fill both -padx 5 -pady 5 |
| pack $tp.bf -side top -expand no -fill x -padx 5 -pady 5 |
| pack $itk_interior.pw -side bottom -expand yes -fill both |
| wm minsize $_top 450 500 |
| |
| # Initialize button state variables for idle (called before update) |
| set BState(BDisplay) disabled |
| set BState(BClear) disabled |
| set BState(BTop) disabled |
| set BState(BUp) disabled |
| |
| # window_name "Kernel Objects" |
| |
| update dummy |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: update - update widget when something changes |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::update {event} { |
| |
| debug "updating kod window" |
| |
| _disable_buttons |
| |
| display_list |
| display_object |
| |
| _restore_buttons |
| |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: display - update the display based on the selection |
| # it can be a list or an actual object |
| # We get here from a press on the Display button or |
| # from a <Double-1> on a line of the list of objects |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::display {} { |
| upvar \#0 $this table_vals |
| if {!$Running && [$lf.s cget -rows] > 1} { |
| gdbtk_busy |
| set linenum [$lf.s index active row] |
| set object $table_vals($linenum,0) |
| debug "display selection on line $linenum $object" |
| incr level |
| set LevelCmd($level) $LevelCmd([expr $level-1]) |
| append LevelCmd($level) $object |
| debug "kod command for level $level is now: $LevelCmd($level)" |
| update dummy |
| # Run idle hooks and cause all other widgets to update |
| gdbtk_idle |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: display_list - display list of objects |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::display_list {} { |
| upvar \#0 $this table_vals |
| |
| debug "displaying list of objects" |
| |
| $lf.s configure -state normal |
| set cmd $LevelCmd($level) |
| debug "new kod command is $cmd" |
| if {[catch "gdb_cmd \"$cmd\"" objects]} { |
| # failed. leave window blank |
| $titl configure -text "Kernel Object Display Failed" |
| $lf.s delete rows 0 [$lf.s index end row] |
| $lf.s configure -state disabled |
| set BState(BDisplay) disabled |
| return |
| } |
| |
| debug "KodWin update: \n$objects" |
| if {[llength $objects] == 0} { |
| $titl configure -text "No Kernel Objects Known" |
| # no objects listed. |
| $lf.s delete rows 0 [$lf.s index end row] |
| $lf.s configure -state disabled |
| set BState(BDisplay) disabled |
| return |
| } |
| |
| # insert each line one at a time |
| set num_lines -1 |
| foreach line [split $objects \n] { |
| if {$num_lines == -1} { |
| if {![string match List* $line]} { |
| if {($level > 0)} { |
| display_object $cmd objects |
| incr level -1 |
| $lf.s configure -state disabled |
| return |
| } else { |
| # if level 0 first line does not start with List ignore it |
| $titl configure -text "List of Kernel Objects" |
| } |
| } else { |
| $titl configure -text $line |
| } |
| # Clear listbox and headers to get new stuff. |
| $lf.s delete rows 0 [$lf.s index end row] |
| } elseif {$line == ""} { |
| break |
| } else { |
| set col 0 |
| set list [split [string trim $line] \t] |
| if {$num_lines == 0} { |
| $lf.s configure -cols [llength $list] -titlerows 1 |
| } |
| foreach item $list { |
| debug "inserting $item at $num_lines,$col" |
| set table_vals($num_lines,$col) $item |
| incr col |
| } |
| } |
| incr num_lines |
| } |
| $lf.s configure -rows [expr {$num_lines + 1}] |
| |
| if {$num_lines > 0} { |
| set BState(BDisplay) active |
| } |
| |
| if {$level == 0} { |
| set BState(BTop) disabled |
| set BState(BUp) disabled |
| } else { |
| set BState(BTop) active |
| set BState(BUp) active |
| } |
| |
| $lf.s configure -state disabled |
| $lf.s see 0,0 |
| $lf.s activate 1,0 |
| |
| _restore_buttons |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: display_object - display information about an object |
| # When called from update we have to reissue the gdb |
| # command to get fresh data |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::display_object {{cmd ""} {obj ""}} { |
| debug "Displaying object details..." |
| upvar $obj objects |
| global kodActivePane |
| debug "Active Pane is $kodActivePane" |
| |
| # Determine which frame to use |
| if {$kodActivePane == "pane2"} { |
| set curpan $t2 |
| upvar \#0 $this-pane2 pane_values |
| if {$cmd != ""} { |
| # save command for update |
| set pane2command $cmd |
| } else { |
| # reuse saved command |
| set cmd $pane2command |
| } |
| } else { |
| set curpan $t1 |
| upvar \#0 $this-pane1 pane_values |
| if {$cmd != ""} { |
| # save command for update |
| set pane1command $cmd |
| } else { |
| # reuse saved command |
| set cmd $pane1command |
| } |
| } |
| debug "curpan $curpan" |
| |
| # here we must take care of the case where the user has activated a window |
| # but it does not have been filled yet. We just return. |
| if {$cmd == ""} { |
| return |
| } |
| |
| $curpan configure -state normal |
| $curpan delete rows 0 [$curpan index end row] |
| if {$obj == ""} { |
| debug "pane kod command is $cmd" |
| if {[catch "gdb_cmd \"$cmd\"" objects] |
| || $objects == ""} { |
| # Failed. Tell user object no longer there. |
| $curpan configure -state disabled |
| return |
| } |
| } |
| |
| set num_lin 0 |
| foreach line [split $objects \n] { |
| set col 0 |
| set list [split [string trim $line] \t] |
| if {$num_lin == 0} { |
| $curpan configure -cols [llength $list] |
| } |
| foreach item $list { |
| set pane_values($num_lin,$col) $item |
| incr col |
| } |
| incr num_lin |
| } |
| $curpan configure -rows $num_lin -state disabled |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: clear - clear detail panes and reset pane selection |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::clear {} { |
| debug "going to clear detail panes and pane selection" |
| $t1 configure -state normal |
| $t2 configure -state normal |
| $t1 delete rows 0 [$t1 index end row] |
| $t2 delete rows 0 [$t2 index end row] |
| $t1 configure -state disabled |
| $t2 configure -state disabled |
| # Default to pane 1 again. |
| global kodActivePane |
| set kodActivePane pane1 |
| set pane1command "" |
| set pane2command "" |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: top - go to the list of types of objects (top level) |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::top {} { |
| debug "going to top from level $level" |
| if {$level > 0} { |
| set level 0 |
| update dummy |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: up - go to the list of objects which led to the current one |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::up {} { |
| debug "going up from level $level..." |
| if {$level > 0} { |
| incr level -1 |
| debug "...to level $level" |
| update dummy |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # DESTRUCTOR - destroy window containing widget |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::destructor {} { |
| upvar \#0 $this table_vals $this-pane1 pane1_vals $this-pane2 pane2_vals |
| global kodActivePane |
| |
| catch {unset table_vals} |
| catch {unset pane1_vals} |
| catch {unset pane2_vals} |
| catch {unset kodActivePane} |
| } |
| |
| # ------------------------------------------------------------------ |
| # PUBLIC METHOD: set_variable - called when user runs `set os' |
| # command |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::set_variable {event} { |
| |
| set value [$event get value] |
| if {[$event get variable] == "os" && $value != ""} { |
| set LevelCmd(0) "info $value " |
| set level 0 |
| update dummy |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: reconfig - used when preferences change |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::reconfig {} { |
| destroy $itk_interior.bf |
| destroy $titl |
| build_win |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: busy - BusyEvent handler |
| # |
| # This method should accomplish blocking |
| # - clicks in the window |
| # - change mouse pointer |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::busy {event} { |
| set Running 1 |
| _disable_buttons |
| cursor watch |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: idle - idle event handler. Run when the target is not |
| # running |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::idle {event} { |
| set Running 0 |
| _restore_buttons |
| cursor {} |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: cursor - set the window cursor |
| # This is a convenience method which simply sets the mouse |
| # pointer to the given glyph. |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::cursor {glyph} { |
| $_top configure -cursor $glyph |
| } |
| |
| # ------------------------------------------------------------------ |
| # PRIVATE METHOD: _disable_buttons - disable all buttons |
| # Used when we are busy and can't take another event |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::_disable_buttons {} { |
| $BTop configure -state disabled |
| $BUp configure -state disabled |
| $BDisplay configure -state disabled |
| $BClear configure -state disabled |
| } |
| |
| # ------------------------------------------------------------------ |
| # PRIVATE METHOD: _restore_buttons - restore all buttons to their |
| # previous states. |
| # Used when we are busy and can't take another event |
| # ------------------------------------------------------------------ |
| itcl::body KodWin::_restore_buttons {} { |
| $BTop configure -state $BState(BTop) |
| $BUp configure -state $BState(BUp) |
| $BDisplay configure -state $BState(BDisplay) |
| # CLEAR is always active, except when busy |
| $BClear configure -state active |
| } |