Autumn 91 - MACINTOSH Q & A
MACINTOSH Q & A
MACINTOSH DEVLOPER TECHNICAL SUPPORT
Q When my application is running, it relies on the MultiFinder's "puppet strings
(which choose Open from the application's File menu and suppress the SFGetFile
dialog) to open a document that was double- clicked in the Finder. Why doesn't this
work under System 7? The high-level event-aware bit in my 'SIZE' resource is clear.
A System 7 will not pull puppet strings for an application that makes use of the
System 7 Standard File routines, such as StandardGetFile and CustomGetFile, nor will
it pull them if the application's high-level event-aware bit is set.
If you update an older application to take advantage of any System 7 features, be sure
to also add support for the 'odoc' and other required Apple events. Sample code showing
how to support the required Apple events is available on the System 7 Golden Master
CD.
Q Why does Gestalt tell me I have Color QuickDraw features on a non-Color QuickDraw
machine?
A The gestaltQuickdrawFeatures ('qdrw') selector, used for determining your system's
Color QuickDraw features, has a bug that causes it to tell you incorrectly that noncolor
machines have color. The fix is quite simple: Gestalt has another selector,
gestaltQuickdrawVersion ('qd '), which simply returns the QuickDraw version
number. This version number is < gestalt8BitQD for classic QuickDraw and >=
gestalt8BitQD for Color QuickDraw (see Inside Macintosh Volume VI, page 3-39, for
more information). The trick is to ask Gestalt for the QuickDraw version first; once
you've determined that you have Color QuickDraw, the 'qdrw' selector is OK to use to
find out specifics.
Q What do we return to the Apple event handler if we get an application error while
processing a standard event, Edition Manager event, or custom Apple event for
commands and queries? Probably not errAENotHandled, since that means we didn't
handle the event, which is different from trying to handle it and failing. Would it be
errAEFail? What if we want to return more specific error information? Do we define
our own errors, or try to use Apple's errors such as memFullErr or parmErr?
A You pass back errAENotHandled, because it's true, and because some simple
applications will not be able to handle anything more than that. What you can also do,
and what most commercial applications will do (particularly applications that want to
be scripting savvy), is add errn and errs parameters to the reply record for that
event (as shown on page 6-49 of Inside Macintosh Volume VI). You can be as
descriptive as you like in the text--the more the better, in fact, since this text will be
seen at the user level usually. The errn value you pass back can be the system error
number; then the sending program may be able to recover and try again.
Q According to the QuickTime Movie Toolbox documentation, "The Movie Toolbox
maintains a set of global variables for every application using it." How much global
memory is required? Our application is shy on global data space.
A The information maintained is not kept with the application's global variables. The
handle created by the EnterMovies call is stored in the system heap, not in the
application heap. You don't have to worry about how much space to allocate in your
application. This initialization does not affect your A5 world either.
EnterMovies initializes everything, including setting up the necessary data space and
creating a handle to it. When you're done, be sure to make a call to ExitMovies to clean
up the QuickTime data. If an application makes multiple calls to EnterMovies, a
different set of "globals," or data area, is set up for each call. A call to ExitMovies
should be made before exiting the area that made the call to EnterMovies. For example,
an application that uses QuickTime will call EnterMovies and set up the QuickTime
world. Then an external may be called upon that wants to use QuickTime. This external
would have to make a call to EnterMovies to set up another QuickTime world for its
use. Before leaving, the external should call ExitMovies to clean up after itself. The
application can then continue to use QuickTime with the original world it set up.
Q Why does the longword at location $0 get changed to 0x40810000 at every trap?
A In System 7, the Process Manager slams a benign value into location $0 to help
protect against bus errors when an application inadvertently dereferences a NIL
pointer. (There's no bus-error checking on writes to ROM, so the "benign value" is
usually ROMBase+$10000.)
If you're debugging, you want the opposite effect: you want these inadvertent accesses
to "cause" bus errors. If you put a different value in location $0 before the Process
Manager starts up (that is, from MacsBug or TMON initialization, or from an INIT like
EvenBetterBusError), it will force that value instead. For more information, see the
"Macintosh Debugging" article in this issue.
Q I'm filling a large buffer with one SCSIRead call. What happens if the Macintosh runs
under System 7 with virtual memory (VM) and parts of my buffer are swapped out?
A Parts of your buffer must not be swapped out. Before calling SCSIGet, you must
ensure that all code and buffers accessed while the SCSI bus is busy are held in
physical memory. If there isn't enough real memory to allocate a full buffer, the
application must request smaller blocks (if possible) from the SCSI device, because
it's not possible to swap in and out any buffer space during a single I/O operation. Page
faults are not serviced while SCSI I/O is in progress. If SCSI I/O is performed at
device driver-level Read or Write calls, VM holds your buffer for you. Otherwise, you
are responsible for doing this yourself. If there is insufficient physical memory for
VM to hold your buffers for you, the Read or Write call fails with an error result.
In general, I/O buffer space used by drivers must be held in real memory for the
duration of the I/O operation. This is especially true for SCSI I/O because VM uses
SCSI to swap virtual memory in and out, and encountering another page fault would
cause a bus error. Device Manager-level I/O handles this automatically, by holding
down the appropriate memory when the driver is entered through a Read or Write call.
The Device Manager does not take care of this for you when the driver is entered
through a Control or Status call, however. If the SCSIRead call is made from within a
device driver as a result of a PBRead, no special action is necessary. Any other type of
code must be very careful not to cause page faults between SCSIGet and SCSIComplete.
This requires holding or placing in the system heap any code or data structures
referenced during this time.
Q Is there anything special that a Macintosh hard disk or a removable cartridge driver
must do to be fully compatible with System 7?
A One important thing you should be aware of regarding removable cartridges is that a
cartridge can't be removable if VM is to use it for a backing store. Some removables
allow you to fix this with a SCSI command to prohibit ejection and, just as important,
the drive must be marked nonejectable in the drive queue.
Here are a couple of suggestions: Read Macintosh Technical Note #285, "Coping with
VM and Memory Mappings." Also, take a look at the Memory Management chapter of
Inside Macintosh Volume VI and the Virtual Memory paper (Goodies:VM Goodies:VM
Paper) on the System 7 Golden Master CD.
Q What does the "!" mean when I use the MacsBug Heap Zone (HZ) command? It
appears in front of one of the zone names listed, or just after the address if the zone
doesn't have a name.
A MacsBug's HZ command does a quick-and-dirty heap check, and if it thinks
something is wrong with a heap, it puts the exclamation point after the address range
of the heap. If you select the heap flagged with a "!" with the Heap Exchange (HX)
command and then use the regular Heap Check (HC) command, MacsBug tells you what
it thinks is wrong with that heap.
Q I want to display only visible files and folders in a Standard File dialog, but I can't
find a way to filter out invisible folders--specifically the 000Move&Rename folder.
The FileFilter routine filters only files, not folders. If I put in a nonzero TypeList,
invisible folders seem to be removed, but I want to open all types of files, just not
invisible files or folders. Any suggestions?
A This is, in fact, impossible under System 6 using general methods. The problem is