Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2001-131
$eventId
ID of event: wwdc2001
$eventContentId
ID of session without event part: 131
$eventShortId
Shortened ID of event: wwdc01
$year
Year of session: 2001
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC01 • Session 131

CarbonLib: Carbon on Mac OS 8 & 9

Mac OS • 56:24

CarbonLib is the system extension that allows Carbon applications to run on Mac OS 8 and 9. This session covers the latest features in CarbonLib and shows you how to design your Mac OS X application so it runs well on Mac OS 8 and 9.

Speakers: Mark Turner, Vince Parsons

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Hello and welcome to session 131. My job as Carbon Technology Manager is to help you bring your application to Mac OS X. But of course, it is critically important to continue to support your customers who are running Mac OS 8 and 9. And that's what we're here to talk about today.

So what is CarbonLib? I'm going to start by defining Carbon as the set of APIs that you can use to write, well I should back up, excuse me, I'll define it as a set of APIs derived from classic Mac OS that you can use to write native Mac OS X programs. CarbonLib then is a system extension that implements the subset of those APIs that are available on Mac OS 8 and 9. And I say subset because although Carbon is derived from classic Mac OS, all current and future development of Carbon APIs is targeted at Mac OS X.

So where it's feasible and where it makes sense, we will continue to bring back some of those APIs and make them run on Mac OS 9 or 8.6. But it's important to understand Our primary goal is to give you the APIs you need to write killer apps for Mac OS X that fully exploit that platform.

It's not always possible for us to go back and re-engineer Mac OS X-style APIs on top of Mac OS 8 or 9. So why did we do CarbonLib then? Simply to allow you to develop for Mac OS X while continuing to support your customers who are going to wait a little bit longer to upgrade.

The greatest thing about Carbon is that it provides a single source solution. The same code can be compiled and run on Mac OS 8, 9, or 10. Of course, you need to conditionalize and test for API availability at runtime as you always have because not all of these APIs are available on every single OS that Carbon supports. We'll get into that a little bit later.

And the second great thing about Carbon is that it can provide a single binary solution because we continue to support the CodeFragmentManager and CFM executables. There are other alternatives as well, including Mac OS, and we'll talk a little bit about that later. But rest assured, the same binaries that you create today for Mac OS 8 or 9 will continue to work on Mac OS X, once they're carbonized, that is. This diagram simply illustrates what is the beauty of Carbon. That your application compiled as a Carbon app will run on Mac OS 8 or 9 calling into CarbonLib and on Mac OS X calling into the Carbon framework and other frameworks available on Mac OS X.

There are two versions of CarbonLib currently available for download from Apple's SDK webpage: CarbonLib 104 and CarbonLib 131. Why two versions? Because CarbonLib 104 is intended for use only on Mac OS 8.1. It provides the basic set of Carbon APIs that you can use to run on Mac OS 8.1 through Mac OS X.

These correspond to the APIs you'll find in the Universal Interfaces version 3.3.2. And with this set of APIs, you can create a good Carbon app that will run on all these platforms. But with CarbonLib 1.3.1, which is the current GM release, you have available to you a much broader set of APIs that more closely match what you'll find on Mac OS X. And I'm going to talk a bit about this later. But the important thing to note is that with CarbonLib 1.3.1, You must target Mac OS 8.6 and later because many of these, well all of these newer APIs cannot be brought back to Mac OS 8.1.

An interesting thing about CarbonLib 131 is that it's self-localizing. It supports all the languages you see listed here. What this means to you is that you don't need to carry around within your installer different versions of CarbonLib for these regions. When your Carbon app is launched, CarbonLib will examine your VERS resource, look for the locale, and localize accordingly. There's not much that needs to be localized: the title of the window menu, and some error strings, and print dialog types of things.

None of this was necessary in CarbonLib 104, so that version doesn't need to be localized at all. There will be more locales supported in future revision of CarbonLib, which we'll get to later. So, to summarize, this is the version of CarbonLib that we recommend you target unless you absolutely need to support Mac OS 8.1.

So I mentioned that you can license CarbonLib. There's no fee for this. It's similar to QuickTime or many of the other technologies that you've probably already licensed from Apple at one point or another. You simply fill out the usual software distribution agreement and then there's a one-page CarbonLib addendum.

The license does include Apple Help 163. That's for you to install on Mac OS 8.6 because the Apple Help Viewer app did not start shipping until Mac OS 9. But by moving your help into the Apple Help HTML format, you can deliver your HTML help content across all these Carbon supported platforms. We recommend that you do that. The CarbonLib 104 license includes Nav Services 101, which we want you to install if you install CarbonLib on an 8.1 system because it fixes some bugs in version 1.0 of Nav Services.

