1)  NO GLOBALS (ESCDELAY etc will be in the struct with accessors)
2)  An init function that returns a struct with a bunch of function pointers in
    it.
3)  UIFC will need to have the ability for the ciolib struct to be passed to
    it.
4)  Will support multiple independent windows.
5)  There will be a compatability library for JUST conio stuff.
6)  Any advanced features not in the conio API will not be present.
7)  Unicode (UTF-8) support... likely X11 first, followed by Curses, SDL and
    Win32.
8)  ANSI mode may never get proper unicode support... or at least not until
    everything else works.
9)  Unicode support will support GR access of the C1 set.  Most importantly,
    this means CSI (\x9b).  This is actually somewhat silly since it will take
    two bytes regardless, but if UCS-2 or something gets added in the future,
    it may make a difference, and there's no reason to show control codes.
10) Greatly expanded attribute sets, and in UTF-8 mode there will be no
    hackiness.  The great bright/bold debate will rage on though... possibly a
    new set/reset mode will be added to control it.
11) Double-height/Double-width/Double-size modes.  As is tradition, all the
    cells covered by the glyph must be the same character and attributes.  This
    opens a whole can of worms regarding how further updates work etc.  I'll
    strive to keep it sane and compatible, which may be impossible.
12) A Unicode cell will potentially have multiple codepoints "in" it.
13) We need a way to specify the initial mode.
14) Multiple screen update modes...
    - Individual cells for modes where each cell has all rending details (ANSI)
    - Per line for modes where each character depends on all before it on the line (Proportional)
    - Per screen for modes where each character depends on every character before it (Prestel)

Some sort of state checkpoint thing... you "save" the checkpoint, and send that
ID back and you get the same state returned.

Stack and state save thing

