all repos — mgba @ c83e4e7e851fcd268296c01eb09f21209486c69a

mGBA Game Boy Advance Emulator

src/platform/qt/GDBWindow.cpp (view raw)

  1/* Copyright (c) 2013-2014 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "GDBWindow.h"
  7
  8#include <QGridLayout>
  9#include <QGroupBox>
 10#include <QLabel>
 11#include <QLineEdit>
 12#include <QMessageBox>
 13#include <QPushButton>
 14#include <QHBoxLayout>
 15#include <QVBoxLayout>
 16
 17#include "GDBController.h"
 18
 19using namespace QGBA;
 20
 21GDBWindow::GDBWindow(GDBController* controller, QWidget* parent)
 22	: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
 23	, m_gdbController(controller)
 24{
 25	setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
 26	QVBoxLayout* mainSegment = new QVBoxLayout;
 27	setLayout(mainSegment);
 28	QGroupBox* settings = new QGroupBox(tr("Server settings"));
 29	mainSegment->addWidget(settings);
 30
 31	QGridLayout* settingsGrid = new QGridLayout;
 32	settings->setLayout(settingsGrid);
 33
 34	QLabel* portLabel = new QLabel(tr("Local port"));
 35	settingsGrid->addWidget(portLabel, 0, 0, Qt::AlignRight);
 36	QLabel* bindAddressLabel = new QLabel(tr("Bind address"));
 37	settingsGrid->addWidget(bindAddressLabel, 1, 0, Qt::AlignRight);
 38
 39	m_portEdit = new QLineEdit("2345");
 40	m_portEdit->setMaxLength(5);
 41	connect(m_portEdit, SIGNAL(textChanged(const QString&)), this, SLOT(portChanged(const QString&)));
 42	settingsGrid->addWidget(m_portEdit, 0, 1, Qt::AlignLeft);
 43
 44	m_bindAddressEdit = new QLineEdit("0.0.0.0");
 45	m_bindAddressEdit->setMaxLength(15);
 46	connect(m_bindAddressEdit, SIGNAL(textChanged(const QString&)), this, SLOT(bindAddressChanged(const QString&)));
 47	settingsGrid->addWidget(m_bindAddressEdit, 1, 1, Qt::AlignLeft);
 48
 49	QHBoxLayout* buttons = new QHBoxLayout;
 50
 51	m_startStopButton = new QPushButton;
 52	buttons->addWidget(m_startStopButton);
 53
 54	m_breakButton = new QPushButton;
 55	m_breakButton->setText(tr("Break"));
 56	buttons->addWidget(m_breakButton);
 57
 58	mainSegment->addLayout(buttons);
 59
 60	connect(m_gdbController, SIGNAL(listening()), this, SLOT(started()));
 61	connect(m_gdbController, SIGNAL(listenFailed()), this, SLOT(failed()));
 62	connect(m_breakButton, SIGNAL(clicked()), controller, SLOT(breakInto()));
 63
 64	if (m_gdbController->isAttached()) {
 65		started();
 66	} else {
 67		stopped();
 68	}
 69}
 70
 71void GDBWindow::portChanged(const QString& portString) {
 72	bool ok = false;
 73	ushort port = portString.toUShort(&ok);
 74	if (ok) {
 75		m_gdbController->setPort(port);
 76	}
 77}
 78
 79void GDBWindow::bindAddressChanged(const QString& bindAddressString) {
 80	bool ok = false;
 81	QStringList parts = bindAddressString.split('.');
 82	if (parts.length() != 4) {
 83		return;
 84	}
 85	int i;
 86	uint32_t address = 0;
 87	for (i = 0; i < 4; ++i) {
 88		ushort octet = parts[i].toUShort(&ok);
 89		if (!ok) {
 90			return;
 91		}
 92		if (octet > 0xFF) {
 93			return;
 94		}
 95		address <<= 8;
 96		address += octet;
 97	}
 98	m_gdbController->setBindAddress(address);
 99}
100
101void GDBWindow::started() {
102	m_portEdit->setEnabled(false);
103	m_bindAddressEdit->setEnabled(false);
104	m_startStopButton->setText(tr("Stop"));
105	m_breakButton->setEnabled(true);
106	disconnect(m_startStopButton, SIGNAL(clicked()), m_gdbController, SLOT(listen()));
107	connect(m_startStopButton, SIGNAL(clicked()), m_gdbController, SLOT(detach()));
108	connect(m_startStopButton, SIGNAL(clicked()), this, SLOT(stopped()));
109}
110
111void GDBWindow::stopped() {
112	m_portEdit->setEnabled(true);
113	m_bindAddressEdit->setEnabled(true);
114	m_startStopButton->setText(tr("Start"));
115	m_breakButton->setEnabled(false);
116	disconnect(m_startStopButton, SIGNAL(clicked()), m_gdbController, SLOT(detach()));
117	disconnect(m_startStopButton, SIGNAL(clicked()), this, SLOT(stopped()));
118	connect(m_startStopButton, SIGNAL(clicked()), m_gdbController, SLOT(listen()));
119}
120
121void GDBWindow::failed() {
122	QMessageBox* failure = new QMessageBox(QMessageBox::Warning, tr("Crash"), tr("Could not start GDB server"),
123	                                       QMessageBox::Ok, this, Qt::Sheet);
124	failure->setAttribute(Qt::WA_DeleteOnClose);
125	failure->show();
126}