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}