In order to move the WindowServer to userspace, I have to eliminate its
dependence on system call facilities. The communication channel with each
client needs to be message-based in both directions.
WSWindowManager::invalidate() had a bug where it would mark the entire screen
rect as dirty, but it wouldn't scheduled a deferred recompose.
This would cause any subsequent calls to invalidate(Rect) to be coalesced
with the pending compose, but the pending compose never happened.
Use the BochsVGA card's virtual-height + virtual-y features to implement
a "hardware double buffering" type scheme.
This is a performance degradation since we now draw a bunch more than before.
But there's also no tearing or cursor flickering. I'm gonna commit this and
try to improve upon it. :^)
Instead of cowboy-calling the VESA BIOS in the bootloader, find the emulator
VGA adapter by scanning the PCI bus. Then set up the desired video mode by
sending device commands.
Work now happens in terms of two messages:
- WM_ClientWantsToPaint
- WM_ClientFinishedPaint
This feels fairly obvious compared to the old Paint/Invalidate.
Instead of clients painting whenever they feel like it, we now ask that they
paint in response to a paint message.
After finishing painting, clients notify the WindowServer about the rect(s)
they painted into and then flush eventually happens, etc.
This stuff leaves us with a lot of badly named things. Need to fix that.
To start painting, call:
gui$get_window_backing_store()
Then finish up with:
gui$release_window_backing_store()
Process will retain the underlying GraphicsBitmap behind the scenes.
This fixes racing between the WindowServer and GUI clients.
This patch also adds a WSWindowLocker that is exactly what it sounds like.
The system can finally idle without burning CPU. :^)
There are some issues with scheduling making the mouse cursor sloppy
and unresponsive that need to be dealt with.
This is pretty cool. :^)
GraphicsBitmaps are now mapped into both the server and the client address
space (usually at different addresses but that doesn't matter.)
Added a GUI syscall for getting a window's backing store, and another one
for invalidating a window so that the server redraws it.
Userspace programs can now open /dev/gui_events and read a stream of GUI_Event
structs one at a time.
I was stuck on a stupid problem where we'd reenter Scheduler::yield() due to
having one of the has_data_available_for_reading() implementations using locks.