|Operating system||OS X|
Carbon is one of Apple Inc.'s C-based application programming interfaces (APIs) for the Macintosh operating system. Carbon provides a good degree of backward compatibility for programs that ran on the now-obsolete Mac OS 8 and 9. Developers could use the Carbon APIs to port their "classic" Mac software to the Mac OS X platform with far less effort than a port to the entirely different Cocoa system which originated in OpenStep.
Carbon was an important part of Apple's strategy for bringing Mac OS X to market, offering a path for quick porting of existing software applications. As the market has increasingly moved to the Cocoa-based frameworks, especially after the release of iOS, the need for a porting library was diluted. Apple did not create a 64-bit version of Carbon while updating their other frameworks in the 2007 time-frame, and eventually deprecated the entire system in OS X 10.8, which was released on July 24, 2012.
Classic Mac OS programming
The original Mac OS used Object Pascal as its primary development platform, and the APIs were heavily based on Pascal's call semantics. Much of the Macintosh Toolbox consisted of procedure calls, passing information back and forth between the API and program using a variety of data structures based on Pascal's variant record concept.
Over time, a number of object libraries evolved on the Mac, notably MacApp and the Think Class Library (TCL) in Pascal, and later versions of MacApp and CodeWarrior's PowerPlant in C++. By the mid-1990s, most Mac software was written in C++ using CodeWarrior.
With the purchase of NeXT in late 1996, Apple developed a new operating system strategy based largely on the existing OpenStep platform. The new Rhapsody was relatively simple, it retained most of OpenStep's existing object libraries under the name "Yellow Box", ported OpenStep's existing GUI to make it look more Mac-like and less NeXT-like, ported several major APIs from the Mac OS to Rhapsody's underlying Unix-like system (notably QuickTime and AppleSearch), and added an emulator known as the "Blue Box" that ran existing Mac OS software.
When this plan was unveiled at the Worldwide Developers Conference in 1997 there was some push-back from existing Mac OS developers, who were upset that their code bases would effectively be locked into an emulator that was unlikely to ever be updated. They took to calling the Blue Box the "penalty box". Larger developers like Microsoft and Adobe balked outright, and refused to consider porting to OpenStep, which was so different from the existing Mac OS that there was little or no portability.
Apple took these concerns to heart. When Steve Jobs announced this change in direction at the 1998 WWDC, he stated that "what developers really wanted was a modern version of the Mac OS, and Apple [was] going to deliver it". The statement was met with thunderous applause. The original Rhapsody concept was eventually released in 1999 as Mac OS X Server 1.0, the only release of its type.
Cocoa and Carbon
In order to offer a real and well supported upgrade path for existing Mac OS code bases, Apple introduced the Carbon system. Carbon consists of many libraries and functions that offer a Mac-like API, but running on top of the underlying Unix-like OS, rather than a copy of the Mac OS running in emulation. The Carbon libraries are extensively cleaned up, modernized and better "protected". While the Mac OS was filled with APIs that shared memory to pass data, under Carbon all such access was re-implemented using accessor subroutines on opaque data types. This allowed Carbon to support true multitasking and memory protection, features Mac developers had been requesting for a decade. Other changes from the pre-existing API removed features which were conceptually incompatible with Mac OS X, or simply obsolete. For example, applications could no longer install interrupt handlers or device drivers.
In order to support Carbon, the entire Rhapsody model of the OS changed. Whereas Rhapsody would effectively be OpenStep with an emulator, under the new system both the OpenStep and Carbon would, where possible, share common code. To do this, many of the useful bits of code from the lower-levels of the OpenStep system, known as Foundation, were re-implemented in a pure-C form. This code became known as Core Foundation, or CF for short. A version of the Yellow Box ported to call CF became the new Cocoa (API), and the Mac-like calls of Carbon also called the same functions. Under the new system, Carbon and Cocoa were peers. This conversion would normally have slowed the performance of Cocoa as the object methods called into the underlying C libraries, but Apple used a technique they called toll-free bridging to reduce this impact.
As part of this conversion, Apple also ported the graphics engine from the license-encumbered Display PostScript to the licence-free Quartz. Quartz provided native calls that could be used from either Carbon or Cocoa, as well as offering Java 2D-like interfaces as well. The underlying operating system itself was further isolated and released as the Darwin (operating system).
Release and evolution
Carbon was introduced in incomplete form in 2000, as a shared library backward-compatible with 1997's Mac OS 8.1. This version allowed developers to port their code to Carbon without losing the ability for those programs to run on existing Mac OS machines. Porting to Carbon became known as "Carbonization". Official Mac OS X support arrived in 2001 with the release of Mac OS X v10.0, the first public version of the new OS. Carbon was very widely used in early versions of Mac OS X by almost all major software houses, even by Apple. The Finder, for instance, remained a Carbon application for many years, finally porting to Cocoa with the release of Mac OS 10.6 in 2009.
The transition to 64-bit Macintosh applications beginning with Mac OS X v10.5, released October 26, 2007, has brought the first major limitations to Carbon. Apple does not provide compatibility between the Macintosh graphical user interface and the C programming language in the 64-bit environment, instead requiring the use of the Objective-C dialect with the Cocoa API. Many commentaries took this to be the first sign of Carbon's eventual disappearance, a position that was re-enforced when Apple stated no new major additions would be added to the Carbon system.
Transition to Cocoa
Despite the purported advantages of Cocoa, the need to rewrite large amounts of legacy code has slowed the transition of Carbon-based applications, famously with Adobe Photoshop, which was eventually updated to Cocoa in April 2010. This also extended to Apple's own flagship software packages, as iTunes and Final Cut Pro (as well as the features in the QuickTime engine which powers it) remained written in Carbon for many years. Both iTunes and Final Cut Pro X have since been released in Cocoa versions.
In 2012, with the release of OS X 10.8 Mountain Lion, most Carbon APIs were considered deprecated. The APIs are still accessible to developers and all Carbon applications will run, but the APIs will no longer be updated. Eventually bit rot will cause Carbon applications to no longer function.
Carbon descends from the Toolbox, and as such, is composed of "Managers". Each Manager is a functionally related API, defining sets of data structures and functions to manipulate them. Managers are often interdependent or layered. Carbon consists of a broad set of functions for managing files, memory, data, the user interface, and other system services. It is implemented as any other API: in Mac OS X, it is spread over several frameworks (each a structure built around a shared library), principally
CoreServices.framework, and in older Mac OS, it resides in a single shared library named
As an umbrella term encompassing all C-language API procedures accessing Mac-specific functionality, Carbon is not designed as a discrete system. Rather, it opens nearly all the functionality of Mac OS X to developers who do not know the Objective-C language required for the broadly equivalent Cocoa API.
Carbon is compatible with all of the several executable formats available for PowerPC Mac OS. Binary compatibility between Mac OS X and previous versions requires use of a Preferred Executable Format file, which Apple never supported in their Xcode IDE.
Newer parts of Carbon tend to be much more object-oriented in their conception, most of them based on Core Foundation. Some Managers, such as the HIView Manager (a superset of the Control Manager), are implemented in C++, but Carbon remains a C API.
Some examples of Carbon Managers:
- File Manager — manages access to the file system, opening closing, reading and writing files.
- Resource Manager — manages access to resources, which are predefined chunks of data a program may require. Calls File Manager to read and write resources from disk files. Examples of resources include icons, sounds, images, templates for widgets, etc.
- Font Manager — manages fonts. Deprecated (as part of QuickDraw) since Mac OS X v10.4, in favor of Apple Type Services (ATS).
- QuickDraw — 2D graphics primitives. Deprecated since Mac OS X v10.4, in favor of Quartz 2D.
- Carbon Event Manager — converts user and system activity into events that code can recognise and respond to.
- HIObject — a completely new object-oriented API which brings to Carbon an OO model for building GUIs. This is available in Mac OS X v10.2 or later, and gives Carbon programmers some of the tools that Cocoa developers have long been familiar with. Starting with Mac OS X v10.2, HIObject is the base class for all GUI elements in Carbon. HIView is supported by Interface Builder, part of Apple's developer tools. Traditionally GUI architectures of this sort have been left to third-party application frameworks to provide. Starting with Mac OS X v10.4, HIObjects are NSObjects and inherit the ability to be serialized into data streams for transport or saving to disk.
- HITheme — uses QuickDraw and Quartz to render graphical user interface (GUI) elements to the screen. HITheme was introduced in Mac OS X v10.3, and Appearance Manager is a compatibility layer on top of HITheme since that version.
- HIView Manager — manages creation, drawing, hit-testing, and manipulation of controls. Since Mac OS X v10.2, all controls are HIViews. In Mac OS X v10.4, the Control Manager was renamed HIView Manager.
- Window Manager — manages creation, positioning, updating, and manipulation of windows. Since Mac OS X v10.2, windows have a root HIView.
- Menu Manager — manages creation, selection, and manipulation of menus. Since Mac OS X v10.2, menus are HIObjects. Since Mac OS X v10.3, menu content may be drawn using HIViews, and all standard menus use HIViews to draw.
The Mac Toolbox's Event Manager originally used a polling model for application design. The application's main event loop asks the Event Manager for an event using GetNextEvent. If there is an event in the queue, the Event Manager passes it back to the application, where it is handled, otherwise it returns immediately. This behavior is called "busy-waiting", running the event loop unnecessarily. Busy-waiting reduces the amount of CPU time available for other applications and decreases battery power on laptops. The classic Event Manager dates from the original Mac OS in 1984, when whatever application was running was guaranteed to be the only application running, and where power management was not a concern.
With the advent of MultiFinder and the ability to run more than one application simultaneously came a new Event Manager call, WaitNextEvent, which allows an application to specify a sleep interval. One easy trick for legacy code to adopt a more efficient model without major changes to its source code is simply to set the sleep parameter passed to WaitNextEvent to a very large value—on OS X, this puts the thread to sleep whenever there is nothing to do, and only returns an event when there is one to process. In this way, the polling model is quickly inverted to become equivalent to the callback model, with the application performing its own event dispatching in the original manner. There are loopholes, though. For one, the legacy toolbox call ModalDialog, for example, calls the older GetNextEvent function internally, resulting in polling in a tight loop without blocking.
Carbon introduces a replacement system, called the Carbon Event Manager. (The original Event Manager still exists for compatibility with legacy applications). Carbon Event Manager provides the event loop for the developer (based on Core Foundation's
CFRunLoop in the current implementation); the developer sets up event handlers and enters the event loop in the main function, and waits for Carbon Event Manager to dispatch events to the application.
In the classic Mac OS, there was no operating system support for application level timers (the lower level Time Manager was available, but executed timer callbacks at interrupt time, during which you could not safely make calls to most Toolbox routines). Timers were usually left to application developers to implement, and this was usually done by counting elapsed time during the idle event - that is, an event that was returned by WaitNextEvent when any other event wasn't available. In order for such timers to have reasonable resolution, developers could not afford WaitNextEvent to delay too long, and so low "sleep" parameters were usually set. This results in highly inefficient scheduling behavior, since the thread will not sleep for very long, instead repeatedly waking to return these idle events. Apple added timer support to Carbon to address this problem—the system can schedule timers with great efficiency.
- Apple Inc. "Introduction to 64-Bit Guide for Carbon Developers".
- Apple Inc. "Choosing a Development Path for Your Carbon User Interface".
- John Nack. "Photoshop, Lightroom, and Adobe's 64-bit roadmap".
- Chris Foresman. "iTunes 10 hands-on: snappier performance, questionable UI choices".
- John Siracusa. "Mac OS X 10.6 Snow Leopard: the Ars Technica review".
- Apple Inc. "Apple Carbon homepage".[dead link]
- Apple Developer Connection: Carbon
- K.J. Bricknell: MACINTOSH C CARBON - A Hobbyist's Guide to Programming the Macintosh in C