June 96 - Macintosh Q & A
Macintosh Q & A
Q Can I assume that the value of the ColorSync CMWorldRef parameter returned by
the NCWNewColorWorld routine isn't NULL if the routine was successful? I'd like to
determine whether a color world exists before trying to use it.
A Yes, you can assume that if no error is returned, the CMWorldRef parameter will
be valid.
Q Can ColorSync 2.0 profiles be embedded in EPS images?
A Yes, you can embed ColorSync profiles into EPS, as well as into PICT and TIFF
formats. For more information on how to do this, see the Macintosh Technical Q&A
"Embedding ICC Profiles" (CS 06). There are also details on how to embed profiles in
PICTs, along with sample code, in Advanced Color Imaging on the Mac OS, page 4-34.
Q How can I determine whether SCSI Manager 4.3 has been loaded by an extension at
startup time?
A Drivers or applications that intend to call the asynchronous SCSI Manager must
check that it's present by checking for the presence of the _SCSIAtomic trap
(0xA089).
While this is sufficient by itself for applications, driver writers must keep in mind
that if the asynchronous SCSI Manager is loaded as a system extension, the driver may
be running before the _SCSIAtomic trap is installed (this is true for the startup
device driver), so simply checking for the existence of the trap when your driver
starts up isn't sufficient. The extension loading process needs to be completed before
you make the check.
One way to do this is to use the accRun mechanism. If you set the dNeedTime flag in
your driver, it will get an accRun call at SystemTask time. You can test for
_SCSIAtomic then, set a flag indicating that you've discovered it, and then optionally
reset the dNeedTime flag so that your driver doesn't get called after you've completed
your discovery process. (Note that this technique is only suitable for old-style
drivers, type 'DRVR'. New PCI-compatible drivers, type 'ndrv', can't use the accRun
mechanism.)
This method isn't foolproof, however. It's possible for your driver to get an accRun
call before all the extensions are loaded, such as when a dialog is presented from an
extension that calls, for instance, ModalDialog (which will eventually dispatch
SystemTask). This results in the driver receiving an accRun call even though there
may be more extensions to follow.
So, in addition to simple determination of the presence of _SCSIAtomic, you need a way
to test that the Finder (or some other application process) has been launched. You can
do this by checking the length of CurApName. CurApName has a -1 length at startup
and becomes positive when a process (such as the Finder) gets launched.
An alternative is to queue up a Notification Manager task without specifying an icon or
sound, but only a response procedure. The procedure will get called after the
extensions finish loading. You can then check for the _SCSIAtomic trap.
Q I'm writing a QuickDraw GX printer driver that supports SCSI and PrinterShare
(server) connection types. I can connect multiple printers to one Macintosh on the
SCSI bus, and I've seen that I can have active print jobs printing on all of them
simultaneously. My question is: Do I have to be concerned about reentrancy when
coding my message overrides?
A There are a few issues you'll need to keep in mind. One is that each copy of your
driver must store any data it needs in its own data space. You can do this by using the
GetMessageHandlerInstanceContext and SetMessageHandlerInstanceContext functions. If
there is common global data that all copies of your driver will need to access, you can
use the functions SetMessageHandlerClassContext and GetMessageHandlerClassContext.
These are documented in Chapter 6 of Inside Macintosh: QuickDraw GX Environment
and Utilities.
For each instance of your driver, you'll also need to watch out for insufficient
memory. You shouldn't need to add much code if you're already checking for error
conditions when attempting to allocate memory within your driver, but if there are
places where you're not checking to make sure that the allocation was actually
successful, you'll need to add code (it's a good idea to always check anyway).
You'll also need to confirm that you don't have multiple instances of your driver trying
to write to the same printer at the same time. There are any number of ways you can
confirm this, including using a shared (ClassContext) data block with a semaphore to
mark whether an instance of your driver was in the middle of a GXWriteDTPData call.
Each instance could then first check that semaphore before attempting to read or write
data from the desktop printer. Be sure to include file locking while your driver is
reading or writing other files.
Finally, if you're writing a PostScript driver, be aware that the PostScript font
downloading code is not reentrant.
In general, you should use these techniques to write any QuickDraw GX printer driver,
whether or not you expect it to need reentrancy.
Q I want to program with Open Transport. What libraries should I link with?
A Here are descriptions of the libraries that come with Open Transport, and why
you might need to link with them.
Let's look first at linking Open Transport with PowerPC code. The basic libraries to
link with are OpenTransportLib and OpenTransportAppPPC.o. If you need AppleTalk
services, also link with OpenTptAppleTalkLib and OpenTptATalkPPC.o. If you need
Internet services, also link with OpenTptInternetLib and OpenTptInetPPC.o.
The OpenTransportUtilLib and OpenTptUtilsAppPPC.o libraries may provide a smaller
footprint if your application deals only with ports. Once you've got it working, try
replacing OpenTransportLib and OpenTransportAppPPC.o with these and see if your
application still links.
The OpenTransportExtnPPC.o and OpenTptUtilsExtnPPC.o libraries replace
OpenTransportAppPPC.o and OpenTptUtilsAppPPC.o if you're writing a standalone code
resource, CFM fragment, or ASLM shared library.
Note that if your code is meant to run on machines with and without Open Transport
(that is, you revert to Classic AppleTalk or MacTCP if Open Transport isn't available),
you should make sure to weak-link with the libraries ending in "Lib." Otherwise the
system will refuse to launch your application when Open Transport isn't installed.
Now let's take a look at linking Open Transport with 680x0 code. The basic libraries to
link with are OpenTransport.o and OpenTransportApp.o. If you need AppleTalk
services, also link with OpenTptATalk.o. If you need Internet services, also link with
OpenTptInet.o.
The OpenTptUtils.o library may provide a smaller footprint if your application deals
only with ports. Once you've got it working, try replacing OpenTransport.o with this
and see if it still links.
The OpenTransportExtn.o library replaces the OpenTransportApp.o if you're writing a