mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-03 13:13:56 +00:00
HLE/Qt: implement sys_tty_read
This commit is contained in:
parent
29270ed673
commit
a19113025c
@ -1,17 +1,87 @@
|
||||
#include "stdafx.h"
|
||||
#include "sys_tty.h"
|
||||
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
|
||||
logs::channel sys_tty("sys_tty");
|
||||
|
||||
extern fs::file g_tty;
|
||||
extern atomic_t<s64> g_tty_size;
|
||||
extern std::array<std::deque<std::string>, 16> g_tty_input;
|
||||
extern std::mutex g_tty_mutex;
|
||||
|
||||
error_code sys_tty_read(s32 ch, vm::ptr<char> buf, u32 len, vm::ptr<u32> preadlen)
|
||||
{
|
||||
sys_tty.fatal("sys_tty_read(ch=%d, buf=*0x%x, len=%d, preadlen=*0x%x)", ch, buf, len, preadlen);
|
||||
sys_tty.trace("sys_tty_read(ch=%d, buf=*0x%x, len=%d, preadlen=*0x%x)", ch, buf, len, preadlen);
|
||||
|
||||
// We currently do not support reading from the Console
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
if (false) // TODO: debug mode check
|
||||
{
|
||||
return CELL_EIO;
|
||||
}
|
||||
|
||||
if (ch > 15 || !buf)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (ch < SYS_TTYP_USER1)
|
||||
{
|
||||
sys_tty.warning("sys_tty_read called with system channel %d", ch);
|
||||
}
|
||||
|
||||
size_t chars_to_read = 0; // number of chars that will be read from the input string
|
||||
std::string tty_read; // string for storage of read chars
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_tty_mutex);
|
||||
|
||||
if (g_tty_input[ch].size() > 0)
|
||||
{
|
||||
// reference to our first queue element
|
||||
std::string& input = g_tty_input[ch].front();
|
||||
|
||||
// we have to stop reading at either a new line, the param len, or our input string size
|
||||
size_t new_line_pos = input.find_first_of("\n");
|
||||
|
||||
if (new_line_pos != input.npos)
|
||||
{
|
||||
chars_to_read = std::min(new_line_pos, static_cast<size_t>(len));
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_to_read = std::min(input.size(), static_cast<size_t>(len));
|
||||
}
|
||||
|
||||
// read the previously calculated number of chars from the beginning of the input string
|
||||
tty_read = input.substr(0, chars_to_read);
|
||||
|
||||
// remove the just read text from the input string
|
||||
input = input.substr(chars_to_read, input.size() - 1);
|
||||
|
||||
if (input.size() == 0)
|
||||
{
|
||||
// pop the first queue element if it was completely consumed
|
||||
g_tty_input[ch].pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!preadlen)
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
*preadlen = (u32)chars_to_read;
|
||||
|
||||
if (chars_to_read > 0)
|
||||
{
|
||||
std::memcpy(buf.get_ptr(), tty_read.c_str(), chars_to_read);
|
||||
sys_tty.success("sys_tty_read(ch=%d, len=%d) read %s with length %d", ch, len, tty_read, *preadlen);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_tty_write(s32 ch, vm::cptr<char> buf, u32 len, vm::ptr<u32> pwritelen)
|
||||
|
@ -64,6 +64,8 @@ extern void network_thread_init();
|
||||
|
||||
fs::file g_tty;
|
||||
atomic_t<s64> g_tty_size{0};
|
||||
std::array<std::deque<std::string>, 16> g_tty_input;
|
||||
std::mutex g_tty_mutex;
|
||||
|
||||
// Progress display server synchronization variables
|
||||
atomic_t<const char*> g_progr{nullptr};
|
||||
|
@ -9,8 +9,15 @@
|
||||
#include <QActionGroup>
|
||||
#include <QScrollBar>
|
||||
#include <QTabBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <deque>
|
||||
#include "Utilities/sema.h"
|
||||
|
||||
extern fs::file g_tty;
|
||||
extern atomic_t<s64> g_tty_size;
|
||||
extern std::array<std::deque<std::string>, 16> g_tty_input;
|
||||
extern std::mutex g_tty_mutex;
|
||||
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
@ -123,8 +130,26 @@ log_frame::log_frame(std::shared_ptr<gui_settings> guiSettings, QWidget *parent)
|
||||
m_tty->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_tty->installEventFilter(this);
|
||||
|
||||
m_tty_input = new QLineEdit();
|
||||
if (m_tty_channel >= 0)
|
||||
{
|
||||
m_tty_input->setPlaceholderText(tr("Channel %0").arg(m_tty_channel));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tty_input->setPlaceholderText(tr("All User Channels"));
|
||||
}
|
||||
|
||||
QVBoxLayout* tty_layout = new QVBoxLayout();
|
||||
tty_layout->addWidget(m_tty);
|
||||
tty_layout->addWidget(m_tty_input);
|
||||
tty_layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_tty_container = new QWidget();
|
||||
m_tty_container->setLayout(tty_layout);
|
||||
|
||||
m_tabWidget->addTab(m_log, tr("Log"));
|
||||
m_tabWidget->addTab(m_tty, tr("TTY"));
|
||||
m_tabWidget->addTab(m_tty_container, tr("TTY"));
|
||||
|
||||
setWidget(m_tabWidget);
|
||||
|
||||
@ -212,6 +237,30 @@ void log_frame::CreateAndConnectActions()
|
||||
m_clearTTYAct = new QAction(tr("Clear"), this);
|
||||
connect(m_clearTTYAct, &QAction::triggered, m_tty, &QTextEdit::clear);
|
||||
|
||||
m_tty_channel_acts = new QActionGroup(this);
|
||||
|
||||
// Special Channel: All
|
||||
QAction* all_channels_act = new QAction(tr("All user channels"), m_tty_channel_acts);
|
||||
all_channels_act->setCheckable(true);
|
||||
all_channels_act->setChecked(m_tty_channel == -1);
|
||||
connect(all_channels_act, &QAction::triggered, [this]()
|
||||
{
|
||||
m_tty_channel = -1;
|
||||
m_tty_input->setPlaceholderText(tr("All user channels"));
|
||||
});
|
||||
|
||||
for (int i = 3; i < 16; i++)
|
||||
{
|
||||
QAction* act = new QAction(tr("Channel %0").arg(i), m_tty_channel_acts);
|
||||
act->setCheckable(true);
|
||||
act->setChecked(i == m_tty_channel);
|
||||
connect(act, &QAction::triggered, [this, i]()
|
||||
{
|
||||
m_tty_channel = i;
|
||||
m_tty_input->setPlaceholderText(tr("Channel %0").arg(m_tty_channel));
|
||||
});
|
||||
}
|
||||
|
||||
// Action groups make these actions mutually exclusive.
|
||||
m_logLevels = new QActionGroup(this);
|
||||
m_nothingAct = new QAction(tr("Nothing"), m_logLevels);
|
||||
@ -253,7 +302,7 @@ void log_frame::CreateAndConnectActions()
|
||||
QMenu* menu = m_log->createStandardContextMenu();
|
||||
menu->addAction(m_clearAct);
|
||||
menu->addSeparator();
|
||||
menu->addActions({ m_nothingAct, m_fatalAct, m_errorAct, m_todoAct, m_successAct, m_warningAct, m_noticeAct, m_traceAct });
|
||||
menu->addActions(m_logLevels->actions());
|
||||
menu->addSeparator();
|
||||
menu->addAction(m_stackAct);
|
||||
menu->addSeparator();
|
||||
@ -265,6 +314,8 @@ void log_frame::CreateAndConnectActions()
|
||||
{
|
||||
QMenu* menu = m_tty->createStandardContextMenu();
|
||||
menu->addAction(m_clearTTYAct);
|
||||
menu->addSeparator();
|
||||
menu->addActions(m_tty_channel_acts->actions());
|
||||
menu->exec(mapToGlobal(pos));
|
||||
});
|
||||
|
||||
@ -274,6 +325,42 @@ void log_frame::CreateAndConnectActions()
|
||||
m_find_dialog->close();
|
||||
});
|
||||
|
||||
connect(m_tty_input, &QLineEdit::returnPressed, [this]()
|
||||
{
|
||||
std::string text = m_tty_input->text().toStdString();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_tty_mutex);
|
||||
|
||||
if (m_tty_channel == -1)
|
||||
{
|
||||
for (int i = 3; i < 16; i++)
|
||||
{
|
||||
g_tty_input[i].push_back(text + "\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tty_input[m_tty_channel].push_back(text + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Write to tty
|
||||
if (m_tty_channel == -1)
|
||||
{
|
||||
text = "All channels > " + text + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
text = fmt::format("%s > %s\n", "Ch.%d", m_tty_channel, text);
|
||||
}
|
||||
g_tty_size -= (1ll << 48);
|
||||
g_tty.write(text.c_str(), text.size());
|
||||
g_tty_size += (1ll << 48) + text.size();
|
||||
|
||||
m_tty_input->clear();
|
||||
});
|
||||
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
|
@ -49,12 +49,15 @@ private:
|
||||
QList<QColor> m_color;
|
||||
QColor m_color_stack;
|
||||
QTextEdit* m_log;
|
||||
QTextEdit* m_tty;
|
||||
QString m_old_text;
|
||||
ullong m_log_counter;
|
||||
bool m_stack_log;
|
||||
|
||||
fs::file m_tty_file;
|
||||
QWidget* m_tty_container;
|
||||
QTextEdit* m_tty;
|
||||
QLineEdit* m_tty_input;
|
||||
int m_tty_channel = -1;
|
||||
|
||||
QAction* m_clearAct;
|
||||
QAction* m_clearTTYAct;
|
||||
@ -73,5 +76,7 @@ private:
|
||||
|
||||
QAction* m_TTYAct;
|
||||
|
||||
QActionGroup* m_tty_channel_acts;
|
||||
|
||||
std::shared_ptr<gui_settings> xgui_settings;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user