So this series of slides coming up here will be familiar to those of you who attended Scott Forstall's Frameworks Overview session. But I want to highlight a few things. So CarbonLib 1.04 does support development from Mac OS 8.1 to Mac OS X. began with all of the Carbon compatible APIs that already existed in Mac OS 8.1.

And then we added the toolbox accessor functions for opaque toolbox data structures, control window and menu properties, Nav Services 1.0, a subset of core foundation functionality, and the first version of the Carbon Printing Manager. This is a solid set of APIs. You can definitely write very good programs targeting this CarbonLib 104 set.

When you step up to CarbonLib 1.3.1 running on 8.6 or later, A whole slew of new APIs become available to you. Using these APIs, you can deliver a much better user experience to your customers. First and foremost, the Carbon Event Manager. This represents the new event model for Carbon applications. We strongly encourage you to adopt the Carbon events.

They will make it easier to write your Carbon applications and also can dramatically improve performance, especially on Mac OS X. Another one I'd like to highlight is the iBCarbonRuntime. This is what allows you to use Interface Builder's nib files on Mac OS 8 and 9. Interface Builder is, as you've probably seen in previous demos here at the show, a much easier way to design your user interface. And now, with the iBCarbonRuntime, you can use those nib files in your CarbonLib applications.

When you're running on Mac OS 9 or later, that brings in some new APIs that were added in Mac OS 9. Most importantly, the HFS+ APIs for improved file management. And if you attended the Carbon Performance Tuning session, you learned a bit about those. As well as many performance and stability enhancements that we brought with Mac OS 9 and 9.1. So if you can't bring your customers to Mac OS X, we really encourage you to try and bring them at least to Mac OS 9.1.

And finally, let's not forget why we're all doing this. When your app runs on Mac OS X, you get Aqua, you get all the new Carbon APIs because that's where they originate, and you get access to all the other APIs that are available to you on Mac OS X: Quartz, all of Core Foundation, even BSD or Cocoa APIs.

I'm not going to get into all the details here. It's pretty well documented now, but these are the basic steps that I recommend you follow. to get your app carbonized. One, go get the CarbonLib SDK. Read the Carbon Reporting Guide. Use CarbonDater to preview the changes you'll need to make.

Begin adopting those new APIs and then finally, aquify your interface because if you don't, Your app is not going to look very good on Mac OS X and that's not the reason why you're doing Carbon in the first place. Let's talk about each of these briefly. The CarbonLib 131 SDK includes both the regular and debugging version of the CarbonLib extension.

The debugging version adds assertions that help you in your development efforts. It also includes stub libraries, the latest universal interfaces, A folder full of documentation with links to more on our website. A bunch of sample code and the Apple Help Viewer 163, which as I mentioned you can install when you're installing on 8.6.

In the documentation folder on the SDK, you will find the Carbon Porting Guide. Props. Read this document. It's 150 pages of great information. It's got step-by-step porting instructions. Lots of great advice and a complete example of porting an application including before and after sample code. And also a section on adopting Carbon events which I think you'll find very interesting.

Next, you should run CarbonData on your app. The instructions for this are in the Carbon Reporting Guide, but it's very simple. You download this tool from our website. Drag your application on top of it. It spits out a text file that contains a list of all the APIs you're importing from the system, as well as some other things like potential accesses to low memory or resources stored in the system heap, both of which are not supported in Carbon. You can look at this file, make sure there's nothing secret in there, mail it to us. We have a server, receives that mail, compares that list against our Carbon database, and in about an hour sends you back a formatted HTML report that looks something like this.

At the top of the report is this nifty pie chart. It gives you an idea of the level of Carbon compatibility you're already at. For each API, or each function that your app imports, we tell you whether it's supported in Carbon, modified in Carbon, not recommended in Carbon or unsupported.

Then the remainder of the report goes on to list specifically for every API that is not fully supported, What that API is, its level of support, and recommendations for alternatives.

[Transcript missing]

Use this report to get a general idea of what you need to do. And I would encourage you during your carbonization process Every once in a while, take your latest binary, drop it on CarbonData and get a new report and see how far you've come. It's a great way to gauge your progress.

So then you have to get to work, right? Changing all kinds of stuff in your code. Much of that is fairly tedious and very simple. Adopting accessors for opaque toolbox data structures, changing your UPPs. We don't support the generic new routine descriptor, for example. You have to use specific ones like new control descriptor, new control action UPP might be one example. All of that is really straightforward and pretty simple, search and replace kind of stuff. There are some APIs that virtually all of you will need to adopt.

