Porting to the BeOS |
GEOFF WOODCOCK: My name's Geoff Woodcock and this is a session on porting. It's going to focus on porting from the MacOS to the BeOS and it's going to be pretty introductory and it's going to focus on the Mac toolbox because figured that was a way I could hit most of you in what you're doing, you know, if I focused on a different OS or on something like PowerPlant, not everybody might know or be using that. So anyway, I hope that works out. And all we're going to do is talk a little bit about managers and how they map the kits and then we're just going to look at sample code for an app test that was written originally on the MacOS and which I ported to the BeOS.
So this is it on the MacOS. It's just a window. When you start the app it brings up a window, does all the title, play, sound. Hear that? Okay. And runs the -- whoops. It's supposed to run the -- why is that coming out? Hmmm. It does the standard file stuff. So let's see here.
There's a very similar app on the BeOS. The other thing it did, which I don't know if you saw, is it put up some text, so there's some text here. Okay. So let's go on to the slides. We're having all kinds of problems. Sorry about that. Okay. This is not going to work. Can you adjust that? Thanks.
So anyway, quick general comparison of the managers and kits and then a detailed comparison of the code written to make this app run.
A SPEAKER: It's in the computer. It's cutting off the top.
GEOFF WOODCOCK: That's better.
So anyway, on the managers on the BeOS you've got kit. On the Mac you're going to probably write C or C++ with a bunch of Pascal stuff from the toolbox. On the Mac list you've got an event loop, normally you've only got one event loop.
On the BeOS you've got messages and implementation of the MessageReceived method in multiple threads and MacOS, most applications are single threaded. BeOS you will be hard-pressed to write an application with one thread.
And the MacOS when you create user interfaces you're just kind of dropping components in the window and you sort of have to keep track of them and draw them and figure out where the mouse clicks are and all that kind of stuff. BeOS has a view containment hierarchy that makes a lot of that stuff a lot simpler. So here's a -- I'm sure a lot of people could argue with some of this stuff, but a quick breakdown of managers on the Mac and comparable kit on the BeOS.
Anything that is user interface-related, text, controls, you know, graphics drawing, is all in the interface kit. We've got Berkeley Sockets, Mac's got Open Transport, Deep Memory Management, well, of course you have to do a lot of that, you all know that, but we don't have a memory manager. And we've got a media kit for multimedia stuff. We've got OpenGL® and 3D kit and on and on and on, so...
These are the things we're going to cover in the app. Window interface controls, text, pictures, sound, menus, dialogs, drag and drop, file typing, we'll talk about resources a little bit. Here's initialization on the Mac. Everybody's done this I'm sure. And on the BeOS the only initialization you really have to do is create an application object and so in this case we've subclassed BApplication to create simple app and all the initialization is hidden within BApplication, so nice and clean.
Okay. Here's a menu creation on the MacOS. Create a menuBarHandle, get the menu set of the resources and add them to the menuBar, then draw the menuBar. Now, this is actually where the MacOS makes things a little easier because they have such a mature resource setup, which the BeOS doesn't have yet.
So when you look at the BeOS code, I'm actually instantiating out here so I'm not pulling them out of resource files. There's no reason you couldn't do that, but you don't have a resident type of tool that does that stuff in a standard type of way with what you get from the BeOS out of the box. So creating a menuBar object and then creating a menu and then creating menu items, adding the items to the menu and now this is the first place where we can really talk about messaging, because when you select a menu in the BeOS, a BMessage is created and sent to some receiver and in the case of menu items, you can use this settarget call if you want to change the default target. Default target is the view that you put in the window and here's adding separator item which again, you're doing with resources on the Mac.
Here's a little more of this. So for example, quit. You know, quit we want to send to the application object so we retarget to the global be_app object. There's only one BApplication object in a running application so be_app is it.
Okay. Then the final thing we do -- I should have pointed out all of this code is happening in our windows subclass. So the last thing you do is add the menuBar to the window. This is another big distinction between the Mac and the Be. The windows on the BeOS or the menus on the BeOS are part of the window. They're not on the application or on the desktop at the top.
And also in DR9, I don't know if you've realized this yet, but there is no separate application menu anymore, so a lot of you are probably going to be moving that menu to the left-hand side of each of your windows or something similar. People have discussed other things like making a standard or a pop-up menu for the application, but who knows.
Okay. And as far as window creation, you guys all know this: GetNewWindow, et cetera, et cetera, SetUpResume. On the MacOS, again, just like with the application, you get most of this for free, when you instantiate -- when you subclass Bwindow. You can pass in parameters, say, whether or not you want it to be resizable or titled or is it a floating window, things like that. That's all in this Window.H, but you don't have to do a lot of that stuff, you get it all for free.
Okay. So once you've created the window you want to put some stuff on it. Here's on the Mac, again, resources make this a little easier because just pull the picture out of the resource and draw it in the window. And on the BeOS you want to DrawBitMap, subclass the view -- actually, in general any time you want to make something do a special drawing, subclass the view and implement the draw method. So in this case I've made a view called BitMapView and I'm going to put an instance of it in the window and when it's time to draw, the draw will be called and the update area will be passed to it and you just call the views DrawBitMap method and pass it to BitMap and that's built.
Okay. Control creation on the map, again from resources, new control. On the BeOS, here again, this is where messaging makes this real nice, because it works just like menus as far as the code you end up having to write. You just make a Be button object and you give it a BMessage and basically when you press the button the window will get that message, so... and you just add that button to the window.
Okay. Here's text drawing on the map, TextEdit stuff. And text drawing on the Be, there's a class called string view, that's just for static text. There's a text control, there's a text view too for other text and that does all the font stuff and sizing stuff, all that good stuff. Again, just instantiate the control, put it in the window, you're done. Here's where it gets a little weird. On the Mac you've got WaitNextEvent, you're waiting for events in a single event use and in the case of menus you've got to handle the keys separately, you know, because the keypress might be a menu with a modifier key. And if it's a mouse click you've got to go and figure out where was the mouse clicked, was it in the menu bar, is there a control underneath the mouse. You've also got to do special stuff for drag grow content.
On the BeOS this stuff all gets routed to MessageReceived of the window and all that stuff like grow and resize. There are things you can override, like frame resize, if you want to handle them, but in the case of this basic application I didn't have to. Like redrawing of controls, redrawing of the depict, you know, the grow icon, you don't have to worry about that stuff, but all the other messaging just ends up right here in MessageReceived.
You can see the menu message here. This is -- in the file panel library you've got calls for making open panels and save panels and again, it's all messaging. The panel comes up, if you want you can retarget it. If you don't retarget it the messages in the case of open end up going to RefsReceived of the application object and that's exactly where you also handle drag and drop. So you only write one piece of code to handle the drag and drop and the file panel stuff.
Updating the window, you've got to go in and get port, set port, figure out what you've got to draw in a picture and redraw it. You've got to call update control; you've got to update the text of that stuff; you've got to draw the grow icon. And like I said before, the only thing you've really got to do in BeOS is if you have things that are doing special drawing then you subclass BView and you implement draw, then you do your drawing and doesn't clear up the rest of your code.
Drag, drop, AppleEvents on the MacOS and on the BeOS, this is that RectsReceived I mentioned and you'll see this in a lot of the objects where a certain real common message is don't go to MessageReceived, they end getting routed directly to hook functions. This is an example of one of them, so if they drag and drop a file or if they select a file to open in an open panel, RectsReceived gets called. You can pull out the entry ref from the message. In this case I just spawn a window, pass the ref.
Here's standard file on the Mac, and this we've already talked about the file panel on the BeOS. Same problem last time, it just stops.
Okay. Creating AboutBox on the Mac and same thing on the Be, this is another hook function. If you create a menu item or anything else that sends a BeAbout requested to the application object, then this hook function gets called.
Okay. So here's playing a sound on Mac, pulling out a resource and calling SoundPlay. On the BeOS it's a little tricky to do it with a resource so I'm just doing it from a file, and there's a little bit of extra code here, because I figured where am I in the directory structure so I could figure out where is the sound file that I can play in the same directory as the application. So that's what all this stuff is up here.
Getting application info, getting a Be entry or a Be directory is the directory that this app is in and then I'm finding the sound file. You can just call it PlaySound. There's something you can wrap around PlaySound called WaitForSound, if you want this thread to stop until the sound is done. So on the MacOS you've got file type and creator and on the BeOS you've got MIME types. And a MIME type, for those of you who aren't familiar with it, it's really just a string with a bunch of hierarchal information separated by slashes and the two most common things you'll see on BApplications are this Be executable which means this is a file that can be executed on the BeOS, and this is the application signature and these last four letters you sort of think of like the type on a MacOS.
And there's a preference panel that you can bring up to associate applications with the correct --
A SPEAKER: That's completely new in DR9?
GEOFF WOODCOCK: Yeah.
A SPEAKER: So what happens to, like, file types from the creator?
GEOFF WOODCOCK: I'm not sure how they get brought across or if they do. Does anybody in the room know?
The question was file types of creators in DR8, do those somehow get mapped as something new in DR9? I'm not sure they really could in a lot of cases. I guess for the type you could. Hmmm, not sure. Sorry.
So anyway, summary: Kits hide a lot of complexity you have to deal with in the Mac toolboxes. In most cases you just subclass implement a few of the methods and you get what you want. All the communication with all of the controls and all the other user interface stuff is all message based and all ends up in MessageReceived normally of a window subclass or of an application subclass.
And Think Threads. You didn't have threads in the MacOS and you do have them here and you're going to use them all over the place, so it's definitely something to keep in the front of your mind. And I know resources are a big thing on the Mac, everybody uses them, they're good for localization, all kinds of other stuff. It's kind of like the Wild West on the BeOS right now. Resources are just -- I want to write a resource with this name and this type and this ID of this size, you don't get anything -- there really isn't a standard for how they're written or the names or anything, so that may be a little troublesome.
So anyway, I brought a couple of the more experienced engineers in the room. Anybody has any specific questions about porting, they can try to answer them.
A SPEAKER: Do you consider the interface kits as a layer on top of the BeOS or do you consider them as an integral part of the BeOS?
GEOFF WOODCOCK: I'd say it's an integral part of the BeOS. Now, I think Benoit is in the room, isn't he? He's the app head guy. Is he still here? He's left the room.
Yes?
A SPEAKER: How do you recommend handling, like, resources under the DR9? Most MacApps will have a ton of stuff in the resource file.
GEOFF WOODCOCK: There's a couple tricky things about that. That was actually one other thing I forgot to mention about resources is that if it's an application, you can put resources in it. If it's not an application, if it's not a pet container then you can't mix data and resources in the same file. It's either a data file or it's a resource file, but it's not both. Now, some people have suggested that you can maybe make this easier by using attributes instead of resources, but there you have a problem because attributes aren't going to be copied across if you go to a file system that doesn't support entries like HSF. So you sort of are kind of stuck putting things in resources that are vital, and as far as specifically how to handle them, like I said, there's no -- there's no standard for that. Just come up with a consistent way of putting data in resources and stick with it for your apps, until -- I'm sure a lot of the tools that do interface building and that kind of stuff are probably going to eventually generate standards.
A SPEAKER: Are the resources actually part of the file itself?
GEOFF WOODCOCK: The resources are.
Anything else? Okay. I guess we're done.
Home | About Be | Be Products | BeWare | Purchase | Events | Developers | Be User Groups | Support