Debugger: Add Inspector UI controls for edit mode.

InspectorWindow:
- Add buttons to control edit mode, and helper functions to maintain
  their state.
- Implement listener hook for memory change events, to track when
  requested memory writes are completed, and update the view accordingly.

Together with the previous batch of commits, this implements the first part
of #9708.
This commit is contained in:
Rene Gollent
2015-05-23 16:54:18 -04:00
parent 6ce909030d
commit 03796a0cef
2 changed files with 125 additions and 1 deletions
@@ -30,7 +30,10 @@
enum {
MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl',
MSG_NAVIGATE_NEXT_BLOCK = 'npnl',
MSG_MEMORY_BLOCK_RETRIEVED = 'mbre'
MSG_MEMORY_BLOCK_RETRIEVED = 'mbre',
MSG_EDIT_CURRENT_BLOCK = 'mecb',
MSG_COMMIT_MODIFIED_BLOCK = 'mcmb',
MSG_REVERT_MODIFIED_BLOCK = 'mrmb'
};
@@ -169,6 +172,12 @@ InspectorWindow::_Init()
.Add(fWritableBlockIndicator = new BStringView("writableIndicator",
_GetCurrentWritableIndicator()))
.AddGlue()
.Add(fEditBlockButton = new BButton("editBlock", "Edit",
new BMessage(MSG_EDIT_CURRENT_BLOCK)))
.Add(fCommitBlockButton = new BButton("commitBlock", "Commit",
new BMessage(MSG_COMMIT_MODIFIED_BLOCK)))
.Add(fRevertBlockButton = new BButton("revertBlock", "Revert",
new BMessage(MSG_REVERT_MODIFIED_BLOCK)))
.End()
.End();
@@ -187,6 +196,14 @@ InspectorWindow::_Init()
fPreviousBlockButton->SetEnabled(false);
fNextBlockButton->SetEnabled(false);
fEditBlockButton->SetTarget(this);
fCommitBlockButton->SetTarget(this);
fRevertBlockButton->SetTarget(this);
fEditBlockButton->SetEnabled(false);
fCommitBlockButton->Hide();
fRevertBlockButton->Hide();
hexMenu->SetLabelFromMarked(true);
hexMenu->SetTargetForItems(fMemoryView);
endianMenu->SetLabelFromMarked(true);
@@ -325,6 +342,43 @@ InspectorWindow::MessageReceived(BMessage* message)
}
break;
}
case MSG_EDIT_CURRENT_BLOCK:
{
_SetEditMode(true);
break;
}
case MSG_MEMORY_DATA_CHANGED:
{
if (fCurrentBlock == NULL)
break;
target_addr_t address;
if (message->FindUInt64("address", &address) == B_OK
&& address >= fCurrentBlock->BaseAddress()
&& address < fCurrentBlock->BaseAddress()
+ fCurrentBlock->Size()) {
fCurrentBlock->Invalidate();
_SetEditMode(false);
fListener->InspectRequested(address, this);
}
break;
}
case MSG_COMMIT_MODIFIED_BLOCK:
{
// TODO: this could conceivably be extended to detect the
// individual modified regions and only write those back.
// That would require potentially submitting multiple separate
// write requests, and thus require tracking all the writes being
// waited upon for completion.
fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(),
fMemoryView->GetEditedData(), fCurrentBlock->Size());
break;
}
case MSG_REVERT_MODIFIED_BLOCK:
{
_SetEditMode(false);
break;
}
default:
{
BWindow::MessageReceived(message);
@@ -357,6 +411,17 @@ InspectorWindow::ThreadStateChanged(const Team::ThreadEvent& event)
}
void
InspectorWindow::MemoryChanged(const Team::MemoryChangedEvent& event)
{
BMessage message(MSG_MEMORY_DATA_CHANGED);
message.AddUInt64("address", event.GetTargetAddress());
message.AddUInt64("size", event.GetSize());
PostMessage(&message);
}
void
InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block)
{
@@ -563,6 +628,53 @@ InspectorWindow::_SetCurrentBlock(TeamMemoryBlock* block)
fCurrentBlock = block;
fMemoryView->SetTargetAddress(fCurrentBlock, fCurrentAddress);
_UpdateWritableOptions();
}
bool
InspectorWindow::_GetWritableState() const
{
return fCurrentBlock != NULL ? fCurrentBlock->IsWritable() : false;
}
void
InspectorWindow::_SetEditMode(bool enabled)
{
if (enabled == fMemoryView->GetEditMode())
return;
status_t error = fMemoryView->SetEditMode(enabled);
if (error != B_OK)
return;
if (enabled) {
fEditBlockButton->Hide();
fCommitBlockButton->Show();
fRevertBlockButton->Show();
} else {
fEditBlockButton->Show();
fCommitBlockButton->Hide();
fRevertBlockButton->Hide();
}
fHexMode->SetEnabled(!enabled);
fEndianMode->SetEnabled(!enabled);
// while the block is being edited, disable block navigation controls.
fAddressInput->SetEnabled(!enabled);
fPreviousBlockButton->SetEnabled(!enabled);
fNextBlockButton->SetEnabled(!enabled);
InvalidateLayout();
}
void
InspectorWindow::_UpdateWritableOptions()
{
fEditBlockButton->SetEnabled(_GetWritableState());
_UpdateWritableIndicator();
}
@@ -46,6 +46,9 @@ public:
virtual void ThreadStateChanged(
const Team::ThreadEvent& event);
virtual void MemoryChanged(
const Team::MemoryChangedEvent& event);
// TeamMemoryBlock::Listener
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
virtual void MemoryBlockRetrievalFailed(
@@ -79,6 +82,12 @@ private:
void _SetToAddress(target_addr_t address);
void _SetCurrentBlock(TeamMemoryBlock* block);
void _SetEditMode(bool enabled);
bool _GetWritableState() const;
void _UpdateWritableOptions();
void _UpdateWritableIndicator();
const char* _GetCurrentWritableIndicator() const;
@@ -92,6 +101,9 @@ private:
MemoryView* fMemoryView;
BButton* fPreviousBlockButton;
BButton* fNextBlockButton;
BButton* fEditBlockButton;
BButton* fCommitBlockButton;
BButton* fRevertBlockButton;
TeamMemoryBlock* fCurrentBlock;
target_addr_t fCurrentAddress;
::Team* fTeam;