In changing the Viewer application over from the old (furniture.h) Wimp interface to the new (composite_window.h) version, it occurred to me that I hadn't done any documentation for the way it works. I'll try to remedy that here.
The ROLF Wimp has always treated a window as a rectangle controlled by the applications with a set of (usually smaller) rectangles, called hotspots, which respond to user input events according to a set of flags (report drags, clicks, activations, etc.). Windows may be opaque (obscuring any windows lower than them on the stack) or translucent (not completely obscuring them).
Initially, the hotspots were defined to be non-overlapping, but that can add a lot of complexity to the application, so the definition was changed so that the last hotspot in the set (now a list, since the order of definition is important) matching a given coordinate is the one that may report the event.
The Wimp behaviour has been fixed for some years, now. I need to add one more function, to return the current keyboard modifier flags (shift key states, etc.) for the filer to use, and to fix a bug in translucent window redrawing.
A window may also be marked as "transient", indicating that it should be informed before an active user input event (i.e. a click, not simple pointer movement) is sent to another process. This enables the implementation of pop-up menus.
Original API (furniture.h)
The original API, defined in furniture.h, wasn't very flexible, and shouldn't be used any more. It allowed an application to request window sizes according to the required size of the application drawn area of a window, which was good, but failed to provide the flexibility to do more "interesting" things, like sharing the horisontal scroll bar area with a status bar. Also, the user input events went through a single set of application provided routines, that had to distinguish between window types and made it difficult to provide standard window types (like a save window).
The new (and probably final) window API provides a C object-oriented interface where the application provides a pointer to a structure containing function pointers to the API which uses that pointer as the first parameter to those functions.
New Window API (window.h)
I spent some considerable time considering various approaches to defining how your application's windows should be laid out by the library, either with North, South, East, West, or a spiral of rectangles out from a central rectangle, etc., until I realised that it would be more work to define any but the most simple windows in that sort of way than to simply write a couple of routines per window type that would fill in the hotspot information for the library, given the window dimensions.
The API now invisibly, routes user events to the appropriate window's routines, which allows standard window types to be implemented without affecting the application code past the initial window creation.
The composite window API is a layer above the windows.h interface which makes the definition of non-overlapping rectangular areas, frames, of the window easier. This, in turn, allows libraries to provide standard window furniture features such as scroll bars and sizer icons.
Each frame provides a similar set of routines to those used in the window.h interface and a composite_window creating application will provide similar routines that the library can ask to provide information about the whereabouts of each frame.
There are some assumptions that can be made by application (and library) authors regarding these routines, namely:
- Only one user event will occur at a time (there's only one pointer)
- Only one window (per process) will be being redrawn at a time
This means that, say, the titlebar implementation can provide a single shared frame structure pointer, plus a routine to set up what it should display when it is drawn.
ROLF applications should be written with the assumption that the Wimp will handle acceleration of window redraws compatible with the system the application is running on. In general, applications should aim to use as little memory as possiblem and let the Wimp worry about buffering.
As an example, on a small-memory device with shared framebuffer memory, the Wimp will probably request the application draws directly to the framebuffer; in a large-memory device, the Wimp may allocate memory for the content of each window and combine them automatically, perhaps with DMA to a separate graphics card, so that the application will never be asked to perform a redraw because of window repositioning. The aim is to converge on an intermediate solution that notices details like how frequently a window's content changes, how quickly redraws complete, etc. and buffers the most processor intensive windows, automatically. (This doesn't happen yet, though.)
ROLF's drawing mechanism is based around an Image library, with a few essential types/interfaces:
- SourceImage (things you can render to a DestinationImage)
- DestinationImage (things you can render SourceImage things to)
- Bitmap (providing both of the above interfaces)
- ScreenRectangle (Rectangles with short (16-bit) values - it's sufficient for a 3m square display at 300dpi)
- rgba16 (The standard colour format, with 16-bits for each of RGB and Alpha)
One of the main aims of the library is to minimise the amount an application has to know about how images are encoded, conversion and optimisation will be provided within the library.
All Images (Source or Destination) represent a rectangular area, not necessarily with a (0, 0) origin.
[ To be continued ]