diff options
author | 2015-11-08 12:56:12 +0100 | |
---|---|---|
committer | 2015-11-08 12:56:12 +0100 | |
commit | 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch) | |
tree | f310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/osd/modules/debugger/debugqt.cpp | |
parent | a57b46ae933badd7441ce1644711dbb851e2b504 (diff) |
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/osd/modules/debugger/debugqt.cpp')
-rw-r--r-- | src/osd/modules/debugger/debugqt.cpp | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/src/osd/modules/debugger/debugqt.cpp b/src/osd/modules/debugger/debugqt.cpp new file mode 100644 index 00000000000..692e58d6551 --- /dev/null +++ b/src/osd/modules/debugger/debugqt.cpp @@ -0,0 +1,364 @@ +// license:BSD-3-Clause +// copyright-holders:Andrew Gardner +//============================================================ +// +// debugqt.c - SDL/QT debug window handling +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#if (!defined(NO_MEM_TRACKING)) +#define NO_MEM_TRACKING +#endif + +#include "debug_module.h" +#include "modules/osdmodule.h" + +#if (USE_QTDEBUG) + +#include <vector> + +#include <QtGui/QtGui> +#include <QtGui/QApplication> + +#include "emu.h" +#include "config.h" +#include "debugger.h" +#include "modules/lib/osdobj_common.h" + +#include "qt/logwindow.h" +#include "qt/mainwindow.h" +#include "qt/dasmwindow.h" +#include "qt/memorywindow.h" +#include "qt/breakpointswindow.h" +#include "qt/deviceswindow.h" +#include "qt/deviceinformationwindow.h" + +class debug_qt : public osd_module, public debug_module +{ +public: + debug_qt() + : osd_module(OSD_DEBUG_PROVIDER, "qt"), debug_module(), + m_machine(NULL) + { + } + + virtual ~debug_qt() { } + + virtual int init(const osd_options &options) { return 0; } + virtual void exit() { } + + virtual void init_debugger(running_machine &machine); + virtual void wait_for_debugger(device_t &device, bool firststop); + virtual void debugger_update(); + +private: + running_machine *m_machine; +}; + +//============================================================ +// "Global" variables to make QT happy +//============================================================ + +int qtArgc = 0; +char** qtArgv = NULL; + +bool oneShot = true; +static MainWindow* mainQtWindow = NULL; + +//============================================================ +// XML configuration save/load +//============================================================ + +// Global variable used to feed the xml configuration callbacks +std::vector<WindowQtConfig*> xmlConfigurations; + + +static void xml_configuration_load(running_machine &machine, int config_type, xml_data_node *parentnode) +{ + // We only care about game files + if (config_type != CONFIG_TYPE_GAME) + return; + + // Might not have any data + if (parentnode == NULL) + return; + + for (int i = 0; i < xmlConfigurations.size(); i++) + delete xmlConfigurations[i]; + xmlConfigurations.clear(); + + // Configuration load + xml_data_node* wnode = NULL; + for (wnode = xml_get_sibling(parentnode->child, "window"); wnode != NULL; wnode = xml_get_sibling(wnode->next, "window")) + { + WindowQtConfig::WindowType type = (WindowQtConfig::WindowType)xml_get_attribute_int(wnode, "type", WindowQtConfig::WIN_TYPE_UNKNOWN); + switch (type) + { + case WindowQtConfig::WIN_TYPE_MAIN: xmlConfigurations.push_back(new MainWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_MEMORY: xmlConfigurations.push_back(new MemoryWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_DASM: xmlConfigurations.push_back(new DasmWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_LOG: xmlConfigurations.push_back(new LogWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_BREAK_POINTS: xmlConfigurations.push_back(new BreakpointsWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_DEVICES: xmlConfigurations.push_back(new DevicesWindowQtConfig()); break; + case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION: xmlConfigurations.push_back(new DeviceInformationWindowQtConfig()); break; + default: continue; + } + xmlConfigurations.back()->recoverFromXmlNode(wnode); + } +} + + +static void xml_configuration_save(running_machine &machine, int config_type, xml_data_node *parentnode) +{ + // We only write to game configurations + if (config_type != CONFIG_TYPE_GAME) + return; + + for (int i = 0; i < xmlConfigurations.size(); i++) + { + WindowQtConfig* config = xmlConfigurations[i]; + + // Create an xml node + xml_data_node *debugger_node; + debugger_node = xml_add_child(parentnode, "window", NULL); + if (debugger_node == NULL) + continue; + + // Insert the appropriate information + config->addToXmlDataNode(debugger_node); + } +} + + +static void gather_save_configurations() +{ + for (int i = 0; i < xmlConfigurations.size(); i++) + delete xmlConfigurations[i]; + xmlConfigurations.clear(); + + // Loop over all the open windows + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (!widget->isVisible()) + continue; + + if (!widget->isWindow() || widget->windowType() != Qt::Window) + continue; + + // Figure out its type + if (dynamic_cast<MainWindow*>(widget)) + xmlConfigurations.push_back(new MainWindowQtConfig()); + else if (dynamic_cast<MemoryWindow*>(widget)) + xmlConfigurations.push_back(new MemoryWindowQtConfig()); + else if (dynamic_cast<DasmWindow*>(widget)) + xmlConfigurations.push_back(new DasmWindowQtConfig()); + else if (dynamic_cast<LogWindow*>(widget)) + xmlConfigurations.push_back(new LogWindowQtConfig()); + else if (dynamic_cast<BreakpointsWindow*>(widget)) + xmlConfigurations.push_back(new BreakpointsWindowQtConfig()); + else if (dynamic_cast<DevicesWindow*>(widget)) + xmlConfigurations.push_back(new DevicesWindowQtConfig()); + else if (dynamic_cast<DeviceInformationWindow*>(widget)) + xmlConfigurations.push_back(new DeviceInformationWindowQtConfig()); + + xmlConfigurations.back()->buildFromQWidget(widget); + } +} + + +//============================================================ +// Utilities +//============================================================ + +static void load_and_clear_main_window_config(std::vector<WindowQtConfig*>& configList) +{ + for (int i = 0; i < configList.size(); i++) + { + WindowQtConfig* config = configList[i]; + if (config->m_type == WindowQtConfig::WIN_TYPE_MAIN) + { + config->applyToQWidget(mainQtWindow); + configList.erase(configList.begin()+i); + break; + } + } +} + + +static void setup_additional_startup_windows(running_machine& machine, std::vector<WindowQtConfig*>& configList) +{ + for (int i = 0; i < configList.size(); i++) + { + WindowQtConfig* config = configList[i]; + + WindowQt* foo = NULL; + switch (config->m_type) + { + case WindowQtConfig::WIN_TYPE_MEMORY: + foo = new MemoryWindow(&machine); break; + case WindowQtConfig::WIN_TYPE_DASM: + foo = new DasmWindow(&machine); break; + case WindowQtConfig::WIN_TYPE_LOG: + foo = new LogWindow(&machine); break; + case WindowQtConfig::WIN_TYPE_BREAK_POINTS: + foo = new BreakpointsWindow(&machine); break; + case WindowQtConfig::WIN_TYPE_DEVICES: + foo = new DevicesWindow(&machine); break; + case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION: + foo = new DeviceInformationWindow(&machine); break; + default: break; + } + config->applyToQWidget(foo); + foo->show(); + } +} + + +static void bring_main_window_to_front() +{ + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (!dynamic_cast<MainWindow*>(widget)) + continue; + widget->activateWindow(); + widget->raise(); + } +} + + +//============================================================ +// Core functionality +//============================================================ + +#if defined(WIN32) && !defined(SDLMAME_WIN32) +bool winwindow_qt_filter(void *message); +#endif + +void debug_qt::init_debugger(running_machine &machine) +{ + if (qApp == NULL) + { + // If you're starting from scratch, create a new qApp + new QApplication(qtArgc, qtArgv); +#if defined(WIN32) && !defined(SDLMAME_WIN32) + QAbstractEventDispatcher::instance()->setEventFilter((QAbstractEventDispatcher::EventFilter)&winwindow_qt_filter); +#endif + } + else + { + // If you've done a hard reset, clear out existing widgets & get ready for re-init + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (!widget->isWindow() || widget->windowType() != Qt::Window) + continue; + delete widget; + } + oneShot = true; + } + + m_machine = &machine; + // Setup the configuration XML saving and loading + config_register(machine, + "debugger", + config_saveload_delegate(FUNC(xml_configuration_load), &machine), + config_saveload_delegate(FUNC(xml_configuration_save), &machine)); +} + + +//============================================================ +// Core functionality +//============================================================ + +#if defined(SDLMAME_UNIX) || defined(SDLMAME_WIN32) +extern int sdl_entered_debugger; +#elif defined(WIN32) +void winwindow_update_cursor_state(running_machine &machine); +#endif + +void debug_qt::wait_for_debugger(device_t &device, bool firststop) +{ +#if defined(SDLMAME_UNIX) || defined(SDLMAME_WIN32) + sdl_entered_debugger = 1; +#endif + + // Dialog initialization + if (oneShot) + { + mainQtWindow = new MainWindow(m_machine); + load_and_clear_main_window_config(xmlConfigurations); + setup_additional_startup_windows(*m_machine, xmlConfigurations); + mainQtWindow->show(); + oneShot = false; + } + + // Insure all top level widgets are visible & bring main window to front + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (!widget->isWindow() || widget->windowType() != Qt::Window) + continue; + widget->show(); + } + + if (firststop) + { + bring_main_window_to_front(); + } + + // Set the main window to display the proper cpu + mainQtWindow->setProcessor(&device); + + // Run our own QT event loop + osd_sleep(50000); + qApp->processEvents(QEventLoop::AllEvents, 1); + + // Refresh everyone if requested + if (mainQtWindow->wantsRefresh()) + { + QWidgetList allWidgets = qApp->allWidgets(); + for (int i = 0; i < allWidgets.length(); i++) + allWidgets[i]->update(); + mainQtWindow->clearRefreshFlag(); + } + + // Hide all top level widgets if requested + if (mainQtWindow->wantsHide()) + { + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (!widget->isWindow() || widget->windowType() != Qt::Window) + continue; + widget->hide(); + } + mainQtWindow->clearHideFlag(); + } + + // Exit if the machine has been instructed to do so (scheduled event == exit || hard_reset) + if (m_machine->scheduled_event_pending()) + { + // Keep a list of windows we want to save. + // We need to do this here because by the time xml_configuration_save gets called + // all the QT windows are already gone. + gather_save_configurations(); + } +#if defined(WIN32) && !defined(SDLMAME_WIN32) + winwindow_update_cursor_state(*m_machine); // make sure the cursor isn't hidden while in debugger +#endif +} + + +//============================================================ +// Available for video.* +//============================================================ + +void debug_qt::debugger_update() +{ + qApp->processEvents(QEventLoop::AllEvents, 1); +} + +#else /* SDLMAME_UNIX */ + MODULE_NOT_SUPPORTED(debug_qt, OSD_DEBUG_PROVIDER, "qt") +#endif + +MODULE_DEFINITION(DEBUG_QT, debug_qt) |