trunk/src/osd/sdl/debugqt.c
| r0 | r19797 | |
| 1 | //============================================================ |
| 2 | // |
| 3 | // debugqt.c - SDL/QT debug window handling |
| 4 | // |
| 5 | // Copyright (c) 1996-2010, Nicola Salmoria and the MAME Team. |
| 6 | // Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | // |
| 8 | // SDLMAME by Olivier Galibert and R. Belmont |
| 9 | // |
| 10 | //============================================================ |
| 11 | |
| 12 | #if !defined(NO_DEBUGGER) |
| 13 | |
| 14 | #include <QtGui/QtGui> |
| 15 | #include <QtGui/QApplication> |
| 16 | |
| 17 | #include "emu.h" |
| 18 | #include "osdsdl.h" |
| 19 | #include "debugger.h" |
| 20 | |
| 21 | #include "debugqtmainwindow.h" |
| 22 | |
| 23 | |
| 24 | //============================================================ |
| 25 | // "Global" variables to make QT happy |
| 26 | //============================================================ |
| 27 | |
| 28 | int qtArgc = 0; |
| 29 | char** qtArgv = NULL; |
| 30 | |
| 31 | bool oneShot = true; |
| 32 | MainWindow* mainQtWindow = NULL; |
| 33 | |
| 34 | |
| 35 | //============================================================ |
| 36 | // Core functionality |
| 37 | //============================================================ |
| 38 | |
| 39 | void sdl_osd_interface::init_debugger() |
| 40 | { |
| 41 | // QT is a magical thing |
| 42 | new QApplication(qtArgc, qtArgv); |
| 43 | } |
| 44 | |
| 45 | |
| 46 | //============================================================ |
| 47 | // Core functionality |
| 48 | //============================================================ |
| 49 | |
| 50 | void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop) |
| 51 | { |
| 52 | if (oneShot) |
| 53 | { |
| 54 | mainQtWindow = new MainWindow(&device, &machine()); |
| 55 | mainQtWindow->show(); |
| 56 | oneShot = false; |
| 57 | } |
| 58 | |
| 59 | // Make sure the main window displays the proper cpu |
| 60 | mainQtWindow->setProcessor(&device); |
| 61 | |
| 62 | // Run our own QT event loop |
| 63 | while (debug_cpu_is_stopped(machine())) |
| 64 | { |
| 65 | qApp->processEvents(QEventLoop::AllEvents, 1); |
| 66 | |
| 67 | // Refresh everyone if requested |
| 68 | if (mainQtWindow->wantsRefresh()) |
| 69 | { |
| 70 | QWidgetList allWidgets = qApp->allWidgets(); |
| 71 | for (int i = 0; i < allWidgets.length(); i++) |
| 72 | allWidgets[i]->update(); |
| 73 | mainQtWindow->clearRefreshFlag(); |
| 74 | } |
| 75 | |
| 76 | // Exit if the machine has been instructed to do so |
| 77 | if (machine().exit_pending()) |
| 78 | { |
| 79 | break; |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | |
| 85 | //============================================================ |
| 86 | // Available for video.* |
| 87 | //============================================================ |
| 88 | |
| 89 | void debugwin_update_during_game(running_machine &machine) |
| 90 | { |
| 91 | qApp->processEvents(QEventLoop::AllEvents, 1); |
| 92 | } |
| 93 | |
| 94 | |
| 95 | |
| 96 | #else |
| 97 | |
| 98 | |
| 99 | #include "sdlinc.h" |
| 100 | |
| 101 | #include "emu.h" |
| 102 | #include "osdepend.h" |
| 103 | #include "osdsdl.h" |
| 104 | |
| 105 | // win32 stubs for linking |
| 106 | void sdl_osd_interface::init_debugger() |
| 107 | { |
| 108 | } |
| 109 | |
| 110 | void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop) |
| 111 | { |
| 112 | } |
| 113 | |
| 114 | // win32 stubs for linking |
| 115 | void debugwin_update_during_game(running_machine &machine) |
| 116 | { |
| 117 | } |
| 118 | |
| 119 | #endif |
trunk/src/osd/sdl/debugqtview.c
| r0 | r19797 | |
| 1 | #include <QtGui/QtGui> |
| 2 | |
| 3 | #include "debugqtview.h" |
| 4 | |
| 5 | |
| 6 | DebuggerView::DebuggerView(const debug_view_type& type, |
| 7 | running_machine* machine, |
| 8 | QWidget* parent) : |
| 9 | QAbstractScrollArea(parent), |
| 10 | m_preferBottom(false), |
| 11 | m_view(NULL), |
| 12 | m_machine(machine) |
| 13 | { |
| 14 | QFont viewFontRequest("Courier"); |
| 15 | viewFontRequest.setFixedPitch(true); |
| 16 | viewFontRequest.setPointSize(12); |
| 17 | setFont(viewFontRequest); |
| 18 | |
| 19 | m_view = m_machine->debug_view().alloc_view(type, |
| 20 | DebuggerView::debuggerViewUpdate, |
| 21 | this); |
| 22 | } |
| 23 | |
| 24 | |
| 25 | void DebuggerView::paintEvent(QPaintEvent* event) |
| 26 | { |
| 27 | // Tell the MAME debug view how much real estate is available |
| 28 | QFontMetrics actualFont = fontMetrics(); |
| 29 | const int fontWidth = actualFont.maxWidth(); |
| 30 | const int fontHeight = actualFont.height(); |
| 31 | m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight)); |
| 32 | |
| 33 | |
| 34 | // Handle the scroll bars |
| 35 | const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y; |
| 36 | const int scrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff; |
| 37 | bool atEnd = false; |
| 38 | if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) |
| 39 | { |
| 40 | atEnd = true; |
| 41 | } |
| 42 | verticalScrollBar()->setRange(0, scrollSize); |
| 43 | if (m_preferBottom && atEnd) |
| 44 | { |
| 45 | verticalScrollBar()->setValue(scrollSize); |
| 46 | } |
| 47 | m_view->set_visible_position(debug_view_xy(0, verticalScrollBar()->value())); |
| 48 | |
| 49 | |
| 50 | // Draw the viewport widget |
| 51 | QPainter painter(viewport()); |
| 52 | painter.fillRect(0, 0, width(), height(), QBrush(Qt::white)); |
| 53 | painter.setBackgroundMode(Qt::OpaqueMode); |
| 54 | painter.setBackground(QColor(255,255,255)); |
| 55 | |
| 56 | // Background control |
| 57 | QBrush bgBrush; |
| 58 | bgBrush.setStyle(Qt::SolidPattern); |
| 59 | painter.setPen(QPen(QColor(0,0,0))); |
| 60 | |
| 61 | size_t viewDataOffset = 0; |
| 62 | const debug_view_xy& visibleCharDims = m_view->visible_size(); |
| 63 | for (int y = 0; y < visibleCharDims.y; y++) |
| 64 | { |
| 65 | for (int x = 0; x < visibleCharDims.x; x++) |
| 66 | { |
| 67 | const unsigned char textAttr = m_view->viewdata()[viewDataOffset].attrib; |
| 68 | |
| 69 | if (x == 0 || textAttr != m_view->viewdata()[viewDataOffset-1].attrib) |
| 70 | { |
| 71 | // Text color handling |
| 72 | QColor fgColor(0,0,0); |
| 73 | QColor bgColor(255,255,255); |
| 74 | |
| 75 | if(textAttr & DCA_ANCILLARY) |
| 76 | { |
| 77 | bgColor.setRgb(0xe0, 0xe0, 0xe0); |
| 78 | } |
| 79 | if(textAttr & DCA_SELECTED) |
| 80 | { |
| 81 | bgColor.setRgb(0xff, 0x80, 0x80); |
| 82 | } |
| 83 | if(textAttr & DCA_CURRENT) |
| 84 | { |
| 85 | bgColor.setRgb(0xff, 0xff, 0x00); |
| 86 | } |
| 87 | if(textAttr & DCA_CHANGED) |
| 88 | { |
| 89 | fgColor.setRgb(0xff, 0x00, 0x00); |
| 90 | } |
| 91 | if(textAttr & DCA_INVALID) |
| 92 | { |
| 93 | fgColor.setRgb(0x00, 0x00, 0xff); |
| 94 | } |
| 95 | if(textAttr & DCA_DISABLED) |
| 96 | { |
| 97 | fgColor.setRgb((fgColor.red() + bgColor.red()) >> 1, |
| 98 | (fgColor.green() + bgColor.green()) >> 1, |
| 99 | (fgColor.blue() + bgColor.blue()) >> 1); |
| 100 | } |
| 101 | if(textAttr & DCA_COMMENT) |
| 102 | { |
| 103 | fgColor.setRgb(0x00, 0x80, 0x00); |
| 104 | } |
| 105 | |
| 106 | bgBrush.setColor(bgColor); |
| 107 | painter.setBackground(bgBrush); |
| 108 | painter.setPen(QPen(fgColor)); |
| 109 | } |
| 110 | |
| 111 | // There is a touchy interplay between font height, drawing difference, visible position, etc |
| 112 | // To test, set the bgcolor to something crazy and see where stuff gets drawn |
| 113 | painter.drawText(x*fontWidth, |
| 114 | y*fontHeight + fontHeight, |
| 115 | QString(m_view->viewdata()[viewDataOffset].byte)); |
| 116 | viewDataOffset++; |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | |
| 122 | void DebuggerView::keyPressEvent(QKeyEvent* event) |
| 123 | { |
| 124 | if (m_view == NULL) |
| 125 | return QWidget::keyPressEvent(event); |
| 126 | |
| 127 | Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); |
| 128 | bool ctrlDown = keyMods.testFlag(Qt::ControlModifier); |
| 129 | |
| 130 | int keyPress = -1; |
| 131 | switch (event->key()) |
| 132 | { |
| 133 | case Qt::Key_Up: |
| 134 | keyPress = DCH_UP; |
| 135 | break; |
| 136 | case Qt::Key_Down: |
| 137 | keyPress = DCH_DOWN; |
| 138 | break; |
| 139 | case Qt::Key_Left: |
| 140 | keyPress = DCH_LEFT; |
| 141 | if (ctrlDown) keyPress = DCH_CTRLLEFT; |
| 142 | break; |
| 143 | case Qt::Key_Right: |
| 144 | keyPress = DCH_RIGHT; |
| 145 | if (ctrlDown) keyPress = DCH_CTRLRIGHT; |
| 146 | break; |
| 147 | case Qt::Key_PageUp: |
| 148 | keyPress = DCH_PUP; |
| 149 | break; |
| 150 | case Qt::Key_PageDown: |
| 151 | keyPress = DCH_PDOWN; |
| 152 | break; |
| 153 | case Qt::Key_Home: |
| 154 | keyPress = DCH_HOME; |
| 155 | if (ctrlDown) keyPress = DCH_CTRLHOME; |
| 156 | break; |
| 157 | case Qt::Key_End: |
| 158 | keyPress = DCH_END; |
| 159 | if (ctrlDown) keyPress = DCH_CTRLEND; |
| 160 | break; |
| 161 | case Qt::Key_0: keyPress = '0'; break; |
| 162 | case Qt::Key_1: keyPress = '1'; break; |
| 163 | case Qt::Key_2: keyPress = '2'; break; |
| 164 | case Qt::Key_3: keyPress = '3'; break; |
| 165 | case Qt::Key_4: keyPress = '4'; break; |
| 166 | case Qt::Key_5: keyPress = '5'; break; |
| 167 | case Qt::Key_6: keyPress = '6'; break; |
| 168 | case Qt::Key_7: keyPress = '7'; break; |
| 169 | case Qt::Key_8: keyPress = '8'; break; |
| 170 | case Qt::Key_9: keyPress = '9'; break; |
| 171 | case Qt::Key_A: keyPress = 'a'; break; |
| 172 | case Qt::Key_B: keyPress = 'b'; break; |
| 173 | case Qt::Key_C: keyPress = 'c'; break; |
| 174 | case Qt::Key_D: keyPress = 'd'; break; |
| 175 | case Qt::Key_E: keyPress = 'e'; break; |
| 176 | case Qt::Key_F: keyPress = 'f'; break; |
| 177 | default: |
| 178 | return QWidget::keyPressEvent(event); |
| 179 | } |
| 180 | |
| 181 | m_view->set_cursor_visible(true); |
| 182 | m_view->process_char(keyPress); |
| 183 | |
| 184 | // Catch the view up with the cursor |
| 185 | verticalScrollBar()->setValue(m_view->visible_position().y); |
| 186 | |
| 187 | viewport()->update(); |
| 188 | update(); |
| 189 | } |
| 190 | |
| 191 | |
| 192 | void DebuggerView::debuggerViewUpdate(debug_view& debugView, void* osdPrivate) |
| 193 | { |
| 194 | // Get a handle to the DebuggerView being updated & redraw |
| 195 | DebuggerView* dView = (DebuggerView*)osdPrivate; |
| 196 | dView->verticalScrollBar()->setValue(dView->view()->visible_position().y); |
| 197 | dView->viewport()->update(); |
| 198 | dView->update(); |
| 199 | } |
| 200 | |
| 201 | |
trunk/src/osd/sdl/debugqtdasmwindow.c
| r0 | r19797 | |
| 1 | #include "debugqtdasmwindow.h" |
| 2 | |
| 3 | #include "debug/debugcon.h" |
| 4 | #include "debug/debugcpu.h" |
| 5 | #include "debug/dvdisasm.h" |
| 6 | |
| 7 | |
| 8 | DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) : |
| 9 | WindowQt(machine, parent) |
| 10 | { |
| 11 | QPoint parentPos = parent->pos(); |
| 12 | setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400); |
| 13 | setWindowTitle("Debug: Disassembly View"); |
| 14 | |
| 15 | // |
| 16 | // The main frame and its input and log widgets |
| 17 | // |
| 18 | QFrame* mainWindowFrame = new QFrame(this); |
| 19 | |
| 20 | // The top frame & groupbox that contains the input widgets |
| 21 | QFrame* topSubFrame = new QFrame(mainWindowFrame); |
| 22 | |
| 23 | // The input edit |
| 24 | m_inputEdit = new QLineEdit(topSubFrame); |
| 25 | connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(expressionSubmitted())); |
| 26 | |
| 27 | // The cpu combo box |
| 28 | m_cpuComboBox = new QComboBox(topSubFrame); |
| 29 | m_cpuComboBox->setMinimumWidth(300); |
| 30 | connect(m_cpuComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(cpuChanged(int))); |
| 31 | |
| 32 | // The main disasm window |
| 33 | m_dasmView = new DebuggerView(DVT_DISASSEMBLY, |
| 34 | m_machine, |
| 35 | this); |
| 36 | |
| 37 | // Force a recompute of the disassembly region |
| 38 | downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc"); |
| 39 | |
| 40 | // Populate the combo box & set the proper cpu |
| 41 | populateComboBox(); |
| 42 | //const debug_view_source *source = mem->views[0]->view->source_list().match_device(curcpu); |
| 43 | //gtk_combo_box_set_active(zone_w, mem->views[0]->view->source_list().index(*source)); |
| 44 | //mem->views[0]->view->set_source(*source); |
| 45 | |
| 46 | |
| 47 | // Layout |
| 48 | QHBoxLayout* subLayout = new QHBoxLayout(topSubFrame); |
| 49 | subLayout->addWidget(m_inputEdit); |
| 50 | subLayout->addWidget(m_cpuComboBox); |
| 51 | subLayout->setSpacing(3); |
| 52 | subLayout->setContentsMargins(2,2,2,2); |
| 53 | |
| 54 | QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); |
| 55 | vLayout->setSpacing(3); |
| 56 | vLayout->setContentsMargins(2,2,2,2); |
| 57 | vLayout->addWidget(topSubFrame); |
| 58 | vLayout->addWidget(m_dasmView); |
| 59 | |
| 60 | setCentralWidget(mainWindowFrame); |
| 61 | |
| 62 | // |
| 63 | // Menu bars |
| 64 | // |
| 65 | // Create two commands |
| 66 | QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); |
| 67 | QAction* runToCursorAct = new QAction("Run To Cursor", this); |
| 68 | breakpointSetAct->setShortcut(Qt::Key_F9); |
| 69 | runToCursorAct->setShortcut(Qt::Key_F4); |
| 70 | connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); |
| 71 | connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); |
| 72 | |
| 73 | // Right bar options |
| 74 | QActionGroup* rightBarGroup = new QActionGroup(this); |
| 75 | QAction* rightActRaw = new QAction("Raw Opcodes", this); |
| 76 | QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); |
| 77 | QAction* rightActComments = new QAction("Comments", this); |
| 78 | rightActRaw->setCheckable(true); |
| 79 | rightActEncrypted->setCheckable(true); |
| 80 | rightActComments->setCheckable(true); |
| 81 | rightActRaw->setActionGroup(rightBarGroup); |
| 82 | rightActEncrypted->setActionGroup(rightBarGroup); |
| 83 | rightActComments->setActionGroup(rightBarGroup); |
| 84 | rightActRaw->setShortcut(QKeySequence("Ctrl+R")); |
| 85 | rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); |
| 86 | rightActComments->setShortcut(QKeySequence("Ctrl+C")); |
| 87 | rightActRaw->setChecked(true); |
| 88 | connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); |
| 89 | |
| 90 | // Assemble the options menu |
| 91 | QMenu* optionsMenu = menuBar()->addMenu("&Options"); |
| 92 | optionsMenu->addAction(breakpointSetAct); |
| 93 | optionsMenu->addAction(runToCursorAct); |
| 94 | optionsMenu->addSeparator(); |
| 95 | optionsMenu->addActions(rightBarGroup->actions()); |
| 96 | } |
| 97 | |
| 98 | |
| 99 | void DasmWindow::cpuChanged(int index) |
| 100 | { |
| 101 | m_dasmView->view()->set_source(*m_dasmView->view()->source_list().by_index(index)); |
| 102 | m_dasmView->viewport()->update(); |
| 103 | } |
| 104 | |
| 105 | |
| 106 | void DasmWindow::expressionSubmitted() |
| 107 | { |
| 108 | const QString expression = m_inputEdit->text(); |
| 109 | downcast<debug_view_disasm*>(m_dasmView->view())->set_expression(expression.toLocal8Bit().data()); |
| 110 | m_dasmView->viewport()->update(); |
| 111 | } |
| 112 | |
| 113 | |
| 114 | void DasmWindow::toggleBreakpointAtCursor(bool changedTo) |
| 115 | { |
| 116 | if (m_dasmView->view()->cursor_visible()) |
| 117 | { |
| 118 | if (debug_cpu_get_visible_cpu(*m_machine) == m_dasmView->view()->source()->device()) |
| 119 | { |
| 120 | offs_t address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address(); |
| 121 | device_debug *cpuinfo = m_dasmView->view()->source()->device()->debug(); |
| 122 | |
| 123 | // Find an existing breakpoint at this address |
| 124 | INT32 bpindex = -1; |
| 125 | for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); |
| 126 | bp != NULL; |
| 127 | bp = bp->next()) |
| 128 | { |
| 129 | if (address == bp->address()) |
| 130 | { |
| 131 | bpindex = bp->index(); |
| 132 | break; |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | // If none exists, add a new one |
| 137 | astring command; |
| 138 | if (bpindex == -1) |
| 139 | { |
| 140 | command.printf("bpset 0x%X", address); |
| 141 | } |
| 142 | else |
| 143 | { |
| 144 | command.printf("bpclear 0x%X", bpindex); |
| 145 | } |
| 146 | debug_console_execute_command(*m_machine, command, 1); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | refreshAll(); |
| 151 | } |
| 152 | |
| 153 | |
| 154 | void DasmWindow::runToCursor(bool changedTo) |
| 155 | { |
| 156 | if (m_dasmView->view()->cursor_visible()) |
| 157 | { |
| 158 | if (debug_cpu_get_visible_cpu(*m_machine) == m_dasmView->view()->source()->device()) |
| 159 | { |
| 160 | offs_t address = downcast<debug_view_disasm*>(m_dasmView->view())->selected_address(); |
| 161 | astring command; |
| 162 | command.printf("go 0x%X", address); |
| 163 | debug_console_execute_command(*m_machine, command, 1); |
| 164 | } |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | |
| 169 | void DasmWindow::rightBarChanged(QAction* changedTo) |
| 170 | { |
| 171 | debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmView->view()); |
| 172 | if (changedTo->text() == "Raw Opcodes") |
| 173 | { |
| 174 | dasmView->set_right_column(DASM_RIGHTCOL_RAW); |
| 175 | } |
| 176 | else if (changedTo->text() == "Encrypted Opcodes") |
| 177 | { |
| 178 | dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED); |
| 179 | } |
| 180 | else if (changedTo->text() == "Comments") |
| 181 | { |
| 182 | dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS); |
| 183 | } |
| 184 | m_dasmView->viewport()->update(); |
| 185 | } |
| 186 | |
| 187 | |
| 188 | void DasmWindow::populateComboBox() |
| 189 | { |
| 190 | if (m_dasmView == NULL) |
| 191 | return; |
| 192 | |
| 193 | m_cpuComboBox->clear(); |
| 194 | for (const debug_view_source* source = m_dasmView->view()->source_list().head(); |
| 195 | source != NULL; |
| 196 | source = source->next()) |
| 197 | { |
| 198 | m_cpuComboBox->addItem(source->name()); |
| 199 | } |
| 200 | } |
trunk/src/osd/sdl/sdl.mak
| r19796 | r19797 | |
| 76 | 76 | # (currently defaults disabled due to causing issues with mouse capture, esp. in MESS) |
| 77 | 77 | NO_USE_XINPUT = 1 |
| 78 | 78 | |
| 79 | # uncomment to try the experimental new Qt debugger (Linux only for now) |
| 80 | #USE_QTDEBUG = 1 |
| 79 | 81 | |
| 80 | 82 | ########################################################################### |
| 81 | 83 | ################## END USER-CONFIGURABLE OPTIONS ###################### |
| r19796 | r19797 | |
| 227 | 229 | ifeq ($(TARGETOS),macosx) |
| 228 | 230 | BASE_TARGETOS = unix |
| 229 | 231 | DEFS += -DSDLMAME_UNIX -DSDLMAME_MACOSX -DSDLMAME_DARWIN |
| 232 | |
| 233 | ifndef USE_QTDEBUG |
| 230 | 234 | DEBUGOBJS = $(SDLOBJ)/debugosx.o |
| 235 | endif |
| 231 | 236 | SYNC_IMPLEMENTATION = ntc |
| 232 | 237 | SDLMAIN = $(SDLOBJ)/SDLMain_tmpl.o |
| 233 | 238 | SDLUTILMAIN = $(SDLOBJ)/SDLMain_tmpl.o |
| r19796 | r19797 | |
| 275 | 280 | ifndef GTK_INSTALL_ROOT |
| 276 | 281 | NO_DEBUGGER = 1 |
| 277 | 282 | else |
| 283 | ifndef QT_USEDEBUG |
| 278 | 284 | DEBUGOBJS = $(SDLOBJ)/debugwin.o $(SDLOBJ)/dview.o $(SDLOBJ)/debug-sup.o $(SDLOBJ)/debug-intf.o |
| 279 | 285 | LIBS += -lgtk-win32-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lglib-2.0 -lgobject-2.0 \ |
| 280 | 286 | -lpango-1.0 -latk-1.0 -lgdk_pixbuf-2.0 |
| r19796 | r19797 | |
| 284 | 290 | -I$(GTK_INSTALL_ROOT)/include/atk-1.0 \ |
| 285 | 291 | -I$(GTK_INSTALL_ROOT)/lib/glib-2.0/include -I$(GTK_INSTALL_ROOT)/lib/gtk-2.0/include |
| 286 | 292 | LDFLAGS += -L$(GTK_INSTALL_ROOT)/lib |
| 293 | endif |
| 287 | 294 | endif # GTK_INSTALL_ROOT |
| 288 | 295 | |
| 289 | 296 | # enable UNICODE |
| 290 | 297 | DEFS += -Dmain=utf8_main -DUNICODE -D_UNICODE |
| 291 | 298 | LDFLAGS += -municode |
| 292 | 299 | |
| 300 | # Qt |
| 301 | ifdef QT_USEDEBUG |
| 302 | QT_INSTALL_HEADERS = $(shell qmake -query QT_INSTALL_HEADERS) |
| 303 | INCPATH += -I$(QT_INSTALL_HEADERS)/QtCore -I$(QT_INSTALL_HEADERS)/QtGui -I$(QT_INSTALL_HEADERS) |
| 304 | QT_LIBS += -L$(shell qmake -query QT_INSTALL_LIBS) -lqtmain -lQtGui -lQtCore -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lmsimg32 -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32 -mwindows |
| 293 | 305 | endif |
| 294 | 306 | |
| 307 | endif |
| 308 | |
| 295 | 309 | ifeq ($(TARGETOS),os2) |
| 296 | 310 | BASE_TARGETOS = os2 |
| 297 | 311 | DEFS += -DSDLMAME_OS2 |
| r19796 | r19797 | |
| 366 | 380 | # add the debugger includes |
| 367 | 381 | INCPATH += -Isrc/debug |
| 368 | 382 | |
| 383 | # copy off the include paths before the sdlprefix & sdl-config stuff shows up |
| 384 | MOCINCPATH := $(INCPATH) |
| 385 | |
| 369 | 386 | # add the prefix file |
| 370 | 387 | INCPATH += -include $(SDLSRC)/sdlprefix.h |
| 388 | INCPATH += -I/work/src/m/sdl |
| 389 | MOCINCPATH += -I/work/src/m/sdl |
| 371 | 390 | |
| 391 | |
| 372 | 392 | #------------------------------------------------- |
| 373 | 393 | # BASE_TARGETOS specific configurations |
| 374 | 394 | #------------------------------------------------- |
| r19796 | r19797 | |
| 398 | 418 | OSDCOREOBJS += $(SDLOBJ)/osxutils.o |
| 399 | 419 | SDLOS_TARGETOS = macosx |
| 400 | 420 | |
| 421 | ifdef USE_QTDEBUG |
| 422 | MOC = @moc |
| 423 | $(SDLOBJ)/%.moc.c: $(SDLSRC)/%.h |
| 424 | $(MOC) $(MOCINCPATH) $(DEFS) $< -o $@ |
| 425 | |
| 426 | DEBUGOBJS = \ |
| 427 | $(SDLOBJ)/debugqt.o \ |
| 428 | $(SDLOBJ)/debugqtview.o \ |
| 429 | $(SDLOBJ)/debugqtwindow.o \ |
| 430 | $(SDLOBJ)/debugqtlogwindow.o \ |
| 431 | $(SDLOBJ)/debugqtdasmwindow.o \ |
| 432 | $(SDLOBJ)/debugqtmainwindow.o \ |
| 433 | $(SDLOBJ)/debugqtmemorywindow.o \ |
| 434 | $(SDLOBJ)/debugqtwindow.moc.o \ |
| 435 | $(SDLOBJ)/debugqtlogwindow.moc.o \ |
| 436 | $(SDLOBJ)/debugqtdasmwindow.moc.o \ |
| 437 | $(SDLOBJ)/debugqtmainwindow.moc.o \ |
| 438 | $(SDLOBJ)/debugqtmemorywindow.moc.o |
| 439 | |
| 440 | LIBS += -framework QtCore -framework QtGui |
| 441 | endif |
| 442 | |
| 401 | 443 | ifndef MACOSX_USE_LIBSDL |
| 402 | 444 | # Compile using framework (compile using libSDL is the exception) |
| 403 | 445 | LIBS += -framework SDL -framework Cocoa -framework OpenGL -lpthread |
| r19796 | r19797 | |
| 417 | 459 | else # ifeq ($(TARGETOS),macosx) |
| 418 | 460 | |
| 419 | 461 | DEFS += -DSDLMAME_UNIX |
| 420 | | DEBUGOBJS = $(SDLOBJ)/debugwin.o $(SDLOBJ)/dview.o $(SDLOBJ)/debug-sup.o $(SDLOBJ)/debug-intf.o |
| 462 | |
| 463 | ifdef USE_QTDEBUG |
| 464 | MOC = @moc-qt4 |
| 465 | $(SDLOBJ)/%.moc.c: $(SDLSRC)/%.h |
| 466 | $(MOC) $(MOCINCPATH) $(DEFS) $< -o $@ |
| 467 | |
| 468 | DEBUGOBJS = \ |
| 469 | $(SDLOBJ)/debugqt.o \ |
| 470 | $(SDLOBJ)/debugqtview.o \ |
| 471 | $(SDLOBJ)/debugqtwindow.o \ |
| 472 | $(SDLOBJ)/debugqtlogwindow.o \ |
| 473 | $(SDLOBJ)/debugqtdasmwindow.o \ |
| 474 | $(SDLOBJ)/debugqtmainwindow.o \ |
| 475 | $(SDLOBJ)/debugqtmemorywindow.o \ |
| 476 | $(SDLOBJ)/debugqtwindow.moc.o \ |
| 477 | $(SDLOBJ)/debugqtlogwindow.moc.o \ |
| 478 | $(SDLOBJ)/debugqtdasmwindow.moc.o \ |
| 479 | $(SDLOBJ)/debugqtmainwindow.moc.o \ |
| 480 | $(SDLOBJ)/debugqtmemorywindow.moc.o |
| 481 | endif |
| 482 | |
| 421 | 483 | LIBGL = -lGL |
| 484 | |
| 422 | 485 | ifeq ($(NO_X11),1) |
| 423 | 486 | NO_DEBUGGER = 1 |
| 424 | 487 | endif |
| r19796 | r19797 | |
| 573 | 636 | LIBS += `pkg-config --libs gtk+-2.0` `pkg-config --libs gconf-2.0` |
| 574 | 637 | #CCOMFLAGS += -DGTK_DISABLE_DEPRECATED |
| 575 | 638 | |
| 639 | # The newer debugger uses QT |
| 640 | ifdef USE_QTDEBUG |
| 641 | INCPATH += `pkg-config QtGui --cflags` |
| 642 | LIBS += `pkg-config QtGui --libs` |
| 643 | endif |
| 644 | |
| 576 | 645 | # some systems still put important things in a different prefix |
| 577 | 646 | LIBS += -L/usr/X11/lib -L/usr/X11R6/lib -L/usr/openwin/lib |
| 578 | 647 | # make sure we can find X headers |
| r19796 | r19797 | |
| 647 | 716 | |
| 648 | 717 | $(LIBOSD): $(OSDOBJS) |
| 649 | 718 | |
| 719 | |
| 650 | 720 | #------------------------------------------------- |
| 651 | 721 | # Tools |
| 652 | 722 | #------------------------------------------------- |
trunk/src/osd/sdl/debugqtmemorywindow.c
| r0 | r19797 | |
| 1 | #include "debugqtmemorywindow.h" |
| 2 | |
| 3 | #include "debug/dvmemory.h" |
| 4 | #include "debug/debugvw.h" |
| 5 | #include "debug/debugcon.h" |
| 6 | #include "debug/debugcpu.h" |
| 7 | |
| 8 | |
| 9 | MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) : |
| 10 | WindowQt(machine, parent) |
| 11 | { |
| 12 | QPoint parentPos = parent->pos(); |
| 13 | setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400); |
| 14 | setWindowTitle("Debug: Memory View"); |
| 15 | |
| 16 | // |
| 17 | // The main frame and its input and log widgets |
| 18 | // |
| 19 | QFrame* mainWindowFrame = new QFrame(this); |
| 20 | |
| 21 | // The top frame & groupbox that contains the input widgets |
| 22 | QFrame* topSubFrame = new QFrame(mainWindowFrame); |
| 23 | |
| 24 | // The input edit |
| 25 | m_inputEdit = new QLineEdit(topSubFrame); |
| 26 | connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(expressionSubmitted())); |
| 27 | |
| 28 | // The memory space combo box |
| 29 | m_memoryComboBox = new QComboBox(topSubFrame); |
| 30 | m_memoryComboBox->setMinimumWidth(300); |
| 31 | connect(m_memoryComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(memoryRegionChanged(int))); |
| 32 | |
| 33 | // The main memory window |
| 34 | m_memTable = new DebuggerView(DVT_MEMORY, |
| 35 | m_machine, |
| 36 | this); |
| 37 | |
| 38 | // Populate the combo box |
| 39 | populateComboBox(); |
| 40 | |
| 41 | |
| 42 | // Layout |
| 43 | QHBoxLayout* subLayout = new QHBoxLayout(topSubFrame); |
| 44 | subLayout->addWidget(m_inputEdit); |
| 45 | subLayout->addWidget(m_memoryComboBox); |
| 46 | subLayout->setSpacing(3); |
| 47 | subLayout->setContentsMargins(2,2,2,2); |
| 48 | |
| 49 | QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); |
| 50 | vLayout->setSpacing(3); |
| 51 | vLayout->setContentsMargins(2,2,2,2); |
| 52 | vLayout->addWidget(topSubFrame); |
| 53 | vLayout->addWidget(m_memTable); |
| 54 | |
| 55 | setCentralWidget(mainWindowFrame); |
| 56 | |
| 57 | // |
| 58 | // Menu bars |
| 59 | // |
| 60 | // Create a byte-chunk group |
| 61 | QActionGroup* chunkGroup = new QActionGroup(this); |
| 62 | QAction* chunkActOne = new QAction("1-byte chunks", this); |
| 63 | QAction* chunkActTwo = new QAction("2-byte chunks", this); |
| 64 | QAction* chunkActFour = new QAction("4-byte chunks", this); |
| 65 | chunkActOne->setCheckable(true); |
| 66 | chunkActTwo->setCheckable(true); |
| 67 | chunkActFour->setCheckable(true); |
| 68 | chunkActOne->setActionGroup(chunkGroup); |
| 69 | chunkActTwo->setActionGroup(chunkGroup); |
| 70 | chunkActFour->setActionGroup(chunkGroup); |
| 71 | chunkActOne->setShortcut(QKeySequence("Ctrl+1")); |
| 72 | chunkActTwo->setShortcut(QKeySequence("Ctrl+2")); |
| 73 | chunkActFour->setShortcut(QKeySequence("Ctrl+4")); |
| 74 | chunkActOne->setChecked(true); |
| 75 | connect(chunkGroup, SIGNAL(triggered(QAction*)), this, SLOT(chunkChanged(QAction*))); |
| 76 | |
| 77 | // Create a address display group |
| 78 | QActionGroup* addressGroup = new QActionGroup(this); |
| 79 | QAction* addressActLogical = new QAction("Logical Addresses", this); |
| 80 | QAction* addressActPhysical = new QAction("Physical Addresses", this); |
| 81 | addressActLogical->setCheckable(true); |
| 82 | addressActPhysical->setCheckable(true); |
| 83 | addressActLogical->setActionGroup(addressGroup); |
| 84 | addressActPhysical->setActionGroup(addressGroup); |
| 85 | addressActLogical->setShortcut(QKeySequence("Ctrl+G")); |
| 86 | addressActPhysical->setShortcut(QKeySequence("Ctrl+Y")); |
| 87 | addressActLogical->setChecked(true); |
| 88 | connect(addressGroup, SIGNAL(triggered(QAction*)), this, SLOT(addressChanged(QAction*))); |
| 89 | |
| 90 | // Create a reverse view radio |
| 91 | QAction* reverseAct = new QAction("Reverse View", this); |
| 92 | reverseAct->setCheckable(true); |
| 93 | reverseAct->setShortcut(QKeySequence("Ctrl+R")); |
| 94 | connect(reverseAct, SIGNAL(toggled(bool)), this, SLOT(reverseChanged(bool))); |
| 95 | |
| 96 | // Create increase and decrease bytes-per-line actions |
| 97 | QAction* increaseBplAct = new QAction("Increase Bytes Per Line", this); |
| 98 | QAction* decreaseBplAct = new QAction("Decrease Bytes Per Line", this); |
| 99 | increaseBplAct->setShortcut(QKeySequence("Ctrl+P")); |
| 100 | decreaseBplAct->setShortcut(QKeySequence("Ctrl+O")); |
| 101 | connect(increaseBplAct, SIGNAL(triggered(bool)), this, SLOT(increaseBytesPerLine(bool))); |
| 102 | connect(decreaseBplAct, SIGNAL(triggered(bool)), this, SLOT(decreaseBytesPerLine(bool))); |
| 103 | |
| 104 | // Assemble the options menu |
| 105 | QMenu* optionsMenu = menuBar()->addMenu("&Options"); |
| 106 | optionsMenu->addActions(chunkGroup->actions()); |
| 107 | optionsMenu->addSeparator(); |
| 108 | optionsMenu->addActions(addressGroup->actions()); |
| 109 | optionsMenu->addSeparator(); |
| 110 | optionsMenu->addAction(reverseAct); |
| 111 | optionsMenu->addSeparator(); |
| 112 | optionsMenu->addAction(increaseBplAct); |
| 113 | optionsMenu->addAction(decreaseBplAct); |
| 114 | } |
| 115 | |
| 116 | |
| 117 | void MemoryWindow::memoryRegionChanged(int index) |
| 118 | { |
| 119 | m_memTable->view()->set_source(*m_memTable->view()->source_list().by_index(index)); |
| 120 | m_memTable->viewport()->update(); |
| 121 | } |
| 122 | |
| 123 | |
| 124 | void MemoryWindow::expressionSubmitted() |
| 125 | { |
| 126 | const QString expression = m_inputEdit->text(); |
| 127 | downcast<debug_view_memory*>(m_memTable->view())->set_expression(expression.toLocal8Bit().data()); |
| 128 | |
| 129 | // Make the cursor pop |
| 130 | m_memTable->view()->set_cursor_visible(true); |
| 131 | |
| 132 | // Check where the cursor is and adjust the scroll accordingly |
| 133 | debug_view_xy cursorPosition = m_memTable->view()->cursor_position(); |
| 134 | // TODO: check if the region is already visible? |
| 135 | m_memTable->verticalScrollBar()->setValue(cursorPosition.y); |
| 136 | |
| 137 | m_memTable->update(); |
| 138 | m_memTable->viewport()->update(); |
| 139 | } |
| 140 | |
| 141 | |
| 142 | void MemoryWindow::chunkChanged(QAction* changedTo) |
| 143 | { |
| 144 | debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view()); |
| 145 | if (changedTo->text() == "1-byte chunks") |
| 146 | { |
| 147 | memView->set_bytes_per_chunk(1); |
| 148 | } |
| 149 | else if (changedTo->text() == "2-byte chunks") |
| 150 | { |
| 151 | memView->set_bytes_per_chunk(2); |
| 152 | } |
| 153 | else if (changedTo->text() == "4-byte chunks") |
| 154 | { |
| 155 | memView->set_bytes_per_chunk(4); |
| 156 | } |
| 157 | m_memTable->viewport()->update(); |
| 158 | } |
| 159 | |
| 160 | |
| 161 | void MemoryWindow::addressChanged(QAction* changedTo) |
| 162 | { |
| 163 | debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view()); |
| 164 | if (changedTo->text() == "Logical Addresses") |
| 165 | { |
| 166 | memView->set_physical(false); |
| 167 | } |
| 168 | else if (changedTo->text() == "Physical Addresses") |
| 169 | { |
| 170 | memView->set_physical(true); |
| 171 | } |
| 172 | m_memTable->viewport()->update(); |
| 173 | } |
| 174 | |
| 175 | |
| 176 | void MemoryWindow::reverseChanged(bool changedTo) |
| 177 | { |
| 178 | debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view()); |
| 179 | memView->set_reverse(changedTo); |
| 180 | m_memTable->viewport()->update(); |
| 181 | } |
| 182 | |
| 183 | |
| 184 | void MemoryWindow::increaseBytesPerLine(bool changedTo) |
| 185 | { |
| 186 | debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view()); |
| 187 | memView->set_chunks_per_row(memView->chunks_per_row() + 1); |
| 188 | m_memTable->viewport()->update(); |
| 189 | } |
| 190 | |
| 191 | |
| 192 | void MemoryWindow::decreaseBytesPerLine(bool checked) |
| 193 | { |
| 194 | debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view()); |
| 195 | memView->set_chunks_per_row(memView->chunks_per_row() - 1); |
| 196 | m_memTable->viewport()->update(); |
| 197 | } |
| 198 | |
| 199 | |
| 200 | void MemoryWindow::populateComboBox() |
| 201 | { |
| 202 | if (m_memTable == NULL) |
| 203 | return; |
| 204 | |
| 205 | m_memoryComboBox->clear(); |
| 206 | for (const debug_view_source* source = m_memTable->view()->source_list().head(); |
| 207 | source != NULL; |
| 208 | source = source->next()) |
| 209 | { |
| 210 | m_memoryComboBox->addItem(source->name()); |
| 211 | } |
| 212 | |
| 213 | // TODO: Set to the proper memory view |
| 214 | //const debug_view_source *source = mem->views[0]->view->source_list().match_device(curcpu); |
| 215 | //gtk_combo_box_set_active(zone_w, mem->views[0]->view->source_list().index(*source)); |
| 216 | //mem->views[0]->view->set_source(*source); |
| 217 | } |
trunk/src/osd/sdl/debugqtmainwindow.c
| r0 | r19797 | |
| 1 | #include "debugqtmainwindow.h" |
| 2 | #include "debug/debugcon.h" |
| 3 | #include "debug/debugcpu.h" |
| 4 | #include "debug/dvdisasm.h" |
| 5 | |
| 6 | |
| 7 | MainWindow::MainWindow(device_t* processor, |
| 8 | running_machine* machine, |
| 9 | QWidget* parent) : |
| 10 | WindowQt(machine, parent), |
| 11 | m_historyIndex(0), |
| 12 | m_inputHistory() |
| 13 | { |
| 14 | setGeometry(300, 300, 1000, 600); |
| 15 | |
| 16 | // |
| 17 | // The main frame and its input and log widgets |
| 18 | // |
| 19 | QFrame* mainWindowFrame = new QFrame(this); |
| 20 | |
| 21 | // The input line |
| 22 | m_inputEdit = new QLineEdit(mainWindowFrame); |
| 23 | connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); |
| 24 | m_inputEdit->installEventFilter(this); |
| 25 | |
| 26 | |
| 27 | // The log view |
| 28 | m_consoleView = new DebuggerView(DVT_CONSOLE, |
| 29 | m_machine, |
| 30 | mainWindowFrame); |
| 31 | m_consoleView->setFocusPolicy(Qt::NoFocus); |
| 32 | m_consoleView->setPreferBottom(true); |
| 33 | |
| 34 | QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); |
| 35 | vLayout->addWidget(m_consoleView); |
| 36 | vLayout->addWidget(m_inputEdit); |
| 37 | vLayout->setSpacing(3); |
| 38 | vLayout->setContentsMargins(4,0,4,2); |
| 39 | |
| 40 | setCentralWidget(mainWindowFrame); |
| 41 | |
| 42 | // |
| 43 | // Menu bars |
| 44 | // |
| 45 | // Create two commands |
| 46 | QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); |
| 47 | QAction* runToCursorAct = new QAction("Run To Cursor", this); |
| 48 | breakpointSetAct->setShortcut(Qt::Key_F9); |
| 49 | runToCursorAct->setShortcut(Qt::Key_F4); |
| 50 | connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); |
| 51 | connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); |
| 52 | |
| 53 | // Right bar options |
| 54 | QActionGroup* rightBarGroup = new QActionGroup(this); |
| 55 | QAction* rightActRaw = new QAction("Raw Opcodes", this); |
| 56 | QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); |
| 57 | QAction* rightActComments = new QAction("Comments", this); |
| 58 | rightActRaw->setCheckable(true); |
| 59 | rightActEncrypted->setCheckable(true); |
| 60 | rightActComments->setCheckable(true); |
| 61 | rightActRaw->setActionGroup(rightBarGroup); |
| 62 | rightActEncrypted->setActionGroup(rightBarGroup); |
| 63 | rightActComments->setActionGroup(rightBarGroup); |
| 64 | rightActRaw->setShortcut(QKeySequence("Ctrl+R")); |
| 65 | rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); |
| 66 | rightActComments->setShortcut(QKeySequence("Ctrl+C")); |
| 67 | rightActRaw->setChecked(true); |
| 68 | connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); |
| 69 | |
| 70 | // Assemble the options menu |
| 71 | QMenu* optionsMenu = menuBar()->addMenu("&Options"); |
| 72 | optionsMenu->addAction(breakpointSetAct); |
| 73 | optionsMenu->addAction(runToCursorAct); |
| 74 | optionsMenu->addSeparator(); |
| 75 | optionsMenu->addActions(rightBarGroup->actions()); |
| 76 | |
| 77 | |
| 78 | // |
| 79 | // Dock windows |
| 80 | // |
| 81 | QMenu* dockMenu = menuBar()->addMenu("Doc&ks"); |
| 82 | |
| 83 | setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); |
| 84 | setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); |
| 85 | |
| 86 | // The processor dock |
| 87 | QDockWidget* cpuDock = new QDockWidget("processor", this); |
| 88 | cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea); |
| 89 | m_procFrame = new ProcessorDockWidget(m_machine, cpuDock); |
| 90 | cpuDock->setWidget(dynamic_cast<QWidget*>(m_procFrame)); |
| 91 | |
| 92 | addDockWidget(Qt::LeftDockWidgetArea, cpuDock); |
| 93 | dockMenu->addAction(cpuDock->toggleViewAction()); |
| 94 | |
| 95 | // The disassembly dock |
| 96 | QDockWidget* dasmDock = new QDockWidget("dasm", this); |
| 97 | dasmDock->setAllowedAreas(Qt::TopDockWidgetArea); |
| 98 | m_dasmFrame = new DasmDockWidget(m_machine, dasmDock); |
| 99 | dasmDock->setWidget(m_dasmFrame); |
| 100 | |
| 101 | addDockWidget(Qt::TopDockWidgetArea, dasmDock); |
| 102 | dockMenu->addAction(dasmDock->toggleViewAction()); |
| 103 | |
| 104 | // Window title |
| 105 | astring title; |
| 106 | title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); |
| 107 | setWindowTitle(title.cstr()); |
| 108 | } |
| 109 | |
| 110 | |
| 111 | void MainWindow::setProcessor(device_t* processor) |
| 112 | { |
| 113 | // Cpu swap |
| 114 | m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_list().match_device(processor)); |
| 115 | m_dasmFrame->view()->view()->set_source(*m_dasmFrame->view()->view()->source_list().match_device(processor)); |
| 116 | |
| 117 | // Scrollbar refresh - seems I should be able to do in the DebuggerView |
| 118 | m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); |
| 119 | m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); |
| 120 | |
| 121 | // Window title |
| 122 | astring title; |
| 123 | title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); |
| 124 | setWindowTitle(title.cstr()); |
| 125 | } |
| 126 | |
| 127 | |
| 128 | // Used to intercept the user clicking 'X' in the upper corner |
| 129 | void MainWindow::closeEvent(QCloseEvent* event) |
| 130 | { |
| 131 | debugActQuit(); |
| 132 | } |
| 133 | |
| 134 | |
| 135 | // Used to intercept the user hitting the up arrow in the input widget |
| 136 | bool MainWindow::eventFilter(QObject* obj, QEvent* event) |
| 137 | { |
| 138 | // Only filter keypresses |
| 139 | QKeyEvent* keyEvent = NULL; |
| 140 | if (event->type() == QEvent::KeyPress) |
| 141 | { |
| 142 | keyEvent = static_cast<QKeyEvent*>(event); |
| 143 | } |
| 144 | else |
| 145 | { |
| 146 | return QObject::eventFilter(obj, event); |
| 147 | } |
| 148 | |
| 149 | // Catch up & down keys |
| 150 | if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) |
| 151 | { |
| 152 | if (keyEvent->key() == Qt::Key_Up) |
| 153 | { |
| 154 | if (m_historyIndex > 0) |
| 155 | m_historyIndex--; |
| 156 | } |
| 157 | else if (keyEvent->key() == Qt::Key_Down) |
| 158 | { |
| 159 | if (m_historyIndex < m_inputHistory.size()) |
| 160 | m_historyIndex++; |
| 161 | } |
| 162 | |
| 163 | // Populate the input edit or clear it if you're at the end |
| 164 | if (m_historyIndex == m_inputHistory.size()) |
| 165 | { |
| 166 | m_inputEdit->setText(""); |
| 167 | } |
| 168 | else |
| 169 | { |
| 170 | m_inputEdit->setText(m_inputHistory[m_historyIndex]); |
| 171 | } |
| 172 | } |
| 173 | else if (keyEvent->key() == Qt::Key_Enter) |
| 174 | { |
| 175 | executeCommand(false); |
| 176 | } |
| 177 | else |
| 178 | { |
| 179 | return QObject::eventFilter(obj, event); |
| 180 | } |
| 181 | |
| 182 | return true; |
| 183 | } |
| 184 | |
| 185 | |
| 186 | void MainWindow::toggleBreakpointAtCursor(bool changedTo) |
| 187 | { |
| 188 | debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); |
| 189 | if (dasmView->cursor_visible()) |
| 190 | { |
| 191 | if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) |
| 192 | { |
| 193 | offs_t address = downcast<debug_view_disasm *>(dasmView)->selected_address(); |
| 194 | device_debug *cpuinfo = dasmView->source()->device()->debug(); |
| 195 | |
| 196 | // Find an existing breakpoint at this address |
| 197 | INT32 bpindex = -1; |
| 198 | for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); |
| 199 | bp != NULL; |
| 200 | bp = bp->next()) |
| 201 | { |
| 202 | if (address == bp->address()) |
| 203 | { |
| 204 | bpindex = bp->index(); |
| 205 | break; |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | // If none exists, add a new one |
| 210 | astring command; |
| 211 | if (bpindex == -1) |
| 212 | { |
| 213 | command.printf("bpset 0x%X", address); |
| 214 | } |
| 215 | else |
| 216 | { |
| 217 | command.printf("bpclear 0x%X", bpindex); |
| 218 | } |
| 219 | debug_console_execute_command(*m_machine, command, 1); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | refreshAll(); |
| 224 | } |
| 225 | |
| 226 | |
| 227 | void MainWindow::runToCursor(bool changedTo) |
| 228 | { |
| 229 | debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); |
| 230 | if (dasmView->cursor_visible()) |
| 231 | { |
| 232 | if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) |
| 233 | { |
| 234 | offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address(); |
| 235 | astring command; |
| 236 | command.printf("go 0x%X", address); |
| 237 | debug_console_execute_command(*m_machine, command, 1); |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | |
| 243 | void MainWindow::rightBarChanged(QAction* changedTo) |
| 244 | { |
| 245 | debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); |
| 246 | if (changedTo->text() == "Raw Opcodes") |
| 247 | { |
| 248 | dasmView->set_right_column(DASM_RIGHTCOL_RAW); |
| 249 | } |
| 250 | else if (changedTo->text() == "Encrypted Opcodes") |
| 251 | { |
| 252 | dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED); |
| 253 | } |
| 254 | else if (changedTo->text() == "Comments") |
| 255 | { |
| 256 | dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS); |
| 257 | } |
| 258 | m_dasmFrame->view()->viewport()->update(); |
| 259 | } |
| 260 | |
| 261 | |
| 262 | void MainWindow::executeCommand(bool withClear) |
| 263 | { |
| 264 | debug_console_execute_command(*m_machine, |
| 265 | m_inputEdit->text().toLocal8Bit().data(), |
| 266 | true); |
| 267 | |
| 268 | // Add history & set the index to be the top of the stack |
| 269 | addToHistory(m_inputEdit->text()); |
| 270 | |
| 271 | // Clear out the text and reset the history pointer only if asked |
| 272 | if (withClear) |
| 273 | { |
| 274 | m_inputEdit->clear(); |
| 275 | m_historyIndex = m_inputHistory.size(); |
| 276 | } |
| 277 | |
| 278 | // Refresh |
| 279 | m_consoleView->viewport()->update(); |
| 280 | m_procFrame->view()->update(); |
| 281 | m_dasmFrame->view()->update(); |
| 282 | } |
| 283 | |
| 284 | |
| 285 | void MainWindow::addToHistory(const QString& command) |
| 286 | { |
| 287 | if (command == "") |
| 288 | return; |
| 289 | |
| 290 | // Always push back when there is no previous history |
| 291 | if (m_inputHistory.size() == 0) |
| 292 | { |
| 293 | m_inputHistory.push_back(m_inputEdit->text()); |
| 294 | return; |
| 295 | } |
| 296 | |
| 297 | // If there is previous history, make sure it's not what you just executed |
| 298 | if (m_inputHistory.back() != m_inputEdit->text()) |
| 299 | { |
| 300 | m_inputHistory.push_back(m_inputEdit->text()); |
| 301 | } |
| 302 | } |
trunk/src/osd/sdl/debugqtmainwindow.h
| r0 | r19797 | |
| 1 | #ifndef __DEBUG_QT_MAIN_WINDOW_H__ |
| 2 | #define __DEBUG_QT_MAIN_WINDOW_H__ |
| 3 | |
| 4 | #include <QtGui/QtGui> |
| 5 | #include <vector> |
| 6 | |
| 7 | #include "debug/dvdisasm.h" |
| 8 | |
| 9 | #include "debugqtview.h" |
| 10 | #include "debugqtwindow.h" |
| 11 | |
| 12 | class DasmDockWidget; |
| 13 | class ProcessorDockWidget; |
| 14 | |
| 15 | |
| 16 | //============================================================ |
| 17 | // The Main Window. Contains processor and dasm docks. |
| 18 | //============================================================ |
| 19 | class MainWindow : public WindowQt |
| 20 | { |
| 21 | Q_OBJECT |
| 22 | |
| 23 | public: |
| 24 | MainWindow(device_t* processor, |
| 25 | running_machine* machine, |
| 26 | QWidget* parent=NULL); |
| 27 | virtual ~MainWindow() {} |
| 28 | |
| 29 | void setProcessor(device_t* processor); |
| 30 | |
| 31 | |
| 32 | protected: |
| 33 | // Used to intercept the user clicking 'X' in the upper corner |
| 34 | void closeEvent(QCloseEvent* event); |
| 35 | |
| 36 | // Used to intercept the user hitting the up arrow in the input widget |
| 37 | bool eventFilter(QObject* obj, QEvent* event); |
| 38 | |
| 39 | |
| 40 | private slots: |
| 41 | void toggleBreakpointAtCursor(bool changedTo); |
| 42 | void runToCursor(bool changedTo); |
| 43 | void rightBarChanged(QAction* changedTo); |
| 44 | |
| 45 | void executeCommand(bool withClear=true); |
| 46 | |
| 47 | |
| 48 | private: |
| 49 | // Widgets and docks |
| 50 | QLineEdit* m_inputEdit; |
| 51 | DebuggerView* m_consoleView; |
| 52 | ProcessorDockWidget* m_procFrame; |
| 53 | DasmDockWidget* m_dasmFrame; |
| 54 | |
| 55 | // Terminal history |
| 56 | int m_historyIndex; |
| 57 | std::vector<QString> m_inputHistory; |
| 58 | void addToHistory(const QString& command); |
| 59 | }; |
| 60 | |
| 61 | |
| 62 | //============================================================ |
| 63 | // Docks with the Main Window. Disassembly. |
| 64 | //============================================================ |
| 65 | class DasmDockWidget : public QWidget |
| 66 | { |
| 67 | Q_OBJECT |
| 68 | |
| 69 | public: |
| 70 | DasmDockWidget(running_machine* machine, QWidget* parent=NULL) : |
| 71 | QWidget(parent), |
| 72 | m_machine(machine) |
| 73 | { |
| 74 | m_dasmView = new DebuggerView(DVT_DISASSEMBLY, |
| 75 | m_machine, |
| 76 | this); |
| 77 | |
| 78 | // Force a recompute of the disassembly region |
| 79 | downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc"); |
| 80 | |
| 81 | QVBoxLayout* dvLayout = new QVBoxLayout(this); |
| 82 | dvLayout->addWidget(m_dasmView); |
| 83 | dvLayout->setContentsMargins(4,0,4,0); |
| 84 | } |
| 85 | |
| 86 | |
| 87 | virtual ~DasmDockWidget() {} |
| 88 | |
| 89 | |
| 90 | DebuggerView* view() { return m_dasmView; } |
| 91 | |
| 92 | |
| 93 | QSize minimumSizeHint() const |
| 94 | { |
| 95 | return QSize(150,150); |
| 96 | } |
| 97 | |
| 98 | |
| 99 | QSize sizeHint() const |
| 100 | { |
| 101 | return QSize(150,200); |
| 102 | } |
| 103 | |
| 104 | |
| 105 | private: |
| 106 | DebuggerView* m_dasmView; |
| 107 | |
| 108 | running_machine* m_machine; |
| 109 | }; |
| 110 | |
| 111 | |
| 112 | //============================================================ |
| 113 | // Docks with the Main Window. Processor information. |
| 114 | //============================================================ |
| 115 | class ProcessorDockWidget : public QWidget |
| 116 | { |
| 117 | Q_OBJECT |
| 118 | |
| 119 | public: |
| 120 | ProcessorDockWidget(running_machine* machine, |
| 121 | QWidget* parent=NULL) : |
| 122 | QWidget(parent), |
| 123 | m_processorView(NULL), |
| 124 | m_machine(machine) |
| 125 | { |
| 126 | m_processorView = new DebuggerView(DVT_STATE, |
| 127 | m_machine, |
| 128 | this); |
| 129 | m_processorView->setFocusPolicy(Qt::NoFocus); |
| 130 | |
| 131 | QVBoxLayout* cvLayout = new QVBoxLayout(this); |
| 132 | cvLayout->addWidget(m_processorView); |
| 133 | cvLayout->setContentsMargins(4,0,4,2); |
| 134 | } |
| 135 | |
| 136 | |
| 137 | virtual ~ProcessorDockWidget() {} |
| 138 | |
| 139 | |
| 140 | DebuggerView* view() { return m_processorView; } |
| 141 | |
| 142 | |
| 143 | QSize minimumSizeHint() const |
| 144 | { |
| 145 | return QSize(150,300); |
| 146 | } |
| 147 | |
| 148 | |
| 149 | QSize sizeHint() const |
| 150 | { |
| 151 | return QSize(200,300); |
| 152 | } |
| 153 | |
| 154 | |
| 155 | private: |
| 156 | DebuggerView* m_processorView; |
| 157 | |
| 158 | running_machine* m_machine; |
| 159 | }; |
| 160 | |
| 161 | |
| 162 | #endif |
trunk/src/osd/sdl/debugqtwindow.c
| r0 | r19797 | |
| 1 | #include <QtGui/QtGui> |
| 2 | |
| 3 | #include "emu.h" |
| 4 | #include "debugger.h" |
| 5 | |
| 6 | #include "debugqtwindow.h" |
| 7 | #include "debugqtlogwindow.h" |
| 8 | #include "debugqtdasmwindow.h" |
| 9 | #include "debugqtmemorywindow.h" |
| 10 | |
| 11 | bool WindowQt::s_refreshAll = false; |
| 12 | |
| 13 | |
| 14 | WindowQt::WindowQt(running_machine* machine, QWidget* parent) : |
| 15 | QMainWindow(parent), |
| 16 | m_machine(machine) |
| 17 | { |
| 18 | // The Debug menu bar |
| 19 | QAction* debugActOpenMemory = new QAction("New &Memory Window", this); |
| 20 | debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M")); |
| 21 | connect(debugActOpenMemory, SIGNAL(triggered()), this, SLOT(debugActOpenMemory())); |
| 22 | |
| 23 | QAction* debugActOpenDasm = new QAction("New &Dasm Window", this); |
| 24 | debugActOpenDasm->setShortcut(QKeySequence("Ctrl+D")); |
| 25 | connect(debugActOpenDasm, SIGNAL(triggered()), this, SLOT(debugActOpenDasm())); |
| 26 | |
| 27 | QAction* debugActOpenLog = new QAction("New &Log Window", this); |
| 28 | debugActOpenLog->setShortcut(QKeySequence("Ctrl+L")); |
| 29 | connect(debugActOpenLog, SIGNAL(triggered()), this, SLOT(debugActOpenLog())); |
| 30 | |
| 31 | QAction* dbgActRun = new QAction("Run", this); |
| 32 | dbgActRun->setShortcut(Qt::Key_F5); |
| 33 | connect(dbgActRun, SIGNAL(triggered()), this, SLOT(debugActRun())); |
| 34 | |
| 35 | QAction* dbgActRunAndHide = new QAction("Run And Hide Debugger", this); |
| 36 | dbgActRunAndHide->setShortcut(Qt::Key_F12); |
| 37 | connect(dbgActRunAndHide, SIGNAL(triggered()), this, SLOT(debugActRunAndHide())); |
| 38 | |
| 39 | QAction* dbgActRunToNextCpu = new QAction("Run to Next CPU", this); |
| 40 | dbgActRunToNextCpu->setShortcut(Qt::Key_F6); |
| 41 | connect(dbgActRunToNextCpu, SIGNAL(triggered()), this, SLOT(debugActRunToNextCpu())); |
| 42 | |
| 43 | QAction* dbgActRunNextInt = new QAction("Run to Next Interrupt on This CPU", this); |
| 44 | dbgActRunNextInt->setShortcut(Qt::Key_F7); |
| 45 | connect(dbgActRunNextInt, SIGNAL(triggered()), this, SLOT(debugActRunNextInt())); |
| 46 | |
| 47 | QAction* dbgActRunNextVBlank = new QAction("Run to Next VBlank", this); |
| 48 | dbgActRunNextVBlank->setShortcut(Qt::Key_F8); |
| 49 | connect(dbgActRunNextVBlank, SIGNAL(triggered()), this, SLOT(debugActRunNextVBlank())); |
| 50 | |
| 51 | QAction* dbgActStepInto = new QAction("Step Into", this); |
| 52 | dbgActStepInto->setShortcut(Qt::Key_F11); |
| 53 | connect(dbgActStepInto, SIGNAL(triggered()), this, SLOT(debugActStepInto())); |
| 54 | |
| 55 | QAction* dbgActStepOver = new QAction("Step Over", this); |
| 56 | dbgActStepOver->setShortcut(Qt::Key_F10); |
| 57 | connect(dbgActStepOver, SIGNAL(triggered()), this, SLOT(debugActStepOver())); |
| 58 | |
| 59 | QAction* dbgActStepOut = new QAction("Step Out", this); |
| 60 | dbgActStepOut->setShortcut(QKeySequence("Shift+F11")); |
| 61 | connect(dbgActStepOut, SIGNAL(triggered()), this, SLOT(debugActStepOut())); |
| 62 | |
| 63 | QAction* dbgActSoftReset = new QAction("Soft Reset", this); |
| 64 | dbgActSoftReset->setShortcut(Qt::Key_F3); |
| 65 | connect(dbgActSoftReset, SIGNAL(triggered()), this, SLOT(debugActSoftReset())); |
| 66 | |
| 67 | QAction* dbgActHardReset = new QAction("Hard Reset", this); |
| 68 | dbgActHardReset->setShortcut(QKeySequence("Shift+F3")); |
| 69 | connect(dbgActHardReset, SIGNAL(triggered()), this, SLOT(debugActHardReset())); |
| 70 | |
| 71 | QAction* dbgActClose = new QAction("Close &Window", this); |
| 72 | dbgActClose->setShortcut(QKeySequence::Close); |
| 73 | connect(dbgActClose, SIGNAL(triggered()), this, SLOT(debugActClose())); |
| 74 | |
| 75 | QAction* dbgActQuit = new QAction("&Quit", this); |
| 76 | dbgActQuit->setShortcut(QKeySequence::Quit); |
| 77 | connect(dbgActQuit, SIGNAL(triggered()), this, SLOT(debugActQuit())); |
| 78 | |
| 79 | // Construct the menu |
| 80 | QMenu* debugMenu = menuBar()->addMenu("&Debug"); |
| 81 | debugMenu->addAction(debugActOpenMemory); |
| 82 | debugMenu->addAction(debugActOpenDasm); |
| 83 | debugMenu->addAction(debugActOpenLog); |
| 84 | debugMenu->addSeparator(); |
| 85 | debugMenu->addAction(dbgActRun); |
| 86 | debugMenu->addAction(dbgActRunToNextCpu); |
| 87 | debugMenu->addAction(dbgActRunNextInt); |
| 88 | debugMenu->addAction(dbgActRunNextVBlank); |
| 89 | debugMenu->addSeparator(); |
| 90 | debugMenu->addAction(dbgActStepInto); |
| 91 | debugMenu->addAction(dbgActStepOver); |
| 92 | debugMenu->addAction(dbgActStepOut); |
| 93 | debugMenu->addSeparator(); |
| 94 | debugMenu->addAction(dbgActSoftReset); |
| 95 | debugMenu->addAction(dbgActHardReset); |
| 96 | debugMenu->addSeparator(); |
| 97 | debugMenu->addAction(dbgActClose); |
| 98 | debugMenu->addAction(dbgActQuit); |
| 99 | } |
| 100 | |
| 101 | |
| 102 | void WindowQt::debugActOpenMemory() |
| 103 | { |
| 104 | MemoryWindow* foo = new MemoryWindow(m_machine, this); |
| 105 | // A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon |
| 106 | // foo->setWindowFlags(Qt::Dialog); |
| 107 | // foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint); |
| 108 | foo->show(); |
| 109 | } |
| 110 | |
| 111 | |
| 112 | void WindowQt::debugActOpenDasm() |
| 113 | { |
| 114 | DasmWindow* foo = new DasmWindow(m_machine, this); |
| 115 | // A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon |
| 116 | // foo->setWindowFlags(Qt::Dialog); |
| 117 | // foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint); |
| 118 | foo->show(); |
| 119 | } |
| 120 | |
| 121 | |
| 122 | void WindowQt::debugActOpenLog() |
| 123 | { |
| 124 | LogWindow* foo = new LogWindow(m_machine, this); |
| 125 | // A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon |
| 126 | // foo->setWindowFlags(Qt::Dialog); |
| 127 | // foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint); |
| 128 | foo->show(); |
| 129 | } |
| 130 | |
| 131 | |
| 132 | void WindowQt::debugActRun() |
| 133 | { |
| 134 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go(); |
| 135 | } |
| 136 | |
| 137 | void WindowQt::debugActRunAndHide() |
| 138 | { |
| 139 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go(); |
| 140 | // TODO: figure out hide |
| 141 | } |
| 142 | |
| 143 | void WindowQt::debugActRunToNextCpu() |
| 144 | { |
| 145 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go_next_device(); |
| 146 | } |
| 147 | |
| 148 | void WindowQt::debugActRunNextInt() |
| 149 | { |
| 150 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go_interrupt(); |
| 151 | } |
| 152 | |
| 153 | void WindowQt::debugActRunNextVBlank() |
| 154 | { |
| 155 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go_vblank(); |
| 156 | } |
| 157 | |
| 158 | void WindowQt::debugActStepInto() |
| 159 | { |
| 160 | debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step(); |
| 161 | } |
| 162 | |
| 163 | void WindowQt::debugActStepOver() |
| 164 | { |
| 165 | debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step_over(); |
| 166 | } |
| 167 | |
| 168 | void WindowQt::debugActStepOut() |
| 169 | { |
| 170 | debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step_out(); |
| 171 | } |
| 172 | |
| 173 | void WindowQt::debugActSoftReset() |
| 174 | { |
| 175 | m_machine->schedule_soft_reset(); |
| 176 | } |
| 177 | |
| 178 | void WindowQt::debugActHardReset() |
| 179 | { |
| 180 | // TODO: Figure out segfault |
| 181 | m_machine->schedule_hard_reset(); |
| 182 | debug_cpu_get_visible_cpu(*m_machine)->debug()->go(); |
| 183 | } |
| 184 | |
| 185 | void WindowQt::debugActClose() |
| 186 | { |
| 187 | close(); |
| 188 | } |
| 189 | |
| 190 | void WindowQt::debugActQuit() |
| 191 | { |
| 192 | m_machine->schedule_exit(); |
| 193 | qApp->closeAllWindows(); |
| 194 | } |