June 96 - Graphical Truffles: Dynamic Display Dilemmas
Graphical Truffles: Dynamic Display Dilemmas
CAMERON ESFAHANI and KENT "LIDBOY" MILLER
In the Dark Ages, an application could examine the graphics
environment once and gather all the information it needed to know.
After the System 7.1.2 Renaissance, the Display Manager made the
graphics environment dynamic, which provided many new features
(and introduced a few implementation issues). In Issue 24 of
develop, the Graphical Truffles column described some important
features of the Display Manager. Here we'll discuss some common
pitfalls that can cause an application to fail in a dynamic display
environment -- and ways you can overcome them.
If you use QuickDraw routines in an existing application, your application may already
support some aspects of the Display Manager without requiring any extra work on
your part. An example we touch on in this column is the graphics mirroring feature,
which allows users to make two graphics devices display the same image. QuickDraw,
whose routines have already been updated to support the Display Manager,
accomplishes graphics mirroring by overlapping the gdRects (global bounds) of the
graphics devices. QuickDraw's internal version of DeviceLoop behaves correctly by
detecting when devices overlap, then rendering the image properly for each device.
This allows overlapping devices to have different color tables or bit depths and still be
imaged correctly.
On this issue's CD, we've included a sample application, SuperFly, which illustrates
several techniques you can use to support a dynamic environment in your application.
Some of the sample code in this column is excerpted from SuperFly.
COMMON ERRORS
When we were integrating the Display Manager into new system software releases, we
encountered some common problems that existing applications had when running in a
dynamic display environment. Here's a list of suggestions regarding things that might
have worked in the past but won't work now; we'll examine each error in turn and
suggest a solution.
• Don't forget to account for mirrored graphics devices when walking the
device list.
• Don't assume that just because your application uses only one logical
display, it's drawing on only one physical device.
• Don't cache the graphics devices and their state on application startup.
• Don't assume that the menu bar will never move.
• Don't assume that menus will be drawn on only one display.
• Don't draw directly to the screen and bypass QuickDraw without checking
for the mirrored case.
• Don't assume that certain 680x0 registers will contain the same values
inside a DeviceLoop drawing procedure as when DeviceLoop was called.
Don't forget to account for mirrored graphics devices when walking the
device list.When writing applications in the past, some programmers assumed that
graphics devices would never overlap. For example, you might assume that if a certain
rectangle is fully contained within a gdRect, it isn't on any other device. To implement
highlighting, your application might walk the device list and invert the selection if the
global rectangle of what you want to highlight intersects the gdRect of that device.
However, when there are two displays with the same gdRect in the device list, the first
inversion accomplishes the highlighting but the second inversion restores the
highlighted area to the original -- unhighlighted -- state.
Solution: Use DeviceLoop for your drawing. If you want to write your own version of