Merge pull request #2703 from unknownbrackets/debugger

Scroll debugger like most things scroll, add context menus
This commit is contained in:
Henrik Rydgård 2013-07-07 23:57:30 -07:00
commit 4744cb71be
9 changed files with 137 additions and 26 deletions

View File

@ -441,19 +441,15 @@ void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam)
{
case SB_LINEDOWN:
windowStart += instructionSize;
curAddress += instructionSize;
break;
case SB_LINEUP:
windowStart -= instructionSize;
curAddress -= instructionSize;
break;
case SB_PAGEDOWN:
windowStart += visibleRows*instructionSize;
curAddress += visibleRows*instructionSize;
break;
case SB_PAGEUP:
windowStart -= visibleRows*instructionSize;
curAddress -= visibleRows*instructionSize;
break;
default:
return;
@ -509,35 +505,29 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam)
switch (wParam & 0xFFFF)
{
case VK_DOWN:
if (curAddress == windowEnd-instructionSize)
{
windowStart += instructionSize;
}
curAddress += instructionSize;
scrollAddressIntoView();
break;
case VK_UP:
if (curAddress == windowStart)
{
windowStart -= instructionSize;
}
curAddress-=instructionSize;
scrollAddressIntoView();
break;
case VK_NEXT:
if (curAddress != windowEnd-instructionSize)
{
if (curAddress != windowEnd-instructionSize && curAddressIsVisible()) {
curAddress = windowEnd-instructionSize;
scrollAddressIntoView();
} else {
windowStart += visibleRows*instructionSize;
curAddress += visibleRows*instructionSize;
scrollAddressIntoView();
}
break;
case VK_PRIOR:
if (curAddress != windowStart)
{
if (curAddress != windowStart && curAddressIsVisible()) {
curAddress = windowStart;
scrollAddressIntoView();
} else {
windowStart -= visibleRows*instructionSize;
curAddress -= visibleRows*instructionSize;
scrollAddressIntoView();
}
break;
case VK_LEFT:
@ -591,6 +581,22 @@ void CtrlDisAsmView::onKeyUp(WPARAM wParam, LPARAM lParam)
}
}
void CtrlDisAsmView::scrollAddressIntoView()
{
u32 windowEnd = windowStart + visibleRows * instructionSize;
if (curAddress < windowStart)
windowStart = curAddress;
else if (curAddress >= windowEnd)
windowStart = curAddress - visibleRows * instructionSize + instructionSize;
}
bool CtrlDisAsmView::curAddressIsVisible()
{
u32 windowEnd = windowStart + visibleRows * instructionSize;
return curAddress >= windowStart && curAddress < windowEnd;
}
void CtrlDisAsmView::redraw()
{
if (dontRedraw == true) return;

View File

@ -82,6 +82,8 @@ public:
void onMouseDown(WPARAM wParam, LPARAM lParam, int button);
void onMouseUp(WPARAM wParam, LPARAM lParam, int button);
void onMouseMove(WPARAM wParam, LPARAM lParam, int button);
void scrollAddressIntoView();
bool curAddressIsVisible();
void redraw();
void getOpcodeText(u32 address, char* dest);
@ -134,7 +136,6 @@ public:
void scrollWindow(int lines)
{
windowStart += lines*instructionSize;
curAddress += lines*instructionSize;
redraw();
}
};

View File

@ -2,6 +2,8 @@
#include <Windows.h>
#include "..\..\Core\Debugger\DebugInterface.h"
extern HMENU g_hPopupMenus;
enum { WM_DEB_RUNTOWPARAM = WM_USER+2,
WM_DEB_GOTOWPARAM,
WM_DEB_GOTOBREAKPOINT,

View File

@ -46,6 +46,8 @@ enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_HITS, BPL_ENABLED, B
// How long (max) to wait for Core to pause before clearing temp breakpoints.
const int TEMP_BREAKPOINT_WAIT_MS = 100;
const int POPUP_SUBMENU_ID_BREAKPOINTLIST = 5;
static FAR WNDPROC DefBreakpointListProc;
static LRESULT CALLBACK BreakpointListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
@ -332,20 +334,64 @@ void CDisasm::gotoBreakpointAddress(int itemIndex)
}
}
void CDisasm::showBreakpointMenu(int itemIndex, const POINT &pt)
{
bool isMemory;
int index = getBreakpointIndex(itemIndex, isMemory);
if (index == -1) return;
MemCheck mcPrev;
BreakPoint bpPrev;
if (isMemory) {
mcPrev = displayedMemChecks_[index];
} else {
bpPrev = displayedBreakPoints_[index];
}
HWND wnd = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
POINT screenPt(pt);
ClientToScreen(wnd, &screenPt);
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_BREAKPOINTLIST);
if (isMemory) {
CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (mcPrev.result & MEMCHECK_BREAK ? MF_CHECKED : MF_UNCHECKED));
} else {
CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED));
}
switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0))
{
case ID_DISASM_DISABLEBREAKPOINT:
if (isMemory) {
CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK));
} else {
CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled);
}
break;
}
}
static char breakpointText[256];
void CDisasm::handleBreakpointNotify(LPARAM lParam)
{
if (((LPNMHDR)lParam)->code == NM_DBLCLK)
const LPNMHDR header = (LPNMHDR)lParam;
if (header->code == NM_DBLCLK)
{
LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
gotoBreakpointAddress(item->iItem);
return;
}
if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
if (header->code == NM_RCLICK)
{
NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
showBreakpointMenu(item->iItem, item->ptAction);
return;
}
if (header->code == LVN_GETDISPINFO)
{
NMLVDISPINFO *dispInfo = (NMLVDISPINFO *)lParam;
bool isMemory;
int index = getBreakpointIndex(dispInfo->item.iItem,isMemory);

View File

@ -42,6 +42,7 @@ private:
int getTotalBreakpointCount();
int getBreakpointIndex(int itemIndex, bool& isMemory);
void updateThreadLabel(bool clear);
void showBreakpointMenu(int itemIndex, const POINT &pt);
public:
int index; //helper

View File

@ -3,6 +3,7 @@
#include <windowsx.h>
#include <commctrl.h>
#include "DebuggerShared.h"
#include "Windows/resource.h"
enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT };
@ -14,6 +15,8 @@ const float threadColumnSizes[] = {
0.20f, 0.15f, 0.15f, 0.15f, 0.15f, 0.20f
};
const int POPUP_SUBMENU_ID_THREADLIST = 6;
void CtrlThreadList::setDialogItem(HWND hwnd)
{
wnd = hwnd;
@ -76,6 +79,51 @@ LRESULT CALLBACK CtrlThreadList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
return (LRESULT)CallWindowProc((WNDPROC)tl->oldProc,hwnd,msg,wParam,lParam);
}
void CtrlThreadList::showMenu(int itemIndex, const POINT &pt)
{
auto threadInfo = threads[itemIndex];
// Can't do it, sorry. Needs to not be running.
if (Core_IsActive())
return;
POINT screenPt(pt);
ClientToScreen(wnd, &screenPt);
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_THREADLIST);
switch (threadInfo.status) {
case THREADSTATUS_DEAD:
case THREADSTATUS_DORMANT:
case THREADSTATUS_RUNNING:
EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_DISABLED);
EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_DISABLED);
break;
case THREADSTATUS_READY:
EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_DISABLED);
EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_ENABLED);
break;
case THREADSTATUS_SUSPEND:
case THREADSTATUS_WAIT:
case THREADSTATUS_WAITSUSPEND:
default:
EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_ENABLED);
break;
}
switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0))
{
case ID_DISASM_THREAD_FORCERUN:
__KernelResumeThreadFromWait(threadInfo.id, 0);
reloadThreads();
break;
case ID_DISASM_THREAD_KILL:
sceKernelTerminateThread(threadInfo.id);
reloadThreads();
break;
}
}
void CtrlThreadList::handleNotify(LPARAM lParam)
{
LPNMHDR mhdr = (LPNMHDR) lParam;
@ -99,6 +147,12 @@ void CtrlThreadList::handleNotify(LPARAM lParam)
SendMessage(GetParent(wnd),WM_DEB_GOTOWPARAM,address,0);
return;
}
if (mhdr->code == NM_RCLICK)
{
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
showMenu(item->iItem, item->ptAction);
return;
}
if (mhdr->code == LVN_GETDISPINFO)
{
@ -188,7 +242,7 @@ void CtrlThreadList::reloadThreads()
items++;
}
while (items > threads.size())
while (items > (int)threads.size())
{
ListView_DeleteItem(wnd,--items);
}
@ -199,7 +253,7 @@ void CtrlThreadList::reloadThreads()
const char* CtrlThreadList::getCurrentThreadName()
{
for (int i = 0; i < threads.size(); i++)
for (size_t i = 0; i < threads.size(); i++)
{
if (threads[i].isCurrent) return threads[i].name;
}

View File

@ -14,6 +14,7 @@ public:
void setDialogItem(HWND hwnd);
void reloadThreads();
void handleNotify(LPARAM lParam);
void showMenu(int itemIndex, const POINT &pt);
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
const char* getCurrentThreadName();
};

Binary file not shown.

Binary file not shown.