Porting Graphics To BeOS
Volume Number: 14
Issue Number: 9
Column Tag: BeTech
Porting Mac Graphics To The BeOS
Written by Dan Parks Sydow
Edited by Bob Boonstra
Translating your Mac application's drawing routines to BeOS
code
Overview of Graphics and the BeOS
For the most part, the scope of this article is limited to explaining how to convert your
Mac application's graphics-related Toolbox calls to code that integrates into a Be
application. To get a more general overview of Mac OS to BeOS porting issues, refer to
the MacTech Magazine article "Porting Code to the BeOS by Michael Rutman, Vol. 13,
No. 1 (January 1997). If you don't know the fundamentals of BeOS programming,
you'll need to learn how to make use of what Be refers to as the software kits. How to
work with the software kits is a topic well beyond the scope of a magazine article -
you'll want to refer to one or more of the BeOS programming resources listed at the
end of this article. With that said, I still feel compelled to devote just a few paragraphs
to summarizing how to use the kits to program the BeOS! After that I move to the real
matter at hand - how to go about translating some commonly implemented Mac OS
graphics code to BeOS graphics code.
Structure of the BeOS
Be applications run on BeOS-compatible computers, which now include
PowerPC-based Macs and most Intel Pentium-based PCs. Between the hardware and a
Be application lies the BeOS operating system software that consists of three layers: a
microkernel layer that communicates with the computer's hardware, a server layer
consisting of a number of servers that each handle the low-level work of common tasks
(such as printing), and a software kit layer that holds several software kits -
dynamically linked libraries (DLLs) that act as a programmer's interface to the
servers and microkernel.
Kits and classes
Collectively, the software kits make up the BeOS application programming interface
(API). Each kit consists of a number of object-oriented classes that a programmer
makes use of when writing a BeOS program. Together, all the classes in the kits form
an application framework. While the code that constitutes your Be application will
most likely include objects derived from classes defined in many of the kits, it will
always include objects derived from classes in two kits: the Application Kit and the
Interface Kit.
A Be application defines an object of a class you derive from the BApplication class.
This application object represents the application itself. The BApplication class,
obviously enough, is defined in the Application Kit. Other classes in this kit establish a
messaging system that makes applications aware of events (such as a click of a mouse
button by the user). This kit also give applications the power to communicate with one
another.
The Interface Kit is by far the largest of the software kits. The classes of this kit exist
to supply applications with a graphical user interface that fully supports
user-interaction. The definition of windows and the elements that are contained in
windows (such as scroll bars, buttons, lists, and text) are all handled by classes in
this kit. Any program that opens a window uses the Interface Kit. Most of the classes
mentioned in this article (such as the BRect class for creating rectangles, the BRegion
class for creating regions, and the BWindow class for creating windows) are a part of
the Interface Kit. In the area of graphics, one of the most important Interface Kit
classes is the BView class. Instances of this class - and of the many classes derived
from it - are all types of views.
Views
In Macintosh programming, drawing takes place within a port in a window. Somewhat
analogous to that on the Be side is the view. In a Be program, drawing doesn't take place
directly within a window (a BWindow object). Instead, it takes place within a view (a
BView object, or an object derived from the BView class). Unlike a Mac port, however,
Be views can be nested. Views aren't readily discernible to the end-user - they exist
as a programmer's means of establishing different drawing areas. Typically a window
will hold an all-encompassing view, and then one or more views within that main
view. Each view is a self-contained drawing environment, so each view can display
text and graphics that appear different from that displayed in other views within the
same window. That is, each view can display text in its own font, draw lines in a
thickness different from lines drawn in other views, and so forth. This technique of
allowing each BeOS view to keep track of its own drawing environment deviates from
the Mac OS, where drawing parameters are stored in QuickDraw globals.
Because all drawing must take place in a view, everything you see within a window
appears in a view. A scroll bar, button, picture, or section of text each lies within its
own view. The Be window titled "Hello" in Figure 1, for example, holds several views.
Each radio button resides in its own view, as does the one pushbutton. The framed text
also exists in its own view. There may also be one large view that holds all these
individual views (you're looking at the window as an end-user, so you can't determine
if that's true or not!).
Figure 1. A Be window holds a number of views.
A view is capable of responding to a message that's sent from the system to a BWindow
object and then on to the view. This messaging system is the principle on which menus
and controls work. It is also a topic worthy of much examination, and is beyond the
scope of this article. There is one messaging topic worthy of note here, however -
window graphics updating, or refreshing.
In the Mac world, a program becomes aware of the need to update a window when the
program's event loop call to WaitNextEvent() obtains an event of type updateEvt from
the system event queue. On the Be side, when a view needs updating a message is
automatically issued by the system. This message is sent to the affected window, and
from there it is directed to the proper view. If more than one of a window's views
needs updating, more than one message will be sent to the window (one per affected
view). The BView class (from which all views are derived) includes a Draw()
member function that automatically gets invoked when a view object receives such a
message. This Draw() function performs the drawing appropriate for that one view.
Drawing the contents of a BView is often application-specific. In such an instance it's
up to your application to override the Draw() function of that view, and to supply the
view-drawing code within the new version of the Draw() function. Consider the
window shown in Figure 1. If the entire window is obscured, then brought back into
view, a number of Draw() functions will be automatically invoked. A radio button is
an object of the BRadioButton class, which is derived from the BControl class, which
itself is derived from the BView class - so each radio button has a Draw() function.
Similarly, the pushbutton is a view - the BButton class is also derived from the
BControl class. Each of these three controls have a Draw() function that gets invoked.
Fortunately for you, the programmer, these Draw() functions know how to draw the
appropriate control without any help from your code. The framed text is of more
interest to you. The rectangle and text reside in an object of an application-defined
class derived from the generic BView class. Here the BView version of Draw() needs to
be overridden and implemented such that it draws the desired contents. Most of the