udpscope: an oscilloscope view for a UDPStreamer source

GTK4 and libadwaita. It receives one UDP stream through the vendored
udpsclient, buffers it in a large ring, and draws it with the vendored
plotter: a trigger with a pre/post event window, a pause that freezes the
window, cursors, measurements, math channels in a node editor, an event cache,
named configurations, preferences, and an export of the visible window to
.npy/.csv. Waveform files can be opened and analysed in place.

The interface is two threads -- a producer that owns the socket and the GTK
main thread that owns every widget and the GL context -- sharing one model
under one mutex, with samples crossing through lock-free rings.

deps/plotter is a submodule pinned to the commit this tree builds against;
deps/udpsclient is vendored in place. docs/claude/ documents the rules that
cost a defect to learn, and SPECS.md is the requirement document.
This commit is contained in:
Martino Ferrari committed 2026-10-11 15:21:40 +02:00
1 parent 8f54841c2c
commit 0e256764d5
41 files changed
+2081 -154

No files matched your search

+27
View File
@@ -78,6 +78,30 @@ add_custom_command(
COMMENT "Compiling udpscope help resources"
VERBATIM)
# --- UI files: GtkBuilder XML in a GResource ----------------------------------
# The third bundle, for the same reason as the other two: `.ui` files are data, so they are compiled
# in rather than looked for at runtime -- and `preprocess="xml-stripblanks"` makes a malformed one a
# build failure with a file and line number, instead of a window that silently refuses to open.
set(UDPSCOPE_UI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/ui)
file(GLOB UDPSCOPE_UI_FILES CONFIGURE_DEPENDS ${UDPSCOPE_UI_DIR}/*.ui)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/udpscope_ui_resources.c
COMMAND ${GLIB_COMPILE_RESOURCES}
--target=${CMAKE_CURRENT_BINARY_DIR}/udpscope_ui_resources.c
--sourcedir=${UDPSCOPE_UI_DIR}
--c-name=udpscope_ui
--generate-source
${UDPSCOPE_UI_DIR}/udpscope-ui.gresource.xml
DEPENDS ${UDPSCOPE_UI_DIR}/udpscope-ui.gresource.xml ${UDPSCOPE_UI_FILES}
COMMENT "Compiling udpscope UI resources"
VERBATIM)
# The generated source carries each file as one C string literal, and a `.ui` is big enough to pass the
# 4095-character minimum the standard requires a compiler to support: `-Woverlength-strings` fires on
# generated *data*, not on anything anyone wrote. Silenced for this one generated file (the icon and
# help bundles are small enough per file never to need it), so the build stays at its four warnings.
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/udpscope_ui_resources.c
PROPERTIES COMPILE_OPTIONS "-Wno-overlength-strings")
# --- build info: version, commit and timestamp compiled into the binary -------
# Written at configure time so add_executable can name the file, and again on every
# build so the commit and the timestamp belong to the binary that is running rather
@@ -100,6 +124,7 @@ set_source_files_properties(${UDPSCOPE_BUILD_INFO} PROPERTIES GENERATED TRUE)
add_executable(udpscope
${CMAKE_CURRENT_BINARY_DIR}/udpscope_resources.c
${CMAKE_CURRENT_BINARY_DIR}/udpscope_help_resources.c
${CMAKE_CURRENT_BINARY_DIR}/udpscope_ui_resources.c
${UDPSCOPE_BUILD_INFO}
src/main.cpp
src/config.cpp
@@ -121,6 +146,8 @@ add_executable(udpscope
src/status_text.cpp
src/shortcuts.cpp
src/help_window.cpp
src/settings.cpp
src/ui_prefs.cpp
src/ui.cpp
src/ui_probe.cpp
src/ui_widgets.cpp