• docs/v322_new.md src/sbbs3/con_hi.cpp getstr.cpp writemsg.cpp

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Nov 8 15:46:34 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/16d0248e3cc9fa1e833acdf0
    Modified Files:
    docs/v322_new.md src/sbbs3/con_hi.cpp getstr.cpp writemsg.cpp
    Log Message:
    Accept Unicode (UTF-8) text in the internal message editor

    On a UTF-8 terminal, the internal editor translated every typed
    character to CP437 and dropped any with no CP437 equivalent (e.g.
    "¨", "¨", "¨"), because its getstr() calls lacked K_UTF8. The subject
    prompt has passed K_UTF8 since f68a24d61b (registry-20-rail,
    2024-02-20), so a subject could hold emoji while the body could not.

    getstr() now handles multi-byte UTF-8 input as characters: the bytes
    of a sequence are collected per keystroke, byte-offsets and display
    columns are tracked separately (via str_width/prev_char/next_char),
    and all editing operations (word-wrap, insert/overwrite, backspace,
    delete, Ctrl-W/Ctrl-D, Home/End, cursor keys, tab stops, centering)
    work on characters and columns. The line-length limit remains a byte
    limit (the caller's buffer size) while the wrap point is the terminal
    width in columns. Edits go through two shared routines (insert_bytes/ delete_range) that print the same screen state as before for CP437
    input.

    redrwstr() moved to getstr.cpp (its only caller) and takes byte
    offsets for both the cursor position and the length, converting to
    columns itself. It previously compared a column count against a byte
    count and so, after a multi-byte character was typed into a K_UTF8
    field (e.g. an emoji in a subject), moved the cursor back to the start
    of the field; text typed next overwrote the character on screen.

    A CP437-translated high-bit character (e.g. "­") typed on a UTF-8
    terminal was stored but never echoed, since the echo branch required
    the buffer to be valid UTF-8. It is now echoed via outchar(), which
    performs the CP437 to UTF-8 translation.

    The editor's per-line byte budget (MAX_LINE_LEN) grows from cols+1 to (cols-1)*UTF8_MAX_LEN+3 to hold multi-byte lines. The old value also
    left no room for the CR/LF of a full-width line: a 79-column line on
    an 80-column terminal lost its LF when the lines were rejoined.

    The "Export ASCII Characters Only" sub-board setting is an export-time conversion and does not restrict local input.

    Fixes #1317

    Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net