#include <sys/timerfd.h>
#include <unistd.h>
+#include <ncurses.h>
+
#include "client.h"
#include "main.h"
#include "logging.h"
void* data = NULL;
int epollfd = -1;
int timerfd = -1;
+ int stdinfd = -1;
int ready;
int r;
goto ERROR;
}
+ // Setup the TUI
+ r = fireperf_tui_init(&ctx->tui, ctx);
+ if (r)
+ goto ERROR;
+
// Set limits
r = set_limits(ctx);
if (r)
goto ERROR;
}
+ // Register the TUI with the event loop
+ stdinfd = fireperf_tui_register(ctx->tui, epollfd);
+ if (stdinfd < 0) {
+ ERROR(ctx, "Could not register the TUI: %s\n", strerror(-stdinfd));
+ goto ERROR;
+ }
+
// Create a timer that fires once a second
timerfd = setup_timer(ctx, epollfd);
if (timerfd < 0) {
if (r)
goto ERROR;
+ // Handle user input
+ } else if (fd == stdinfd) {
+ r = fireperf_tui_action(ctx->tui);
+ if (r)
+ goto ERROR;
+
// Handle everything else
} else {
switch (ctx->mode) {
}
ERROR:
+ // Terminate the TUI
+ fireperf_tui_finish(ctx->tui);
+
switch (ctx->mode) {
case FIREPERF_MODE_CLIENT:
fireperf_client_free(ctx, data);
--- /dev/null
+/*#############################################################################
+# #
+# fireperf - A network benchmarking tool #
+# Copyright (C) 2024 IPFire Development Team #
+# #
+# 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 3 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 <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+
+#include <ncurses.h>
+
+#include "ctx.h"
+#include "tui.h"
+
+struct fireperf_tui {
+ struct fireperf_ctx* ctx;
+
+ // The main screen
+ WINDOW* screen;
+
+ // The frame around the screen
+ WINDOW* frame;
+
+ // The status bar
+ WINDOW* status;
+};
+
+static int fireperf_tui_setup_frame(struct fireperf_tui* tui) {
+ int r;
+
+ // Create the window
+ tui->frame = newwin(LINES - 1, COLS, 0, 0);
+ if (!tui->frame)
+ return 1;
+
+ // Make my brush blue
+ wattron(tui->frame, COLOR_PAIR(3));
+
+ // Draw a box around the frame
+ box(tui->frame, 0, 0);
+
+ // Reset my brush
+ wattroff(tui->frame, COLOR_PAIR(3));
+
+ // Refresh
+ wrefresh(tui->frame);
+
+ return 0;
+}
+
+static int fireperf_tui_setup_status(struct fireperf_tui* tui) {
+ int r;
+
+ // Create the window
+ tui->status = newwin(1, COLS, LINES - 1, 0);
+ if (!tui->status)
+ return 1;
+
+ // Create status line
+ move(LINES - 1, 0);
+
+ const char* help = "Press 'q' to quit";
+
+ // Write in black & white
+ wattron(tui->status, COLOR_PAIR(4));
+
+ // Push the help text to the right
+ for (int i = 0; i < COLS - strlen(help); i++)
+ waddch(tui->status, ' ');
+
+ // Write the help text
+ waddstr(tui->status, help);
+
+ // Reset the colour
+ wattroff(tui->status, COLOR_PAIR(4));
+
+ // Refresh
+ wrefresh(tui->status);
+
+ return 0;
+}
+
+static int fireperf_tui_setup(struct fireperf_tui* tui) {
+ int r;
+
+ // Start ncurses
+ tui->screen = initscr();
+ if (!tui->screen)
+ return -errno;
+
+ // We would like to see colours
+ start_color();
+
+ // Configure a few colours
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+ init_pair(2, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(3, COLOR_BLUE, COLOR_BLACK);
+ init_pair(4, COLOR_BLACK, COLOR_WHITE);
+
+ // Enable raw mode
+ raw();
+
+ // Disable character echoing
+ noecho();
+
+ // Set the cursor to the top
+ curs_set(0);
+
+ // Configure the keyboard
+ keypad(stdscr, 1);
+
+ // ???
+ halfdelay(1);
+
+ // Refresh!
+ refresh();
+
+ // Setup the frame
+ r = fireperf_tui_setup_frame(tui);
+ if (r)
+ return r;
+
+ // Setup the status bar
+ r = fireperf_tui_setup_status(tui);
+ if (r)
+ return r;
+
+ // Refresh!
+ refresh();
+
+ return 0;
+}
+
+int fireperf_tui_init(struct fireperf_tui** tui, struct fireperf_ctx* ctx) {
+ struct fireperf_tui* t = NULL;
+ int r;
+
+ // Allocate the TUI
+ t = calloc(1, sizeof(*t));
+ if (!t)
+ return -errno;
+
+ // Store a reference to the context
+ t->ctx = ctx;
+
+ // Perform the basic setup
+ r = fireperf_tui_setup(t);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+void fireperf_tui_finish(struct fireperf_tui* tui) {
+ endwin();
+
+ free(tui);
+}
+
+int fireperf_tui_register(struct fireperf_tui* tui, int epollfd) {
+ const int fd = STDIN_FILENO;
+ int r;
+
+ struct epoll_event ev = {
+ .events = EPOLLIN|EPOLLET,
+ .data.fd = fd,
+ };
+
+ // Register the timer with the event loop
+ r = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);
+ if (r)
+ return -errno;
+
+ return fd;
+}
+
+/*
+ Called when the user presses a button
+*/
+int fireperf_tui_action(struct fireperf_tui* tui) {
+ int c;
+
+ for (;;) {
+ // Fetch the next character
+ c = getch();
+ if (c < 0)
+ break;
+
+ switch (c) {
+ // Quit
+ case 'q':
+ return -ESHUTDOWN;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*#############################################################################
+# #
+# fireperf - A network benchmarking tool #
+# Copyright (C) 2024 IPFire Development Team #
+# #
+# 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 3 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 FIREPERF_TUI_H
+#define FIREPERF_TUI_H
+
+struct fireperf_tui;
+
+#include "ctx.h"
+
+int fireperf_tui_init(struct fireperf_tui** tui, struct fireperf_ctx* ctx);
+void fireperf_tui_finish(struct fireperf_tui* tui);
+
+int fireperf_tui_register(struct fireperf_tui* tui, int epollfd);
+int fireperf_tui_action(struct fireperf_tui* tui);
+
+#endif /* FIREPERF_TUI_H */