mirror of https://github.com/xemu-project/xemu.git
ui: Add interface to configure socket networking
This commit is contained in:
parent
8bfb9913ae
commit
d31e10cc59
|
@ -115,6 +115,7 @@
|
|||
|
||||
#include "ui/xemu-settings.h"
|
||||
#include "ui/xemu-notifications.h"
|
||||
#include "ui/xemu-net.h"
|
||||
|
||||
#define MAX_VIRTIO_CONSOLES 1
|
||||
|
||||
|
@ -4381,6 +4382,14 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef XBOX
|
||||
int xemu_net_enabled;
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_NETWORK_ENABLED, &xemu_net_enabled);
|
||||
if (xemu_net_enabled) {
|
||||
xemu_net_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
qemu_opts_foreach(qemu_find_opts("object"),
|
||||
user_creatable_add_opts_foreach,
|
||||
object_create_delayed, &error_fatal);
|
||||
|
|
|
@ -37,6 +37,7 @@ sdl.mo-objs := \
|
|||
xemu-hud.o \
|
||||
xemu-input.o \
|
||||
xemu-monitor.o \
|
||||
xemu-net.o \
|
||||
xemu-settings.o \
|
||||
xemu-shaders.o \
|
||||
|
||||
|
|
107
ui/xemu-hud.cc
107
ui/xemu-hud.cc
|
@ -30,6 +30,7 @@
|
|||
#include "xemu-monitor.h"
|
||||
#include "xemu-version.h"
|
||||
#include "xemu-data.h"
|
||||
#include "xemu-net.h"
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/examples/imgui_impl_sdl.h"
|
||||
|
@ -95,6 +96,9 @@ static void ShowSettingsWindow(bool* p_open);
|
|||
bool show_about_window = false;
|
||||
static void ShowAboutWindow(bool* p_open);
|
||||
|
||||
bool show_network_window = false;
|
||||
static void ShowNetworkWindow(bool* p_open);
|
||||
|
||||
bool show_demo_window = false;
|
||||
|
||||
float ui_scale = 1.0;
|
||||
|
@ -244,7 +248,8 @@ static void ShowMainMenu()
|
|||
{
|
||||
if (ImGui::BeginMenu("Machine"))
|
||||
{
|
||||
ImGui::MenuItem("Input", NULL, &show_input_window);
|
||||
ImGui::MenuItem("Input", NULL, &show_input_window);
|
||||
ImGui::MenuItem("Network", NULL, &show_network_window);
|
||||
ImGui::MenuItem("Settings", NULL, &show_settings_window);
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(running ? "Pause" : "Run")) {
|
||||
|
@ -526,6 +531,7 @@ void xemu_hud_render(SDL_Window *window)
|
|||
if (show_settings_window) ShowSettingsWindow(&show_settings_window);
|
||||
if (show_monitor_window) ShowMonitorConsole(&show_monitor_window);
|
||||
if (show_about_window) ShowAboutWindow(&show_about_window);
|
||||
if (show_network_window) ShowNetworkWindow(&show_network_window);
|
||||
if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window);
|
||||
|
||||
if (notification.active) {
|
||||
|
@ -1280,3 +1286,102 @@ static void ShowFirstBootWindow(bool* p_open)
|
|||
static FirstBootWindow console;
|
||||
console.Draw("First Boot", p_open);
|
||||
}
|
||||
|
||||
struct NetworkWindow
|
||||
{
|
||||
char remote_addr[64];
|
||||
char local_addr[64];
|
||||
|
||||
NetworkWindow()
|
||||
{
|
||||
const char *tmp;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &tmp);
|
||||
strncpy(remote_addr, tmp, sizeof(remote_addr)-1);
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &tmp);
|
||||
strncpy(local_addr, tmp, sizeof(local_addr)-1);
|
||||
}
|
||||
|
||||
~NetworkWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void Draw(const char* title, bool* p_open)
|
||||
{
|
||||
ImVec2 size(400*ui_scale, 250*ui_scale);
|
||||
|
||||
ImGui::SetNextWindowSize(size, ImGuiCond_Appearing);
|
||||
if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_enabled = xemu_net_is_enabled();
|
||||
|
||||
ImGui::TextWrapped(
|
||||
"xemu socket networking works by sending and recieving packets over "
|
||||
"UDP which encapsulate the network traffic that the machine would "
|
||||
"send or recieve when connected to a Local Area Network (LAN)."
|
||||
);
|
||||
|
||||
ImGui::Dummy(ImVec2(0, 5*ui_scale));
|
||||
ImGui::Separator();
|
||||
ImGui::Dummy(ImVec2(0, 5*ui_scale));
|
||||
|
||||
ImGui::Columns(2, "", false);
|
||||
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33);
|
||||
|
||||
ImGuiInputTextFlags flg = 0;
|
||||
if (is_enabled) {
|
||||
flg |= ImGuiInputTextFlags_ReadOnly;
|
||||
}
|
||||
|
||||
ImGui::Text("Remote Host");
|
||||
ImGui::SameLine(); HelpMarker("The remote <IP address>:<Port> to forward packets to (e.g. 1.2.3.4:9368)");
|
||||
ImGui::NextColumn();
|
||||
float w = ImGui::GetColumnWidth()-10*ui_scale;
|
||||
ImGui::SetNextItemWidth(w);
|
||||
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
|
||||
ImGui::InputText("###remote_host", remote_addr, sizeof(remote_addr), flg);
|
||||
if (is_enabled) ImGui::PopStyleVar();
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Text("Local Host");
|
||||
ImGui::SameLine(); HelpMarker("The local <IP address>:<Port> to recieve packets on (e.g. 0.0.0.0:9368)");
|
||||
ImGui::NextColumn();
|
||||
ImGui::SetNextItemWidth(w);
|
||||
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
|
||||
ImGui::InputText("###local_host", local_addr, sizeof(local_addr), flg);
|
||||
if (is_enabled) ImGui::PopStyleVar();
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Columns(1);
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+20)*ui_scale);
|
||||
ImGui::Text("Status: %sEnabled", is_enabled ? "" : "Not ");
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+25)*ui_scale);
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)*ui_scale);
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
if (ImGui::Button(is_enabled ? "Disable" : "Enable", ImVec2(120*ui_scale, 0))) {
|
||||
if (!is_enabled) {
|
||||
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, remote_addr);
|
||||
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, local_addr);
|
||||
xemu_net_enable();
|
||||
} else {
|
||||
xemu_net_disable();
|
||||
}
|
||||
xemu_settings_set_bool(XEMU_SETTINGS_NETWORK_ENABLED, xemu_net_is_enabled());
|
||||
xemu_settings_save();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
};
|
||||
|
||||
static void ShowNetworkWindow(bool* p_open)
|
||||
{
|
||||
static NetworkWindow console;
|
||||
console.Draw("Network", p_open);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* xemu Network Management
|
||||
*
|
||||
* Wrapper functions to configure network settings at runtime.
|
||||
*
|
||||
* Copyright (C) 2020 Matt Borgerson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "xemu-net.h"
|
||||
#include "xemu-settings.h"
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "monitor/qdev.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "net/net.h"
|
||||
#include "net/hub.h"
|
||||
|
||||
static const char *id = "xemu-netdev";
|
||||
static const char *id_hubport = "xemu-netdev-hubport";
|
||||
|
||||
void xemu_net_enable(void)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
||||
NetClientState *nc = qemu_find_netdev(id);
|
||||
if (nc != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *local_addr, *remote_addr;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &remote_addr);
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &local_addr);
|
||||
|
||||
// Create the UDP netdev
|
||||
QDict *qdict = qdict_new();
|
||||
qdict_put_str(qdict, "id", id);
|
||||
qdict_put_str(qdict, "type", "socket");
|
||||
qdict_put_str(qdict, "udp", remote_addr);
|
||||
qdict_put_str(qdict, "localaddr", local_addr);
|
||||
QemuOpts *opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &error_abort);
|
||||
qobject_unref(qdict);
|
||||
netdev_add(opts, &local_err);
|
||||
if (local_err) {
|
||||
qemu_opts_del(opts);
|
||||
error_report_err(local_err);
|
||||
// error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the hubport
|
||||
qdict = qdict_new();
|
||||
qdict_put_str(qdict, "id", id_hubport);
|
||||
qdict_put_str(qdict, "type", "hubport");
|
||||
qdict_put_int(qdict, "hubid", 0);
|
||||
qdict_put_str(qdict, "netdev", id);
|
||||
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &error_abort);
|
||||
qobject_unref(qdict);
|
||||
netdev_add(opts, &local_err);
|
||||
if (local_err) {
|
||||
qemu_opts_del(opts);
|
||||
error_report_err(local_err);
|
||||
// error_propagate(errp, local_err);
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_netdev(const char *name)
|
||||
{
|
||||
NetClientState *nc;
|
||||
QemuOpts *opts;
|
||||
|
||||
nc = qemu_find_netdev(name);
|
||||
if (!nc) {
|
||||
// error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
// "Device '%s' not found", name);
|
||||
return;
|
||||
}
|
||||
|
||||
opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
|
||||
if (!opts) {
|
||||
// error_setg(errp, "Device '%s' is not a netdev", name);
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_opts_del(opts);
|
||||
qemu_del_net_client(nc);
|
||||
}
|
||||
|
||||
void xemu_net_disable(void)
|
||||
{
|
||||
remove_netdev(id);
|
||||
remove_netdev(id_hubport);
|
||||
}
|
||||
|
||||
int xemu_net_is_enabled(void)
|
||||
{
|
||||
NetClientState *nc;
|
||||
nc = qemu_find_netdev(id);
|
||||
return (nc != NULL);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* xemu Network Management
|
||||
*
|
||||
* Wrapper functions to configure network settings at runtime.
|
||||
*
|
||||
* Copyright (C) 2020 Matt Borgerson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XEMU_NETWORK_H
|
||||
#define XEMU_NETWORK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void xemu_net_enable(void);
|
||||
void xemu_net_disable(void);
|
||||
int xemu_net_is_enabled(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -53,6 +53,11 @@ struct xemu_settings {
|
|||
char *controller_2_guid;
|
||||
char *controller_3_guid;
|
||||
char *controller_4_guid;
|
||||
|
||||
// [network]
|
||||
int net_enabled; // Boolean
|
||||
char *net_local_addr;
|
||||
char *net_remote_addr;
|
||||
};
|
||||
|
||||
struct enum_str_map {
|
||||
|
@ -95,6 +100,10 @@ struct config_offset_table {
|
|||
[XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID] = { CONFIG_TYPE_STRING, "input", "controller_2_guid", offsetof(struct xemu_settings, controller_2_guid), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID] = { CONFIG_TYPE_STRING, "input", "controller_3_guid", offsetof(struct xemu_settings, controller_3_guid), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID] = { CONFIG_TYPE_STRING, "input", "controller_4_guid", offsetof(struct xemu_settings, controller_4_guid), { .default_str = "" } },
|
||||
|
||||
[XEMU_SETTINGS_NETWORK_ENABLED] = { CONFIG_TYPE_BOOL, "network", "enabled", offsetof(struct xemu_settings, net_enabled), { .default_bool = 0 } },
|
||||
[XEMU_SETTINGS_NETWORK_LOCAL_ADDR] = { CONFIG_TYPE_STRING, "network", "local_addr", offsetof(struct xemu_settings, net_local_addr), { .default_str = "0.0.0.0:9368" } },
|
||||
[XEMU_SETTINGS_NETWORK_REMOTE_ADDR] = { CONFIG_TYPE_STRING, "network", "remote_addr", offsetof(struct xemu_settings, net_remote_addr), { .default_str = "1.2.3.4:9368" } },
|
||||
};
|
||||
|
||||
static const char *settings_path;
|
||||
|
|
|
@ -42,6 +42,9 @@ enum xemu_settings_keys {
|
|||
XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID,
|
||||
XEMU_SETTINGS_NETWORK_ENABLED,
|
||||
XEMU_SETTINGS_NETWORK_LOCAL_ADDR,
|
||||
XEMU_SETTINGS_NETWORK_REMOTE_ADDR,
|
||||
XEMU_SETTINGS__COUNT,
|
||||
XEMU_SETTINGS_INVALID = -1
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue