diff --git a/gui/include/settings.h b/gui/include/settings.h index c52b42f..1088185 100644 --- a/gui/include/settings.h +++ b/gui/include/settings.h @@ -38,6 +38,13 @@ enum class ControllerButtonExt ANALOG_STICK_RIGHT_Y_DOWN = (1 << 25), }; +enum class DisconnectAction +{ + AlwaysNothing, + AlwaysSleep, + Ask +}; + class Settings : public QObject { Q_OBJECT @@ -95,6 +102,9 @@ class Settings : public QObject ChiakiConnectVideoProfile GetVideoProfile(); + DisconnectAction GetDisconnectAction(); + void SetDisconnectAction(DisconnectAction action); + QList GetRegisteredHosts() const { return registered_hosts.values(); } void AddRegisteredHost(const RegisteredHost &host); void RemoveRegisteredHost(const HostMAC &mac); diff --git a/gui/include/settingsdialog.h b/gui/include/settingsdialog.h index 13a40c9..90235c9 100644 --- a/gui/include/settingsdialog.h +++ b/gui/include/settingsdialog.h @@ -34,6 +34,7 @@ class SettingsDialog : public QDialog Settings *settings; QCheckBox *log_verbose_check_box; + QComboBox *disconnect_action_combo_box; QComboBox *resolution_combo_box; QComboBox *fps_combo_box; @@ -48,6 +49,7 @@ class SettingsDialog : public QDialog private slots: void LogVerboseChanged(); + void DisconnectActionSelected(); void ResolutionSelected(); void FPSSelected(); diff --git a/gui/include/streamsession.h b/gui/include/streamsession.h index 94399ad..0790b48 100644 --- a/gui/include/streamsession.h +++ b/gui/include/streamsession.h @@ -48,6 +48,7 @@ class ChiakiException: public Exception struct StreamSessionConnectInfo { + Settings *settings; QMap key_map; HardwareDecodeEngine hw_decode_engine; uint32_t log_level_mask; @@ -71,6 +72,7 @@ class StreamSession : public QObject SessionLog log; ChiakiSession session; ChiakiOpusDecoder opus_decoder; + bool connected; Controller *controller; #if CHIAKI_GUI_ENABLE_SETSU @@ -103,8 +105,11 @@ class StreamSession : public QObject explicit StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent = nullptr); ~StreamSession(); + bool IsConnected() { return connected; } + void Start(); void Stop(); + void GoToBed(); void SetLoginPIN(const QString &pin); diff --git a/gui/include/streamwindow.h b/gui/include/streamwindow.h index 3e664bc..b554cc7 100644 --- a/gui/include/streamwindow.h +++ b/gui/include/streamwindow.h @@ -34,11 +34,12 @@ class StreamWindow: public QMainWindow ~StreamWindow() override; private: + const StreamSessionConnectInfo connect_info; StreamSession *session; AVOpenGLWidget *av_widget; - void Init(const StreamSessionConnectInfo &connect_info); + void Init(); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/gui/src/settings.cpp b/gui/src/settings.cpp index 2f5bc95..d8653aa 100644 --- a/gui/src/settings.cpp +++ b/gui/src/settings.cpp @@ -136,6 +136,25 @@ ChiakiConnectVideoProfile Settings::GetVideoProfile() return profile; } +static const QMap disconnect_action_values = { + { DisconnectAction::Ask, "ask" }, + { DisconnectAction::AlwaysNothing, "nothing" }, + { DisconnectAction::AlwaysSleep, "sleep" } +}; + +static const DisconnectAction disconnect_action_default = DisconnectAction::Ask; + +DisconnectAction Settings::GetDisconnectAction() +{ + auto v = settings.value("settings/disconnect_action", disconnect_action_values[disconnect_action_default]).toString(); + return disconnect_action_values.key(v, disconnect_action_default); +} + +void Settings::SetDisconnectAction(DisconnectAction action) +{ + settings.setValue("settings/disconnect_action", disconnect_action_values[action]); +} + void Settings::LoadRegisteredHosts() { registered_hosts.clear(); diff --git a/gui/src/settingsdialog.cpp b/gui/src/settingsdialog.cpp index 56c63a6..146629e 100644 --- a/gui/src/settingsdialog.cpp +++ b/gui/src/settingsdialog.cpp @@ -85,6 +85,23 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa log_directory_label->setReadOnly(true); general_layout->addRow(tr("Log Directory:"), log_directory_label); + disconnect_action_combo_box = new QComboBox(this); + QList> disconnect_action_strings = { + { DisconnectAction::AlwaysNothing, "Do Nothing"}, + { DisconnectAction::AlwaysSleep, "Enter Sleep Mode"}, + { DisconnectAction::Ask, "Ask"} + }; + auto current_disconnect_action = settings->GetDisconnectAction(); + for(const auto &p : disconnect_action_strings) + { + disconnect_action_combo_box->addItem(tr(p.second), (int)p.first); + if(current_disconnect_action == p.first) + disconnect_action_combo_box->setCurrentIndex(disconnect_action_combo_box->count() - 1); + } + connect(disconnect_action_combo_box, SIGNAL(currentIndexChanged(int)), this, SLOT(DisconnectActionSelected())); + + general_layout->addRow(tr("Action on Disconnect:"), disconnect_action_combo_box); + auto about_button = new QPushButton(tr("About Chiaki"), this); general_layout->addRow(about_button); connect(about_button, &QPushButton::clicked, this, [this]() { @@ -140,7 +157,7 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa UpdateBitratePlaceholder(); audio_buffer_size_edit = new QLineEdit(this); - audio_buffer_size_edit->setValidator(new QIntValidator(1024, 0x20000)); + audio_buffer_size_edit->setValidator(new QIntValidator(1024, 0x20000, audio_buffer_size_edit)); unsigned int audio_buffer_size = settings->GetAudioBufferSizeRaw(); audio_buffer_size_edit->setText(audio_buffer_size ? QString::number(audio_buffer_size) : ""); stream_settings_layout->addRow(tr("Audio Buffer Size:"), audio_buffer_size_edit); @@ -249,6 +266,11 @@ void SettingsDialog::ResolutionSelected() UpdateBitratePlaceholder(); } +void SettingsDialog::DisconnectActionSelected() +{ + settings->SetDisconnectAction(static_cast(disconnect_action_combo_box->currentData().toInt())); +} + void SettingsDialog::LogVerboseChanged() { settings->SetLogVerbose(log_verbose_check_box->isChecked()); diff --git a/gui/src/streamsession.cpp b/gui/src/streamsession.cpp index dd4ddfd..ef3a62d 100644 --- a/gui/src/streamsession.cpp +++ b/gui/src/streamsession.cpp @@ -30,6 +30,7 @@ #define SETSU_UPDATE_INTERVAL_MS 4 StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString host, QByteArray regist_key, QByteArray morning) + : settings(settings) { key_map = settings->GetControllerMappingForDecoding(); hw_decode_engine = settings->GetHardwareDecodeEngine(); @@ -58,6 +59,7 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje audio_output(nullptr), audio_io(nullptr) { + connected = false; chiaki_opus_decoder_init(&opus_decoder, log.GetChiakiLog()); audio_buffer_size = connect_info.audio_buffer_size; @@ -135,6 +137,11 @@ void StreamSession::Stop() chiaki_session_stop(&session); } +void StreamSession::GoToBed() +{ + chiaki_session_goto_bed(&session); +} + void StreamSession::SetLoginPIN(const QString &pin) { QByteArray data = pin.toUtf8(); @@ -299,8 +306,10 @@ void StreamSession::Event(ChiakiEvent *event) switch(event->type) { case CHIAKI_EVENT_CONNECTED: + connected = true; break; case CHIAKI_EVENT_QUIT: + connected = false; emit SessionQuit(event->quit.reason, event->quit.reason_str ? QString::fromUtf8(event->quit.reason_str) : QString()); break; case CHIAKI_EVENT_LOGIN_PIN_REQUEST: diff --git a/gui/src/streamwindow.cpp b/gui/src/streamwindow.cpp index 91ae8b0..678d40c 100644 --- a/gui/src/streamwindow.cpp +++ b/gui/src/streamwindow.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,8 @@ #include StreamWindow::StreamWindow(const StreamSessionConnectInfo &connect_info, QWidget *parent) - : QMainWindow(parent) + : QMainWindow(parent), + connect_info(connect_info) { setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(qApp->applicationName() + " | Stream"); @@ -36,7 +38,7 @@ StreamWindow::StreamWindow(const StreamSessionConnectInfo &connect_info, QWidget try { - Init(connect_info); + Init(); } catch(const Exception &e) { @@ -51,7 +53,7 @@ StreamWindow::~StreamWindow() delete av_widget; } -void StreamWindow::Init(const StreamSessionConnectInfo &connect_info) +void StreamWindow::Init() { session = new StreamSession(connect_info, this); @@ -98,10 +100,42 @@ void StreamWindow::mouseReleaseEvent(QMouseEvent *event) session->HandleMouseEvent(event); } -void StreamWindow::closeEvent(QCloseEvent *) +void StreamWindow::closeEvent(QCloseEvent *event) { if(session) + { + if(session->IsConnected()) + { + bool sleep = false; + switch(connect_info.settings->GetDisconnectAction()) + { + case DisconnectAction::Ask: { + auto res = QMessageBox::question(this, tr("Disconnect Session"), tr("Do you want the PS4 to go into sleep mode?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + switch(res) + { + case QMessageBox::Yes: + sleep = true; + break; + case QMessageBox::Cancel: + event->ignore(); + return; + default: + break; + } + break; + } + case DisconnectAction::AlwaysSleep: + sleep = true; + break; + default: + break; + } + if(sleep) + session->GoToBed(); + } session->Stop(); + } } void StreamWindow::SessionQuit(ChiakiQuitReason reason, const QString &reason_str)