OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [gdbtcl/] [memwin.itb] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# Memory display window class definition for Insight.
2
# Copyright 1998, 1999, 2001 Red Hat, Inc.
3
#
4
# This program is free software; you can redistribute it and/or modify it
5
# under the terms of the GNU General Public License (GPL) as published by
6
# the Free Software Foundation; either version 2 of the License, or (at
7
# your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
 
14
# ------------------------------------------------------------------
15
#  METHOD:  constructor - build the dialog
16
# ------------------------------------------------------------------
17
body MemWin::constructor {args} {
18
  global _mem
19
  debug $args
20
  eval itk_initialize $args
21
 
22
  set top [winfo toplevel $itk_interior]
23
  gdbtk_busy
24
 
25
  set _mem($this,enabled) 1
26
  set bg white
27
 
28
  if {![info exists type(1)]} {
29
    set type(1) char
30
    set type(2) short
31
    set type(4) int
32
    set type(8) "long long"
33
  }
34
 
35
  if {[pref getd gdb/mem/menu] != ""} {
36
    set mbar 0
37
  }
38
 
39
  # Load defaults from preferences.
40
  set size [pref getd gdb/mem/size]
41
  set numbytes [pref getd gdb/mem/numbytes]
42
  set format [pref getd gdb/mem/format]
43
  set ascii [pref getd gdb/mem/ascii]
44
  set ascii_char [pref getd gdb/mem/ascii_char]
45
  set bytes_per_row [pref getd gdb/mem/bytes_per_row]
46
  set color [pref getd gdb/mem/color]
47
 
48
  init_addr_exp
49
  build_win
50
  gdbtk_idle
51
}
52
 
53
# ------------------------------------------------------------------
54
#  METHOD:  destructor - destroy the dialog
55
# ------------------------------------------------------------------
56
body MemWin::destructor {} {
57
  if {[winfo exists $prefs_win]} {
58
    $prefs_win cancel
59
  }
60
}
61
 
62
 
63
# ------------------------------------------------------------------
64
#  METHOD:  build_win - build the main memory window
65
# ------------------------------------------------------------------
66
body MemWin::build_win {} {
67
  global tcl_platform gdb_ImageDir _mem ${this}_memval
68
 
69
  set maxlen 0
70
  set maxalen 0
71
  set saved_value ""
72
 
73
  if { $mbar } {
74
    menu $itk_interior.m -tearoff 0
75
    $top configure -menu $itk_interior.m
76
    $itk_interior.m add cascade -menu $itk_interior.m.addr \
77
      -label "Addresses" -underline 0
78
    set m [menu $itk_interior.m.addr]
79
    $m add check -label " Auto Update" -variable _mem($this,enabled) \
80
      -underline 1 -command "after idle $this toggle_enabled"
81
    $m add command -label " Update Now" -underline 1 \
82
      -command "$this update_address" -accelerator {Ctrl+U}
83
    $m add separator
84
    $m add command -label " Preferences..." -underline 1 \
85
      -command "$this create_prefs"
86
  }
87
 
88
  # Numcols = number of columns of data
89
  # numcols = number of columns in table (data plus headings plus ASCII)
90
  # if numbytes are 0, then use window size to determine how many to read
91
  if {$numbytes == 0} {
92
    set Numrows 8
93
  } else {
94
    set Numrows [expr {$numbytes / $bytes_per_row}]
95
  }
96
  set numrows [expr {$Numrows + 1}]
97
 
98
  set Numcols [expr {$bytes_per_row / $size}]
99
  if {$ascii} {
100
    set numcols [expr {$Numcols + 2}]
101
  } else {
102
    set numcols [expr {$Numcols + 1}]
103
  }
104
 
105
  table $itk_interior.t -titlerows 1 -titlecols 1 -variable ${this}_memval \
106
    -roworigin -1 -colorigin -1 -bg $bg \
107
    -browsecmd "$this changed_cell %s %S" -font src-font\
108
    -colstretch unset -rowstretch unset -selectmode single \
109
    -xscrollcommand "$itk_interior.sx set" -resizeborders none \
110
    -cols $numcols -rows $numrows -autoclear 1
111
 
112
  if {$numbytes} {
113
    $itk_interior.t configure -yscrollcommand "$itk_interior.sy set"
114
    scrollbar $itk_interior.sy -command [list $itk_interior.t yview]
115
  } else {
116
    $itk_interior.t configure -rowstretchmode none
117
  }
118
  scrollbar $itk_interior.sx -command [list $itk_interior.t xview] -orient horizontal
119
  $itk_interior.t tag config sel -bg [$itk_interior.t cget -bg] -relief sunken
120
  $itk_interior.t tag config active -bg lightgray -relief sunken -wrap 0
121
 
122
  # rebind all events that use tkTableMoveCell to our local version
123
  # because we don't want to move into the ASCII column if it exists
124
  bind $itk_interior.t          "$this memMoveCell %W -1  0; break"
125
  bind $itk_interior.t          "$this memMoveCell %W  1  0; break"
126
  bind $itk_interior.t          "$this memMoveCell %W  0 -1; break"
127
  bind $itk_interior.t  "$this memMoveCell %W  0  1; break"
128
  bind $itk_interior.t  "$this memMoveCell %W 0 1; break"
129
  bind $itk_interior.t  "$this memMoveCell %W 0 1; break"
130
 
131
  # bind button 3 to popup
132
  bind $itk_interior.t <3> "$this do_popup %X %Y"
133
 
134
  # bind Paste and button2 to the paste function
135
  # this is necessary because we want to not just paste the
136
  # data into the cell, but we also have to write it
137
  # out to real memory
138
  bind $itk_interior.t  [format {after idle %s paste %s %s} $this %x %y]
139
  bind $itk_interior.t <> [format {after idle %s paste %s %s} $this %x %y]
140
 
141
  menu $itk_interior.t.menu -tearoff 0
142
  bind_plain_key $top Control-u "$this update_address"
143
 
144
  # bind resize events
145
  bind $itk_interior  "$this newsize %h"
146
 
147
  frame $itk_interior.f
148
  iwidgets::spinint $itk_interior.f.cntl -labeltext " Address " -width 20 \
149
    -command "after idle $this update_address_cb" \
150
    -increment "after idle $this incr_addr -1" \
151
    -decrement "after idle $this incr_addr 1" \
152
    -validate {} \
153
    -textbackground white
154
 
155
  $itk_interior.f.cntl delete 0 end
156
  $itk_interior.f.cntl insert end $addr_exp
157
 
158
  balloon register [$itk_interior.f.cntl childsite].uparrow \
159
    "Scroll Up (Decrement Address)"
160
  balloon register [$itk_interior.f.cntl childsite].downarrow \
161
    "Scroll Down (Increment Address)"
162
 
163
  if {!$mbar} {
164
    button $itk_interior.f.upd -command "$this update_address" \
165
      -image [image create photo -file [::file join $gdb_ImageDir check.gif]]
166
    balloon register $itk_interior.f.upd "Update Now"
167
    checkbutton $itk_interior.cb -variable _mem($this,enabled) -command "$this toggle_enabled"
168
    balloon register $itk_interior.cb "Toggles Automatic Display Updates"
169
    grid $itk_interior.f.upd $itk_interior.f.cntl -sticky ew -padx 5
170
  } else {
171
    grid $itk_interior.f.cntl x -sticky w
172
    grid columnconfigure $itk_interior.f 1 -weight 1
173
  }
174
 
175
  # draw top border
176
  set col 0
177
  for {set i 0} {$i < $bytes_per_row} { incr i $size} {
178
    set ${this}_memval(-1,$col) [format " %X" $i]
179
    incr col
180
  }
181
 
182
  if {$ascii} {
183
    set ${this}_memval(-1,$col) ASCII
184
  }
185
 
186
  # fill initial display
187
  if {$nb} {
188
    update_address
189
  }
190
 
191
  if {!$mbar} {
192
    grid $itk_interior.f x -row 0 -column 0 -sticky nws
193
    grid $itk_interior.cb -row 0 -column 1 -sticky news
194
  } else {
195
    grid $itk_interior.f -row 0 -column 0 -sticky news
196
  }
197
  grid $itk_interior.t -row 1 -column 0 -sticky news
198
  if {$numbytes} { grid $itk_interior.sy -row 1 -column 1 -sticky ns }
199
  grid $itk_interior.sx -sticky ew
200
  grid columnconfig  $itk_interior 0 -weight 1
201
  grid rowconfig  $itk_interior 1 -weight 1
202
  focus $itk_interior.f.cntl
203
 
204
  window_name "Memory"
205
}
206
 
