Specifications
Apple II Technical Notes
2 of 4 #75: BeginUpdate Anomaly
So What’s the Problem?
The problem is that the updateRgn is not a very good place to save the visRgn. Since
InvalRect and InvalRgn modify the updateRgn, if either of these two calls is made between
a BeginUpdate and EndUpdate, they modify the saved visRgn. When the update is finished,
EndUpdate restores the modified visRgn instead of the original.
The solution to this problem seems simple enough: don’t call InvalRect or InvalRgn
between BeginUpdate and EndUpdate. Unfortunately, there are other calls which can call
BeginUpdate, EndUpdate, InvalRect, and InvalRgn, so an application might
inadvertently call one of these routines.
If this situation isn’t bad enough already, you could really mess things up by opening another
window between BeginUpdate and EndUpdate calls. Opening a window at this time may
seem like a perfectly normal thing (i.e., to display an alert); however, opening a window forces the
recalculation of the visRgn for any windows obscured by the new window. If the window being
updated has its visRgn recalculated, the application obviously loses the visRgn that
BeginUpdate created. This doesn’t seem too serious since the visRgn is restored to the entire
visible part of the window when the new window is closed; however, it does mean that the
application would have to update the entire window instead of the original updateRgn.
Unfortunately, the Window Manager also posts update events for the portion of the window that
was obscured, and it does this by changing the updateRgn. Of course the updateRgn for the
window being updated is really the visRgn that is being “safely” preserved until the
EndUpdate call. So, there are some really good reasons why this can’t be done.
Okay, so along with not making calls to InvalRect and InvalRgn between BeginUpdate
and EndUpdate, an application cannot open any other windows either. Good.
Now to make things even worse.
Starting with System 5.0, some toolbox functions are stored on disk in dynamic segments and
loaded when they are first called. For example, CopyPixels is in a dynamic segment in System
versions 5.0 through 5.0.3. If the startup disk is not available and the system prompts for it
between BeginUpdate and EndUpdate by calling AlertWindow, the bad things discussed
above happen.
Starting with System 6.0, the system is smart enough not to prompt for a disk using
AlertWindow if a window update is in progress. (Internally, GS/OS calls WindStatus to see
if it can prompt on the graphics screen. If BeginUpdate has been called more times than
EndUpdate, WindStatus fibs by returning with the carry set. GS/OS takes the hint and
prompts for the disk with a text dialog instead.)