If you're currently using standard file, now is the time to stop. Nav Services has been around since Mac OS 8. It's a much better UI and it's supported on Mac OS X as well as 8 and 9 through Carbon. We need you to adopt Nav Services and I'll also describe some other benefits of that later.

The Carbon Printing Manager is necessary for anyone who's going to print because Mac OS X has a very different print architecture than Mac OS 8 and 9. And the Carbon Printing Manager hides that from you. By providing a high-level API that supports both platforms, when you're printing on Mac OS 8 or 9, it calls through to the classic print manager and uses the same classic drivers that you're already familiar with.

When you're running on Mac OS X, it uses Mac OS X's native print drivers to deliver its output. You don't really need to be aware of that. The API is fairly straightforward. We try to make it as simple as possible for you to convert to the Carbon Printing Manager without totally altering your print loop.

And finally for help, delivering help to your customers, Apple has standardized on HTML help delivered through the Apple Help Viewer. So we no longer support Apple Guide or Balloon Help. We encourage you to adopt the Apple Help Viewer APIs, and if you do things like tooltips and whatnot, then you should use help tags.

And then the last step, you've got your app up and running now, you want to make it look good on Mac OS X. First thing I would advise you to do is to create a new high quality 128 by 128 bit icon. Your icon... is the first thing a user sees. It is their introduction to your application. And a beautiful, well-designed, informative icon tells the user that you care and that you want to deliver the best possible application.

Next, you'll need to adopt a system appearance, or at least we highly recommend that you adopt system appearance through things like the Appearance Manager and other APIs that we've made available to you to automatically So, we're going to start with the first step, which is to adopt, or excuse me, to automatically appear as an, with an Aqua interface on Mac OS X or with the Platinum interface on Mac OS 8 and 9.

And also you need to follow the Aqua Layout Guidelines. Both of these steps are much easier if you use Interface Builder to design your interface and then use the nib files resulting from that to... will display this interface on Mac OS 8 and 9 or Mac OS X. And finally, we recommend that you adopt the Sheets APIs. We've made these very easy for you now because Nav Services and the Carbon Printing Manager both support Sheets.

So what this means is a single set of Sheets APIs will do the right thing on Mac OS 8 and 9 and Mac OS X. So when your app is running on 8 or 9, you'll continue to get application modal dialogs and when you're running on 10, you'll get document modal Sheets.

Documentation. The definitive source of API support in Carbon is the header files. So always look there first. You want to know, is this particular API supported in Carbon? For every function, it will state right in the headers what level of Carbon support is available. After that, the Carbon spec. Great place to look for more information about APIs, not only availability, but recommendations for unsupported APIs.

The Carbon specification is the source of the information that gets put in your Carbon data report. I'll talk about that in a second. I've already mentioned the Carbon porting guide. Lastly, TechNote 2003 is sort of a mini-porting guide. It's not specific to Carbon developers, but it provides a lot of useful information for anyone moving code from 8 or 9 to Mac OS X.

So the Carbon spec lists all the APIs and the universal interfaces, those that are supported as well as unsupported. gives you the inclusion status, tells you what version of CarbonLib or Carbon that they're available in, And also, when applicable, what version of the OS is required to support that API. And for APIs that aren't fully supported, The spec generally provides guidelines or recommendations for alternative APIs. Here's a picture of the Carbon spec. This page is on the memory manager. You can see that Maximum Sys is unsupported.

More masters, for example, is not recommended. And we tell you there, you should instead use more master pointers. And as you can see, More Master Pointers says Carbon applications should use this function instead of More Masters. In all cases, for supported APIs, we tell you what version of Carbon it's available in and that they're available on 8.1 and later. Again, it's very useful information. It is not updated as frequently as the header files, so there's some lag. That's why you should always look in the headers first.

The spec is generally updated. Several times a year and I think over time we're going to get in closer sync. For additional documentation, I highly recommend the Learning Carbon book from O'Reilly. I hope you all picked it up. How many of you got the Learning Cocoa book? Okay, leave the room.

I'm having an informal competition with my Cocoa Technology Manager counterpart and she's winning right now, which is rather perturbing. So I'd like you all to go out and buy the Learning Carbon book now. There's a Carbon tips and tricks web page. You should bookmark this page. There's a lot of great information there.

created by our developer technical support group so that they find issues common to Carbon developers. They document that on the web page there. In fact, I'll be referring to that a few more times in this discussion. Finally, the Carbon Developer homepage. That always contains pointers to the latest SDKs, what's new with Carbon development, things of that nature and I recommend that you bookmark that one and check back frequently.

