All notable changes to this project will be documented in this file.
- Stuffit 1.5.1 archives (
.sit) now generated as a distribution artifact alongside.dskand.hqx, containing Flynn and About Flynn. Expand with StuffIt Expander on the Mac.
- Cross-application clipboard broken under System 6 MultiFinder: the
app4Evthandler ignoredconvertClipboardFlag, so Flynn never calledLoadScrap/UnloadScrapon suspend/resume. Text copied in other apps was invisible to Flynn's paste and Show Clipboard, and text copied in Flynn never reached other apps. - MacBinary headers for
Flynn.binnow carry the build's creation/modification date instead of the epoch, so Finder no longer shows deployed copies as "Fri Jan 1 1904".
- HIG-appropriate modal dialogs: dBoxProc on System 6, movableDBoxProc on System 7 (draggable title bar)
- All modal dialogs centered on screen (horizontal center, upper-third vertical)
- Background window redraw when dragging movable modals on System 7
- Edit Favorite dialog: redesigned with title bar (noGrowDocProc), split Font/Size popups, Theme/Backspace/Echo settings per favorite
- Manage Favorites dialog: title bar added for consistency (noGrowDocProc)
- Status bar shows Backspace (BS/DEL) and Local Echo (Echo On/Off) indicators
- Theme engine: 9 built-in themes (Light, Dark, Solarized Light/Dark, Tokyo Light/Dark, Green Screen, Classic, Platinum) with 4 optional themes (Dracula, Monokai, Nord, Gruvbox)
- Per-window settings: theme, terminal type, backspace, and local echo are independent per session
- Per-bookmark theme/backspace/local echo persistence (saved alongside existing per-bookmark font/terminal type)
- New sessions inherit active session's theme and input settings (falls back to prefs on first launch)
- Theme submenu under Options menu on color systems (System 7+), simple Dark Mode On/Off toggle on mono (System 6)
- docs/THEMES.md: developer guide for creating custom themes
- Session logging (Cmd+L): continuous output logging to text file with ANSI escape sequence filtering, CR deduplication, and sensitive data warning in log header
- Print support (Cmd+P): Page Setup and Print via Printing Manager with paginated output, Geneva 9pt header/footer, Monaco 9pt terminal content, and ImageWriter spool printing
- Telnet NOP keep-alive: sends IAC NOP after 120 seconds idle to prevent NAT/firewall drops
- Reconnect (Cmd+R): reconnect to same host after disconnect, also available in File menu
- Reconnect button on disconnect alert: one-click reconnect when remote host closes connection
- Reset Terminal in Control menu: clears screen and resets parser state without disconnecting
- Clear Scrollback in Edit menu: frees scrollback buffer for long sessions
- Find in Scrollback (Cmd+F) with Find Again (Cmd+G): search backward through terminal content
- Show Clipboard viewer window in Edit menu: TextEdit display with scrollbars, resize support
- GURL Apple Event handler: System 7 browsers can hand off telnet:// URLs to Flynn
- Window position saved to preferences and restored on next launch
- Multi-session status bar toggle applied wrong theme: resize loop loaded per-session font but not per-session theme, so all windows were redrawn with the active session's theme (System 7 color only)
- Grow box (size box) not redrawn on window activate/deactivate: DrawGrowIcon was missing from handle_activate, so cascaded windows whose grow box was never obscured showed a stale/empty grow box after switching (both mono and color)
- Window port backColor not synced with theme on session switch: PaintBehind filled exposed regions with stale white/black instead of the session's theme background (System 7 color only)
- Status bar showed global terminal type instead of per-session type: all sessions displayed prefs.terminal_type rather than their own negotiated ttype
- Out of memory on 3rd session with color themes: SIZE resource calculation did not account for per-session CellColor arrays or the shared GWorld offscreen buffer; color builds now floor at 1024KB preferred partition (System 6 mono builds unaffected)
- Color selection not highlighting empty cells beyond text: selected runs of plain spaces were skipped in the color rendering path, causing multi-row selections to only highlight characters (System 7 only; mono unaffected)
- Selection highlighting not following content during scroll: selection coordinates were screen-relative but not adjusted when scroll_offset changed, so the highlight stayed in place while content scrolled underneath (both mono and color)
- Light theme white-on-white after theme switch: cursor_blink left themed ForeColor (white from Dark) in window port, corrupting CopyBits color mapping; reset port colors before CopyBits and restore after cursor_blink
- Stale pixels on surviving window after multi-session close: DisposeWindow only updates previously-obscured region; added InvalRect on full portRect in session_destroy_and_fixup
- Out of memory on repeated theme switching: GWorld free/realloc cycle (~137KB) fragmented heap; added term_ui_repaint_offscreen() that invalidates content without freeing buffers
- drain_one() always returned 0 (no data): session_process_data zeroed read_len before the return-value check; track had_data separately
- favorites_add() sentinel bug: bm_theme_id/bm_backspace_bs/bm_local_echo initialized to 0 (wrong value) instead of -1 (use global default) via memset; now captures actual session values
- Backspace popup in Edit Favorite:
^Hand^?were parsed as Menu Manager metacharacters by AppendMenu, graying out items; fixed with SetMenuItemText - Status bar not updating on Backspace/Local Echo toggle from Options menu
- Color desync: reverted pointer-rotation scroll to memmove (fixes gray/wrong ANSI colors after scroll on System 7)
- Dark theme white holes: skip color GWorld for non-white-bg themes, draw directly to window (avoids Window Manager BeginUpdate white fill)
- Disconnect color preservation: snap_color buffer saves/restores CellColor data alongside TermCell content
- Theme bleed-through on window close: all destroy paths use session_destroy_and_fixup to restore surviving session's theme
- Per-session theme globals swapped in idle loop, update handler, and activate handler
- Drawing code uses theme_is_dark() instead of prefs.dark_mode for per-session correctness
- Cursor blink no longer fires during scrollback view (caused XOR artifact over scrollback content)
- DNS response parser signed short overflow on crafted RDLEN values
- OSC parameter accumulation signed short overflow (guard tightened)
- Window title from OSC 0/2 now strips control characters (bytes < 0x20)
- Window resize on font change used wrong status bar height calculation
- Grow box and scrollbar column not redrawn after window resize snap-to-grid
- Cell width uses CharWidth('M') instead of widMax (fixes spacing with scaled bitmap fonts)
- Status bar color cache invalidation after GWorld rendering on System 7
- Zero-width selection no longer renders inverted cell on single click
- Clicks in disconnected terminal sessions ignored (prevents stale color artifacts)
- Scroll rendering reverted to memmove (pointer rotation caused color desync on System 7; mono unaffected)
- Smoother bulk output: smaller draw batches, shorter jump scroll deadline, reduced drain loop cap
- Font and Size split into separate submenus (matching Geomys HIG)
- New fonts: New York (System 6+), Helvetica, Times, Palatino (System 7 only, added at runtime)
- Size submenu: 9, 10, 12, 14 — any font/size combination now possible
- Options menu uses Apple HIG action verbs: "Turn Dark Mode On/Off", "Show/Hide Status Bar", "Turn Local Echo On/Off", "Switch Backspace to BS/DEL (^H/^?)"
- Removed trailing colons from all dialog labels (Connect, Favorites, DNS Server, Finger, Find)
- Edit Favorite: Host and Port on same row, all settings show resolved values (no ambiguous "Default" option)
- Favorites popup menus list current value first for Backspace and Echo
- DNS Server moved from File menu to Options menu
- Status bar always white with black text regardless of dark mode (chrome, not content)
- File menu reorganized: New, Close, Reconnect, Finger, Save, Quit
- Finger shortcut changed from Cmd+F to Cmd+I (Cmd+F now Find, matching Geomys)
- Screen row pointer table eliminates row×132 multiply on all screen accesses (+200 bytes/session)
- Color row pointer table eliminates multiply for color array access on System 7
- Glyph cache uses direct lookup table instead of linear search (O(1) vs O(49))
- Charset-is-standard cached flag reduces per-character struct reads in fast path
- Pre-computed cell height fractions eliminate divides in glyph rendering
- adjust_cursor() only called on mouse movement, not every idle tick
- Color cube RGB decomposition uses subtraction loops instead of division (no hardware divide on 68000)
- DNS resolver stack buffers made static (saves ~1.5KB stack)
- Deduplicated show_ttype_popup between connect and bookmark edit dialogs
- Removed dead code: TelnetState.sb_opt, favorites_init_menu(), redundant telnet_init zeroing
- Build flag: -fomit-frame-pointer frees A6 register on 68000
- Inline TERM_DIRTY_ROW macro saves JSR/RTS overhead per dirty-row mark
- Gate cached_fg_idx invalidation on actual TextFace change (saves ~24us/trap on color systems)
- Factor drain_one()/check_keepalive() helpers in event loop (~55 lines deduped)
- Deduplicate term_put_cp437 cell-write logic via term_put_char (~25 lines removed)
- Convert snap_screen/snap_color from inline array/Ptr to Handle, sized to active dimensions (3.8KB at 80x24 vs 13.2KB at 132x50), freed immediately after disconnect restore
- iBeam cursor when mouse is over terminal text area (arrow elsewhere)
- Click-and-drag text selection not highlighting or selecting wrong text (shadow buffer optimization was skipping rows where only selection changed)
- Zoom box in window title bar per Apple HIG (zoomDocProc)
- Click to toggle between user-sized window and standard 80x24 grid
- Sets standard state to default terminal dimensions
- Sends NAWS update to server on zoom while connected
- Scrollbar width from 16 to 15 pixels, matching Geomys UI dimensions
- Build system: renamed macplus preset to lite, full is now default
- README: added direct download links, auto-updated in release.sh
- BUILD.md examples updated to reflect full as default preset
- BUILD.md: added apt-get install line for Debian/Ubuntu prerequisites
- Finger protocol client (RFC 1288) — File > Finger... (Cmd+F)
- Query user information on remote hosts via TCP port 79
- Host, username, and verbose (/W) fields in Finger dialog
- Finger forwarding: user@host@gateway auto-splits and routes correctly
- Remembers last finger host/username across launches
- Status bar shows "finger | [user@]host"
- Window title includes "(finger)" suffix
- Per-bookmark protocol selection (Telnet or Finger) in bookmark editor
- Favorites submenu dispatches finger bookmarks correctly
- Configurable build system with 16 compile-time feature flags
- 3 build presets: minimal (~256KB), lite (~384KB), full (~768KB)
- Every major feature can be toggled:
--finger,--color,--glyphs,--cp437,--clipboard,--savefile,--bookmarks,--darkmode,--dblwidth,--altscreen,--offscreen,--statusbar,--cursorstyles,--tabstops - Configurable sessions (1-4) and scrollback lines (0-256)
- SIZE resource (Finder memory partition) dynamically computed from enabled features
- Presets applied first, individual flags override:
--preset minimal --finger --bookmarks - Three-layer guard pattern: CMake source exclusion, header no-op stubs, inline #ifdef guards (~163 guard sites across 26 files)
- FlynnPrefs struct unchanged for cross-build prefs compatibility
- Three release editions: Flynn (full), Flynn Lite, Flynn Minimal
- Build documentation:
docs/BUILD.mdwith complete flag reference, memory costs, presets, and examples - Direct offscreen memory writes bypass QuickDraw traps for rendering (font bitmap cache, direct glyph blit, direct erase/fill)
- Shadow buffer skips unchanged rows via memcmp
- Scroll sync uses memmove instead of CopyBits
- Color GWorld offscreen buffer eliminates flicker on System 7
- Optimized scrollbar arrow scrolling: ScrollRect + offscreen memmove renders only 1 row per arrow click instead of full 24-row redraw
- Dark mode rendering bugs: white bar at window bottom, status bar artifacts, stale offscreen content
- Offscreen buffer reuse: clear pixel data when reusing for different window with same dimensions (prevented stale session content bleed)
- Scrollback ring buffer index: corrected formula for partially-filled buffers (was sb_head+sb_count+sb_row, now sb_head+sb_row)
- Drain loop data race: process pending TCP data before checking for disconnect state transition
- System 7 GWorld rendering stability and artifact fixes
- icl8/ics8 icon polarity for System 7 color displays
- 68000 address error in offscreen_fill_rect
- Default build uses full preset: 4 sessions, 192-line scrollback, ~768KB
- Binary size: 91KB minimal, 125KB default, 130KB full
- Release script builds all 3 presets and uploads 6 artifacts per release
- FlynnPrefs v12 (finger_host, finger_user, bookmark_protocol[])
- File menu: Finger... inserted at position 2, items renumbered
- Control menu disabled for finger sessions
- Bookmark edit dialog: protocol popup (Telnet/Finger), dialog enlarged
- Performance and security review: hardening, leak fixes, dead code removal, optimizations, and refactoring
- Double-buffered rendering, local echo, fast key repeat, send-then-poll echo, 3 new emoji, glyph bitmap cache
- Bookmark list overflow, ScrollRect dark mode flash, ScrollRect dirty flag misalignment, stale offscreen on session destroy, multi-window cross-session blit
- 12 performance improvements (ScrollRect 10x, partial CopyBits 95%, jump scrolling 7-10x, batched TCP reads, double-DrawText bold 14.5x, mono path split, glyph run merging, etc.), plus offscreen-based update events/dark mode/resize, prefs v10
- Build size: ~119KB (up from ~103KB, offscreen buffer and glyph cache)
- Memory: ~90KB/session mono, ~110KB/session color
- Option+Space (Ctrl-Space) not recognized: vkey_to_base table was 48 entries, Space at vkey 0x31 (49) fell outside it. Extended table to include Space, enabling Ctrl-Space (0x00) for tmux prefix and similar
- Option+/ (Ctrl-/) not recognized: added '/' to vkey_to_base table with special case since '/' & 0x1F produces wrong value (0x0F instead of 0x1F)
- ANSI-BBS disconnect losing goodbye screen: telnet_init() zeroed the session's preferred_ttype before the snapshot restore check, so bookmark-specific ANSI-BBS sessions saw the global pref (e.g. xterm) and incorrectly restored the pre-clear snapshot. Now saves the session's terminal type before reset
- 13 new Unicode glyph mappings: flower/florette dingbats (U+273E-2741), snowflake (U+2744), sparkles (U+2728), flower emoji (🌸🌺🌼🌟💫), plus 2 new QuickDraw primitives (flower, snowflake)
- OSC 4 palette color query (rgb:RRRR/GGGG/BBBB replies from 256-color palette), OSC 10/11 default fg/bg color queries (dark_mode-aware), OSC 12/112 cursor color set/reset (no-op on monochrome XOR cursor)
- Hierarchical submenus: Options menu now uses Font and Terminal Type submenus (20 items → 5), fixing menu scrolling off-screen on Mac Plus. File menu uses Favorites submenu for bookmark entries
- Backspace mode toggle: DEL (0x7F) default for xterm/VT220, BS (0x08) for ANSI-BBS. Auto-switches when changing terminal type; manual override in Options menu ("Backspace Sends BS" checkmark)
- Send Ctrl-H and Send Ctrl-X items in Control menu
- Prefs v8→v9 migration for backspace_bs field
- Dark mode shutter effect on monochrome: EraseRect (white) → draw → InvertRect caused visible white flash per row. Now renders directly with PaintRect (black bg) + srcBic/patBic (white drawing)
- BBS goodbye screen not displayed on disconnect: drain remaining TCP data before closing on TIME_WAIT; skip snapshot restore for ANSI-BBS terminal type to preserve goodbye screen
- DNS lookup failure after prefs migration: backspace_bs field was inserted before dns_server in the FlynnPrefs struct, shifting all subsequent fields by 1 byte. DNS server "1.1.1.1" became ".1.1.1" (invalid), and username lost its first character. Fixed validation to reject leading-dot IPs and reset dns_server in migration
- Backspace mode not auto-enabled when connecting with ANSI-BBS terminal type via bookmark or new session (only worked from Options menu)
- Bookmarks renamed to Favorites throughout UI (menus, dialogs, labels)
- Terminal Type menu reordered: xterm, xterm-256color, VT100, VT220, ANSI-BBS (display order decoupled from internal storage indices)
- Connection status window widened from 240→320px, hostname truncation 40→50 chars to accommodate longer hostnames
- Performance: hot path optimizations in terminal parser and draw routines
- Security: bounds checking on terminal response buffer flush
- Dead code removal: ~50 lines removed, unused functions and defines cleaned up
- Defensive improvements: conn_send() rejects zero-length writes, removed unused idle_skip field from Connection struct
- CP437/ANSI-BBS terminal emulation for bulletin board systems
- Full 256-entry CP437 lookup table mapping each byte to ASCII, Mac Roman, or QuickDraw glyph rendering
- cp437_mode bypasses UTF-8 decoder for raw byte rendering, essential for BBS art using 0x80-0x9F range (C1 control code collision in UTF-8 mode)
- ANSI-BBS terminal type in TTYPE negotiation, settings, preferences menu, and connect dialog — follows BBS community convention (ansi-bbs = CP437)
- True SGR attribute rendering
- Italic (SGR 3) via TextFace(italic)
- Strikethrough (SGR 9) via horizontal line at cell mid-height
- Dim (SGR 2) halves foreground RGB on color systems
- Blink (SGR 5/6) promotes background to bright colors (DOS-style)
- Bold-to-bright color promotion: SGR 1;30-37m promotes to bright colors (indices 8-15), matching standard ANSI/BBS behavior
- UTF-8 CP437 fallback for BBSes that send raw CP437 bytes despite xterm-256color TTYPE negotiation
- 57 new QuickDraw glyph primitives: double-line box drawing, mixed junctions, smileys, Greek/math symbols (160+ total primitives)
- 18 fractional block element glyphs (U+2581-U+258F, U+2594-U+2595)
- 60 sextant characters (U+1FB00-U+1FB3B) as 2x3 grid patterns
- DNS-over-TCP fallback for NAT environments
- Rendering diagnostic script (
scripts/render-test.sh)
- DNS resolution through NAT: Snow's DaynaPORT rewrites UDP source IPs, causing Flynn to reject valid DNS responses. Removed redundant source IP validation (txn_id match already authenticates responses)
- Backspace sends BS (0x08) instead of DEL (0x7F) for BBS compatibility (Linux telnetd accepts both; BBSes universally expect BS)
- Bytes 0xF8-0xFF silently dropped by UTF-8 parser — now route to CP437
- Legacy Computing chars (U+1FB00-U+1FBFF) produced double '??' instead of single '?' (they are single-width, not wide)
- Glyph count: 103 → 160+ QuickDraw primitives
- Dead code removal: 25 cases from boxdraw_to_dec() superseded by glyph tables, 3 cases from unicode_symbol_to_macroman(), dead block element fallback block (~50 lines, ~700 bytes recovered)
- Performance: eliminated double cell fetch in draw_row() (~80K cycles/redraw saved on 68000), replaced dark shade MULU with shift operation
- New source files:
cp437.c,cp437.h
- Version bump to 1.9.1 (docs and build metadata only)
- 256-color support on System 7 with Color QuickDraw
- Full 256-color palette: 16 ANSI colors + 216 color cube + 24 grayscale
- Truecolor (24-bit) SGR sequences downgraded to nearest 256-color match
- Palette Manager rendering via PmForeColor/PmBackColor for performance
- Color windows with NewCWindow/NewPalette on System 7, standard NewWindow on System 6
- Runtime detection via SysEnvirons() hasColorQD — zero impact on System 6
- Per-cell foreground and background colors stored in CellColor arrays
- ATTR_HAS_COLOR (bit 6) flag for fast skip of default-colored cells
- Color-aware dark mode: swaps default fg/bg, skips InvertRect on color systems
- New source files:
color.c,color.h - Memory: +52KB per session on System 7 color, zero on System 6 monochrome
- 38 new QuickDraw primitive glyphs (103 total, up from 65):
- Outline triangles: △ ▽ ▷ ◁ (U+25B3, U+25BD, U+25B7, U+25C1)
- Small filled triangles: ▸ ◂ (U+25B8, U+25C2)
- Diamonds: ◆ ◇ (U+25C6, U+25C7)
- Half-circle variants: ◐ ◑ ◒ ◓ (U+25D0-U+25D3)
- Fisheye circle: ◉ (U+25C9)
- Six-pointed star: ✶ (U+2736)
- Circled operators: ⊙ ⊕ ⊖ ⊗ (U+2299, U+2295-U+2297)
- Superscript digits: ⁰¹²³⁴⁵⁶⁷⁸⁹ (U+2070, U+00B9, U+00B2, U+00B3, U+2074-U+2079)
- Subscript digits: ₀₁₂₃₄₅₆₇₈₉ (U+2080-U+2089)
- Superscripts/subscripts rendered at 60% font size with scaled positioning
- Terminal type not saved between sessions — Connect dialog now persists the last-used terminal type (xterm, VT220, VT100, xterm-256color)
- Cursor XOR artifacts on color systems — arrow key editing on System 7 caused stale inverse highlights because CSI cursor movement didn't mark rows dirty. Now tracks cursor position changes and marks affected rows
- Disconnect screen preservation — screen buffer snapshotted on full clear (ESC[2J) and restored on disconnect, instead of wiping to blank
- Session not cleaned up on bookmark connect failure — now properly destroys session if TCP connect fails after window was created
- Replaced all
sprintfwithsnprintfacross 15 call sites (defense-in-depth buffer overflow protection) - Added bounds check to TTYPE/TSPEED subnegotiation buffer in telnet.c
- Glyph emoji base relocated from 0x60 to 0x80 to accommodate expanded primitive range (0x00-0x66)
- Lazy allocation of alt-screen and scrollback color arrays — deferred until first use, saving up to 38.5KB/session on System 7
- Screen snapshot moved from shared static to per-session Terminal struct for multi-session correctness; only triggers on full-screen clear instead of every data receive (~1.5ms/receive saved on 68000)
- Color default restore deferred to end of row instead of per-run, reducing redundant RGBForeColor/RGBBackColor traps by 10-15%
- Removed idle polling skip counter — eliminates 8.5ms average added latency on keystroke echo
- Single-session fast path in event loop — skips save/load state cycling when only one session is open
- Idle WaitNextEvent timeout reduced from 500ms to 167ms when disconnected
- SIZE resource increased from 640KB/512KB to 768KB/640KB for 4-session color headroom
- Removed ~450 lines of dead code: deleted dnr.c/dnr.h (superseded by dns.c), 14 unused functions, 4 unused defines, deduplicated ATTR_HAS_COLOR definition
- Build size: ~103KB (down from ~110KB after dead code removal)
- Memory per session: ~79KB System 6 mono, ~92KB System 7 color (initial), ~130KB fully loaded with alt screen and scrollback color
- Add icon family resources (icl4, icl8, ics#, ics4, ics8) for System 7 Finder compatibility — custom Flynn icon now displays correctly instead of generic application icon
- System 7 improvements (all conditional, System 6 behavior unchanged):
- MultiFinder suspend/resume: proper app4Evt handling, cursor blink stops when backgrounded, WaitNextEvent sleep increases to 60 ticks when suspended
- Required Apple Events: kAEOpenApplication, kAEQuitApplication handlers for System 7 compliance (Finder can request clean quit)
- StandardPutFile: modern System 7 save dialog for Save Contents, falls back to SFPutFile on System 6
- Notification Manager: flashes Apple menu diamond when a session disconnects while Flynn is in the background
- Machine type in About dialog: shows "Running on Macintosh Plus" (or SE, II, IIci, etc.) via Gestalt
- About dialog simplified per Apple HIG: condensed to app name/version, machine type, copyright, and GitHub link
- Save Contents... (Cmd+S): save terminal scrollback and screen buffer to a plain text file via SFPutFile dialog. Creates TEXT/ttxt files readable by TeachText. Default filename is the connection hostname.
- New savefile.c/savefile.h module for file save functionality
- File menu reorganized per Apple HIG:
- "Save Contents..." (Cmd+S) in its own section
- "Bookmarks..." (Cmd+B) leads the bookmark section
- Recent bookmarks listed under Bookmarks
- "Add Bookmark..." (renamed from "Save as Bookmark...") moved after recents
- Separators between file operations, save, and bookmark management
- Cmd+S reassigned from "Save as Bookmark" to "Save Contents" (standard HIG convention for Cmd+S = save to file)
- "Add Bookmark..." is now a dynamic menu item, enabling proper bookmark section grouping with Bookmarks... as the section leader
- Major codebase refactor: main.c reduced from 3,478 to ~494 lines (86% reduction)
- Extracted dialogs.c: all dialog handling (connect, bookmarks, about, disconnect)
- Extracted menus.c: menu management with per-menu dispatch handlers
- Extracted input.c: keyboard/mouse handling with data-driven key mapping tables
- Extracted clipboard.c: copy/paste/select all operations
- Extracted macutil.c: shared utilities (c2pstr, sprintfp, set_wtitlef, clear_window_bg)
- Extended session.c: font presets, ttype/font string helpers, window resize, init from prefs
- Collapsed identical telnet option handlers with fallthrough in telnet.c
- Extracted conn_resolve_host() from conn_connect() in connection.c
- Split handle_menu() into per-menu handlers (handle_file_menu, handle_edit_menu, etc.)
- Data-driven key mapping replaces if/else chain in handle_key_down()
- Total compiled LOC reduced from 12,027 to 10,036 (17% reduction)
- Remote disconnect preserves terminal screen content (was wiped by terminal_reset)
- Window repaint after disconnect alert restores terminal content in all modes
- Dead conn_open_dialog() from connection.c
- 6 unused TCP wrapper functions from tcp.c (~256 lines)
- MacTCP.h: add forward declarations for struct GetAddrParamBlock, ICMPParamBlock, TCPiopb, and UDPiopb to eliminate "declared inside parameter list" compiler warnings
- tcp.h: alias proc typedefs (TCPIOCompletionProc, TCPNotifyProc, etc.) to actual MacTCP UPP types instead of incompatible ProcPtr/re-declared function pointers, eliminating all -Wincompatible-pointer-types warnings
- MacTCP.h: convert from classic Mac CR to Unix LF line endings for consistent cross-platform source formatting
- Edit > Select All (Cmd+A) to select entire terminal screen for copying
- Per-bookmark settings: username, terminal type, and font saved per bookmark
- Per-session font and terminal type: bookmark overrides apply only to that session; Options menu checkmarks reflect the active session
- Recent bookmarks in File menu (up to 5 most recently used)
- Save as Bookmark (Cmd+S): save current session as a bookmark, pre-filled from the active connection (host, port, username, font, terminal type)
- Auto-save bookmark settings: changing font or terminal type via Options menu automatically updates the originating bookmark
- Default button outlines on all dialogs per Apple HIG (3px FrameRoundRect)
- Cmd+. (Cancel) keyboard shortcut in all dialogs per Apple HIG
- Tab key cycles through edit fields in Connect and Edit Bookmark dialogs
- Connection progress window with status updates (Resolving, Connecting) and watch cursor during DNS/TCP operations
- Scrollback position indicator on right edge of terminal (rail + thumb)
- Session count header ("N of 4 Sessions") in Window menu
- Bookmarks popup in Connect dialog (shows selected name, checkmark)
- xterm-256color terminal type option
- Custom Finder icon for "Flynn Preferences" file (ICN# 129, FREF/BNDL)
- System 7 Preferences folder support: preferences stored in System Folder's Preferences folder on System 7+ (unchanged on System 6)
- Startup optimization: Connect dialog appears in under 1 second (was 5-6s) by deferring MacTCP initialization to first connection attempt, deferring session/window creation until user clicks Connect, and reordering menu state updates after dialog
- Connection status window shows "Connecting to..." for IP addresses instead of "Resolving..." (DNS resolution is skipped for direct IPs)
- Options menu (renamed from Preferences; shorter, period-appropriate)
- Menu bar order: File, Edit, Options, Control, Window (Window at end per HIG)
- Control menu: Ctrl keys grouped alphabetically, then Break and Escape
- File > Close Session (Cmd+W) disconnects, destroys session, and closes window; closing last session keeps Flynn running (use Quit to exit)
- Window menu is now just the dynamic session list
- All error alerts use StopAlert, info alerts use NoteAlert per Apple HIG
- DNS timeout reduced from 15s to 5s per attempt for faster failure feedback
- Session windows cascade with 30px offset (was 20px)
- Remote disconnect shows "(disconnected)" in window title bar
- "Flynn Prefs" renamed to "Flynn Preferences" (matches Apple convention)
- Preferences I/O uses directory-aware PBH*Sync calls for System 7 compat
- MacTCP initialization failure now shows "MacTCP is not available" alert instead of silently failing
- Copy always grayed out in Edit menu (update_menus timing with MenuSelect)
- Cross-session copy/paste: selection state destroyed by idle loop cycling
- Selection auto-cleared within 17ms by incoming data, making copy nearly impossible on active connections
- Per-session font corruption when opening sessions with different fonts
- Telnet: reject unknown options before array indexing (prevents opts[-1] memory corruption from malicious servers)
- Telnet: track and discard overflowed SB subnegotiations
- Terminal: full UTF-8 validation (overlong, surrogates, invalid codepoints)
- Terminal: CSI parameter signed overflow check, SGR skip bounds checks
- Terminal: snprintf for DSR response, null-terminate OSC on all exit paths
- DNS: cap record counts to 64, limit compression pointer hops to 128
- Replace strcpy with strncpy+buflen in ttype/font string helpers
- snprintf in long2ip() to prevent buffer overrun
- Validate port range 1-65535 in connect dialog
- Validate DNS server IP on preferences load
- Multiple simultaneous sessions (up to 4) in separate windows
- Session struct bundles Window, Connection, TelnetState, Terminal per session
- UIState save/load pattern for per-session cursor blink and text selection
- Per-connection idle polling skip counter (moved from file-scope static)
- Window menu (MENU 133, between Edit and Preferences)
- Close Window (Cmd+W) closes active session window
- Dynamic window list with checkmark on active session
- Clicking between windows switches active session
- File menu (renamed from "Session")
- "New Session..." (Cmd+N, was "Connect...") — auto-creates new window if current session is already connected
- "Close Session" (was "Disconnect") — disconnects active session
- Bookmarks open in new session if current is connected
- Per-session event routing via window refCon
- Mouse events routed via FindWindow → session_from_window
- Key events routed to front window's session
- Update/activate events routed via WindowPtr
- Font changes and dark mode toggle apply to all session windows
- Quit confirms if any session is connected, destroys all on exit
- Close box on individual windows closes just that session
- Version: 1.1.1 → 1.5.0
- SIZE resource increased from 512KB/384KB to 640KB/512KB
- Memory per session: ~73KB (Terminal 52KB + Connection 12.5KB + TCP 8KB + misc)
- New source files:
session.c,session.h - Single-session performance overhead: ~100µs per idle tick (negligible)
- 11 box-drawing primitive glyphs (U+2500-U+253C): ─│┌┐└┘├┤┬┴┼, drawn with edge-to-edge QuickDraw LineTo for seamless tiling
- 3 shade characters (U+2591-U+2593): ░▒▓, rendered with QuickDraw ltGray/gray/dkGray fill patterns
- Glyph count: 51 → 65 primitives (15 emoji unchanged)
- MacBinary II CRC-16 recalculated after creator code patch, fixing "application is busy or damaged" deployment errors
- Move build.sh and release.sh into scripts/ directory
- Dev builds use SHA-only naming (Flynn-d724f2b), tagged releases use version-only (Flynn-1.1.1)
- Replace CRT-filtered screenshots with clean cropped captures
- Clean up documentation: remove redundant DEVLOG, trim README, consolidate screenshots
- Mark ROADMAP and AUDIT docs as historical
- Unicode glyph rendering system (
glyphs.c/glyphs.h)- 51 QuickDraw primitive glyphs: arrows, geometric shapes, block elements, card suits, musical notes, mathematical symbols, and more — drawn natively with LineTo, PaintRect, PaintOval, PaintPoly, and PaintArc
- 15 monochrome 10x10 bitmap emoji rendered via CopyBits (2-cell wide): grinning face, heart eyes, thumbs up, fire, star, checkmark, crossmark, warning, lightning, sun, moon, skull, rocket, party popper, sparkles
- Braille pattern rendering (U+2800-U+28FF) — 256 dot-grid patterns drawn as filled circles in a 2x4 grid per cell
- Binary search codepoint-to-glyph lookup table for fast mapping
- Bold variants: thicker lines (PenSize 2,1) and larger fills for primitives
- U+00B7 middle dot rendered as centered PaintOval (was misrouted through Latin-1 Mac Roman table producing wrong character)
- Bold text spacing drift: DrawText() with bold TextFace increases advance width by 1px per character, causing cumulative rightward drift that consumed adjacent spaces. Replaced all DrawText calls with per-character MoveTo+DrawChar for absolute positioning (draw_row, draw_line_char fallback, draw_glyph_prim fallback)
- DCS parser content leak: ESC inside DCS string shared PARSE_OSC_ESC state, causing DCS content to leak as visible text. Added dedicated PARSE_DCS_ESC state
- CSI parameter overflow: TERM_MAX_PARAMS was 8, but truecolor SGR sequences (38;2;R;G;B foreground + 48;2;R;G;B background) need 12+ params. Increased to 16 with bounds checking
- CSI colon sub-parameter parsing for SGR 38:2:R:G:B truecolor sequences (colon-separated variant)
- UTF-8 error recovery: new start byte mid-sequence now resets decoder and reprocesses (was producing garbage output)
- Invisible Unicode characters (ZWSP, ZWJ, variation selectors, combining marks, BOM) now absorbed silently instead of rendering as '?'
- Unicode spaces (en space, em space, thin space, hair space) mapped to ASCII space instead of '?'
- Version: 1.0.1 → 1.1.0
- Terminal parser expanded to 9 states (added PARSE_DCS_ESC)
- TERM_MAX_PARAMS: 8 → 16
- New source files:
glyphs.c,glyphs.h - Build size: ~110KB (up from ~98KB, glyph tables and bitmap data added)
- TCP connect timeout enabled (commandTimeoutValue = 30 seconds)
- Previously commented out, causing ~5 minute UI freeze when networking was unavailable (no command timeout = wait forever)
- Verified compatibility with System 7.5.5 and Open Transport
- Updated README, About Flynn, and CHANGELOG to document System 7 / Open Transport support
- Control menu with 6 items for sending control sequences without a
physical Ctrl key:
- Send Ctrl-C, Send Ctrl-D, Send Ctrl-Z, Send Escape, Send Ctrl-L, Send Break (Telnet IAC BRK)
- Menu items enabled only when connected
- MENU resource 132 added, MBAR updated to include it
- Keystroke buffering to prevent character loss during fast typing
- Drains all pending key events from the Mac event queue before sending
- Batches multiple keystrokes into a single TCP send (reduces per-key blocking from synchronous _TCPSend)
- Single keystrokes still send immediately for interactive feel
- key_send_buf[256] with buffer_key_send() and flush_key_send()
- README: Added Claude Code attribution, navigation TOC, and expanded Acknowledgments (Retro68, Snow emulator as individual entries)
- About dialog version updated to 1.0.0 (updated to 1.0.1 in next release)
- Version: 0.11.1 → 1.0.0
- Additional font options: Courier 10, Chicago 12, Geneva 9, Geneva 10
- Preferences > Fonts menu expanded from 2 to 6 items
- CheckItem logic compares both font_id and font_size
- Window resizing with grow box
- Drag-to-resize terminal window, snaps to cell boundaries
- Terminal buffer increased to 132x50 max (from 80x24)
- Min window size: 20x5 cells
- Grow icon drawn clipped (avoids scroll bar lines)
- NAWS renegotiation sent on resize while connected
- Proportional font rendering
- Detects proportional fonts (Chicago, Geneva) in
term_ui_set_font() - Uses per-character MoveTo+DrawChar to keep text aligned with cell grid
- Detects proportional fonts (Chicago, Geneva) in
- Username auto-login field in Connect dialog
- Sends username automatically on connect (with short delay)
- Username saved in preferences (v5→v6 migration) and pre-filled
- charCode-based arrow key fallback for M0110A keyboards
- Clear terminal screen on remote disconnect
- Resets terminal and clears window before showing alert
- Cursor misalignment with proportional fonts (Chicago, Geneva)
- DrawText advanced pen by actual glyph width, not cell width
- Initial window too large on launch (clamped to 80x24 default, not 132x50 max)
- Connect dialog labels improved ("Host or IP:", info text removed)
- Version: 0.10.1 → 0.11.0
- FlynnPrefs bumped to v6 (adds username field)
- TERM_MAX_COLS/TERM_MAX_ROWS: 132x50, TERM_DEFAULT_COLS/TERM_DEFAULT_ROWS: 80x24
- Memory impact: buffer increase adds ~29KB (total ~60KB, within 4MB limit)
- Custom DNS resolver using MacTCP UDP (
dns.c/dns.h)- Bypasses broken
dnrpcode resource (crashes on failed lookups due to Retro68 calling convention mismatch) - Sends A-record queries to configurable DNS server (default: 1.1.1.1)
- 15-second timeout per attempt, 2 retry attempts
- Parses DNS responses including CNAME chains
- Error-specific alerts: "Host not found", "DNS lookup timed out", "DNS lookup failed"
- Bypasses broken
- DNS Server preference dialog (DLOG 133)
- Accessible from Preferences > Networking > DNS Server...
- User can set any IP address as their DNS server
- Validates IP format before saving
- Persisted in FlynnPrefs (dns_server field)
- Hostname validation in Connect dialog
- Rejects malformed IPs (e.g., doubled addresses like "1.2.3.41.2.3.4")
- Validates DNS label length and character rules
_UDPRcv()and_UDPBfrReturn()wrappers in tcp.c
- Version: 0.10.0 → 0.10.1
- Preferences menu reorganized into labeled sections: Fonts, Terminal Type, Networking, Misc (disabled section headers)
- FlynnPrefs bumped to v5 (adds dns_server[16] field)
- Connection struct gains dns_server field for per-connection DNS config
- tcp.h converted from CR to LF line endings
- Preferences menu (replacing Font menu, MENU 131)
- Terminal type selection: xterm, VT220, VT100 with checkmark
- Dark mode toggle for white-on-black rendering
- Font selection (Monaco 9/12) retained from Font menu
- Dark/light mode rendering
- XOR-based inverse on monochrome display (black bg, white text)
- DEC Special Graphics line-drawing works in both modes
- Cursor blink (patXor) works identically in both modes
- ICON resource in About dialog (32x32 mono, same as Finder icon)
- Preferred terminal type in TTYPE negotiation
- User-selected type sent first, then cycles through remaining types
- Preferences v3→v4 migration (terminal_type, dark_mode fields)
- Version: 0.9.1 → 0.10.0
- Font menu renamed to Preferences menu with expanded items
- About dialog layout: taller (215px), consistent margins, icon added
- 800K floppy image (Flynn.dsk) now includes Read Me and correct FLYN creator code
- FlynnPrefs struct gains terminal_type and dark_mode fields
- TelnetState gains preferred_ttype field
- Build size: ~90KB (estimated)
- Custom Finder icon (ICN#/BNDL/FREF resources)
- 32x32 monochrome CRT terminal with >_ prompt
- BNDL and FREF associate icon with creator code 'FLYN'
- Signature resource ('FLYN' 0) for Finder identification
- "Flynn Read Me" TeachText documentation
- Usage guide, features, keyboard shortcuts, M0110 key mappings
- Troubleshooting, bookmarks, font selection, credits
- Deployed as TEXT/ttxt to HFS image alongside Flynn
- BinHex (.hqx) archive output in build
- build.sh generates Flynn.hqx for cross-platform distribution
- Text-safe encoding preserves resource fork via email/web/BBS
- About dialog now shows https://www.ecliptik.com
- Flynn deployed in its own folder on HFS disk (:Flynn:)
- Version: 0.9.0 → 0.9.1
- Settings menu renamed to "Font" (only contains font options)
- MENU 131 title, all constants and variables renamed
- build.sh now converts Read Me to Mac CR line endings and prints folder-based deployment instructions
- Build size: ~88KB (up from ~87KB, icon resources added)
- Session bookmarks (Phase 11)
- Bookmark struct (name, host, port) stored in preferences, max 8
- Bookmark manager dialog (DLOG 131) with Add/Edit/Delete/Connect buttons
- UserItem-based list display with click selection and inverse highlight
- Add/Edit bookmark dialog (DLOG 132) with Name/Host/Port fields
- Dynamic Session menu: bookmarks appear below Quit separator
- One-click connect from Session menu bookmark items
- Preferences v1→v2→v3 migration for bookmark and font fields
- Extracted
conn_connect()fromconn_open_dialog()for direct connect
- Font selection (Phase 12)
- Settings menu (MENU 131) with Monaco 9 and Monaco 12 options
- Runtime cell dimensions via
GetFontInfo()measurement term_ui_set_font()changes font and recomputes gridactive_cols/active_rowsin Terminal struct for dynamic grid sizing- Window resized with
SizeWindow()to fit computed grid - NAWS renegotiation sent on font change while connected
- Font preference saved/restored across launches (font_id, font_size)
- Checkmark on active font in Settings menu
- xterm compatibility (Phase 13)
- Application keypad mode (DECKPAM/DECKPNM, ESC =/ESC >)
- Numpad keys send SS3 sequences in application mode
- TTYPE cycling: xterm → VT220 → VT100 (first response is "xterm")
- Silent consumption of mouse reporting modes (?1000-1006)
- Silent consumption of focus events (?1004) and cursor blink (?12)
- UTF-8 support (Phase 14)
- UTF-8 decoder state machine (2/3/4-byte sequences)
- Unicode box-drawing (U+2500-U+257F) → DEC Special Graphics (33 mappings)
- Unicode Latin-1 Supplement (U+0080-U+00FF) → Mac Roman (128-entry table)
- Unicode symbols → Mac Roman (em/en dash, curly quotes, bullet, ellipsis, euro, pi, delta, sqrt, infinity, trademark, not-equal, etc.)
- Wide character/emoji → 2-cell
??placeholder - Emoji modifier/ZWJ/skin-tone/variation-selector sequence absorption
- Unmapped codepoints render as
?fallback
- Screen not cleared on disconnect:
do_disconnect()now callsterminal_reset(),telnet_init(), and redraws window - Overlapping
strncpyUB inconn_connect()when called fromconn_open_dialog()— host parameter pointed to same buffer - UTF-8 fallback character was Mac Roman 0xB7 (Σ sigma) instead of
?
- Version: 0.8.0 → 0.9.0
- Session menu expanded: Connect, Disconnect, Bookmarks, Quit + dynamic bookmarks
- MBAR resource updated to include Settings menu (128, 129, 130, 131)
- Prefs version bumped to 3 (bookmark_count, bookmarks[8], font_id, font_size)
- ~40 TERM_COLS/TERM_ROWS references in terminal.c changed to active_cols/active_rows
- Build size: ~87KB (up from ~77KB)
- DEC Special Graphics line-drawing characters via QuickDraw
draw_line_char()renders box-drawing glyphs using MoveTo/LineTo- 18 character mappings: corners (┌┐└┘), tees (├┤┬┴), cross (┼), horizontal (─), vertical (│), diamond (◆), checkerboard (▒), centered dot (·), degree (°), plus/minus (±)
- Bold attribute renders thicker lines (PenSize 2,1)
- Inverse attribute renders white-on-black (PaintRect + patBic)
- Unknown graphic characters fall back to regular text rendering
- TUI apps now display proper box-drawing borders (tmux, mc, dialog)
- OSC title parsing: semicolon separator was included in title string (e.g. ";Test Title" instead of "Test Title") due to osc_param being modified during digit parsing, causing the semicolon check to be skipped
- Version: 0.7.0 → 0.8.0
- terminal_ui.c draw_row() dispatches ATTR_DEC_GRAPHICS runs to draw_line_char()
- Build size: ~77KB (up from ~76KB)
- Alternate screen buffer (DECSET ?1049/?1047/?47)
- Save/restore main screen (3.8KB static buffer in Terminal struct)
- Scrollback frozen during alt screen (vi, nano, less don't pollute history)
- Clear on switch, restore on switch back
- OSC window title (ESC]0;title BEL / ESC]2;title ST)
- Window title bar shows "Flynn - <title>" when set by remote host
- Reverts to "Flynn - " when title is empty
- DCS string consumption (PARSE_DCS state, consumed until ST)
- Application cursor keys (DECCKM, DECSET ?1)
- Arrow keys send ESC O A/B/C/D when enabled (vi, tmux navigation)
- Auto-wrap toggle (DECAWM, DECSET ?7)
- No-autowrap mode overwrites at right margin instead of wrapping
- Origin mode (DECOM, DECSET ?6)
- Cursor positioning relative to scroll region when enabled
- Insert/Replace mode (IRM, CSI 4 h/l)
- Insert mode shifts line right before placing characters
- Character set designation (ESC ( 0/B, ESC ) 0/B)
- G0/G1 charset tracking, ATTR_DEC_GRAPHICS bit (0x08) in TermCell.attr
- SI/SO charset switching (0x0E/0x0F)
- Shift Out activates G1, Shift In activates G0
- DECSC/DECRC extended (ESC 7/8 now save/restore charsets, origin mode, autowrap)
- Secondary DA response (CSI > c → ESC[>1;10;0c, VT220)
- Primary DA upgraded to VT220 (ESC[?62;1;6c, was VT100 ESC[?1;2c)
- Soft reset (DECSTR, CSI ! p)
- Resets attributes, charsets, modes, scroll region, cursor
- CSI s/u cursor save/restore (ANSI alternative to ESC 7/8)
- Bracketed paste mode (DECSET ?2004)
- Pasted text wrapped in ESC[200~/ESC[201~ markers when enabled
- F-key support (F1-F12)
- ADB virtual keycodes for extended keyboards
- Cmd+1..0 sends F1-F10 for M0110 keyboards without function keys
- SGR extended color fix
- 256-color (38;5;N) and truecolor (38;2;R;G;B) sub-parameters now skipped cleanly instead of misinterpreted as blink/underline
- Additional SGR attribute mappings for monochrome
- Dim (2) clears bold, italic (3) maps to underline, blink (5/6) maps to bold
- Bright foreground (90-97) maps to bold
- Reset codes: not-italic (23), blink-off (25)
- Version: 0.6.1 → 0.7.0
- DA response identifies as VT220 (was VT100)
- 8-state parser (added PARSE_OSC, PARSE_OSC_ESC, PARSE_DCS)
- Terminal struct gains ~4KB for alternate screen buffer, charset state, DEC modes, OSC buffer, and window title fields
- Build size: ~78KB (up from ~70KB)
- Reduced WaitNextEvent timeout from 5 ticks (83ms) to 1 tick (17ms) for faster character echo and improved interactive responsiveness
- Replaced
memset(pb, 0, sizeof(*pb))in_TCPStatus()with explicit field initialization, eliminating ~200 bytes of unnecessary zeroing per event loop iteration (matches wallops-146 reference pattern) - Cached
sel.activeflag per row indraw_row(), avoiding 80 function calls toterm_ui_sel_contains()per row when no selection is active - Cached
TextFace()value indraw_row()to skip redundant Toolbox calls for consecutive attribute runs with the same style - Version: 0.6.0 → 0.6.1
- Mouse-based text selection in terminal window
- Click-and-drag to select text (stream selection, not rectangular)
- Double-click to select word (contiguous non-space characters)
- Shift-click to extend selection from cursor to click point
- Selection renders as inverse video (XOR ATTR_INVERSE per cell)
- Already-inverse cells render as normal when selected (double inversion)
- Cursor blink suppressed during active selection
- Selection-aware copy (Cmd+C)
- If text is selected: copies only selected text (partial first/last rows)
- If no selection: copies entire visible 80x24 screen (existing behavior)
- Trailing spaces trimmed per row, CR between rows
- Selection automatically cleared on keypress or incoming server data
- New functions in terminal_ui: Selection struct, 11 public API functions
- GetDblTime via low-memory global 0x02F0 (Retro68 compatibility)
- Version: 0.5.1 → 0.6.0
- Build size: ~70KB (up from ~65KB)
- terminal_ui.c draw_row() now computes effective attributes per cell for selection overlay
- Cmd+. sends Escape to remote host (classic Mac "Cancel" convention)
- Clear/NumLock key (vkey 0x47) sends Escape (available on M0110A keypad)
- charCode 0x1B fallback sends Escape from any source (USB/ADB keyboards)
- Escape key had no effect in Snow emulator — the M0110A keyboard has no
physical Escape key, so Snow's
akm0110::translatedrops host Escape key events entirely. Cmd+. and Clear key now provide Escape functionality. - Host Ctrl key had no effect in Snow — the M0110 has no physical Ctrl key. Option+letter (existing fix from 0.5.0) remains the correct way to send control characters on M0110/M0110A keyboards.
- Menu state management (
update_menus()in main.c)- Connect grayed out when connected, Disconnect grayed out when disconnected
- Copy/Paste enabled only when connected
SystemEdit()call for desk accessory support
- Scrollback viewing with keyboard navigation
- Cmd+Up/Down scrolls one line, Cmd+Shift+Up/Down scrolls one page
- Window title shows "[Scroll: -N]" indicator when scrolled back
- New incoming data automatically returns to live view
terminal_get_display_cell()reads from scrollback ring buffer
- Copy/paste support via Mac clipboard (scrap)
- Cmd+C copies visible 80x24 screen text (trailing spaces trimmed per row)
- Cmd+V pastes clipboard text to connection in 256-byte chunks
- Copy is scrollback-aware (uses display cells, not live screen)
- Proper About dialog (DLOG 130)
- "Flynn", "Version 0.5.0", description, copyright, credits
- Uses
GetNewDialog()/ModalDialog()/DisposeDialog()
- Settings persistence (
settings.c/settings.h)FlynnPrefsstruct saved to "Flynn Prefs" file (type 'pref', creator 'FLYN')- Host and port remembered across launches
- Connect dialog pre-fills from saved preferences
- Option key as Ctrl modifier for M0110 keyboard
optionKeymodifier bit mapped to control characters (key & 0x1F)- Fixes ESC and Ctrl+key on real M0110 keyboard (no physical Ctrl key)
- Quit confirmation alert when connected ("Disconnect and quit?")
- Connection lost notification alert when remote host closes connection
- Cursor visibility control (DECTCEM: ESC[?25h / ESC[?25l)
- Device Attribute response (DA: ESC[c → ESC[?1;2c, VT100 with AVO)
- Device Status Report response (DSR: ESC[6n → cursor position report, ESC[5n → OK)
- Generic ALRT 128 resource with OK/Cancel buttons for alerts
- Version: 0.4.0 → 0.5.0
- New source files:
settings.c,settings.h - Resource file expanded with About dialog (DLOG/DITL 130) and alert (ALRT/DITL 128)
- Terminal struct gains
cursor_visible,response[],response_lenfields
- Dedicated terminal UI renderer (
terminal_ui.c/terminal_ui.h)- Monaco 9pt font, 6×12 pixel character cells with 2px margins
- Batched
DrawText()calls scanning for attribute runs per row - Bold via
TextFace(bold), underline viaTextFace(underline) - Inverse video via
PaintRect+srcBictransfer mode - XOR block cursor with ~30-tick blink interval
- Per-row dirty flags for efficient partial redraw
- Direct drawing in null event handler (bypasses BeginUpdate/EndUpdate)
- Full keyboard input mapping in
handle_key_down()- Arrow keys → VT100 escape sequences (
ESC[A/B/C/D) - Home, End, Page Up, Page Down, Forward Delete
- Delete/Backspace → DEL (0x7F), Return → CR (0x0D), Tab → HT (0x09)
- Escape key (0x1B), Ctrl+key combinations
- Cmd+key menu shortcuts preserved
- Arrow keys → VT100 escape sequences (
- Screen freeze after row 24 (critical):
_TCPStatus()was the only TCP function missingmemset(pb, 0, sizeof(*pb)). Stale parameter block data caused incorrectamtUnreadDatareporting, which led_TCPRcv()(30-second blocking timeout) to hang the entire event loop after the terminal scrolled. Fixed by adding the memset and reducing the timeout to 1 second. - Switched from
term_ui_invalidate()(InvalRect → updateEvt) to directterm_ui_draw()calls in the null event handler for immediate rendering
- Build size: 64KB (up from 61KB)
- All 14 test scenarios now pass (echo, arrow keys, Ctrl+C, nano, vi)
- Client-side Telnet protocol engine (
telnet.c/telnet.h)- 9-state IAC parser with full option negotiation
- ECHO, SGA, BINARY, TTYPE (VT100), NAWS (80x24), TSPEED (19200)
- Adapted from subtext-596 server-side implementation (inverted for client)
- VT100 terminal emulation engine (
terminal.c/terminal.h)- 80x24 screen buffer with 96-line scrollback ring buffer
- Full cursor movement, screen/line clear, insert/delete, scroll regions
- Text attributes: bold, underline, inverse
- CSI parameter parser supporting up to 8 parameters
- Wired telnet and terminal into main event loop
- Data flow: TCP → telnet_process → terminal_process → display
- IAC responses automatically sent back to server
- Basic Monaco 9pt text rendering in window
- Retro68 GCC 12.2.0 compatibility (MacTCP.h, API renames, missing headers)
- In-repo toolchain build (
build.sh, Retro68-build/ gitignored) - DLOG resource missing
noAutoCenterfield for Rez
- Renamed project from telnet-m68k to Flynn
- App creator code changed from
TELNtoFLYN - Window title, about dialog, and menu items now say "Flynn"
- Snow workspace renamed to
flynn.snoww - Updated all documentation, paths, and git remote references
- Copyright year updated to 2026
- Project scaffolding: directory structure, CMakeLists.txt for Retro68
- Minimal Mac application skeleton (main.c) with Toolbox init, event loop, menus
- Resource file (telnet.r) with Apple/File/Edit menus and SIZE resource
- MacTCP wrapper (tcp.c/h) from wallops-146 by jcs
- DNS resolution (dnr.c/h) from wallops-146 by jcs
- Utility functions (util.c/h) from wallops-146 by jcs
- MacTCP.h header from wallops-146
- README.md with build instructions and acknowledgments
- LICENSE (ISC) with full attribution for derived code
- Development journal (JOURNAL.md)
- .gitignore for build artifacts, disk images, ROMs, reference materials
- Snow emulator setup with Mac Plus workspace (
diskimages/flynn.snoww) - SCSI hard drive image with System 6.0.8 installed via automated GUI
- X11 GUI automation guide (
docs/SNOW-GUI-AUTOMATION.md) - Testing guide (
docs/TESTING.md) with Snow and Basilisk II documentation - Development log (
docs/DEVLOG.md) with System 6.0.8 installation walkthrough - Installation screenshots (
docs/screenshots/) - Disk creation and driver extraction scripts (
tools/scripts/)