C++ backend with SSE streaming (reuses qpwgraph PipeWire callbacks). Svelte frontend with custom SVG canvas for port-level connections. Features: - Live PipeWire graph via SSE - Drag output->input port to connect - Double-click or select+Delete to disconnect - Node positions saved to localStorage - Pan (drag bg) and zoom (scroll) - Port type coloring (audio=green, midi=red, video=blue)
70 lines
1.8 KiB
C++
70 lines
1.8 KiB
C++
#include "graph_engine.h"
|
|
#include "web_server.h"
|
|
|
|
#include <csignal>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <unistd.h>
|
|
#include <atomic>
|
|
|
|
static std::atomic<bool> g_running(true);
|
|
|
|
static void signal_handler(int sig) {
|
|
g_running = false;
|
|
fprintf(stderr, "\npwweb: caught signal %d, shutting down...\n", sig);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int port = 9876;
|
|
|
|
// Parse optional port argument
|
|
if (argc > 1) {
|
|
port = atoi(argv[1]);
|
|
if (port <= 0 || port > 65535) {
|
|
fprintf(stderr, "usage: pwweb [port]\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
signal(SIGINT, signal_handler);
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
pwgraph::GraphEngine engine;
|
|
|
|
fprintf(stderr, "pwweb: connecting to PipeWire...\n");
|
|
if (!engine.open()) {
|
|
fprintf(stderr, "pwweb: failed to connect to PipeWire.\n");
|
|
fprintf(stderr, " Make sure XDG_RUNTIME_DIR is set: export XDG_RUNTIME_DIR=/run/user/$(id -u)\n");
|
|
return 1;
|
|
}
|
|
|
|
pwgraph::WebServer server(engine, port);
|
|
|
|
// Wire change notifications to broadcast
|
|
engine.setOnChange([&server]() {
|
|
server.broadcastGraph();
|
|
});
|
|
|
|
if (!server.start()) {
|
|
fprintf(stderr, "pwweb: failed to start web server on port %d\n", port);
|
|
engine.close();
|
|
return 1;
|
|
}
|
|
|
|
fprintf(stderr, "pwweb: server running at http://localhost:%d\n", port);
|
|
fprintf(stderr, "pwweb: API at http://localhost:%d/api/graph\n", port);
|
|
fprintf(stderr, "pwweb: press Ctrl+C to stop\n");
|
|
|
|
// Main loop — just wait for shutdown signal
|
|
while (g_running) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
|
}
|
|
|
|
fprintf(stderr, "pwweb: shutting down...\n");
|
|
server.stop();
|
|
engine.close();
|
|
|
|
fprintf(stderr, "pwweb: goodbye.\n");
|
|
return 0;
|
|
}
|