Okay, so that's it for the getting started part. Let's dig in, let's talk about some of the things that you're likely to encounter now as you begin your development efforts. So the first thing you need to do is to The first step as you Carbonize your app, or when you're ready to run as a Carbon app, is create a plist resource. This tells Mac OS X that you are a Carbon application.

It is nothing more than the property list, the XML property list that you would create for a bundled Mac OS X application. That same information simply pasted into a resource in your CFM single binary application. You still need to maintain your VERS, Open, FRF, and all these other resources for compatibility with Mac OS 8 or 9.

But when you're running as a Carbon app, On Mac OS X, the plist resource supersedes and overrules the information in your resources. And this is documented in TechNote 2013. By the way, many people ask me about the CarbZero resource, which was the first way that we recommended people identify their Carbon application. We still recommend that you include a CarbZero resource. However, you must include a PList resource as well.

It is very important that you continue to test for API availability at runtime as you always have. When you have an application that can run on Mac OS 8, 9 or 10, it's no different than supporting an app when you had an app that ran on 6, 7 and 8. Some APIs are available in different OS releases that aren't available in others. So the way to do this, first and foremost, is to use Gestalt.

Gestalt is the best way to test for base functionality like "Is QuickTime installed?" and then When you need to test for specific APIs that may not be supported across all versions of QuickTime, then use a T vector test to find out if that specific function that you need is there.

If you haven't used the T-Bector test before, this is documented on the Tips & Tricks web page. And finally, do not rely on the CarbonLib version to determine whether a particular API is available because CarbonLib sits on top of Mac OS 8 or 9 and in most cases is simply exporting the APIs that are available in the underlying OS.

So it's not a reliable indicator of whether a particular API is there for you at runtime. An example of this would be if you said, "Oh, I'm running on CarbonLib 1.3.1. The HFS+ APIs must be available to me. You would be wrong because those APIs were introduced in Mac OS 9. So your Gestalt test would tell you that right up front.

Accessing non-carbon APIs. Yes, you can. We don't encourage it. It makes your code less portable and more difficult to maintain, but the option is available to you. And the way you do that is using the get shared library function to find interface lib and then the find symbol function to locate the specific function that you want to call. And this again is documented in the tips and tricks web page. Be sure that you verify that you're not running on Mac OS X because InterfaceLib is not available there.

If you're doing the proper error checking with Get Shared Library, you'll of course find out it won't return interface lib, but we find that a lot of developers forget to do that. They just assume that it's always going to return with interface lib, and when it doesn't, they crash. Try to avoid that.

There's a few things you need to be aware of when you're writing an app that can run in two very different memory environments. I'm sure you're all aware that Mac OS X provides essentially unlimited address space. Okay, four gigs, that's a lot. The main thing here is don't try and allocate all of it.

It has performance implications. There's a finite amount of RAM in the system and even hard disk space for backing store may potentially be limited and of course it's a lot slower. So use what you need and give it up when you're done. That's really all you have to do.

If you're currently using freemem, find out how much memory is available for you to allocate. You're going to find that that's not very useful on Mac OS X because it returns essentially a meaningless value. And it returns that same value every time you call it, which is currently 20 megabytes. We might change that. It doesn't matter. It's just an amount that we set to kind of allow apps who aren't being very smart about it to continue to run.

And another final point is if you're using zones to manage memory right now, you should know that your Grow Zone proc won't be called on Mac OS X. Zones are essentially, well they're unsupported in Mac OS X. Most of the zone functions are simply no ops on X. On Mac OS 8 and 9, you need to continue to do all the same things you've always done to manage memory there. RAM footprint. This is primarily of concern to apps running on 8 or 9.

CarbonLib introduces, it brings in some extra code that you're probably, wasn't there before with InterfaceLib and so you need to adjust your memory requirements accordingly. And the amount varies widely so we can't really give any specific recommendations other than retest and requalify with CarbonLib. You'll need to increase your stack and your heap some amount.

If you do plug-ins or if you either write plug-ins or use plug-ins in your app, you should know that Carbon apps can load interface Lib-based plug-ins, no problem. That's on Mac OS 8 or 9. On Mac OS X, of course, they can't because interface Lib is not available there. Non-Carbon apps cannot load Carbon plugins. CarbonLib explicitly checks at launch time that the host app is Carbon and if an interface Lib-based plugin tries to load, it will be refused.