207
# ------------------------------------------------------------------
208
#  METHOD:  paste - paste callback. Update cell contents after paste
209
# ------------------------------------------------------------------
210
body MemWin::paste {x y} {
211
  edit [$itk_interior.t index @$x,$y]
212
}
213
 
214
# ------------------------------------------------------------------
215
#  METHOD:  validate - because the control widget wants this
216
# ------------------------------------------------------------------
217
body MemWin::validate {val} {
218
  return $val
219
}
220
 
221
# ------------------------------------------------------------------
222
#  METHOD:  create_prefs - create memory preferences dialog
223
# ------------------------------------------------------------------
224
body MemWin::create_prefs {} {
225
  if {$Running} { return }
226
 
227
  # make sure row height is set
228
  if {$rheight == ""} {
229
    set rheight [lindex [$itk_interior.t bbox 0,0] 3]
230
  }
231
 
232
  set prefs_win [ManagedWin::open MemPref -force -over $this\
233
                   -transient -win $this \
234
                   -size $size -format $format -numbytes $numbytes \
235
                   -bpr $bytes_per_row -ascii $ascii \
236
                   -ascii_char $ascii_char -color $color]
237
}
238
 
239
# ------------------------------------------------------------------
240
#  METHOD:  changed_cell - called when moving from one cell to another
241
# ------------------------------------------------------------------
242
body MemWin::changed_cell {from to} {
243
  #debug "moved from $from to $to"
244
  #debug "value = [$itk_interior.t get $from]"
245
  if {$saved_value != ""} {
246
    if {$saved_value != [$itk_interior.t get $from]} {
247
      edit $from
248
    }
249
  }
250
  set saved_value [$itk_interior.t get $to]
251
}
252
 
253
# ------------------------------------------------------------------
254
#  METHOD:  edit - edit a cell
255
# ------------------------------------------------------------------
256
body MemWin::edit { cell } {
257
  global _mem ${this}_memval
258
 
259
  #debug "edit $cell"
260
 
261
  if {$Running || $cell == ""} { return }
262
  set rc [split $cell ,]
263
  set row [lindex $rc 0]
264
  set col [lindex $rc 1]
265
  set val [$itk_interior.t get $cell]
266
 
267
  if {$col == $Numcols} {
268
    # editing the ASCII field
269
    set addr [expr {$current_addr + $bytes_per_row * $row}]
270
    set start_addr $addr
271
 
272
    # calculate number of rows to modify
273
    set len [string length $val]
274
    set rows 0
275
    while {$len > 0} {
276
      incr rows
277
      set len [expr {$len - $bytes_per_row}]
278
    }
279
    set nb [expr {$rows * $bytes_per_row}]
280
 
281
    # now process each char, one at a time
282
    foreach c [split $val ""] {
283
      if {$c != $ascii_char} {
284
        scan $c %c char
285
        if {[catch {gdb_set_mem $addr [format %02x $char] 1} res]} {
286
          error_dialog $res
287
 
288
          # reset value
289
          set ${this}_memval($row,$col) $saved_value
290
          return
291
        }
292
      }
293
      incr addr
294
    }
295
    set addr $start_addr
296
    set nextval 0
297
    # now read back the data and update the widget
298
    catch {gdb_get_mem $addr $format $size $nb $bytes_per_row $ascii_char} vals
299
    for {set n 0} {$n < $nb} {incr n $bytes_per_row} {
300
      set ${this}_memval($row,-1) [format "0x%x" $addr]
301
      for { set col 0 } { $col < [expr {$bytes_per_row / $size}] } { incr col } {
302
        set ${this}_memval($row,$col) [lindex $vals $nextval]
303
        incr nextval
304
      }
305
      set ${this}_memval($row,$col) [lindex $vals $nextval]
306
      incr nextval
307
      incr addr $bytes_per_row
308
      incr row
309
    }
310
    return
311
  }
312
 
313
  # calculate address based on row and column
314
  set addr [expr {$current_addr + $bytes_per_row * $row + $size * $col}]
315
  #debug "  edit $row,$col         [format "%x" $addr] = $val"
316
 
317
  # Pad the value with zeros, if necessary
318
  set s [expr {$size * 2}]
319
  set val [format "0x%0${s}x" $val]
320
 
321
  # set memory
322
  if {[catch {gdb_set_mem $addr $val $size} res]} {
323
    error_dialog $res
324
 
325
    # reset value
326
    set ${this}_memval($row,$col) $saved_value
327
    return
328
  }
329
 
330
  # read it back
331
  # FIXME - HACK ALERT - This call causes trouble with remotes on Windows.
332
  # This routine is in fact called from within an idle handler triggered by
333
  # memMoveCell.  Something evil happens in that handler that causes gdb to
334
  # start writing this changed value into all the visible cells...
335
  # I have not figured out the cause of this, so for now I commented this
336
  # line out.  It will only matter if the write did not succeed, and this was
337
  # not a very good way to tell the user about that anyway...
338
  #
339
  # catch {gdb_get_mem $addr $format $size $size $size ""} val
340
  # delete whitespace in response
341
  set val [string trimright $val]
342
  set val [string trimleft $val]
343
  set ${this}_memval($row,$col) $val
344
}
345
 
