summaryrefslogtreecommitdiff
path: root/gdb/gdbtk/library/kod.itb
blob: 3140733d483e2d65c394895075107ac2d1f11f8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# 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
}