[Haiku-commits] r31122 - haiku/trunk/src/apps/debugger/gui/team_window
bonefish at BerliOS
bonefish at mail.berlios.de
Fri Jun 19 19:31:25 CEST 2009
Author: bonefish
Date: 2009-06-19 19:31:24 +0200 (Fri, 19 Jun 2009)
New Revision: 31122
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31122&view=rev
Added:
haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp
haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h
Modified:
haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp
haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h
Log:
Added view to show registers. Doesn't look particularly nice, but seems to work.
Added: haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp 2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp 2009-06-19 17:31:24 UTC (rev 31122)
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "RegisterView.h"
+
+#include <stdio.h>
+
+#include <new>
+
+#include "table/TableColumns.h"
+
+#include "Architecture.h"
+#include "CpuState.h"
+#include "Register.h"
+
+
+// #pragma mark - RegisterValueColumn
+
+
+class RegisterView::RegisterValueColumn : public StringTableColumn {
+public:
+ RegisterValueColumn(int32 modelIndex, const char* title, float width,
+ float minWidth, float maxWidth, uint32 truncate = B_TRUNCATE_MIDDLE,
+ alignment align = B_ALIGN_RIGHT)
+ :
+ StringTableColumn(modelIndex, title, width, minWidth, maxWidth,
+ truncate, align)
+ {
+ }
+
+protected:
+ virtual BField* PrepareField(const Variant& value) const
+ {
+ char buffer[64];
+ return StringTableColumn::PrepareField(
+ Variant(_ToString(value, buffer, sizeof(buffer)),
+ VARIANT_DONT_COPY_DATA));
+ }
+
+ virtual int CompareValues(const Variant& a, const Variant& b)
+ {
+ // If neither value is a number, compare the strings. If only one value
+ // is a number, it is considered to be greater.
+ if (!a.IsNumber()) {
+ if (b.IsNumber())
+ return -1;
+ char bufferA[64];
+ char bufferB[64];
+ return StringTableColumn::CompareValues(
+ Variant(_ToString(a, bufferA, sizeof(bufferA)),
+ VARIANT_DONT_COPY_DATA),
+ Variant(_ToString(b, bufferB, sizeof(bufferB)),
+ VARIANT_DONT_COPY_DATA));
+ }
+
+ if (!b.IsNumber())
+ return 1;
+
+ // If either value is floating point, we compare floating point values.
+ if (a.IsFloat() || b.IsFloat()) {
+ double valueA = a.ToDouble();
+ double valueB = b.ToDouble();
+ return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
+ }
+
+ uint64 valueA = a.ToUInt64();
+ uint64 valueB = b.ToUInt64();
+ return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
+ }
+
+private:
+ const char* _ToString(const Variant& value, char* buffer,
+ size_t bufferSize) const
+ {
+ if (!value.IsNumber())
+ return value.ToString();
+
+ switch (value.Type()) {
+ case B_FLOAT_TYPE:
+ case B_DOUBLE_TYPE:
+ snprintf(buffer, bufferSize, "%g", value.ToDouble());
+ break;
+ case B_INT8_TYPE:
+ case B_UINT8_TYPE:
+ snprintf(buffer, bufferSize, "0x%02x", value.ToUInt8());
+ break;
+ case B_INT16_TYPE:
+ case B_UINT16_TYPE:
+ snprintf(buffer, bufferSize, "0x%04x", value.ToUInt16());
+ break;
+ case B_INT32_TYPE:
+ case B_UINT32_TYPE:
+ snprintf(buffer, bufferSize, "0x%08lx", value.ToUInt32());
+ break;
+ case B_INT64_TYPE:
+ case B_UINT64_TYPE:
+ default:
+ snprintf(buffer, bufferSize, "0x%016llx", value.ToUInt64());
+ break;
+ }
+
+ return buffer;
+ }
+};
+
+
+// #pragma mark - RegisterTableModel
+
+
+class RegisterView::RegisterTableModel : public TableModel {
+public:
+ RegisterTableModel(Architecture* architecture)
+ :
+ fArchitecture(architecture),
+ fCpuState(NULL)
+ {
+ }
+
+ ~RegisterTableModel()
+ {
+ }
+
+ void SetCpuState(CpuState* cpuState)
+ {
+ fCpuState = cpuState;
+
+ NotifyRowsChanged(0, CountRows());
+ }
+
+ virtual int32 CountColumns() const
+ {
+ return 2;
+ }
+
+ virtual int32 CountRows() const
+ {
+ return fArchitecture->CountRegisters();
+ }
+
+ virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, Variant& value)
+ {
+ if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
+ return false;
+
+ const Register* reg = fArchitecture->Registers() + rowIndex;
+
+ switch (columnIndex) {
+ case 0:
+ value.SetTo(reg->Name(), VARIANT_DONT_COPY_DATA);
+ return true;
+ case 1:
+ if (fCpuState == NULL)
+ return false;
+ if (!fCpuState->GetRegisterValue(reg, value))
+ value.SetTo("?", VARIANT_DONT_COPY_DATA);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+private:
+ Architecture* fArchitecture;
+ CpuState* fCpuState;
+};
+
+
+// #pragma mark - RegisterView
+
+
+RegisterView::RegisterView(Architecture* architecture)
+ :
+ BGroupView(B_VERTICAL),
+ fArchitecture(architecture),
+ fRegisterTable(NULL),
+ fRegisterTableModel(NULL)
+{
+ SetName("Registers");
+}
+
+
+RegisterView::~RegisterView()
+{
+ SetCpuState(NULL);
+ fRegisterTable->SetTableModel(NULL);
+ delete fRegisterTableModel;
+}
+
+
+/*static*/ RegisterView*
+RegisterView::Create(Architecture* architecture)
+{
+ RegisterView* self = new RegisterView(architecture);
+
+ try {
+ self->_Init();
+ } catch (...) {
+ delete self;
+ throw;
+ }
+
+ return self;
+}
+
+
+void
+RegisterView::SetCpuState(CpuState* cpuState)
+{
+ if (cpuState == fCpuState)
+ return;
+
+ if (fCpuState != NULL)
+ fCpuState->RemoveReference();
+
+ fCpuState = cpuState;
+
+ if (fCpuState != NULL)
+ fCpuState->AddReference();
+
+ fRegisterTableModel->SetCpuState(fCpuState);
+}
+
+
+void
+RegisterView::TableRowInvoked(Table* table, int32 rowIndex)
+{
+}
+
+
+void
+RegisterView::_Init()
+{
+ fRegisterTable = new Table("register list", 0);
+ AddChild(fRegisterTable->ToView());
+
+ // columns
+ fRegisterTable->AddColumn(new StringTableColumn(0, "Register", 80, 40, 1000,
+ B_TRUNCATE_END, B_ALIGN_LEFT));
+ fRegisterTable->AddColumn(new RegisterValueColumn(1, "Value", 80, 40, 1000,
+ B_TRUNCATE_END, B_ALIGN_RIGHT));
+
+ fRegisterTableModel = new RegisterTableModel(fArchitecture);
+ fRegisterTable->SetTableModel(fRegisterTableModel);
+
+ fRegisterTable->AddTableListener(this);
+}
Added: haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h 2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h 2009-06-19 17:31:24 UTC (rev 31122)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef REGISTER_VIEW_H
+#define REGISTER_VIEW_H
+
+#include <GroupView.h>
+
+#include "table/Table.h"
+#include "Team.h"
+
+
+class Architecture;
+
+
+class RegisterView : public BGroupView, private TableListener {
+public:
+ RegisterView(Architecture* architecture);
+ ~RegisterView();
+
+ static RegisterView* Create(Architecture* architecture);
+ // throws
+
+ void SetCpuState(CpuState* cpuState);
+
+private:
+ class RegisterValueColumn;
+ class RegisterTableModel;
+
+private:
+ // TableListener
+ virtual void TableRowInvoked(Table* table, int32 rowIndex);
+
+ void _Init();
+
+private:
+ Architecture* fArchitecture;
+ CpuState* fCpuState;
+ Table* fRegisterTable;
+ RegisterTableModel* fRegisterTableModel;
+};
+
+
+#endif // REGISTER_VIEW_H
Modified: haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp 2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp 2009-06-19 17:31:24 UTC (rev 31122)
@@ -16,8 +16,10 @@
#include <AutoLocker.h>
+#include "CpuState.h"
#include "ImageListView.h"
#include "MessageCodes.h"
+#include "RegisterView.h"
#include "TeamDebugModel.h"
@@ -32,8 +34,10 @@
fActiveThread(NULL),
fListener(listener),
fTabView(NULL),
+ fLocalsTabView(NULL),
fThreadListView(NULL),
fImageListView(NULL),
+ fRegisterView(NULL),
fRunButton(NULL),
fStepOverButton(NULL),
fStepIntoButton(NULL),
@@ -95,7 +99,16 @@
_HandleThreadStateChanged(threadID);
break;
}
-// case MSG_THREAD_CPU_STATE_CHANGED:
+ case MSG_THREAD_CPU_STATE_CHANGED:
+ {
+ int32 threadID;
+ if (message->FindInt32("thread", &threadID) != B_OK)
+ break;
+
+ _HandleCpuStateChanged(threadID);
+ break;
+ }
+
// case MSG_THREAD_STACK_TRACE_CHANGED:
default:
@@ -131,18 +144,18 @@
void
TeamWindow::ThreadCpuStateChanged(const Team::ThreadEvent& event)
{
-// BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
-// message.AddInt32("thread", event.GetThread()->ID());
-// PostMessage(&message);
+ BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
+ message.AddInt32("thread", event.GetThread()->ID());
+ PostMessage(&message);
}
void
TeamWindow::ThreadStackTraceChanged(const Team::ThreadEvent& event)
{
-// BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
-// message.AddInt32("thread", event.GetThread()->ID());
-// PostMessage(&message);
+ BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
+ message.AddInt32("thread", event.GetThread()->ID());
+ PostMessage(&message);
}
@@ -162,7 +175,7 @@
.End()
.AddSplit(B_HORIZONTAL, 3.0f)
.Add(new BTextView("source view"), 3.0f)
- .Add(new BTextView("variables view"))
+ .Add(fLocalsTabView = new BTabView("locals view"))
.End()
.End()
.End();
@@ -183,6 +196,14 @@
.Add(fImageListView = ImageListView::Create())
.Add(new BTextView("source files"));
+ // add local variables tab
+ BView* tab = new BTextView("Variables");
+ fLocalsTabView->AddTab(tab);
+
+ // add registers tab
+ tab = fRegisterView = RegisterView::Create(fDebugModel->GetArchitecture());
+ fLocalsTabView->AddTab(tab);
+
fThreadListView->SetTeam(fDebugModel->GetTeam());
fImageListView->SetTeam(fDebugModel->GetTeam());
@@ -210,6 +231,15 @@
AutoLocker<TeamDebugModel> locker(fDebugModel);
_UpdateRunButtons();
+
+ CpuState* cpuState = fActiveThread != NULL
+ ? fActiveThread->GetCpuState() : NULL;
+ Reference<CpuState> reference(cpuState);
+ // hold a reference until the register view has one
+
+ locker.Unlock();
+
+ fRegisterView->SetCpuState(cpuState);
}
@@ -258,6 +288,26 @@
}
+void
+TeamWindow::_HandleCpuStateChanged(thread_id threadID)
+{
+ // We're only interested in the currently selected thread
+ if (fActiveThread == NULL || threadID != fActiveThread->ID())
+ return;
+
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+ CpuState* cpuState = fActiveThread != NULL
+ ? fActiveThread->GetCpuState() : NULL;
+ Reference<CpuState> reference(cpuState);
+ // hold a reference until the register view has one
+
+ locker.Unlock();
+
+ fRegisterView->SetCpuState(cpuState);
+}
+
+
// #pragma mark - Listener
Modified: haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h 2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h 2009-06-19 17:31:24 UTC (rev 31122)
@@ -15,6 +15,7 @@
class BButton;
class BTabView;
class ImageListView;
+class RegisterView;
class TeamDebugModel;
@@ -53,14 +54,17 @@
void _UpdateRunButtons();
void _HandleThreadStateChanged(thread_id threadID);
+ void _HandleCpuStateChanged(thread_id threadID);
private:
TeamDebugModel* fDebugModel;
::Thread* fActiveThread;
Listener* fListener;
BTabView* fTabView;
+ BTabView* fLocalsTabView;
ThreadListView* fThreadListView;
ImageListView* fImageListView;
+ RegisterView* fRegisterView;
BButton* fRunButton;
BButton* fStepOverButton;
BButton* fStepIntoButton;
More information about the Haiku-commits
mailing list