Table of Contents
Be Developer Classifieds are an opportunity for Be developers to tell each other about projects they're working on, are thinking about working on, or would like to work on. Here's your chance to request assistance on a project, or make your talents known to other projects. For more information, check out the Classified Ads section in the Registered Be Developer area. Job Opening: BeOS Engineer MGI is expanding its VideoWave II/BeOS group. We are seeking a senior developer in the Toronto area with the following qualifications: The successful candidate will have thorough experience writing code for a shipping commercial product. Contact: Reid Ellis <reide@mgisoft.com>, Program Manager for VideoWave II/BeOS
BeWare: Post Your R4 Software Be will begin posting R4 BeWare on December 14th, when we begin shipping R4. Developers will be able to submit R4 applications any time before that. BeWare will continue to post R3 applications for the PowerPC side since, theoretically, R3 apps for PPC should still run on R4 PPC.
Online Opportunity: BeOS Webring Has your BeOS website joined the BeOS Webring? Do it today! <http://www.planbe.com/beosring.html>
BEDEPOT.COM: New BeOS Software The BEDEPOT.COM section of the Be Developer Newsletter is for announcing the launch of commercial products on BeDepot.com. For more information about how to get your application listed, go to: <http://www.bedepot.com/vendor/comarketing.asp>
BE ENGINEERING INSIGHTS: R4 Drag-and-Drop By Jon Watte hplus@be.com
One of the nice things we added in R4 was a more flexible drag-and-drop protocol. Many developers have already peeked inside the BMessage being dragged when you grab a clipping >from ShowImage in an effort to try and figure out how it works. Because it actually involves more than one message, and we would like all programs on BeOS to do the right thing, I'm going to document the current protocol. First, the code! You can find it at: <ftp://ftp.be.com/pub/samples/interface_kit/dragme.zip> The application is simple. Start it, and it shows a window with a little image in it. You can click on the image to drag it around on your screen. If you drag it into a Tracker window, the Tracker creates a clipping file that the application saves the image into. If you drag the image to the Trash can, the application closes the window, the only way it knows how to remove the image. While not the best example of intuitive user interface design, it serves the purpose of illustrating drag-and-drop pretty well. The basic idea behind the new drag-and-drop protocol (DnD for short) is that the initiator of the drag doesn't have to produce the data in all formats it can possibly generate just to start dragging. Instead, it puts into the message a list of the formats it knows how to generate using the data being dragged. In this case, the DragView inside the DragMe window is the initiator. The recipient of the drag message, in this case the Tracker, can then look through the message for data formats it likes and send a reply to the message back to the initiator asking for one of these formats. Currently, the Tracker uses the first format added to the list of formats, unless you hold down the Control key. In that case it gives you a list of possible formats, or the option to cancel the drag altogether. Note that DragMe provides only one format of data, while ShowImage provides all formats available through the Translation Kit. Once the target (in this case the Tracker) chooses a format and sends a message back to the initiator, the initiator extracts all the data it needs from its internal data storage, and puts it either in a new message sent back to the target, or in a newly created file specified by the target. If the data is sent back to the target in a BMessage, this message is called the "data message," as opposed to the "dragged message" which was the first message, or the "reply" sent from the target to the initiator. That the target creates the file has to do with needing to preserve the drop point as the icon location in the Tracker window, which is better kept internal to the target than exposed in the API. The nitty-gritty of setting up the drag is found inside
The MIME string of data types you know how to provide should be added to the drag message in the attribute named "be:types". The magic type B FILE MIME TYPE means that we can create "a file" in addition to MIME data within a data message. It's OK to not add any other types at all, if all you know how to do is to save files. That makes direct data exchange between your application and other applications impossible without using temporary files, though, so you typically want to do both. If you use the B FILE MIME TYPE type, you should also add the MIME types of files you know how to create (which may be different from the types you know how to put in data messages) into the attribute "be:filetypes". DragView uses a copy of the content BBitmap as the drag indicator. That works fine because the bitmap is small. If the bitmap is larger, you should consider just dragging an outline BRect. You'll note that we use the new form of DragMessage found in R4, which allows you to specify a drawing mode for the dragging; we use B OP ALPHA because we prepare the dragging BBitmap specifically with alpha in mind. We also specify the window (rather than the view) as the reply destination for the dragged message. The actions we know about are B COPY TARGET and B TRASH TARGET. The former has the target send a request for data as reply; the latter does not require you to send the data anywhere, but instead indicates that the target wants you to remove the data being dragged (typically because the user dragged to the Trash). Possible actions are added to the "be:actions" attribute of the drag message. The "be:clip name" attribute is optional, and gives a hint to the destination for what the file name might be if it wants to create a clipping file. The target is free to ignore this hint and create a clipping file with any name it wants. In So what do you have to do to be at the receiving end of this
protocol? Not much, really. You receive B SIMPLE DATA
messages just like messages that have real data in them. If
the B SIMPLE DATA message doesn't have a data type you
understand in it, you can look for be:types to see if the
initiator can provide data of some type you understand. If
so, you send a reply back to the initiator (using
That's it. Now don't drag your feet; go and implement drag-and-drop in your application today!
BE ENGINEERING INSIGHTS: The Configuration Manager, Part I By Victor Tsou vyt@be.com
The configuration manager, first introduced in BeOS Release 3, has been rewritten for Release 4. It is primarily used for supporting ISA Plug-and-Play devices, although its services will also be enlisted to help integrate PCMCIA. The HOTD is <drivers/config manager.h>. Stare at it, then continue reading. The configuration manager provides five classes of services:
1. Initializing and uninitializing. The configuration manager is implemented as a module, a construct introduced in R4 that is accessible only from kernel space. A module exposes itself to drivers via a structure of function pointers in a bid to be a better ioctl than ioctl. Modules are loaded as needed and unloaded when no longer used. To initialize the configuration manager, simply load the module in the usual fashion: config manager for driver module info *module; if (get module(B CONFIG MANAGER FOR DRIVER MODULE NAME, (module info **)&module) < 0) return B ERROR; Conversely, to uninitialize:
Out of respect for reference counting, your driver should maintain a one-to-one correspondence between calls to get module and calls to put module. 2. Enumerating and reporting information about devices. Once the configuration manager has been loaded, your device driver will feel compelled to scan for devices it knows about. The function status t (*get next device info)( bus type bus, uint64 *cookie, struct device info *info, uint32 info size); iterates through the devices on the specified bus, placing info size bytes of information about each device in a device info structure. For example, the following loop runs through the ISA devices: /* cookie = 0 signals start of enumeration */ uint64 cookie = 0; struct device info info; For completeness, the device info declaration: struct device info { /* Size in bytes of bus-independent and * bus-dependent data for this device */ uint32 size; /* Offset, relative to the start of the structure, * to the bus-dependent data for the device */ uint32 bus dependent info offset; /* B ISA BUS or B PCI BUS */ bus type bus; /* Device code, a la PCI */ device type devtype; /* "Normally unique and persistent" id for the * device */ uint32 id[4]; /* Device-independent flags */ uint32 flags; /* If config status is B OK, the device is working * properly. Otherwise, the device is disabled and * should be ignored by device drivers */ status t config status; }; The configuration manager will report up to size bytes of information about the device. This includes both bus-independent data, as described by the device info structure, and bus-dependent data, which appear beginning at offset bus dependent info offset in the returned buffer. Since you can't know how large the device information buffer should be until after you've read it, the configuration manager provides an additional function to load the device info for a specific device: status t (*get device info for)( uint64 device, struct device info *info, uint32 len); The revised loop now looks like this (with error checks stripped out): while (module->get next device info(B ISA BUS, &cookie, &info, sizeof(device info)) == B OK) { struct device info *dinfo; struct isa info *iinfo; /* only worry about configured devices */ if (config status != B OK) continue; dinfo = malloc(info.size); module->get device info for( cookie, &dinfo, info.size); iinfo = (struct isa info *)((char *)dinfo + info.bus dependent info offset); ... free(dinfo); } ISA bus-dependent information is stored as isa info, defined in <drivers/isapnp.h>, and PCI-specific data are stored as pci info, defined in <drivers/PCI.h>. A driver typically peeks at the bus-dependent information to determine whether it can control a particular device. 3. Reporting the current configuration for devices. Once a driver has identified a known device, it must fetch the device's configuration. This is done via a pair of functions: status t (*get size of current configuration for)( uint64 device); status t (*get current configuration for)( uint64 device, struct device configuration *config, uint32 len); These functions are usually called this way: status t result; struct device configuration *config; result = module->get size of current configuration for(cookie); if (result < 0) return B ERROR; config = malloc(result); if (!config) return B ERROR; if (module->get current configuration for( cookie, config, result) < B OK) { free(config); return B ERROR; } ... free(config); The device configuration is an array of resource descriptors representing the resources (IRQs, DMAs, I/O ports, and memory) assigned to the device. Resource descriptors come in two flavors. IRQs and DMAs are described as masks, while I/O ports and memory are described as ranges. Masks are bitfields, with the nth bit representing the nth IRQ or DMA. Exactly one of the bits will be set in each mask. Ranges are described by two values, the minbase and the len, with the range running from minbase to minbase + len - 1, inclusive. 4. Interpreting configuration information. The following routines help drivers wade through device configurations: status t (*count resource descriptors of type)( const struct device configuration *config, resource type type); status t (*get nth resource descriptor of type)( const struct device configuration *config, uint32 n, resource type type, resource descriptor *descriptor, uint32 descriptor size); These function precisely as their names and prototypes suggest. 5. Reporting possible configurations for devices. The configuration manager selects configurations for devices based on sets of possible configurations reported by each device. Drivers typically won't ever need to access these configurations; they're provided for the benefit of device management utilities such as the new Devices preference application. status t (*get size of possible configurations for)( uint64 device); status t (*get possible configurations for)( uint64 device, struct possible device configurations *possible, uint32 len);
#define NEXT POSSIBLE(c) \ (c) = (struct device configuration *) \ ((uchar *)(c) + \ sizeof(struct device configuration) + \ (c)->num resources * \ sizeof(resource descriptor)) struct device configuration *config = possible->possible + 0; for (i=0;i<possible->num possible;i++) { ... NEXT POSSIBLE(config); } Descriptors for possible configurations differ slightly from their current configuration counterparts since they represent a set of possible choices rather than a single selection. Masks may have multiple bits set, with each bit representing a possible IRQ or DMA setting. Ranges are described by a minbase, a maxbase, a basealign, and a len, describing a range starting between minbase and maxbase, in increments of basealign, and having length len. Most APIs make more sense when you see them in action, so next time we'll develop an application demonstrating the use of the configuration manager.
DEVELOPERS' WORKSHOP: Back to Basics By Stephen Beaulieu hippo@be.com "Developers' Workshop" is a weekly feature that provides
answers to our developers' questions, or topic requests.
To submit a question, visit
http://www.be.com/developers/suggestion_box.html.
In this article I'm going to reinvestigate some of the basic
building blocks of the BeOS. We'll look at what I'll call
the AppKit model: BMessages, BLoopers, BHandlers, and
BMessengers.
The BMessage is fundamentally a data container, commonly
used to hold both instructions and data to be acted upon.
BHandlers are objects that perform an action when BMessages
are delivered to them; they handle the incoming message.
BLoopers are threaded BHandlers that run a message loop,
waiting for incoming BMessages and dispatching them to the
appropriate BHandlers. BMessengers are system wide tokens
that represent a given BLooper-BHandler pair, delivering
messages to (and replies from) the specified BHandler.
The most visible examples of BLoopers and BHandlers are
BApplications, BWindows, and BViews. These lie at the heart
of the BeOS APIs, and are common to most BeOS applications.
Many developers, however, seem to use the AppKit model only
in their interface areas, where it is pretty much required.
Since the AppKit model has other valid uses, I'm going to
offer some design ideas that may persuade developers to take
advantage of its versatility.
First though, a list of the AppKit model's advantages and
disadvantages to keep in mind while reviewing my designs.
Advantages:
Disadvantages:
Keeping these advantages and disadvantages in mind, here are
two design schemes that use the AppKit model: the Handler as
Data Object and Handler as Operation.
Handler as Data Object
In this scheme, the BHandler contains both the data to be
acted upon and the knowledge of how modifications are to be
performed. The data is encapsulated in a self-modifying
object. BMessages serve as instructions for what actions to
perform. The BLooper serves as the initial interface to the
various objects, but would usually pass back BMessengers for
the appropriate data objects, so the outside processes can
deal with them directly.
Example: Transaction Server
Here, the data object can be independently acted upon by
multiple threads/applications while in a guaranteed
consistent state. BMessages instruct the server to create,
delete, or modify objects. Change notifications can be sent
back to all interested processes. Furthermore, the
transactions can be recorded so that a previous state could
be reinstated by rewinding the transaction stack.
Handler as Operation
In this scheme, each BHandler represents an operation that
can be performed on some data. The BMessage carries the data
to modify and instructions about which operations to carry
out. The BLooper serves as a common interface to the
operations, investigating the instructions and passing the
data to the operations in the correct order, then sending
the modified data back to its origin.
Example: Data Filters
Use BHandlers to represent add-on filters to manipulate
data. Have each add-on create an entry function that returns
a BHandler that performs the appropriate filter. Then simply
pass the data to each filter as appropriate. This could be
parallelized by calling the entry function for a new
BHandler for each thread that needs a copy of the filter, at
the expense of more memory.
Example: State Machine
A BLooper represents a state machine, with BHandlers
representing each state. The looper passes the appropriate
instructions off to each state, which responds to them and
asks the BLooper to change state when appropriate. In this
example, the BLoopers might contain the data to act upon,
rather than a BMessage, but the view from the BHandler is
the same.
You can find some simple example code for these two schemes
at:
<ftp://ftp.be.com/pub/samples/application_kit/AppKitModel.zip>
Both schemes perform the same work, transforming strings to
uppercase, lowercase, or mixed case (with every word
capitalized.) They implement the code to modify the strings
the same way, using the BString class functions: ToUpper,
ToLower, and CapitalizeEachWord. They also act on the same
two strings. The only difference between the two examples is
the schemes used to organize the code (and correspondingly,
the printed output).
This structure is obviously overkill for simple string
modification, but the schemes become more useful as the
complexity of the data and operations increases. Strings are
just an easy way to demonstrate the various designs. The
Notes file in each folder explains how the project is put
together. Also, note that both applications are useful only
when run from the command line, as all feedback is through
I hope these designs can be helpful in your programs, or at
least will start you thinking more about the overall design
of your application.
A week ago, when the rumors of AOL's acquisition of Netscape
were confirmed, I didn't think it had much immediate impact
on our company. Others differed. I received several e-mail
messages asking what our position was. Correspondents were
of the opinion that every move against Microsoft implicitly
favors us, and thought the reference to an "AOL appliance"
indicated an opportunity for a BeOS-powered Web appliance.
And, last Friday, I found this in the San Jose Mercury News:
<http://www.mercurycenter.com/premium/business/docs/loveqa27.htm>
Selected quotations from the full story:
One leading critic of this acquisition is Jamie Love, an
antitrust economist and director of the Ralph
Nader-affiliated Consumer Project on Technology in
Washington, D.C. His group was among those that
successfully lobbied for the government to change
WorldCom Inc.'s plans to acquire MCI Communications
Corp., the long-distance phone company, earlier this
year.
Now, Love wants to block the AOL-Netscape agreement
because he believes it eliminates Netscape, a significant
Microsoft rival, and gives two companies -- AOL and
Microsoft -- too much power to impose their own
company-controlled software on the Internet.
Love discussed his concerns with Mercury News staff in
the following edited answers to questions posed by
e-mail.
[...]
Q: So what changes might you seek in the AOL-Netscape
deal?
A: There are several areas where the AOL-Netscape merger
concerns us. Will AOL and Microsoft exert so much power
in e-commerce that they can extort revenues from firms
that they feature for their customers? Will they
undermine non-affiliated technologies for new multimedia
services? Will AOL strike a deal with Microsoft to drop
support for applications that run on Linux (a version of
the Unix operating system that is freely available on the
Internet) or other operating systems? Maybe AOL could (be
compelled to) agree to support AOL and Netscape on Linux
or BeOS (an operating system made by Be, Inc.) and
promote greater choices for PC operating systems.
This is healthy publicity, and probably even friendlier in
intent than the plug we got from Bill Gates at Microsoft's
shareholders meeting almost three weeks ago. But we
shouldn't let only others speak on our behalf, however
eloquent and motivated.
First, I heard and read suggestions that since the
AOL/Netscape deal was against Microsoft then there must be
something in it for us. The logic is understandable:
Microsoft abuses its dominant position, so let's do anything
we can to diminish their power. This is flawed logic,
however. A benevolent regime doesn't automatically follow a
toppled tyrant, as history and contemporary events
demonstrate painfully enough.
In our view, being against Microsoft isn't good or bad in
itself. What is good is more choice -- real choice -- not,
for example, the kind we used to have with only two cellular
service providers in town, GTE and Cellular One. Economists
established long ago that oligopolies aren't really an
improvement over monopolies. With this in mind, let's hope
the AOL/Netscape deal really does create more choice, not
the kind of diversity that results only in more people like
us, not more people like them.
(For another very good piece on the topic, see Denise
Caruso's November 30th column in the New York Times:
<http://www.nytimes.com/library/tech/98/11/biztech/articles/30digi.html>).
Personally, I imagine Microsoft thinks there must be a god
and she likes Bill. Try selling this script in Hollywood:
right in the middle of the "trial of the century," two of
the cyber-tyrant's alleged victims merge to form an Internet
powerhouse that subverts, if not entirely kills off, the
DOJ's argument. The studio would banish you to North Korea
on a mission to teach market economics.
Just ten days ago, Microsoft's PR machine was straining
against the bad impressions generated by Bill Gates' video
deposition. Now they're working full time on the new
message: We told you so, Microsoft is a company constantly
under competitive threat.
As for Web appliances, yes, the concept is gaining momentum
and the BeOS could make a contribution at the intersection
of two requirements, rich multimedia user experience, the NC
with charm, and a small core enabling fast, inexpensive
devices. That would create more choice. Unless Microsoft,
never asleep at the wheel, embraces and extends it -- as
always. I hear they already have a name for it. PortalPC.
Has a nice ring to it.
1997 Be Newsletters | 1995 & 1996 Be Newsletters Copyright ©1998 Be, Inc. Be is a registered trademark, and BeOS, BeBox, BeWare, GeekPort, the Be logo and the BeOS logo are trademarks of Be, Inc. All other trademarks mentioned are the property of their respective owners. Comments about this site? Please write us at webmaster@be.com. |