If you've been to the Carbon events session, the Carbon performance tuning, actually most of the keynotes on the first day, you've probably heard over and over again, Stop polling. Polling is bad, especially on Mac OS X. Not so bad on Mac OS 9, nobody really notices, but on Mac OS X it really kills performance.

One of the best ways to do that is to adopt Carbon Events. The Carbon Event Manager simplifies your code because it can handle for you your human interface elements. It can drag your windows, resize, draw the menu bar, all these things for you. It takes that out of your event loop and manages it for you.

And it can eliminate the need for null event processing. I'll talk about that in a second. The biggest areas where we find application developers are polling is with mouse tracking. There's a very simple way to stop doing that using Carbon Events. If you have code right now that uses getMouse, button, stillDown, those kinds of functions in a tight loop, You can instead use track mouse location. It doesn't alter your loop at all. It's very simple to adopt. But the difference is the track mouse location does not return until the mouse is moved or a button is released. That makes for a much more efficient system.

And finally, we continue to support wait next event in Carbon. No problem there, but you should be aware that there are some differences in wait next event's behavior under Carbon. And the primary one is that the sleep time that you request is what you're going to get unless an event arrives for your app.

So if you request six ticks, you will not get control back in two ticks with a null event. You'll get return after six ticks. So the important thing here is that you can't get control back in two ticks. is we really recommend that you use large sleep times. Two or three months should be sufficient for most applications. And then use Carbon timers to get processing time when you need it.

I think the best thing to say is that if you're relying on null events right now to do idle time processing, you'll find that it's not going to work reliably under Carbon. So really you should adopt Carbon event timers. And it doesn't alter your event loop. You can still keep using wait next event, but just start using timers. You'll be much happier. Your customers will be much happier because your app and the rest of the system will be more responsive.

And finally, I'd like to put in a little plug for application packaging. This is the preferred way to deliver your apps.

[Transcript missing]

It supports the localization scheme of Mac OS X. It works on all file systems, flat file systems as well as HFS. And a single package can deliver more than one binary. So you can deliver a CFM executable for Mac OS 8 and 9 and a Mac OS executable for Mac OS X.

TechNote 1188 describes packaging today on Mac OS 9. We are working on improved package support in an upcoming version of CarbonLib and I'll talk a bit more about that later. And now, I would like to bring up a very special guest, Vince Parsons of the Adobe Acrobat engineering team, to share with you his experiences porting Acrobat to Carbon.

Okay, so Mark thought it would be a good idea if someone who's actually been through this process I'm going to say a few words about our experiences, what we learned, the mistakes we made, and hopefully we can teach a little bit from what we learned and so you won't make the same mistakes we did.

So I'm calling this CarbonLib from the trenches. So it's kind of a group of tips, tricks, and gotchas we discovered during the development of Acrobat Reader 5. So first, why did we use CarbonLib? We've got a large legacy code base and we wanted to move that toward 10, but we didn't want to sacrifice our 9 and 8 development. We also didn't want to have two different sets of code bases and two different binaries. We wanted a single binary that worked everywhere with a single code base that worked everywhere.

We also wanted to have an easy way to debug the Carbon API code that we're using. Even with the latest version of Metaworks they distributed to show, the debugging on OS 9 is still more mature. So you can debug your Carbon APIs on 9 as well as 10 if you use CarbonLib. And they also provide the debugging CarbonLib library which gives you lots of nice asserts when you're using the APIs incorrectly.

And the other thing we got is we got a lot of goodies that came free with CarbonLib. Core Foundation, MLTE, and Carbon Events are used extensively in Acrobat. Core Foundation and MLTE are available on OS 9 but the latest and greatest versions are only delivered via CarbonLib. So you want to make sure you go that route.

So a few tips. So as Mark discussed, there are several runtime differences you have to worry about. There's of course the menu layout. So quit and preferences belong over under the application menu, not under the file and edit or wherever preferences typically goes. And rather than just do a check on system version of 10, you should probably use the Gestalt menu manager Aqua layout bit. That way it's more dependable and you should actually avoid system version checks in general. The help menu is another issue.

To get the help menu on 9 there was an API for it. On 10 the help menu doesn't actually exist. There's a new API with part of Carbon called HM get help menu. That API will on 10 actually create the help menu if it isn't already there and will return it to you on 8 and 9 as well as tell you which offset from the beginning of the menu the first item actually exists. So if you go to the menu and you click on 8 and 9 when they have the show balloons and those sorts of items, it will let you know what offset off the beginning to use when adding your own menu items.

