2 * Copyright 2012-2016, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
5 #include "WatchPromptWindow.h"
9 #include <LayoutBuilder.h>
11 #include <MenuField.h>
14 #include <TextControl.h>
16 #include "AutoLocker.h"
18 #include "AppMessageCodes.h"
19 #include "Architecture.h"
20 #include "CppLanguage.h"
21 #include "IntegerValue.h"
22 #include "MessageCodes.h"
23 #include "SyntheticPrimitiveType.h"
24 #include "UserInterface.h"
25 #include "Watchpoint.h"
28 WatchPromptWindow::WatchPromptWindow(Architecture
* architecture
,
29 target_addr_t address
, uint32 type
, int32 length
,
30 UserInterfaceListener
* listener
)
32 BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW
,
33 B_AUTO_UPDATE_SIZE_LIMITS
| B_CLOSE_ON_ESCAPE
),
34 fInitialAddress(address
),
36 fInitialLength(length
),
37 fArchitecture(architecture
),
42 fAddressExpressionInfo(NULL
),
43 fLengthExpressionInfo(NULL
),
48 fArchitecture
->AcquireReference();
52 WatchPromptWindow::~WatchPromptWindow()
54 fArchitecture
->ReleaseReference();
56 if (fLanguage
!= NULL
)
57 fLanguage
->ReleaseReference();
59 if (fAddressExpressionInfo
!= NULL
) {
60 fAddressExpressionInfo
->RemoveListener(this);
61 fAddressExpressionInfo
->ReleaseReference();
64 if (fLengthExpressionInfo
!= NULL
) {
65 fLengthExpressionInfo
->RemoveListener(this);
66 fLengthExpressionInfo
->ReleaseReference();
72 WatchPromptWindow::Create(Architecture
* architecture
, target_addr_t address
,
73 uint32 type
, int32 length
, UserInterfaceListener
* listener
)
75 WatchPromptWindow
* self
= new WatchPromptWindow(architecture
, address
,
76 type
, length
, listener
);
91 WatchPromptWindow::_Init()
93 fLanguage
= new CppLanguage();
96 text
.SetToFormat("0x%" B_PRIx64
, fInitialAddress
);
97 fAddressInput
= new BTextControl("Address:", text
, NULL
);
98 fAddressExpressionInfo
= new ExpressionInfo(text
);
99 fAddressExpressionInfo
->AddListener(this);
101 text
.SetToFormat("%" B_PRId32
, fInitialLength
);
102 fLengthInput
= new BTextControl("Length:", text
, NULL
);
103 fLengthExpressionInfo
= new ExpressionInfo(text
);
104 fLengthExpressionInfo
->AddListener(this);
106 int32 maxDebugRegisters
= 0;
107 int32 maxBytesPerRegister
= 0;
108 uint8 debugCapabilityFlags
= 0;
109 fArchitecture
->GetWatchpointDebugCapabilities(maxDebugRegisters
,
110 maxBytesPerRegister
, debugCapabilityFlags
);
112 BMenu
* typeMenu
= new BMenu("Watch type");
114 BMenuItem
* watchTypeItem
= new BMenuItem("Read", NULL
);
115 watchTypeItem
->SetEnabled(
116 (debugCapabilityFlags
& WATCHPOINT_CAPABILITY_FLAG_READ
) != 0);
117 typeMenu
->AddItem(watchTypeItem
);
119 watchTypeItem
= new BMenuItem("Write", NULL
);
120 watchTypeItem
->SetEnabled(
121 (debugCapabilityFlags
& WATCHPOINT_CAPABILITY_FLAG_WRITE
) != 0);
122 typeMenu
->AddItem(watchTypeItem
);
124 watchTypeItem
= new BMenuItem("Read/Write", NULL
);
125 watchTypeItem
->SetEnabled(
126 (debugCapabilityFlags
& WATCHPOINT_CAPABILITY_FLAG_READ_WRITE
) != 0);
127 typeMenu
->AddItem(watchTypeItem
);
129 fTypeField
= new BMenuField("Type:", typeMenu
);
130 BLayoutItem
* labelItem
= fTypeField
->CreateLabelLayoutItem();
131 labelItem
->View()->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
132 BLayoutBuilder::Group
<>(this, B_VERTICAL
)
133 .SetInsets(B_USE_DEFAULT_SPACING
)
134 .AddGroup(B_HORIZONTAL
, 4.0f
)
137 .AddGroup(B_HORIZONTAL
, 4.0f
)
140 .Add(fTypeField
->CreateMenuBarLayoutItem())
142 .AddGroup(B_HORIZONTAL
, 4.0f
)
144 .Add((fWatchButton
= new BButton("Set",
145 new BMessage(MSG_SET_WATCHPOINT
))))
146 .Add((fCancelButton
= new BButton("Cancel",
147 new BMessage(B_QUIT_REQUESTED
))))
150 fWatchButton
->SetTarget(this);
151 fCancelButton
->SetTarget(this);
153 fTypeField
->Menu()->SetLabelFromMarked(true);
154 fTypeField
->Menu()->ItemAt(fInitialType
)->SetMarked(true);
159 WatchPromptWindow::Show()
167 WatchPromptWindow::ExpressionEvaluated(ExpressionInfo
* info
, status_t result
,
168 ExpressionResult
* value
)
170 BMessage
message(MSG_EXPRESSION_EVALUATED
);
171 message
.AddInt32("result", result
);
172 message
.AddPointer("info", info
);
173 BReference
<ExpressionResult
> reference
;
175 reference
.SetTo(value
);
176 message
.AddPointer("value", value
);
179 if (PostMessage(&message
) == B_OK
)
185 WatchPromptWindow::MessageReceived(BMessage
* message
)
187 switch (message
->what
) {
188 case MSG_EXPRESSION_EVALUATED
:
190 BString errorMessage
;
191 BReference
<ExpressionResult
> reference
;
192 ExpressionResult
* value
= NULL
;
193 ExpressionInfo
* info
= NULL
;
194 if (message
->FindPointer("info",
195 reinterpret_cast<void**>(&info
)) != B_OK
) {
199 if (message
->FindPointer("value",
200 reinterpret_cast<void**>(&value
)) == B_OK
) {
201 reference
.SetTo(value
, true);
202 if (value
->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE
) {
203 Value
* primitive
= value
->PrimitiveValue();
204 if (dynamic_cast<IntegerValue
*>(primitive
) != NULL
) {
205 BVariant resultVariant
;
206 primitive
->ToVariant(resultVariant
);
207 if (info
== fAddressExpressionInfo
) {
208 fRequestedAddress
= resultVariant
.ToUInt64();
211 fRequestedLength
= resultVariant
.ToInt32();
214 primitive
->ToString(errorMessage
);
216 errorMessage
.SetTo("Unsupported expression result.");
218 status_t result
= message
->FindInt32("result");
219 errorMessage
.SetToFormat("Failed to evaluate expression: %s",
223 if (fRequestedLength
<= 0)
224 errorMessage
= "Watchpoint length must be at least 1 byte.";
226 if (!errorMessage
.IsEmpty()) {
227 BAlert
* alert
= new(std::nothrow
) BAlert("Edit Watchpoint",
228 errorMessage
.String(), "Close");
234 fListener
->ClearWatchpointRequested(fInitialAddress
);
235 fListener
->SetWatchpointRequested(fRequestedAddress
,
236 fTypeField
->Menu()->IndexOf(fTypeField
->Menu()->FindMarked()),
237 fRequestedLength
, true);
239 PostMessage(B_QUIT_REQUESTED
);
243 case MSG_SET_WATCHPOINT
:
245 fRequestedAddress
= 0;
246 fRequestedLength
= 0;
248 fAddressExpressionInfo
->SetTo(fAddressInput
->Text());
249 fListener
->ExpressionEvaluationRequested(fLanguage
,
250 fAddressExpressionInfo
);
252 fLengthExpressionInfo
->SetTo(fLengthInput
->Text());
253 fListener
->ExpressionEvaluationRequested(fLanguage
,
254 fLengthExpressionInfo
);
259 BWindow::MessageReceived(message
);