346
 
347
# ------------------------------------------------------------------
348
#  METHOD:  toggle_enabled - called when enable is toggled
349
# ------------------------------------------------------------------
350
body MemWin::toggle_enabled {} {
351
  global _mem
352
 
353
  if {$Running} { return }
354
  if {$_mem($this,enabled)} {
355
    update_address
356
    set bg white
357
    set state normal
358
  } else {
359
    set bg gray
360
    set state disabled
361
  }
362
  $itk_interior.t config -background $bg -state $state
363
}
364
 
365
# ------------------------------------------------------------------
366
#  METHOD:  update - update widget after every PC change
367
# ------------------------------------------------------------------
368
body MemWin::update {event} {
369
  global _mem
370
  if {$_mem($this,enabled)} {
371
    update_address
372
  }
373
}
374
 
375
# ------------------------------------------------------------------
376
#  METHOD:  idle - memory window is idle, so enable menus
377
# ------------------------------------------------------------------
378
body MemWin::idle {event} {
379
  # Fencepost
380
  set Running 0
381
 
382
  # Cursor
383
  cursor {}
384
 
385
  # Enable menus
386
  if {$mbar} {
387
    for {set i 0} {$i <= [$itk_interior.m.addr index last]} {incr i} {
388
      if {[$itk_interior.m.addr type $i] != "separator"} {
389
        $itk_interior.m.addr entryconfigure $i -state normal
390
      }
391
    }
392
  }
393
 
394
  # Enable control
395
  $itk_interior.f.cntl configure -state normal
396
}
397
 
398
 
399
# ------------------------------------------------------------------
400
#  METHOD: busy - BusyEvent handler
401
#                 Disable menus 'cause we're busy updating things.
402
# ------------------------------------------------------------------
403
body MemWin::busy {event} {
404
  # Fencepost
405
  set Running 1
406
 
407
  # cursor
408
  cursor watch
409
 
410
  # Disable menus
411
  if {$mbar} {
412
    for {set i 0} {$i <= [$itk_interior.m.addr index last]} {incr i} {
413
      if {[$itk_interior.m.addr type $i] != "separator"} {
414
        $itk_interior.m.addr entryconfigure $i -state disabled
415
      }
416
    }
417
  }
418
 
419
  # Disable control
420
  $itk_interior.f.cntl configure -state disabled
421
}
422
 
423
# ------------------------------------------------------------------
424
#  METHOD: newsize - calculate how many rows to display when the
425
#  window is resized.
426
# ------------------------------------------------------------------
427
body MemWin::newsize {height} {
428
  if {$dont_size || $Running} {
429
    return
430
  }
431
 
432
  # only add rows if numbytes is zero
433
  if {$numbytes == 0} {
434
    ::update idletasks
435
 
436
    # make sure row height is set
437
    if {$rheight == ""} {
438
      set rheight [lindex [$itk_interior.t bbox 0,0] 3]
439
    }
440
 
441
    set theight [winfo height $itk_interior.t]
442
    set Numrows [expr {$theight / $rheight}]
443
    $itk_interior.t configure -rows $Numrows
444
    update_addr
445
  }
446
}
447
 
448
# ------------------------------------------------------------------
449
#  METHOD: update_address_cb - address entry widget callback
450
# ------------------------------------------------------------------
451
body MemWin::update_address_cb {} {
452
  set new_entry 1
453
  update_address [$itk_interior.f.cntl get]
454
}
455
 
