I remembered I have a keyboard for my Palm Vx which I can use on the train.
Let me know what other topics you would like me to cover.
andy
Widget Redisplay
Widget redisplay follows the general asynchronous nature of redisplay
in general - that is items for display are updated separately to their
actual visual representation. For instance a tab control has serveral
lisp structures associated with it. When the tab structure is changed,
thes lisp structures are changed, but it is not until redisplay proper
that you actually see any change. There are several reasons for doing
it this way, one is that it conforms more closely to the second rule
of redisplay - not to call lisp during redisplay. The actual mechanics
of this is encoded in two image instance methods -
update_image_instance and redisplay_subwindow with obvious
meanings. These methods delegate to widget specific versions via
update_widget and redisplay_widget. These in turn delegate to device
and format specific methods - for example layout_update and
mswindows_button_redisplay.
update_image_instance bears further discussion since it encapsulates
behaviour that is important to understand. To change a widget the
image instance is not manipulated directly, but rather its
instantiator is changed and then these changes are propogated to image
instances that are instantiated by this instantiator. However, in
order for this behaviour to work properly it is important that the
image instances are not recreated - as would be the case in a naive
implementation - unless absolutely necessary. Thus, the image instance
cache for widgets is keyed on the glyph identity and the widget type
*not* on the instantiator. When image_instantiate is called it looks
up the image_instance based on its glyph and domain and if a match is
found update_image_instance is called with the new instantiator. The
cache is keyed on the image type as well as the glyph because it would
be impossible to merely update an image instance representing one gui
widget to another; for instance converting a button to a tree-view.
update_image_instance compares the original instantiator and then
calls widget_update with only those keyword-value pairs that have
changed. The individual image instance update functions then update
the internal structure of the widget using those values.
However, herein lies a problem - redisplay optimizes which parts of
the screen it is going to display by comparing current and future
redisplay structures, however in the case of glyphs the glyphs are the
same object in both sets of structures. This is because otherwise
glyphs and image instances would be recreated each time redisplay was
called. So how does redisplay know whether to actually update the
displayed properties of image instances? The solution is a set of
`dirty' bits in the image instance which are set depending on what
changes update_image_instance has actually made. The flags also need
to be propagated up to the glyph so that redisplay can tell easily
whether something might have been changed or not. We say `might' here
because it is possible for the same glyph to have diffferent
instantiators in different domains and thus redisplay must update only
the image instances for the instantiator that has changed. The
dirtiness or otherwise of a glyph is encapsulated in
imge_instance_changed and also compare_runes. When a
determination of dirtiness has been made the image is redisplayed
using redisplay_subwindow. This propogates the lisp structure
changes (in gui_item) into on-screen properties and then marks the
structure and instantiator as up-to-date. In both X and mswindows a
lot of generic updating is done in mswindows_redisplay_widget and
x_redisplay_widget. In fact under X this is pretty much the only
function that gets called since the updates are then delegated to
lwlib to handle.
Show replies by date