Skip to content

Native apps for Windows, macOS and Linux - #3

Merged
Neo-Desktop merged 9 commits into
mainfrom
claude/project-thread-u09q93
Nov 6, 2026
Merged

Neo-Desktop merged 9 commits into
mainfrom
claude/project-thread-u09q93

Conversation

@Neo-Desktop

Copy link
Copy Markdown
Contributor

Requested by Sydney · project thread

Summary

Three native desktop apps for D-Modem, built on one shared C library:

  • libdmodemctl (core/): a small C library with no I/O and no threads. It handles the AT session (command queue, call state, escape and hang-up, caller ID), the settings model from AT!M, the call statistics from AT#UD, a VT100 screen, and dmodemd's startup lines. It has 230+ checks, also run under ASan and UBSan.
  • Linux (linux/): GTK 4, libadwaita and VTE.
  • Windows (windows/): plain Win32 C++98 with ANSI APIs, so one binary runs on Windows 95 through 11. It builds with Open Watcom (build-watcom.sh) and also with MinGW or MSVC through CMake. On 9x it connects to a modem over TCP or a COM port.
  • macOS (macos/): SwiftUI, with the project generated by XcodeGen. The SIP password is kept in the keychain.

All three have the same pages: Modem, Terminal (including the modem's AT!CF and AT!CT setup screens), Settings, Call Stats and Log. They use the brand icon and banner. The design is described in docs/design.md.

This depends on D-Modem/D-Modem's AT!M pull request for the Settings page. Without it, the other pages still work.

Testing

  • The Linux app was run under Xvfb against a live dmodemd (see the screenshots in docs/images).
  • The Windows app was built with MinGW and run under Wine against a live dmodemd over TCP. The Modem, Settings, Terminal, configurator and Call Stats pages all worked. Two bugs found this way are fixed here:
    • After Alt-X the app stayed in configurator mode, because the final OK was dropped from AT!CF's long screen line.
    • The group boxes had paint glitches.
  • The macOS app and the Open Watcom build have not been compiled locally. CI builds both, and this PR is how they get checked.

Generated by Claude Code

A plain C library with no I/O of its own, so the Windows, macOS and
Linux apps can each be only views: the AT session (commands, their
responses, the call's state from the result codes, hanging up through
the escape), the settings model from AT!M, the call statistics from
AT#UD, a small ANSI terminal screen for the configurator, and reading
dmodemd's start-up lines.  Tested against dmodemd's own output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
Starts dmodemd as the user and opens its pty, or opens a modem that
already runs.  Five pages: Modem (state, dial, answer, hang up, start
and stop, the device for other programs), Terminal (a VTE on the modem,
with the full-screen and command-line setup), Settings (a row for each
of the modem's settings from AT!M, applied at once; the init string),
Call Stats (AT#UD as rows, and ATI11) and Log (dmodemd's output).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
- windows/: the Windows app in plain Win32 C++ (ANSI APIs, Win95
  common controls, Winsock 1.1), so that it runs on Windows 95 and
  later: Modem, Terminal, Settings, Call Stats and Log pages over
  libdmodemctl.  dmodemd is started where Windows can run it; on 9x
  the app reaches a modem over TCP or a COM port.  build-watcom.sh
  builds it with Open Watcom; CMake builds it with MinGW or MSVC.
- macos/: the SwiftUI app (XcodeGen project), with the terminal drawn
  from libdmodemctl's screen, the SIP password in the keychain.
- The app icon (assets/dmodem.svg, from the brand's jack art) as .ico
  and an asset catalogue, by tools/icons.js and tools/icons.py.
- libdmodemctl: anonymous enums (Swift imports them as constants),
  Backspace as BS (the modem's S5), key table without designated
  initialisers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
- .github/workflows/build.yml: Linux (with the tests, and again with
  ASan and UBSan), Windows 95 and later with Open Watcom, Windows with
  MSVC, and macOS with XcodeGen and xcodebuild.
- libdmodemctl: a line over 4 KiB keeps its end, not its start.  AT!CF
  sends its screens with no line ends and its OK after the last one, so
  the OK was lost and the app stayed in the configurator after Alt-X.
- Windows: the pages without WS_CLIPCHILDREN, so that the page paints
  inside its group boxes.
- Screenshots of the Windows app, run under Wine against dmodemd.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
@Neo-Desktop Neo-Desktop self-assigned this Nov 6, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
…fore stopping

Open Watcom's C takes only constants in an aggregate's initialiser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B82eRVTPinTtLUajudobBC
@Neo-Desktop
Neo-Desktop merged commit 1891815 into main Nov 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants