2020-10-14 19:12:33 +00:00
|
|
|
// Copyright 2020, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Remote debugging UI.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup gui
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "xrt/xrt_config_drivers.h"
|
|
|
|
|
|
|
|
#include "util/u_misc.h"
|
2020-12-18 15:24:03 +00:00
|
|
|
#include "util/u_logging.h"
|
2020-10-14 19:12:33 +00:00
|
|
|
|
|
|
|
#include "math/m_api.h"
|
|
|
|
|
|
|
|
#include "gui_common.h"
|
|
|
|
#include "gui_imgui.h"
|
|
|
|
|
|
|
|
#include "remote/r_interface.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Structs and defines.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* A GUI scene that lets the user select a user device.
|
|
|
|
* @implements gui_scene
|
|
|
|
*/
|
|
|
|
struct gui_remote
|
|
|
|
{
|
|
|
|
struct gui_scene base;
|
|
|
|
|
|
|
|
struct r_remote_connection rc;
|
|
|
|
|
|
|
|
struct r_remote_data reset;
|
|
|
|
struct r_remote_data data;
|
|
|
|
|
|
|
|
bool cheat_menu;
|
2022-05-28 11:04:25 +00:00
|
|
|
|
|
|
|
char address[1024];
|
|
|
|
int port;
|
2020-10-14 19:12:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const ImVec2 zero_dims = {0, 0};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef XRT_BUILD_DRIVER_REMOTE
|
|
|
|
static void
|
2021-01-14 14:13:48 +00:00
|
|
|
handle_draggable_vec3_f32(const char *name, struct xrt_vec3 *v, const struct xrt_vec3 *reset)
|
2020-10-14 19:12:33 +00:00
|
|
|
{
|
|
|
|
float min = -256.0f;
|
|
|
|
float max = 256.0f;
|
|
|
|
char tmp[256];
|
|
|
|
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s.reset", name);
|
|
|
|
|
|
|
|
if (igArrowButton(tmp, ImGuiDir_Left)) {
|
|
|
|
*v = *reset;
|
|
|
|
}
|
|
|
|
|
|
|
|
igSameLine(0, 3);
|
|
|
|
igDragFloat3(name, (float *)v, 0.005f, min, max, "%+f", 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-01-14 14:13:48 +00:00
|
|
|
handle_draggable_quat(const char *name, struct xrt_quat *q, const struct xrt_quat *reset)
|
2020-10-14 19:12:33 +00:00
|
|
|
{
|
|
|
|
float min = -1.0f;
|
|
|
|
float max = 1.0f;
|
|
|
|
|
|
|
|
char tmp[256];
|
|
|
|
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s.reset", name);
|
|
|
|
|
|
|
|
if (igArrowButton(tmp, ImGuiDir_Left)) {
|
|
|
|
*q = *reset;
|
|
|
|
}
|
|
|
|
|
|
|
|
igSameLine(0, 3);
|
|
|
|
igDragFloat4(name, (float *)q, 0.005f, min, max, "%+f", 1.0f);
|
|
|
|
|
|
|
|
// Avoid invalid
|
|
|
|
if (q->x == 0.0f && q->y == 0.0f && q->z == 0.0f && q->w == 0.0f) {
|
|
|
|
q->w = 1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// And make sure it's a unit rotation.
|
|
|
|
math_quat_normalize(q);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
handle_downable_button(const char *name)
|
|
|
|
{
|
|
|
|
igButton(name, zero_dims);
|
2021-01-14 14:13:48 +00:00
|
|
|
return igIsItemHovered(ImGuiHoveredFlags_RectOnly) && igIsMouseDown(ImGuiMouseButton_Left);
|
2020-10-14 19:12:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-28 14:16:59 +00:00
|
|
|
static void
|
|
|
|
handle_input(struct r_remote_controller_data *d)
|
|
|
|
{
|
|
|
|
igText("Hover buttons and sliders to touch component.");
|
|
|
|
bool touched = false;
|
|
|
|
|
|
|
|
d->system_click = handle_downable_button("System");
|
|
|
|
d->system_touch = igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
igSameLine(0, 3);
|
|
|
|
|
|
|
|
d->a_click = handle_downable_button("A");
|
|
|
|
d->a_touch = igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
igSameLine(0, 3);
|
|
|
|
|
|
|
|
d->b_click = handle_downable_button("B");
|
|
|
|
d->b_touch = igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
igSameLine(0, 3);
|
|
|
|
|
|
|
|
igCheckbox("Active", &d->active);
|
|
|
|
|
|
|
|
// Squeeze
|
|
|
|
igSliderFloat("Squeeze Value", &d->squeeze_value.x, 0, 1, "%.2f", 0);
|
|
|
|
igSliderFloat("Squeeze Force", &d->squeeze_force.x, 0, 1, "%.2f", 0);
|
|
|
|
|
|
|
|
// Trigger
|
|
|
|
igText("Value > 0.0 causes touch, 0.7 > causes click");
|
|
|
|
igSliderFloat("Trigger", &d->trigger_value.x, 0, 1, "%.2f", 0);
|
|
|
|
touched |= igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
d->trigger_click = d->trigger_value.x > 0.7;
|
|
|
|
touched |= d->trigger_value.x > 0.0001;
|
|
|
|
d->trigger_touch = touched;
|
|
|
|
|
|
|
|
// Thumbstick
|
|
|
|
touched = false;
|
|
|
|
d->thumbstick_click = handle_downable_button("Thumbstick Click");
|
|
|
|
touched |= igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
igSliderFloat2("Thumbstick", &d->thumbstick.x, -1, 1, "%.2f", 0);
|
|
|
|
touched |= igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
d->thumbstick_touch = touched;
|
|
|
|
|
|
|
|
// Trackpad
|
|
|
|
touched = false;
|
|
|
|
igSliderFloat2("Trackpad", &d->trackpad.x, -1, 1, "%.2f", 0);
|
|
|
|
touched |= igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
igSliderFloat("Trackpad Force", &d->trackpad_force.x, 0, 1, "%.2f", 0);
|
|
|
|
touched |= igIsItemHovered(ImGuiHoveredFlags_RectOnly);
|
|
|
|
touched |= d->trackpad_force.x >= 0.0001f;
|
|
|
|
d->trackpad_touch = touched;
|
|
|
|
}
|
|
|
|
|
2020-10-14 19:12:33 +00:00
|
|
|
static void
|
|
|
|
render_cheat_menu(struct gui_remote *gr, struct gui_program *p)
|
|
|
|
{
|
|
|
|
struct r_remote_data *d = &gr->data;
|
|
|
|
|
|
|
|
if (igButton("Reset all", zero_dims)) {
|
|
|
|
*d = gr->reset;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (igButton("Interactive Throw #1", zero_dims)) {
|
|
|
|
#if 0
|
|
|
|
d->left.pose.position.x = -1.0f;
|
|
|
|
d->left.pose.position.y = 1.0f;
|
|
|
|
d->left.pose.position.z = -3.0f;
|
|
|
|
#else
|
|
|
|
d->left.pose.position.x = -0.200000f;
|
|
|
|
d->left.pose.position.y = 1.300000f;
|
|
|
|
d->left.pose.position.z = -0.500000f;
|
|
|
|
d->left.pose.orientation.x = 0.000000f;
|
|
|
|
d->left.pose.orientation.y = 0.000000f;
|
|
|
|
d->left.pose.orientation.z = 0.000000f;
|
|
|
|
d->left.pose.orientation.w = 1.000000f;
|
|
|
|
d->left.linear_velocity.x = -0.770000f;
|
|
|
|
d->left.linear_velocity.y = 3.255000f;
|
|
|
|
d->left.linear_velocity.z = -2.620000f;
|
|
|
|
d->left.angular_velocity.x = 0.000000f;
|
|
|
|
d->left.angular_velocity.y = 0.000000f;
|
|
|
|
d->left.angular_velocity.z = 0.000000f;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (igButton("Interactive Throw #2", zero_dims)) {
|
|
|
|
#if 0
|
|
|
|
d->left.pose.position.x = 1.0f;
|
|
|
|
d->left.pose.position.y = 1.1f;
|
|
|
|
d->left.pose.position.z = -4.0f;
|
|
|
|
#else
|
|
|
|
d->left.pose.position.x = -0.200000f;
|
|
|
|
d->left.pose.position.y = 1.300000f;
|
|
|
|
d->left.pose.position.z = -0.500000f;
|
|
|
|
d->left.pose.orientation.x = 0.858999f;
|
|
|
|
d->left.pose.orientation.y = -0.163382f;
|
|
|
|
d->left.pose.orientation.z = -0.000065f;
|
|
|
|
d->left.pose.orientation.w = 0.485209f;
|
|
|
|
d->left.linear_velocity.x = 0.000000f;
|
|
|
|
d->left.linear_velocity.y = 0.000000f;
|
|
|
|
d->left.linear_velocity.z = 0.000000f;
|
|
|
|
d->left.angular_velocity.x = -10.625000f;
|
|
|
|
d->left.angular_velocity.y = 0.000000f;
|
|
|
|
d->left.angular_velocity.z = 0.000000f;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (igButton("Interactive Throw #3", zero_dims)) {
|
|
|
|
#if 0
|
|
|
|
d->left.pose.position.x = 0.0f;
|
|
|
|
d->left.pose.position.y = 3.0f;
|
|
|
|
d->left.pose.position.z = -5.0f;
|
|
|
|
#else
|
|
|
|
d->left.pose.position.x = -0.200000f;
|
|
|
|
d->left.pose.position.y = 1.300000f;
|
|
|
|
d->left.pose.position.z = -0.500000f;
|
|
|
|
d->left.pose.orientation.x = 0.862432f;
|
|
|
|
d->left.pose.orientation.y = 0.000000f;
|
|
|
|
d->left.pose.orientation.z = 0.000000f;
|
|
|
|
d->left.pose.orientation.w = 0.506174f;
|
|
|
|
d->left.linear_velocity.x = 0.000000f;
|
|
|
|
d->left.linear_velocity.y = 0.000000f;
|
|
|
|
d->left.linear_velocity.z = -1.830000f;
|
|
|
|
d->left.angular_velocity.x = -16.900000f;
|
|
|
|
d->left.angular_velocity.y = 0.000000f;
|
|
|
|
d->left.angular_velocity.z = 0.000000f;
|
|
|
|
#endif
|
2022-01-18 20:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (igButton("XR_EXT_hand_tracking Touch Index Fingertips", zero_dims)) {
|
|
|
|
d->left.pose.position.x = -0.0250000f;
|
|
|
|
d->left.pose.position.y = 1.300000f;
|
|
|
|
d->left.pose.position.z = -0.500000f;
|
|
|
|
d->left.pose.orientation.x = 0.000000f;
|
|
|
|
d->left.pose.orientation.y = 0.000000f;
|
|
|
|
d->left.pose.orientation.z = 0.000000f;
|
|
|
|
d->left.pose.orientation.w = 1.000000f;
|
|
|
|
d->left.linear_velocity.x = 0.000000f;
|
|
|
|
d->left.linear_velocity.y = 0.000000f;
|
|
|
|
d->left.linear_velocity.z = -1.830000f;
|
|
|
|
d->left.angular_velocity.x = -16.900000f;
|
|
|
|
d->left.angular_velocity.y = 0.000000f;
|
|
|
|
d->left.angular_velocity.z = 0.000000f;
|
|
|
|
|
|
|
|
d->left.hand_curl[0] = 0.0f;
|
|
|
|
d->left.hand_curl[1] = 0.0f;
|
|
|
|
d->left.hand_curl[2] = 0.0f;
|
|
|
|
d->left.hand_curl[3] = 0.0f;
|
|
|
|
d->left.hand_curl[4] = 0.0f;
|
|
|
|
|
|
|
|
|
|
|
|
d->right.pose.position.x = 0.0250000f;
|
|
|
|
d->right.pose.position.y = 1.300000f;
|
|
|
|
d->right.pose.position.z = -0.500000f;
|
|
|
|
d->right.pose.orientation.x = 0.000000f;
|
|
|
|
d->right.pose.orientation.y = 0.000000f;
|
|
|
|
d->right.pose.orientation.z = 0.000000f;
|
|
|
|
d->right.pose.orientation.w = 1.000000f;
|
|
|
|
d->right.linear_velocity.x = 0.000000f;
|
|
|
|
d->right.linear_velocity.y = 0.000000f;
|
|
|
|
d->right.linear_velocity.z = -1.830000f;
|
|
|
|
d->right.angular_velocity.x = -16.900000f;
|
|
|
|
d->right.angular_velocity.y = 0.000000f;
|
|
|
|
d->right.angular_velocity.z = 0.000000f;
|
|
|
|
|
|
|
|
d->right.hand_curl[0] = 0.0f;
|
|
|
|
d->right.hand_curl[1] = 0.0f;
|
|
|
|
d->right.hand_curl[2] = 0.0f;
|
|
|
|
d->right.hand_curl[3] = 0.0f;
|
|
|
|
d->right.hand_curl[4] = 0.0f;
|
2020-10-14 19:12:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (igButton("Dump left", zero_dims)) {
|
2020-12-18 15:24:03 +00:00
|
|
|
U_LOG_RAW(
|
|
|
|
"d->left.pose.position.x = %ff;\n"
|
|
|
|
"d->left.pose.position.y = %ff;\n"
|
|
|
|
"d->left.pose.position.z = %ff;\n"
|
|
|
|
"d->left.pose.orientation.x = %ff;\n"
|
|
|
|
"d->left.pose.orientation.y = %ff;\n"
|
|
|
|
"d->left.pose.orientation.z = %ff;\n"
|
|
|
|
"d->left.pose.orientation.w = %ff;\n"
|
|
|
|
"d->left.linear_velocity.x = %ff;\n"
|
|
|
|
"d->left.linear_velocity.y = %ff;\n"
|
|
|
|
"d->left.linear_velocity.z = %ff;\n"
|
|
|
|
"d->left.angular_velocity.x = %ff;\n"
|
|
|
|
"d->left.angular_velocity.y = %ff;\n"
|
|
|
|
"d->left.angular_velocity.z = %ff;\n",
|
2021-01-14 14:13:48 +00:00
|
|
|
d->left.pose.position.x, d->left.pose.position.y, d->left.pose.position.z,
|
|
|
|
d->left.pose.orientation.x, d->left.pose.orientation.y, d->left.pose.orientation.z,
|
|
|
|
d->left.pose.orientation.w, d->left.linear_velocity.x, d->left.linear_velocity.y,
|
|
|
|
d->left.linear_velocity.z, d->left.angular_velocity.x, d->left.angular_velocity.y,
|
2020-12-18 15:24:03 +00:00
|
|
|
d->left.angular_velocity.z);
|
2020-10-14 19:12:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define POSE(prefix) \
|
|
|
|
do { \
|
|
|
|
handle_draggable_vec3_f32(#prefix ".pose.position", &d->prefix.pose.position, \
|
|
|
|
&r->prefix.pose.position); \
|
|
|
|
handle_draggable_quat(#prefix ".pose.orientation", &d->prefix.pose.orientation, \
|
|
|
|
&r->prefix.pose.orientation); \
|
2020-10-14 19:12:33 +00:00
|
|
|
} while (false)
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define LIN_ANG(prefix) \
|
|
|
|
do { \
|
|
|
|
handle_draggable_vec3_f32(#prefix ".linear_velocity", &d->prefix.linear_velocity, \
|
|
|
|
&r->prefix.linear_velocity); \
|
|
|
|
handle_draggable_vec3_f32(#prefix ".angular_velocity", &d->prefix.angular_velocity, \
|
|
|
|
&r->prefix.angular_velocity); \
|
2020-10-14 19:12:33 +00:00
|
|
|
} while (false)
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define BUTTONS(prefix) \
|
|
|
|
do { \
|
2022-05-28 14:16:59 +00:00
|
|
|
handle_input(&d->prefix); \
|
2020-10-14 19:12:33 +00:00
|
|
|
} while (false)
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define CURL(prefix, name, index) igDragFloat(#prefix "." #name, &d->prefix.hand_curl[index], 0.01, 0.0, 1.0, "%f", 0);
|
|
|
|
#define HAND(prefix) \
|
|
|
|
do { \
|
2022-01-18 20:33:11 +00:00
|
|
|
igCheckbox("Hand tracking Active", &d->prefix.hand_tracking_active); \
|
2021-01-14 14:13:48 +00:00
|
|
|
CURL(prefix, little, 0); \
|
|
|
|
CURL(prefix, ring, 1); \
|
|
|
|
CURL(prefix, middle, 2); \
|
|
|
|
CURL(prefix, index, 3); \
|
|
|
|
CURL(prefix, thumb, 4); \
|
2020-11-18 17:33:23 +00:00
|
|
|
} while (false)
|
|
|
|
|
2020-10-14 19:12:33 +00:00
|
|
|
static void
|
|
|
|
on_connected(struct gui_remote *gr, struct gui_program *p)
|
|
|
|
{
|
|
|
|
const struct r_remote_data *r = &gr->reset;
|
|
|
|
struct r_remote_data *d = &gr->data;
|
|
|
|
|
2022-03-21 13:14:19 +00:00
|
|
|
igPushIDPtr(&d->hmd); // Make all IDs unique.
|
2020-10-14 19:12:33 +00:00
|
|
|
POSE(hmd);
|
2022-03-21 13:14:19 +00:00
|
|
|
igPopID(); // Pop unique IDs
|
2020-10-14 19:12:33 +00:00
|
|
|
|
2022-03-21 13:14:19 +00:00
|
|
|
igPushIDPtr(&d->left); // Make all IDs unique.
|
2020-10-14 19:12:33 +00:00
|
|
|
POSE(left);
|
|
|
|
LIN_ANG(left);
|
|
|
|
BUTTONS(left);
|
2020-11-18 17:33:23 +00:00
|
|
|
HAND(left);
|
2022-03-21 13:14:19 +00:00
|
|
|
igPopID(); // Pop unique IDs
|
2020-10-14 19:12:33 +00:00
|
|
|
|
2022-03-21 13:14:19 +00:00
|
|
|
igPushIDPtr(&d->right); // Make all IDs unique.
|
2020-10-14 19:12:33 +00:00
|
|
|
POSE(right);
|
|
|
|
LIN_ANG(right);
|
|
|
|
BUTTONS(right);
|
2020-11-18 17:33:23 +00:00
|
|
|
HAND(right);
|
2022-03-21 13:14:19 +00:00
|
|
|
igPopID(); // Pop unique IDs
|
2020-10-14 19:12:33 +00:00
|
|
|
|
|
|
|
igCheckbox("Predefined poses", &gr->cheat_menu);
|
|
|
|
if (gr->cheat_menu) {
|
|
|
|
render_cheat_menu(gr, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
r_remote_connection_write_one(&gr->rc, &gr->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_not_connected(struct gui_remote *gr, struct gui_program *p)
|
|
|
|
{
|
2022-05-28 11:04:25 +00:00
|
|
|
igInputText("Address", gr->address, sizeof(gr->address), 0, NULL, NULL);
|
|
|
|
igSliderInt("Port", &gr->port, 0, UINT16_MAX, "%i", 0);
|
|
|
|
|
|
|
|
bool connect = igButton("Connect", zero_dims);
|
|
|
|
|
|
|
|
igSameLine(0, 4.0f);
|
|
|
|
|
|
|
|
if (igButton("Exit", zero_dims)) {
|
|
|
|
gui_scene_delete_me(p, &gr->base);
|
2020-10-14 19:12:33 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-28 11:04:25 +00:00
|
|
|
if (!connect) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r_remote_connection_init(&gr->rc, gr->address, gr->port);
|
2020-10-14 19:12:33 +00:00
|
|
|
r_remote_connection_read_one(&gr->rc, &gr->reset);
|
|
|
|
r_remote_connection_read_one(&gr->rc, &gr->data);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Scene functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
scene_render(struct gui_scene *scene, struct gui_program *p)
|
|
|
|
{
|
|
|
|
struct gui_remote *gr = (struct gui_remote *)scene;
|
|
|
|
(void)gr;
|
|
|
|
|
|
|
|
igBegin("Remote control", NULL, 0);
|
|
|
|
|
|
|
|
#ifdef XRT_BUILD_DRIVER_REMOTE
|
|
|
|
if (gr->rc.fd < 0) {
|
|
|
|
on_not_connected(gr, p);
|
|
|
|
} else {
|
|
|
|
on_connected(gr, p);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
igText("Not compiled with the remote driver");
|
|
|
|
if (igButton("Exit", zero_dims)) {
|
|
|
|
gui_scene_delete_me(p, &gr->base);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
igEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
scene_destroy(struct gui_scene *scene, struct gui_program *p)
|
|
|
|
{
|
|
|
|
struct gui_remote *gr = (struct gui_remote *)scene;
|
|
|
|
(void)gr;
|
|
|
|
|
|
|
|
free(scene);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* 'Exported' functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2022-06-01 13:44:51 +00:00
|
|
|
gui_scene_remote(struct gui_program *p, const char *address)
|
2020-10-14 19:12:33 +00:00
|
|
|
{
|
|
|
|
struct gui_remote *gr = U_TYPED_CALLOC(struct gui_remote);
|
|
|
|
|
|
|
|
gr->base.render = scene_render;
|
|
|
|
gr->base.destroy = scene_destroy;
|
|
|
|
gr->rc.fd = -1;
|
|
|
|
|
2022-05-28 11:04:25 +00:00
|
|
|
// GUI input defaults.
|
2022-06-01 13:44:51 +00:00
|
|
|
if (address != NULL) {
|
|
|
|
snprintf(gr->address, sizeof(gr->address), "%s", address);
|
|
|
|
} else {
|
|
|
|
snprintf(gr->address, sizeof(gr->address), "localhost");
|
|
|
|
}
|
2022-05-28 11:04:25 +00:00
|
|
|
gr->port = 4242;
|
|
|
|
|
2020-10-14 19:12:33 +00:00
|
|
|
gui_scene_push_front(p, &gr->base);
|
|
|
|
}
|