Issue 3-7, February 18, 1998

Be Engineering Insights: Repositioning Yourself!

By Erich Ringewald

This week, two separate articles caught my eye. They were about companies repositioning technologies they have already spent a lot of time and effort on over the last few years. First was Java, the all-singing, all-dancing programming language that would break down the Babelian barriers amongst all the varied client platforms in the world. With total portability and write once run everywhere going for it, all (or all but the most performance critical) applications would be written in Java, once.

But now, with Netscape and others announcing their abandonment of client-side Java development entirely, Java is being repositioned as a "server-side technology." While the value of platform neutral, easily distributable, interpreted binaries for server applications is eluding me at present, I watch with interest for further news.

Second was the mumbled repositioning by Apple of Rhapsody as a "server OS." I'll admit, we've heard with decreasing frequency about the future of Rhapsody since the keynote session at Macworld Expo in January 1997 where Gil Amelio introduced Rhapsody as the future OS for Apple, and Steve Jobs and Steve Wozniak as "founder-advisors" returned to provide occasional direction to the company.

A lot *has* happened since then (anybody heard more from Woz?), but even I was surprised to see Apple's announcement of the future of Rhapsody as a server OS, intended to complement and not to replace the aging Mac OS. When Russell Brady, Apple's spokesman delivering this information was questioned about the apparent change in plans, he responded, "We've never positioned Rhapsody as anything but a server OS; anything else was made up by the press." Hello?

Anyway, these repositionings got me to thinking about how we're doing over the past few years as far as keeping to our original business objectives. And I'm pleased to say that I think we've repositioned very little. Our goal of providing a next generation operating system for use with digital media (e.g. audio, video) has gone unchanged. Which is not to say we haven't course corrected a little.

We did start in the hardware business as well as the software business. Because two processors are better than one, especially when dealing with streaming media, we built our OS to efficiently use more than one CPU. At that time (the era of Mac OS and pre-NT), however, no one was building inexpensive multiprocessor machines, so we built the BeBox, a dual PowerPC desktop machine. A little while later, others began building multiprocessor machines, so wasting as little time and money as possible, we ported the BeOS to their platforms and got out of the hardware business.

When we realized that a high performance, 64-bit file system is critical to any OS wanting to call itself a media OS, we scrapped our original file system and replaced it with one designed for digital video. And when it seemed that Steve Jobs was hell bent on widening the gap between the Intel installed base and the PowerPC installed base, we ported the OS again.

We've come a long way by being responsive to the changing market conditions around us, all the while holding true to our original goals. Next month's Be Developer Conference gives us another opportunity to listen to what is probably the most savvy segment of our customers and colleagues, the developers. I'm looking forward to seeing you there and collecting suggestions for next year's course corrections.

Just don't ask us to become a server OS.


Be Engineering Insights: BeWare 101

By Melanie Walker

I have a confession. I live for BeWare. The best part of my day is when I sit down at my BeBox with a cup of tea to ftp the incoming apps to my machine. My job is to test them. I unzip them, install them, give them a go. If they pass the "pretty indestructible" test, I add them to the BeWare area of the Be web site http://www.be.com/beware/index.html.

For those of you who are new to the BeOS, I thought I'd explain briefly how BeWare works. And some of you "old hands" might be interested in hearing about recent changes in BeWare. I'll also give you pointers on how to find the BeWare you're looking for, and where to go for tips and recommendations.

BeWare Is...

BeWare is an area on the Be web site where you'll find freeware, shareware, and commercial applications and utilities to download. There's a wide variety of BeWare apps, that run the gamut from games and audio players to development languages and utilities. This makes BeWare a great resource for both users and developers. Developers have an added benefit —many BeWare developers include their source code with their applications.

Within BeWare, you can peruse available applications alphabetically, by category ("Audio," "Video," "Utilities," etc.), or by selecting "What's New" for a list of recent arrivals. For each application you'll find a description of the app, file size information, alternate download sites, links to related web pages, and sometimes screen shots.

To download an item from BeWare, you can either click on the download link, or once you know the file name, you can ftp it directly from ftp://ftp.be.com. Once you've downloaded the app successfully and expanded it, you're set to go.

Uploading BeWare

You must be a registered Be Developer to upload BeWare. (For more information on becoming a registered developer, see http://www.be.com/developers/.) Once you've registered, the upload process is simple and direct. You'll find the complete guidelines for uploading BeWare at http://www.be.com/developers/ftp/, but here's a summary:

Fill out the "Add BeWare" form in the Registered Developer Area http://www.be.com/developers/, upload your app, and send e-mail to ftparchive@be.com with the name of your app in the subject field. Within the day, your app should be up on BeWare.

Just one caveat: Since the BeWare section is generated by scripts that manipulate the information in the BeWare record you create, it is very important to fill out your BeWare record accurately. For example, if you list your application as "foobar.zip", when you upload your app, make sure it's called "foobar.zip", and not "foo_bar.zip", "Foobar.zip," or some other variant.

Recent Changes in the BeWare Area

If you haven't visited BeWare for a while, you'll discover that it's been reorganized. Applications and utilities are now classified within each category according to their function. For example, within the Audio category, sub-categories include "Editing," "Playback," and "Recording." You'll also notice that when you click on an application's name, you go to a page dedicated to that BeWare application. Giving each app its own page cuts down on loading time and gives the author more space to include a description or links to screen shots and other related URLs. All in the name of better service!

Looking for New BeWare?

If you're eager to try new BeWare, but don't know where to begin, there are several places to look for recommendations. Be hosts the BeWare Gem of the Day on the front page of the web site. Other sources for reviews and recommendations include BeOS Central, Be Leading Edge, and Be Dope.


Developers' Workshop: BeOS Programming Basics: Part 1

By Eric Shepherd

[Webmaster's Note: This article has been corrected since its original publication. Eric's next article will discuss the BeOS's coordinate system in more detail, along with how to set up and respond to user interaction in a menu bar.]

As we draw closer to the first release of BeOS for Intel, a whole new generation of BeOS programmers is preparing to enter unknown territory. In order to help introduce them to writing BeOS applications (and to help PowerPC programmers get started with the BeOS), my next few articles for the Be Newsletter will comprise a brief introductory course on BeOS programming.

This week, we're going to build a very basic application. Can you say "Hello, world?" This article and the sample application we'll create will show you how to do that.

Yes, that's right, we'll be writing "Hello World" as a BeOS application. We'll create application, window, and view objects, and draw text into a view. This article won't tell you everything you'll ever need to know, but it should at least get you up and running with your first application so you can start experimenting. In fact, you should keep a copy of the Be Developer's Guide or the online Be Book handy as you read this article.

For this project, you'll need the following header files included in your source code:

#include <Application.h>
#include <Window.h>
#include <View.h>

Let's begin at the beginning: The BApplication class. This class defines a BeOS application. In essence, the BApplication class represents the link between your application and the Application Server. The Application Server handles messaging, imaging, and other good stuff that most applications need to do. So before you can draw on the screen or accept or transmit messages, you have to create a BApplication object.

Typically, you'll do this by creating your own class, derived from BApplication, so you can augment or override certain methods to customize the behavior of your application. In our Hello World program, we'll be creating a class called HelloApp to serve this purpose. An application's main() function's primary duty is to create the BApplication (or an object of a class derived from BApplication) and to invoke it. Before we create HelloApp, let's look at a typical main() function (in fact, this is the main() our Hello World program will use):

void main(void) {
  HelloApp *theApp;    // Pointer to our application object
  theApp = new HelloApp;

  theApp->Run();

  delete theApp;
}

All main() does here is create a new HelloApp object, which is derived from BApplication, as we'll see in a few moments. Once that's done, the application's Run() method is invoked. The Run() method is the application's event loop. It won't return until the application is terminated.

Once the Run() method returns, we delete the application object, since our program is about to terminate, so we don't need the object anymore.

It's useful to remember that the global variable be_app always points to your application's BApplication object. That means you don't have to keep a pointer to your application object around if you don't want to, although if you call any custom methods added to the object, you'll need to cast be_app to your class.

Now let's look at the HelloApp class:

class HelloApp : public BApplication {
  public:
    HelloApp();

  private:
    HelloWindow    *theWindow;
};

As mentioned earlier, HelloApp is derived from BApplication. We only need the constructor to get done what we need to do, so that's the only public method we define. A single private variable, theWindow, is used to store a pointer to our application's window.

Let's check out the HelloApp constructor:

HelloApp::HelloApp()
      : BApplication("application/x-vnd.Be-HelloWorld")
{
  BRect windowRect;

  windowRect.Set(50,50,200,200);
  theWindow = new HelloWindow(windowRect);
}

The HelloApp constructor defers to the BApplication constructor, passing the string "application/x-vnd.Be-HelloWorld". This odd-looking string is the application's signature. It specifies that the application is an application, and that the vendor is Be, Incorporated. The application's name is "HelloWorld". This is the standard way we identify applications; this string can be used by other programs to locate your application and pass messages to it.

Once the object has been constructed, we create a BRect. BRect is a rectangle object (described in the Interface Kit chapter of the Be Developer's Guide). It's used to define a rectangular area on the screen, given the top, left, right, and bottom edges of the rectangle, and it has several methods for setting and retrieving the position and size of the rectangle.

One of these methods is Set(), which we use to set the rectangle to occupy the area from (50,50) to (200,200) in space. This establishes a rectangle 151 pixels wide and 151 pixels tall. The arguments to Set() are in the order: left, top, right, bottom.

That BRect object is then passed to the HelloWindow constructor when we create our window object; this rectangle is used to position and size the window on the screen when it is created. Note that we save the window pointer in the HelloApp's theWindow field. That must mean it's time to look over the HelloWindow class:

class HelloWindow : public BWindow {
  public:
    HelloWindow(BRect frame);
    virtual bool QuitRequested();
};

The HelloWindow class has a constructor, which accepts a BRect object as an argument (as discussed previously), and a QuitRequested() method. Note that HelloWindow is derived from BWindow, which is the class from which all windows are derived on the BeOS.

HelloWindow::HelloWindow(BRect frame)
      : BWindow(frame, "Hello World", B_TITLED_WINDOW,
        B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
{
  AddChild(new HelloView(Bounds()));
  Show();
}

The constructor, shown above, defers to the BWindow constructor to set up the window. The frame rectangle specified as the argument to the constructor is passed through, and the window's name is specified by the string "Hello World". B_TITLED_WINDOW is a flag indicating the type of window to create: A standard window with a tab at the top where the title and close box should draw.

B_NOT_RESIZABLE and B_NOT_ZOOMABLE are flags that indicate that the window can't be zoomed (it won't have a zoom box) or resized.

Once the window is constructed, we need to add a view to the window. Views are containers for other views. This is an interesting concept, and it's an important one to understand. Windows are containers for views. You typically can't draw directly into a window. You have to create a view and attach it to the window first.

A window can have as many or as few views attached to it as you want, and each view can have subviews. We'll develop this further in my next article. For now, our application's window has a single view.

In our case, we want the view to be the exact size of the window, and fill the window completely. So when we instantiate our HelloView (which we'll look at shortly), we pass the BRect returned by the Bounds() method. Bounds() is a method of the BWindow class that returns the "bounds rectangle" of the window.

The bounds rectangle is a rectangle that indicates the area occupied by a window, but in coordinates local to the window. This is another important concept to grasp.

If your computer has a 640 x 480 screen, the top-left corner of the screen has the coordinates (0,0) and the bottom-right corner of the screen is at (639,479). These are called "screen coordinates." When you create a window, you specify the location of the window on the screen using screen coordinates.

Once the window has been created, anything you do inside that window is done in "local coordinates." Just as screen coordinates have the top-left corner of the screen at (0,0), local coordinates have the top-left corner of the window at (0,0).

The Bounds() method in the BWindow class returns the window's rectangle in local coordinates, so in our program's case, this rectangle will be (0,0)-(150,150), which is exactly what we want.

We pass this BRect to the HelloView constructor so the view will fill the entire window. We'll study the HelloView class next.

The HelloView pointer that's returned by new is then passed to BWindow's AddChild() method. As we already learned, windows are containers for views. The views that a window contains are called "children." The AddChild() method, then, adds a view to a window, thereby making that view a child of the window. Once a view is added to a window, any drawing done inside the view is visible in the window (assuming both the view and the window are visible, but we'll get into that another time).

Once the child view has been added to the window, we call Show(). This BWindow method makes the window visible—all BWindows are hidden until you call this method.

The other method we define for the HelloWindow class, QuitRequested(), is called whenever someone attempts to close our window. This happens if the user clicks the close box, for example. Here's the code:

bool HelloWindow::QuitRequested() {
  be_app->PostMessage(B_QUIT_REQUESTED);
  return true;
}

This is very simple. We simply post a B_QUIT_REQUESTED message to the application. By default, when a BApplication object receives this message, its Run() method simply exits (which then returns control to our main() function, which deletes the application object and exits).

Then we return true to indicate that we're granting permission to close the window. If QuitRequested() returns false, this indicates to the caller that for whatever reason, they shouldn't close the window. An obvious application of this would be to present an alert reminding the user they haven't saved their work yet, with the option for the user cancel whatever operation was about to close the window.

Finally, let's see the HelloView class, which is derived from BView. Views are the contexts in which all drawing is done.

class HelloView : public BView {
  public:
    HelloView(BRect frame);
    virtual void Draw(BRect updateRect);
};

Our HelloView class has a constructor, which accepts a BRect identifying the size and position the view should occupy within its parent, and a Draw() method, which is called by the Application Server to update the contents of the view.

The constructor looks like this:

HelloView::HelloView(BRect frame)
      : BView(frame, "HelloView", B_FOLLOW_ALL_SIDES,
              B_WILL_DRAW) {
}

As you can tell, we don't do anything in the constructor: We simply defer to the BView constructor, passing through the frame rectangle. The view's name is "HelloView". We specify the B_FOLLOW_ALL_SIDES flag for our resizing mode, which indicates that the view will always fill the complete window, even if the window is moved or resized, and the B_WILL_DRAW flag, which tells the Application Server that we're implementing a Draw() method that needs to be called for updates.

The Application Server calls Draw() whenever the window's contents need to be updated. This occurs if another window passes in front of ours, or when the window is initially shown. A BRect is passed to the method, indicating the area of the view that needs to be redrawn.

void HelloView::Draw(BRect updateRect) {
  MovePenTo(BPoint(20,75));      // Move pen
  DrawString("Hello, world!");
}

As you can see, in Hello World, we're ignoring the updateRect. We position the pen at coordinates (20,75) by creating a BPoint object (which represents a point on the screen) with those coordinates, then passing that point to the MovePenTo() method.

Once the pen has been positioned where we want it, we call DrawString() to draw the message "Hello, world!" into the view.

The sample code for my article will be on the Be FTP site in: ftp://ftp.be.com/pub/samples/intro/obsolete/helloworld_article.zip

In my next article, we'll investigate how you can use multiple views in a window, and begin looking at some basic user interface features. For now, poke through the Be Developer's Guide and the Application.h, Window.h, and View.h header files and do some exploring on your own.


BeDC, Be Dope, and Be Europe

By Jean-Louis Gassée

It's a laundry list, but let's start with Be Europe. Last week, in telling how we "paved the runway," i.e., raised the funds needed to launch the BeOS platform in the Intel space, I left a significant pothole in my story. I forgot to credit the Be Europe team for its contribution to this successful financing round. At the last tally, slightly less than 25% of the funds raised came from Europe, and we couldn't have done it without Jean Calmon and his team. I'm red-faced for my slip of the electric pencil.

Now Be Dope, which attentive readers of our Web site have noticed a reference to. Check it out, it is good entertainment and, occasionally, good information—http://www.geocities.com/SiliconValley/Bay/7587/.

However, I must take exception to an item that offers an ingenious explanation for my name. Among other twists, the story alleges that I was actually born in New Jersey. I guess I should be flattered, right?

Since my past is under scrutiny, I might as well confess. I wasn't born in New Jersey. As always though, there is a grain of truth: I once worked in New Jersey. During a lapse in sanity, because I believed what was printed in Fortune magazine before Stewart Alsop started contributing, and because I listened to a headhunter, I ended up working for a company based in the charming locale of Florham Park, NJ. That company was Exxon Office Systems.

Exxon misexecuted a belief in the right idea: Information as the oil of the 21st century. They were right—we know who the new Standard Oil is and who the new Rockefellers are—but their concept of a bit wasn't helpful in the computer business. So, all right, I did it, in New Jersey, but it was a genuine misunderstanding on both sides.

I'm indisputably French, as John Dvorak attested. Feeling my pain, he once introduced me as the mind of a Frenchman unfortunately trapped in the body of a Frenchman. Too true. In any case, read Be Dope, even more fun and relevant than Wired—and a lot easier on the eye.

As for my e-mail .sig, I'll have to drop the Dvorak quotation soon, it's getting old. I'm taking suggestions, you know where to find me. I could use "a French farmer abducted by aliens and raised in California by VCs," but that could be construed as slander by the venture community whose existence I cherish and whose name I only invoke with the greatest respect. Suggestions should be mindful of family values (this recommendation is meant particularly for a certain Be engineer whose T-shirts would cause HR to faint, if we had an HR department).

Lastly, the Be Developers' Conference.
http://www.be.com/developers/BeDC_schedule.html is the link to the program of the event. Contrary to our previous conferences, we're not holding it on a weekend, or preceding or following another industry event, and we are even charging $95 for it, a little less if you registered early.

Beyond the "free" T-shirt and the wonderful buffet lunches, we intend to make the content and delivery of the sessions worth your time and money. Much has evolved in the BeOS, beyond and because of the move to Intel-based hardware—new applications, more function in the OS, new tools and utilities. Please come and see what the Be engineers and your colleagues and competitors have done. I look forward to seeing you in four weeks.

Creative Commons License
Legal Notice
This work is licensed under a Creative Commons Attribution-Non commercial-No Derivative Works 3.0 License.