Some other issues are window attributes. So when you're creating a window with the Create New Window API, there are several attributes that are 10 only. And if you actually create a window with these attributes on 8 or 9, it will fail and you will just get a null window back.

So there are some Gestalt checks provided for actually checking those attributes. And just make sure you check the Gestalt bits before you assign the attributes to the window so the create works. And the other thing is memory management. Handles make little sense on OS X. They make great sense, both handles and 10-mem handles, on OS 9. You can check the Gestalt memory map sparse to know whether you're in a sparse environment and you should use just pointers. Or if you're not, then you should use the handles like you're used to under 8 and 9.

So most applications will call outside of the core set of APIs that are part of Carbon. It's just a fact of life. And Acrobat does it and it's actually not a big deal. For calling to the OS X only APIs, just use the callMacoFramework sample that's part of the SDK as a guide. It's a simple case of you load a framework, find an entry point in it, and you call it. You can use this to call directly into Core Graphics, you can call into I/O Kit, any of the 10 only APIs that are currently exported only through Mac OS.

You can also call stuff that exists only in 8 and 9. If you're patching traps, yes, we still patch a trap in Acrobat. It's a big no-no, but we do it. So you can still call a get-shared library in interface lib or whatever is the appropriate library for the API you're looking for. And do find symbol, and just again, call the function pointer. So you can do that for dealing with patching traps, heap zones, any of the things that aren't supported in the Carbon API.

So you've heard a lot this week about drawing text, and everyone says, "Make sure you draw text the right way," because drawing text the old way looks really, really bad on 10. So most of us still have drawString and drawText calls, and yes, it does work, but it looks bad. The drawThemeTextBox API has been discussed a lot this conference. It works. It works well. It draws anti-aliased with core graphics.

It also, because it takes a CFString as an argument, removes a lot of the issues of encoding and font selection for you. So if the text, you can just pass it in as a CFString, the OS automatically figures out, "Oh, this is Japanese. Oh, this is Roman." And we'll pick the appropriate font if you have the language kit installed, and we'll display the text correctly. And starting with CarbonLib 1.3.1, it is now available on 8 and 9, not just on 10. Amen.

So, like many Adobe apps, we have plugins and we have legacy plugins that are linked to InterfaceLib. We have to support them because they're an existing technology. And we found a few caveats with dealing with plugins that you should be made aware of. First of all, when a plugin that's InterfaceLib based creates a window with, say, Nucy window, it will not necessarily be created in the right layer. There's a very distinct difference between the modal and the document and the floating and those sorts of layers with CarbonLib and on 10.

They will pretty much always be created in the document layer. So if you have a modal dialog created from a plugin, it may end up in the wrong layer. And this is always true if you use a custom proc ID because the system can't even try to guess what type of window it is. So to solve this, if you see that a plugin's created a window, you can call setWindowClass on it or the forthcoming setWindowGroup API and just move it from the document layer to the appropriate layer and all will be well.

Another thing to think about is Carbon events. Now if you're moving toward Carbon events, and Carbon events are coming anytime you call waitNextEvent, or if you're calling runEventLoop, or there are several other ways. Anytime you call into a plugin, they're often going to call modal dialog, they're going to call waitNextEvent directly, they're going to call things which may cause your Carbon events and Carbon timers to be called.

And so just because you're calling into a plugin doesn't mean you can't be ready for your code to be called back at any time. So just be aware if you have any re-entrancy issues in your Carbon event handlers or your timers, make sure you think about those before you start dealing with the plugin issues. So a few tricks.

There are a whole suite of APIs as part of Carbon based on CFString. The wonderful thing about these, and I'm sorry, you can create controls, windows, menus, almost all the major UI elements can be created with CFStrings for their titles. This allows your UI code to be completely font and encoding agnostic.

Again, as I'm mentioning, you stick in a Japanese CFString, you stick in a Roman CFString, you stick in a Chinese CFString, the OS does the rest. You just pass the string, it sets the font for you, deals with all the encoding issues. It also makes it easy if you want to have a Roman and a non-Roman checkbox, say, next to each other, because just passing the string, you can have any number of fonts in the dialog for the various controls, and Carbon takes care of it for you if the fonts are available. Mark Turner, Vince Parsons There are a couple of limitations. There are issues with regard to using these on OS 9 and 8.

The menu and window titles are always going to be the system font. You can pass in another string with a different coding. Due to limitations of the underlying OS, they will always be the system font. And they're also limited to 255 bytes because they are translated into a Pascal string to go into the existing functions that are underneath in the real OS.

