summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/i18n.h7
-rw-r--r--client/i18n/en_us.h6
-rw-r--r--client/main.h5
-rw-r--r--client/serial.c15
-rw-r--r--client/setup.c3
-rw-r--r--client/term.h7
-rw-r--r--client/term_linux.c29
-rw-r--r--client/ui.c114
-rw-r--r--client/ui.h8
9 files changed, 185 insertions, 9 deletions
diff --git a/client/i18n.h b/client/i18n.h
new file mode 100644
index 0000000..11fd576
--- /dev/null
+++ b/client/i18n.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#ifndef W2_LANG_DEFAULT
+#define W2_LANG_DEFAULT
+#include "i18n/en_us.h"
+#endif
+
diff --git a/client/i18n/en_us.h b/client/i18n/en_us.h
new file mode 100644
index 0000000..4117ef6
--- /dev/null
+++ b/client/i18n/en_us.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#define W2_UI_CONN_STAT_CONNECTED "connected"
+#define W2_UI_CONN_STAT_DISCONNECTED "disconnected"
+#define W2_UI_CONN_STAT_PING "ping"
+#define W2_UI_BATT_STAT_BATTERY "battery"
diff --git a/client/main.h b/client/main.h
index 462da73..693db91 100644
--- a/client/main.h
+++ b/client/main.h
@@ -5,6 +5,11 @@
typedef struct {
unsigned int ping;
uint8_t ping_id;
+ bool ping_received;
+
+ bool connected;
+ uint8_t battery_level;
+
w2_s_cmd_info_tx info;
w2_s_cmd_sens_tx io;
} w2_s_client_state;
diff --git a/client/serial.c b/client/serial.c
index 0d0bca7..9efb966 100644
--- a/client/serial.c
+++ b/client/serial.c
@@ -1,3 +1,5 @@
+#include <memory.h>
+
#include "serial.h"
#include "../shared/protocol.h"
#include "../shared/serial_parse.h"
@@ -10,16 +12,25 @@ void w2_serial_main() {
}
void w2_cmd_ping_tx(w2_s_bin *data) {
- // TODO: check ping id
+ W2_CAST_BIN(w2_s_cmd_ping_tx, data, cast);
+
+ if (g_w2_state.ping_received) return;
+ if (g_w2_state.ping_id != cast->id) return;
g_w2_state.ping = w2_timer_end(W2_TIMER_PING);
+ g_w2_state.ping_received = true;
+
printf("ping measured, %ims\n", g_w2_state.ping);
}
+
void w2_cmd_expt_tx(w2_s_bin *data) { printf("w2_cmd_expt_tx()\n"); }
void w2_cmd_mode_tx(w2_s_bin *data) { printf("w2_cmd_mode_tx()\n"); }
void w2_cmd_cord_tx(w2_s_bin *data) { printf("w2_cmd_cord_tx()\n"); }
void w2_cmd_bomd_tx(w2_s_bin *data) { printf("w2_cmd_bomd_tx()\n"); }
void w2_cmd_sens_tx(w2_s_bin *data) { printf("w2_cmd_sens_tx()\n"); }
-void w2_cmd_info_tx(w2_s_bin *data) { printf("w2_cmd_info_tx()\n"); }
+
+void w2_cmd_info_tx(w2_s_bin *data) {
+ memcpy(&g_w2_state.info, data->data, sizeof(w2_s_cmd_info_tx));
+}
void w2_cmd_ping_rx(w2_s_bin *data) { return; }
void w2_cmd_mode_rx(w2_s_bin *data) { return; }
diff --git a/client/setup.c b/client/setup.c
index 2e8cce7..5eb6c13 100644
--- a/client/setup.c
+++ b/client/setup.c
@@ -6,6 +6,7 @@
#include "commands.h"
#include "serial.h"
#include "setup.h"
+#include "term.h"
// pointers for endianness check
static const uint16_t _test = 1;
@@ -23,6 +24,8 @@ void w2_client_setup(int argc, char **argv) {
exit(1);
}
+ w2_term_raw_mode();
+
w2_cmd_setup_handlers();
w2_send_info();
diff --git a/client/term.h b/client/term.h
new file mode 100644
index 0000000..a60dc2c
--- /dev/null
+++ b/client/term.h
@@ -0,0 +1,7 @@
+#pragma once
+
+/** set terminal to raw mode */
+void w2_term_raw_mode();
+/** set ui canvas props */
+void w2_term_props();
+
diff --git a/client/term_linux.c b/client/term_linux.c
new file mode 100644
index 0000000..2a88d6c
--- /dev/null
+++ b/client/term_linux.c
@@ -0,0 +1,29 @@
+#ifdef W2_HOST_LINUX
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "term.h"
+#include "ui.h"
+
+void w2_term_raw_mode() {
+ fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+ struct termios term;
+ tcgetattr(STDIN_FILENO, &term);
+ term.c_lflag &= ~(ECHO | ICANON);
+ term.c_cc[VTIME] = 0;
+ term.c_cc[VMIN] = 1;
+ tcsetattr(STDIN_FILENO, 0, &term);
+}
+
+void w2_term_props() {
+ struct winsize window;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
+
+ g_w2_ui_canvas.width = window.ws_col;
+ g_w2_ui_canvas.height = window.ws_row;
+}
+
+#endif
diff --git a/client/ui.c b/client/ui.c
index 239065c..84408bb 100644
--- a/client/ui.c
+++ b/client/ui.c
@@ -1,4 +1,13 @@
+#include <string.h>
+
+#include "../shared/util.h"
+#include "../shared/bin.h"
+#include "i18n.h"
+#include "main.h"
#include "ui.h"
+#include "term.h"
+
+w2_s_ui_tty_canvas g_w2_ui_canvas;
void w2_ui_main() {
w2_ui_update();
@@ -6,9 +15,108 @@ void w2_ui_main() {
}
void w2_ui_update() {
- // measure terminal width and height
+ w2_term_props();
+}
+
+void w2_ui_paint() {
+ w2_ui_paint_statusbar();
+}
+
+void w2_ui_align(char* text, w2_e_alignment align, unsigned int length) {
+ unsigned int padding = 0;
+
+ switch(align) {
+ case W2_UI_ALIGN_LEFT: {
+ break;
+ }
+ case W2_UI_ALIGN_CENTER: {
+ unsigned int middle = length / 2;
+ unsigned int offset = strlen(text) / 2;
+ padding = W2_MAX(0, middle - offset);
+ break;
+ }
+ case W2_UI_ALIGN_RIGHT: {
+ unsigned int right = length;
+ unsigned int offset = strlen(text);
+ padding = W2_MAX(0, right - offset);
+ break;
+ }
+ }
+
+ char* temp = calloc(length, 1);
+ sprintf(temp, "%*s%s", padding, "", text);
+ memcpy(text, temp, length);
+ free(temp);
+}
+
+char* w2_ui_pt_sb_con_sts() {
+ char* connected = g_w2_state.connected ? W2_UI_CONN_STAT_CONNECTED : W2_UI_CONN_STAT_DISCONNECTED;
+ char* out = calloc(g_w2_ui_canvas.width, 1);
+ sprintf(out, "%s, %ims %s", connected, g_w2_state.ping, W2_UI_CONN_STAT_PING);
+ w2_ui_align(out, W2_UI_ALIGN_LEFT, g_w2_ui_canvas.width);
+ return out;
+}
+char* w2_ui_pt_sb_ver_num() {
+ char* out = calloc(g_w2_ui_canvas.width, 1);
+ sprintf(out, "(%s)", g_w2_state.info.build_str);
+ w2_ui_align(out, W2_UI_ALIGN_CENTER, g_w2_ui_canvas.width);
+ return out;
+}
+char* w2_ui_pt_sb_bat_sts() {
+ char* out = calloc(g_w2_ui_canvas.width, 1);
+ sprintf(out, "%s %i%%", W2_UI_BATT_STAT_BATTERY, g_w2_state.battery_level);
+ w2_ui_align(out, W2_UI_ALIGN_RIGHT, g_w2_ui_canvas.width);
+ return out;
}
-void w2_ui_paint() { w2_ui_paint_statusbar(); }
+void w2_ui_nullsub(char* str, unsigned int length) {
+ for (int i = 0; i < length; i++) if (str[i] == 0x00) str[i] = ' ';
+}
+
+void w2_ui_overlay(char *bottom, char *top, unsigned int length) {
+ w2_ui_nullsub(bottom, length);
+ w2_ui_nullsub(top, length);
+
+ unsigned int start = 0;
+ for (int i = 0; i < length; i++) {
+ start = i;
+ if (top[start] != ' ') break;
+ }
+ unsigned int stop = 0;
+ for (int i = 0; i < length; i++) {
+ stop = length - i;
+ if (top[stop] != ' ') break;
+ }
+
+ for (int i = 0; i < length; i++) {
+ if (i >= start && i <= stop) bottom[i] = top[i];
+ }
+}
+
+// char* w2_ui_pt_sb_logic_mode() {}
+// char* w2_ui_pt_sb_exceptions() {}
+// char* w2_ui_pt_sb_tabbar() {}
+
+void w2_ui_paint_statusbar() {
+ char top_row[g_w2_ui_canvas.width];
+
+ char* con_sts = w2_ui_pt_sb_con_sts();
+ char* ver_num = w2_ui_pt_sb_ver_num();
+ char* bat_sts = w2_ui_pt_sb_bat_sts();
+
+ w2_ui_overlay(top_row, con_sts, g_w2_ui_canvas.width);
+ w2_ui_overlay(top_row, ver_num, g_w2_ui_canvas.width);
+ w2_ui_overlay(top_row, bat_sts, g_w2_ui_canvas.width);
+
+ printf("%s", top_row);
+
+ free(con_sts);
+ free(ver_num);
+ free(bat_sts);
+
+ // w2_ui_pt_sb_connection_status();
+ // w2_ui_pt_sb_connection_status();
+ // w2_ui_pt_sb_connection_status();
+ printf("\n");
+}
-void w2_ui_paint_statusbar() {}
diff --git a/client/ui.h b/client/ui.h
index afb0817..36266ba 100644
--- a/client/ui.h
+++ b/client/ui.h
@@ -42,10 +42,10 @@ void w2_ui_paint_statusbar();
/** update and paint */
void w2_ui_main();
-/** echo ansi color code for foreground color */
-void w2_ui_set_fg(w2_e_colors color);
-/** echo ansi color code for background color */
-void w2_ui_set_bg(w2_e_colors color);
+/** get ansi color code for foreground color */
+char* w2_ui_set_fg(w2_e_colors color);
+/** get ansi color code for background color */
+char* w2_ui_set_bg(w2_e_colors color);
/** align `text` `align` with `text` buffer length `length` */
void w2_ui_align(char *text, w2_e_alignment align, unsigned int length);