For CONIOng:
Layers:
0  - Solid fixed background (doesn't scoll)
1  - Text area background (scrolls, text area)
2  - Text area background bitmap (scrolls, text area)
3  - Text area background pixel (scrolls, text area)
4  - Bitmap background (doesn't scroll)
5  - Pixel background (doesn't scroll)
6  - Text area foreground (scrolls, text area)
7  - Text area foreground bitmap (scrolls, text area)
8  - Text area foreground pixel (scrolls, text area)
9  - Bitmap foreground (doesn't scroll)
10 - Pixel foreground layer (doesn't scroll)

Layer Attributes:
Layer 0:  "colour"
Layer 1:  <none>
Layer 2:  <none>
Layer 3:  "hidden"
Layer 4:  <none>
Layer 5:  "hidden"
Layer 6:  <none>
Layer 7:  <none>
Layer 8:  "hidden"
Layer 9:  <none>
Layer 10: "hidden"

A text area can be defined as having a given width and height with the
top-left corner positioned at any pixel location.  Text areas use a fixed
width font, and have multiple planes... text background, background bitmap,
background pixels, text foreground, foreground bitmap, foreground pixels
It will have the following attributes:
Fonts
Codepage
Tab stops
Cursor position
Auto-wrap
Blink enabled
Cursor vidible
Palette definition
Foreground visible
Foreground bitmaps visible
Foreground pixels visible
Background visible
Background bitmaps visible
Background pixels visible
Z-index
"Current" cell attributes (see below)

Each character cell will have the following attributes:
Codepoints (array)
Foreground colour
Background colour
Font
Flags
- Bold
- Increased intensity
- Faint
- decreased intensity
- second colour
- Italic
- Underline
- Slow Blink (< 150/min)
- Fast Blink (> 150/min)
- Negative
- Concealed
- crossed-out (Overstrike)
- Fraktur (Gothic)
- Double underline
- Framed
- Encircled
- Overlined
- Ideogram underline (right)
- Ideogram double underline (right)
- Ideogram overline (left)
- Ideogram double overline (left)
- Ideogram stress
- Double overstrike
- Double-wide
- Double-high
- Superscript
- Subscript

Bitmap layers contain zero or more bitmaps (likely WebP, maybe others)
which have a stacking order in the layer. Attributes:
position
hidden
paused (not animated)
Z-index

Pixel layers are simply an array of pixels that may be directly
manipulated.  No attributes are planned.

For the bitmap and pixel layers associated with a text area, they will
scroll with the text in that area.

Unicode fonts of last resort:
Unscii... a retro computing font...
http://viznut.fi/unscii/

Unifont... the mother of all fonts...
https://unifoundry.com/unifont/index.html

For Unicode, we're not going to want the fonts in the image I don't
think, so they'll need to be loaded from disk/rasterized on demand.
This means a cache that we can use bsearch() on... which means we'll
need something like an epoch to age things out of the cache, and the
cache will need to be cleared after each connection... and presumably
at certain other points during a connection.  Getting this right with
epoch stuff is going to prove tricky, but be necessary to prevent
blocking while waiting to render a glyph (essentially, it must *always*
be possible to add a new glyph without blocking).

Further, "fonts" will need to have a source map as well... loading
a CP437 font will only update specific glyphs for example, and those
will be spread out around the space, so "stacks" of fonts, each
entry listing ranges to map will be needed, and we'll want to use
bsearch() there too.

General architecture:

Bitmap output layer: single API for putting pixels in a rectangle.
                     - maintains the "current" screen
                     - multiple are stacked for final output
                     - when stacked, tries to do as few scalings as possible
                     - has an epoch
                     - can register an input source
                     - can regiser a menu bar
Input source: mouse and keyboard input, passes events to a callback or pipe
              - input *must be* unicode
              - needs to have modifier support... at least ALT
Text output layer: single API for adding text to the "screen"
                   - maintains the "current" screen
                   - has an epoch, potentially per-line and per-cell
                   - can flush to output (curses, bitmap, etc)
                   - can register an input source
                   - can regiser a menu bar
UI layer: This one is where it gets weird... being able to do TUI and
          GUI means being able to exist inside or outside of the text
          output layer... and when outside, having the bitmap output
          "inside" of it.  It likely makes sense to just have this as
          mostly TUI with extra "status bar" type things and a "menu bar"
          thing.
          - can register a menu bar
          - Maybe an input source?
          - Is this where the status bar lives?
Menu bar: Generic menu bar interface that has "preference" levels so only
          one of the registered menu bars is used.  Registers callbacks
          and keyboard shortcuts, and can have options dynamically disabled.
          - Maybe an input source?
Status bar: Some fancy something that allows a GUI status bar as well as a
            text one.
Encoding Translator: Converts from one encoding to another
                     - One of the two encodings is always expected to be unicode
                     - Must support both UTF-8 and UTF-32 at a minimum
Terminal Emulator: Bidirectional pipe with remote
                   - Has four IO paths...
                     - Input from remote
                     - Output to remote
                     - Input from keyboard - has translation of some kind...
                     - Input from mouse
                   - Outputs to a text output layer and/or a bitmap layer
                   - Can output audio
Audio output: Can output simple tones and samples
              - Want MIDI support
              - Want streaming support
              - Want tracker support
Connection interface: For "remote" connections
                      - Telnet/SSH/pty/etc.
                      - Implements codepage/unicode translation?
                        - If so, this is where the "line at a time" telnet mode
                          needs to live, which is awkward.
Unconnected UI: Settings, List, etc.

Having a uint32_t (or uint64_t if needed) representation of a sequence will
allow using binsearch() to find the handler.
5 bits - one to indicate each of the following is populated
       - if this bit isn't set, the corresponding bits must be zero
1 bit  - Indicates more than one intermediate character
5 bits for first char (ctrl function C0)
6 bits for second char (ctrl code C1)
2 bits for private parameter character
4 bits for intermediate character
6 bits for final character
= 29 bits

Possible names:
PixelPerfect
PixelPusher
Glarmak

SyncTERM should integrate with the "system" keyring