Another thing to think about is the Create Window from Nib API. Interface Builder has been talked a lot about in this conference. You can create your dialogs and windows in Interface Builder and then create them in a Carbon app with Create Window from Nib. This works on 8.6, 9, and 10. It's a whole lot easier than dealing with D-logs and diddles.

If you have existing D-logs, you can import them directly into Interface Builder. You go to the File menu, say Import Resource. It's there. It also has native support for several of the new control types. You can do your bevel buttons, your round buttons, your progress bars, all the types that previously with a D-log diddle you had to create control resources and it was rather difficult.

A couple of issues with regard to nib files is they have to be external. You cannot embed a nib file into your application as a resource. And this again goes toward the packaging issue. And the nib file is actually a package itself containing a few files and that has to sit outside of your main executable.

If you want to actually use Create Window from Nib, see the converter nib sample on the Carbon SDK. And it gives a good description of how to load the nib file and then create the window from it. So with all things with new technologies, there are a few gotchas.

So there are several APIs that are currently marked as OS X only. Don't assume they'll stay that way. Several APIs have migrated from being X only APIs into CarbonLib over time. I mean, a couple examples: getApplicationTextEncoding, addIn1.2, drawThemeTextBox, addIn1.3.1. There's going to be more in the future. Don't make assumption that if drawThemeTextBox exists that you're on X, or any particular API. If you're checking on its existence, assume that means the API exists, not what OS you're running.

And as Mark said, avoid checking the Carbon version from Gestalt. While it's useful in some minor areas, in most cases it's a problem. This is because if you ask OS X, it says 1.3, and you ask OS 9, it says 1.3. They don't mean the same thing, because the versions of CarbonLib and OS X have not matched up as nicely as they had hoped.

It's always good to use narrow Gestalt checks if you can. Check for unresolved functions with a T vector test. And if you do need to check for a CarbonLib version, say to work around for a bug or some other issue like that, combine it with a system check so that you know you're running on Mac OS 9 and this is the CarbonLib version. The only time we call this API is at lunch because we require CarbonLib 1.2.5 and later. That's the only time we check for this API because it's a good baseline to work from.

So resource chain management. So the Carbon APIs added a few new APIs for us to modify the resource chain. Previously we had, if you wanted to modify it, you could either open and close or you could modify the chain directly if you knew the structure. Right now there are new APIs for inserting a resource file, detaching a resource file, there's several other APIs dealing with this. Use these wisely, especially under CarbonLib.

As a developer who uses plugins, it's very tempting to every time you call into a plugin, set up the resource chain, put everything in you need, call the plugin, and then as soon as the plugin returns, you pull everything out of the resource chain so you have no resource collisions.

This doesn't work as well as we'd hoped. First, There's an issue with regard to it's not the most efficient thing to do. It's far more efficient to set up your resource chain in the right order at the beginning and then do your get resources and the collisions won't happen if the things are aligned all the way you want them to be.

Also, there's a bug in Nav Services in Mac OS 8.6 through 9.1 that will cause your resource chain to be corrupted in certain scenarios. So if you actually modify the resource chain from a Carbon event handler or timer that's called during a Nav call, because Nav will call waitNextEvent while its dialogues are up, it will actually corrupt the resource chain when you return from Nav. So if you do modify the resource chain from a Carbon event timer or handler, make sure you don't do it during a Nav call.

So there are a few things that OS X does for you just behind the scenes that CarbonLib doesn't, and you've got to make sure you do them yourself. A couple examples: Create root control. If you want to use the new control embedding architecture built into Carbon, you have to create root control on OS 8 and 9. On 10 it's automatic, on 8 and 9 you have to call it explicitly or have a DLGX resource next to your DLOG.

Also, idle controls. On 10, again, they do that for you to animate their buttons, to animate their progress bars, chasing arrows, etc. On OS 8 and 9, if you don't call idle controls yourself, they won't animate. So if you want the chasing arrows, the progress bar to animate correctly, stick a call to idle controls in a Carbon timer and that'll take care of it.

So printing. Printing is an interesting issue for Acrobat because we do a lot of it. And moving toward the printing manager APIs in Carbon, several things you want to be aware of. First, the Carbon printing manager on 8 and 9 is really just a wrap around the existing print manager. And a lot of the APIs for getting page sizes and things like that are just wrappers around PR general calls.

So a few mistakes we made, and hopefully I can let you avoid them, is use the session APIs. The non-session APIs do work. The session APIs work much better. And we did the non-session first and then rewrote our whole printing code using the session ones. Also, write your printing code for 10 first, not the other way around. Again, we made this mistake. We wrote it for 9, got it working, tried it on 10, didn't work at all.