456
# ------------------------------------------------------------------
457
#  METHOD: update_address - update address and data displayed
458
# ------------------------------------------------------------------
459
body MemWin::update_address { {ae ""} } {
460
  if {$ae == ""} {
461
    set addr_exp [string trimleft [$itk_interior.f.cntl get]]
462
  } else {
463
    set addr_exp $ae
464
  }
465
 
466
  set saved_addr $current_addr
467
  if {[string match {[a-zA-Z_&0-9\*]*} $addr_exp]} {
468
    # Looks like an expression
469
    set retVal [catch {gdb_eval "$addr_exp"} current_addr]
470
    if {$retVal || [string match "No symbol*" $current_addr] || \
471
          [string match "Invalid *" $current_addr]} {
472
      BadExpr $current_addr
473
      return
474
    }
475
    if {[string match {\{*} $current_addr]} {
476
      set current_addr [lindex $current_addr 1]
477
      if {$current_addr == ""} {
478
        return
479
      }
480
    }
481
  } elseif {[string match {\$*} $addr_exp]} {
482
    # Looks like a local variable
483
    catch {gdb_eval "$addr_exp"} current_addr
484
    if {$current_addr == "No registers.\n"} {
485
      # we asked for a register value and debugging hasn't started yet
486
      return
487
    }
488
    if {$current_addr == "void"} {
489
      BadExpr "No Local Variable Named \"$addr_ex\""
490
      return
491
    }
492
  } else {
493
    # something really strange, like "0.1" or ""
494
    BadExpr "Can't Evaluate \"$addr_expr\""
495
    return
496
  }
497
 
498
  # Check for spaces
499
  set index [string first \  $current_addr]
500
  if {$index != -1} {
501
    incr index -1
502
    set current_addr [string range $current_addr 0 $index]
503
  }
504
 
505
  # set table background
506
  $itk_interior.t config -bg white -state normal
507
  catch {update_addr}
508
}
509
 
510
# ------------------------------------------------------------------
511
#  METHOD:  BadExpr - handle a bad expression
512
# ------------------------------------------------------------------
513
body MemWin::BadExpr {errTxt} {
514
  if {$new_entry} {
515
    tk_messageBox -type ok -icon error -message $errTxt
516
    set new_entry 0
517
  }
518
  # set table background to gray
519
  $itk_interior.t config -bg gray -state disabled
520
  set current_addr $saved_addr
521
  set saved_addr ""
522
}
523
 
524
# ------------------------------------------------------------------
525
#  METHOD:  incr_addr - callback from control widget to increment
526
#  the current address.
527
# ------------------------------------------------------------------
528
body MemWin::incr_addr {num} {
529
 
530
  if {$current_addr == ""} {
531
    return
532
  }
533
  set old_addr $current_addr
534
 
535
  # You have to be careful with address calculations here, since the memory
536
  # space of the target may be bigger than a long, which will cause Tcl to
537
  # overflow.  Let gdb do the calculations instead.
538
 
539
  set current_addr [gdb_cmd "printf \"%u\", $current_addr + $num * $bytes_per_row"]
540
 
541
  # A memory address less than zero is probably not a good thing...
542
  #
543
 
544
  if {($num < 0 && [gdb_eval "$current_addr > $old_addr"]) \
545
      ||($num > 0 && [gdb_eval "$current_addr < $old_addr"]) } {
546
    bell
547
    set current_addr $old_addr
548
    return
549
  }
550
  $itk_interior.t config -background white -state normal
551
  update_addr
552
  $itk_interior.f.cntl clear
553
  $itk_interior.f.cntl insert 0 [format "0x%x" $current_addr]
554
}
555
 
556
 
557
# ------------------------------------------------------------------
558
#  METHOD:  update_addr - read in data starting at $current_addr
559
#  This is just a helper function for update_address.
560
# ------------------------------------------------------------------
561
body MemWin::update_addr {} {
562
  global _mem ${this}_memval
563
 
564
  gdbtk_busy
565
  set addr $current_addr
566
 
567
  set row 0
568
 
569
  if {$numbytes == 0} {
570
    set nb [expr {$Numrows * $bytes_per_row}]
571
  } else {
572
    set nb $numbytes
573
  }
574
  set nextval 0
575
  set num [expr {$bytes_per_row / $size}]
576
  if {$ascii} {
577
    set asc $ascii_char
578
  } else {
579
    set asc ""
580
  }
581
 
582
  set retVal [catch {gdb_get_mem $addr $format \
583
                       $size $nb $bytes_per_row $asc} vals]
584
 
585
  if {$retVal || [llength $vals] == 0}  {
586
    # FIXME gdb_get_mem does not always return an error when addr is invalid.
587
    BadExpr "Couldn't get memory at address: \"$addr\""
588
    gdbtk_idle
589
    debug "gdb_get_mem returned return code: $retVal and value: \"$vals\""
590
    return
591
  }
592
 
593
  set mlen 0
594
  for {set n 0} {$n < $nb} {incr n $bytes_per_row} {
595
    set x [format "0x%x" $addr]
596
    if {[string length $x] > $mlen} {
597
      set mlen [string length $x]
598
    }
599
    set ${this}_memval($row,-1) $x
600
    for { set col 0 } { $col < $num } { incr col } {
601
      set x [lindex $vals $nextval]
602
      if {[string length $x] > $maxlen} {set maxlen [string length $x]}
603
      set ${this}_memval($row,$col) $x
604
      incr nextval
605
    }
606
    if {$ascii} {
607
      set x [lindex $vals $nextval]
608
      if {[string length $x] > $maxalen} {set maxalen [string length $x]}
609
      set ${this}_memval($row,$col) $x
610
      incr nextval
611
    }
612
    incr addr $bytes_per_row
613
    incr row
614
  }
615
  # set default column width to the max in the data columns
616
  $itk_interior.t configure -colwidth [expr {$maxlen + 1}]
617
  # set border column width
618
  $itk_interior.t width -1 [expr {$mlen + 1}]
619
  if {$ascii} {
620
    # set ascii column width
621
    $itk_interior.t width $Numcols [expr {$maxalen + 1}]
622
  }
623
 
624
  gdbtk_idle
625
}
626
 
627
# ------------------------------------------------------------------
628
#  METHOD:  hidemb - hide the menubar.  NOT CURRENTLY USED
629
# ------------------------------------------------------------------
630
body MemWin::hidemb {} {
631
  set mbar 0
632
  reconfig
633
}
634
 
635
# ------------------------------------------------------------------
636
#  METHOD:  reconfig - used when preferences change
637
# ------------------------------------------------------------------
638
body MemWin::reconfig {} {
639
  debug
640
  set addr_exp [string trimright [string trimleft $addr_exp]]
641
  set wh [winfo height $top]
642
 
643
  if [winfo exists $itk_interior.m] { destroy $itk_interior.m }
644
  if [winfo exists $itk_interior.cb] { destroy $itk_interior.cb }
645
  if [winfo exists $itk_interior.f.upd] { destroy $itk_interior.f.upd }
646
  if [winfo exists $itk_interior.sy] { destroy $itk_interior.sy }
647
  destroy $itk_interior.f.cntl $itk_interior.f $itk_interior.t \
648
    $itk_interior.sx
649
 
650
  set dont_size 1
651
 
652
  # If the fonts change, then you will need to recompute the
653
  # row height.  Ditto for switch from fixed number of rows to
654
  # depends on size.
655
 
656
  set rheight ""
657
 
658
  # Update preferences to reflect new reality
659
  pref setd gdb/mem/size $size
660
  pref setd gdb/mem/numbytes $numbytes
661
  pref setd gdb/mem/format $format
662
  pref setd gdb/mem/ascii $ascii
663
  pref setd gdb/mem/ascii_char $ascii_char
664
  pref setd gdb/mem/bytes_per_row $bytes_per_row
665
  pref setd gdb/mem/color $color
666
 
667
  build_win
668
  set dont_size 0
669
  ::update
670
 
671
  if {$numbytes == 0} {
672
    newsize $wh
673
  }
674
}
675
 
676
# ------------------------------------------------------------------
677
#  METHOD:  do_popup - Display popup menu
678
# ------------------------------------------------------------------
679
body MemWin::do_popup {X Y} {
680
  if {$Running} { return }
681
  $itk_interior.t.menu delete 0 end
682
  $itk_interior.t.menu add check -label "Auto Update" -variable _mem($this,enabled) \
683
    -underline 0 -command "$this toggle_enabled"
684
  $itk_interior.t.menu add command -label "Update Now" -underline 0 \
685
    -command "$this update_address"
686
  $itk_interior.t.menu add command -label "Go To [$itk_interior.t curvalue]" -underline 0 \
687
    -command "$this goto [$itk_interior.t curvalue]"
688
  $itk_interior.t.menu add command -label "Open New Window at [$itk_interior.t curvalue]" -underline 0 \
689
    -command [list ManagedWin::open -force MemWin -addr_exp [$itk_interior.t curvalue]]
690
  $itk_interior.t.menu add separator
691
  $itk_interior.t.menu add command -label "Preferences..." -underline 0 \
692
    -command "$this create_prefs"
693
  tk_popup $itk_interior.t.menu $X $Y
694
}
695
 
696
# ------------------------------------------------------------------
697
#  METHOD:  goto - change the address of the current memory window
698
# ------------------------------------------------------------------
699
body MemWin::goto { addr } {
700
  set current_addr $addr
701
  $itk_interior.f.cntl delete 0 end
702
  $itk_interior.f.cntl insert end $addr
703
}
704
 
705
# ------------------------------------------------------------------
706
#  METHOD:  init_addr_exp - initialize address expression
707
#  On startup, if the public variable "addr_exp" was not set,
708
#  then set it to the start of ".data" if found, otherwise "$pc"
709
# ------------------------------------------------------------------
710
body MemWin::init_addr_exp {} {
711
  if {$addr_exp == ""} {
712
    set err [catch {gdb_cmd "info file"} result]
713
    if {!$err} {
714
      foreach line [split [string trim $result] \n] {
715
        if {[scan $line {%x - %x is %s} start stop section] == 3} {
716
          if {$section == ".data"} {
717
            set addr_exp [format "%#08x" $start]
718
            break
719
          }
720
        }
721
      }
722
    }
723
    if {$addr_exp == ""} {
724
      set addr_exp \$pc
725
    }
726
  }
727
}
728
 
729
# ------------------------------------------------------------------
730
#  METHOD:  cursor - set the cursor
731
# ------------------------------------------------------------------
732
body MemWin::cursor {glyph} {
733
  # Set cursor for all labels
734
  # for {set i 0} {$i < $bytes_per_row} {incr i $size} {
735
  #   $itk_interior.t.h.$i configure -cursor $glyph
736
  # }
737
  $top configure -cursor $glyph
738
}
739
 
740
# memMoveCell --
741
#
742
# Moves the location cursor (active element) by the specified number
743
# of cells and changes the selection if we're in browse or extended
744
# selection mode.
745
#
746
# Don't allow movement into the ASCII column.
747
#
748
# Arguments:
749
# w - The table widget.
750
# x - +1 to move down one cell, -1 to move up one cell.
751
# y - +1 to move right one cell, -1 to move left one cell.
752
 
753
body MemWin::memMoveCell {w x y} {
754
  if {[catch {$w index active row} r]} return
755
  set c [$w index active col]
756
  if {$ascii && ($c == $Numcols)} {
757
    # we're in the ASCII column so behave differently
758
    if {$y == 1} {set x 1}
759
    if {$y == -1} {set x -1}
760
    incr r $x
761
  } else {
762
    incr r $x
763
    incr c $y
764
    if { $c < 0 } {
765
      if {$r == 0} {
766
        set c 0
767
      } else {
768
        set c [expr {$Numcols - 1}]
769
        incr r -1
770
      }
771
    } elseif { $c >= $Numcols } {
772
      if {$r >= [expr {$Numrows - 1}]} {
773
        set c [expr {$Numcols - 1}]
774
      } else {
775
        set c 0
776
        incr r
777
      }
778
    }
779
  }
780
  if { $r < 0 } { set r 0 }
781
  $w activate $r,$c
782
  $w see active
783
}
784
 
785
# ------------------------------------------------------------
786
#  PUBLIC METHOD:  error_dialog - Open and error dialog.
787
#    Arguments:
788
#        msg      - The message to display in the dialog
789
#        modality - The dialog modailty. Default: task
790
#        type     - The dialog type (tk_messageBox).
791
#                    Default: ok
792
# ------------------------------------------------------------
793
body MemWin::error_dialog {msg {modality task} {type ok}} {
794
  set parent [winfo toplevel [namespace tail $this]]
795
  tk_messageBox -icon error -title Error -type $type \
796
    -modal $modality -message $msg -parent $parent
797
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.