Twin is targetting a system without an MMU (and without much in the way of
process control), so "applications" are more likely to look like threads
than separate processes. As such, I'm using pthreads to simulate that
environment.

Building applications is largely a matter of creating enough infrastructure
so that you can write a new application without having to go change all of
the existing ones. I've had a brief chat with Owen Taylor who had some
simple suggestions:

Mark dirty and queue a recompute/redraw instead of attempting to
update the display in place

Nested windows aren't a feature

Keep behaviour simple

Keyboards and text input are a pain

With this in mind, I've done a few simple things. The first was to split
out the screen update into a separate thread. Applications paint into their
windows and just ignore the screen update process. Mostly. The one thing
we've learned with Composite is that applications really need to tell the
system when they're drawing and when the image is ready for publication.
Given that information, it's trivial to ensure that the display always
presents a consistent picture.

Under Composite, we'll probably need some kind of double buffering so that
areas of the screen can be repainted even while windows occupying those
areas are busy drawing. Otherwise, a busy application could "lock out" the
screen in those areas for a long time.

In Twin, I expect applications to be "well behaved", so I'm waiving the
ability to update at any time in exchange for saving piles of memory.
Instead, whenever an application is busy drawing, the screen won't get
updated. When all of the applications are idle again, the screen will get
updated.

That much was easy enough to get working; now it's on to event
distribution. I've already got a separate thread reading events from the X
connection. I'll try constructing event queues and having that thread
dump events into those queues so that the application thread can process
them synchronously with respect to output stuff.