This is because X is far pickier about the way you use the print manager. If you don't call things in quite the right order in the right way, X will not like it, but it'll work fine in CarbonLib. So we ended up having to rewrite our printing code yet again for X, and once we had it running on X, it worked everywhere.

The biggest thing we ran into was some driver incompatibilities. Not all drivers are fully compatible with CarbonLib. You'll see this come up in several different ways. Some features will just be ignored that are part of the print driver. For example, reverse order printing, invert pages, rotation, end up printing, those sorts of things. They just may get totally ignored and your user may choose to do two-up printing and it comes up without that choice.

Other drivers will not print color. They'll print just complete grayscale. Again, this is caused to incompatibilities between CarbonLib and the printer drivers. Apple is currently working with the driver vendors to solve these issues. So in the long run, this will not be an issue. But in the short run, be very aware that this will hit you if you are doing lots of printing.

And the most important thing: be sure to test, and a lot. As new versions of CarbonLib come out, Test them as quickly as you can. Treat each new version of CarbonLib like it's a whole new version of OS 9 because in many ways it is. The seeds do get posted on the ADC website for Select and Premier members. When they show up, get them immediately if you've already got a shipping application or if you're close to shipping.

Test your entire product because you can test your product far better than Apple ever could. While they may find some things, you'll find things that they never thought to look at. You don't want to discover that once you've got an app that's actually out there and shipping that suddenly your user gets a new version of CarbonLib through a software update and your app breaks. This has happened to several third parties.

You don't want it to happen to you. Get the new seeds and test them immediately and report bugs. You don't want to discover that once you've got an app that's actually out there and shipping that suddenly your user gets a new version of CarbonLib through a software update and your app breaks. This has happened to several third parties. You don't want it to happen to you. Get the new seeds and test them immediately and report bugs. Get the new seeds and test them immediately and report bugs. Get the new seeds and test them immediately and report bugs. bugs.

The only way that's going to get fixed is if you report bugs, and do that through bugreport.apple.com. So that's that's the biggest thing I want to leave with you, is don't let incompatibilities affect you. And that's it for my part, thank you very much, and good luck in your carbonizing.

Thank you Vince. Great presentation. You know, Vince and his team contributed immensely to improvements in CarbonLib and you guys can too by filing bugs and feature requests. So I really encourage you to do that. I'm going to stress it again at the end. Where are we going with CarbonLib? We're going forward. I hope it's apparent to you by now that Apple is investing heavily in Carbon and will continue to do so.

As I said earlier, as much as possible, we will try and bring back new Carbon APIs and make them run on 8 or 9. That will make your development efforts easier, obviously. But it's important to understand our focus is Mac OS X. But we will continue to support all the Carbon APIs we've already introduced.

So what's next with Carbon and CarbonLib? CarbonLib 1.4. It's currently seated. You can download it from the ADC website. CarbonLib 1.4 includes some new APIs to more closely match what you'll find on Mac OS X. Improved application package support, as I mentioned earlier, is coming in CarbonLib 1.4. and support for more localizations: Brazilian Portuguese, Korean, Danish and some others.

Give us feedback as soon as possible. We're early in the seed stage right now. So the sooner you give us your feedback, the more likely it is that we can fix that bug or add that feature that you really want. How do you do that? BugReport.apple.com. Any ADC member, even online members, can file bugs using our bug reporter system. They're funneled directly into engineering and acted upon. So please use that method. For non-technical feedback, you can send it to [email protected]. I will see it, others will see it, and it's also a useful feedback mechanism.

I encourage you to sign up for the Carbon Development Discussion List at lists.apple.com. This is a great place to get your questions answered as well as share your knowledge with other developers. It's monitored by thousands of developers and a whole bunch of Apple engineers as well. If you need one-on-one support, that's available through our Developer Technical Support group. You email [email protected]. This is fee-based support. Those of you who are selected Premier members receive a certain amount of tech support incidents with your membership, but anybody can purchase those.

Which brings us to the roadmap. Well, most of these sessions have gone by already, but I encourage you to watch on ADC TV or on the DVDs when they come out the session on the Carbon Event Manager. Remember, improve performance, stop polling, make your code easier. Carbon Windows and Menus, more of the same.

And the application packaging and document binding where you'll learn about packages and also how to How to use launch services to bind your document types to your applications on Mac OS X. If you have feedback that you'd like to give to the high level toolbox team, The feedback forum is today at 3:30, so right after this session in room C. This is me again. I am the Carbon Technology Manager, so I'm the guy you should send your issues and concerns to.