Recent Comments

on the Annotated Be Book.

Note: There is a mailing list that gets notification of new annotations on the Be Book. The idea is that people can discuss annotations, suggest improvements, and make yet more annotations! To subscribe, send mail to listar and say subscribe bebook in the subject line or body.


status_t GetPreferredApp(char *signature, app_verb verb = B_OPEN) const

When there is no preferred app, you're supposed to get a NULL char *. That seems broken.The function does however return B_ENTRY_NOT_FOUND.

-- Jonas Sundstrom, May 11, 2002 on The Storage Kit/MimeType.html

There's an additional constructor in the header that acts as a copy-constructor: BBitmap(BBitmap *).
-- Gregor Rosenauer, March 1, 2002 on The Interface Kit/Bitmap.html

GetIcon(), GetTrackerIcon don't tell you what BBitmap they require: 16x16 in B_CMAP8-colorspace, so that's a BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_CMAP8).

see BMimeType::GetIcon() , SetIcon() where the Bitmap is specified.

-- Gregor Rosenauer, March 1, 2002 on The Storage Kit/NodeInfo.html

BNodeInfo::GetPreferredApp() returns garbage, while BMimeType::GetPreferredApp() works fine.

As a workaround, you can use BNodeInfo::GetType() and create a BMimeType-instance with the type, which calls GetPreferredApp().

-- Gregor Rosenauer, March 1, 2002 on The Storage Kit/NodeInfo.html

Menu controls as labels:

If you plan on using a pop-up menu for a label, ala the screen prefs window, make certain you use the BMenuField object. It'll save you the trial-and-error time of testing BMenu, BMenuBar, and BPopUpMenu.

-- Michael Armida, February 10, 2002 on The Interface Kit/Box.html

OpenViewTransaction() and CloseViewTransaction() do not exist. Use the similar Begin- and End-() methods found in the headers instead.
-- Gregor Rosenauer, January 23, 2002 on The Interface Kit/Window.html

The serial port driver in R5 is broken and will allow a serial port to be opened multiple times. This means that opening a BSerialPort will always succeed, but you'll be "sharing" the port with every other application that opened it!

An alternative viewpoint is that this is the right behaviour, and that you should use O_EXCL mode if you want exclusive use of the serial port. In that case, BSerialPort is broken, because it does not do that (probably because at one point, a serial port really couldn't be opened more than once).

To work around this, you should try opening the serial port first in exclusive mode, to test if it's already being used. If it's not, you can close it again and open the BSerialPort. There is still a race-condition there, but it's better than nothing.

-- Marco Nelissen, December 29, 2001 on The Device Kit/SerialPort.html

In the Play() function, the table lists items 15 and 16 as "RESERVED", this is not true, these are used for BShape drawing.

The functions look like:

StrokeShape(void* user, BShape* shape);

and

FillShape(void* user, BShape* shape);

-- Alan Ellis , December 4, 2001 on The Interface Kit/Shape.html

The book says that the Clipping Region for a view is only active when the view is attached to a window. It does also clip views attached to a Bitmap.
-- Pete Goodeve, September 10, 2001 on The Interface Kit/ViewGraphicsState.html

The book says...

Currently, GetNextDirents() only reads one dirent at a time, no matter how many you ask for.

Actually, it does work. It's just that most underlying file systems only handle finding one directory entry at a time. For ones which do handle multiples (like AGMSRAMFileSystem), you need to use the d_reclen field and add it to the start of the first entry to get to the next entry in the buffer (the entries are variable sized - depending on the length of the file name and padding). Note that most of the ones which handle only 1 dirent set the d_reclen to inappropriate values.

-- Alexander G. M. Smith , September 6, 2001 on The Storage Kit/Directory.html

dprintf also doesn't print octal numbers, so %o does nothing (not even print out an o). Not too important, except for conveniently printing out file permission bits (that rwxrwxrwx stuff).
-- Alexander G. M. Smith , August 20, 2001 on Drivers/KernelFunctions.html

in this exemple :

WRONG : if (modifiers() | B_SHIFT_KEY) { /* a shift key is down */ }

you must change the OR ( | ) per AND ( & ) with or that will never working

GOOD : if (modifiers() & B_SHIFT_KEY) { /* a shift key is down */ }

-- cedric vincent, August 13, 2001 on Keyboard/KeyboardModKeys.html

When a BScrollView is resized, you may see some visual bugs, mostly with the focus (if any) rectangle. To fix this, don't forget to set B_WILL_DRAW and B_FRAME_EVENTS flags in the scrollview constructor:
BListView * lv;
BScrollView * sv;
BRect rlv;

rlv = Bounds();

rlv.right -= B_V_SCROLL_BAR_WIDTH;

lv = new BListView(rlv, "my_list", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES); sv = new BScrollView("my_list_scrollview", lv, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS, false, true);

-- Philippe Houdoin, August 8, 2001 on The Interface Kit/ScrollView.html

Uniqueness of Data, aka, why my first post was wrong

It turns out that BMessage's data is uniquely identified by *name* and not type. The BeBook isn't too clear on this. From the AddData() section:

These functions return ... B_BAD_TYPE if the data can't be added to an existing array because it's the wrong type...

Perhaps I just completely got the wrong idea into my head, but in case its not spelled out somewhere else, this subtle hint does mean that you cannot have two fields with the same name and different types, whether or not the first or second is indexed with multiple values. Each name, therefore, can be used to uniquely identify the fields involved (index optional).

Therefore, my first comment about orthogonal functions is incorrect, as the functions are as orthogonal as necessary (and possible).

-- Michael Armida, August 3, 2001 on The Application Kit/Message.html

RemoveName(), RemoveData() - indices are compacted as you remove them to keep them all contiguous and sequential. That is, if you remove index 2 out of 5, you now have data available at indicies 0, 1, 2, and 3. Smells like BList?
-- Michael Armida, July 30, 2001 on The Application Kit/Message.html

BMessage: Orthogonal functions, please!

In case you're ever doing something very funky in terms of manipulating data, and you're considering using a BMessage as your data container, be aware that there are some inconsistencies with the functions that may give you a headache. The BeBook plainly states that fields are identified by type and name, and alternately, index. This level of specificity is supported for our favorite functions: Add...(), Find...(), Replace...(). However, for Remove...(), and GetInfo(), its a serious pain in the ass to find the exact same field you were talking about in the other functions. Just a warning - check it out before you end up writing an annoying wrapper layer to consistently manipulate the data.

-- Michael Armida, July 30, 2001 on The Application Kit/Message.html

Append vs. Output Operator <<

I've run into trouble using the output operator with character strings (const char*). The following:

char output[50]; sprintf(output, "%d", 3.5 ); stringdata<...never worked correctly, however, changing the last line to:

stringdata.Append(output);

...worked fine. My advice is to avoid the output operator for those non-weird data types.

-- Michael Armida, July 30, 2001 on The Support Kit/String.html

The B_QUIT_ON_WINDOW_CLOSE flag should work with R5.
-- Axel Dörfler, July 28, 2001 on The Interface Kit/Window.html

Constructor:

All arguments are copied, even though The Book isn't too specific about it. Specifically, the entry_ref and BMessengers are copied.

-- Michael Armida, July 24, 2001 on The Storage Kit/FilePanel.html

The book says "If the thread count is positive, the semaphore is available and the current acquisition succeeds." Shouldn't that be "If the thread count is >= the decrement value..." so that acquiring a semaphore with a decrement larger than 1 will wait until the count has gotten big enough? Otherwise the trick for allowing multiple readers and just one writer, which works by initialising the semaphore to N, having readers use a decrement of 1 and writers a decrement of N, just won't work.
-- Alexander G. M. Smith , July 21, 2001 on The Kernel Kit/Semaphores.html

MessageReceived() - I hope this isn't a big rehash for everyone, but after months of development I've just discovered a way to get everybody's favorite compiler to stop complaining when you declare variables inside a switch() statement. This is quite common in MessageReceived(), when handling a response to some incoming message. You cannot declare any new variables within the case statement itself, instead, you have a number of options:

1) move all variable declarations up to the top of the switch() block, even those that conditionally aren't going to be used (no fun).

2) Branch out using an unobtrusive function call. I prefer inlining these functions, so I do end up a whole block of "inline void" functions that start with "Handle...". This gets really annoying when adding many cases. Your code ends up looking like:

case SOME_CASE_HERE:
	HandleSomething(msg);
	break;

3) Use a block. This starts a new scope and GCC will be quiet if you declare variables within it. Your code looks like this:

case SOME_CASE_HERE:
	{ //block brackets
		...
	}
	break;

I like option #3 - it saves you a lot of function declarations.

-- Michael Armida, July 16, 2001 on The Application Kit/Handler.html

The EnqueueMessage() function actually takes possestion of the message you pass it, so do not try to delete it your self, or use a stack based BMessage instance with it.
-- , June 15, 2001 on The Input Server/InputServerDevice.html

If you have a media_raw_audio_format instance and want to make a media_format out of it, do the following:
format.type=B_MEDIA_RAW_AUDIO;
memcpy(&format.u.raw_audio, &raw_format, sizeof(media_raw_audio_format));
You can't use format.u.raw_audio=raw_format because format.u.raw_audio is actually a media_multi_audio_format and there is no assignment operator and no cast-operator to cast the right-hand side of the assignment. The bad thing is that casting the left-hand side of the assignment does compile, but doesn't work: the data doesn't get copied.
-- Jac Goudsmit, June 15, 2001 on The Media Kit/misc_api.html

Since BTimedEventQueue only cleans up events when they are flushed and since BMediaEventLooper's control loop removes events from the event queues after they are handled by HandleEvent, the HandleEvent function has to clean up any events it handles. That means: it has to Recycle incoming buffers and it should clean up user events. You can call the virtual CleanUpEvent function to clean up user events, but you have to explicitly call Recycle to recycle a buffer (i.e. there is no way to clean up standard events).
-- Jac Goudsmit, May 30, 2001 on The Media Kit/MediaEventLooper.html

Important: events are only "cleaned up" when they are flushed from a BTimedEventQueue. When an event is Removed, the cleanup code in the event is ignored.
-- Jac Goudsmit, May 30, 2001 on The Media Kit/TimedEventQueue.html

Important: events are only "cleaned up" when they are flushed from a BTimedEventQueue. When an event is Removed, the cleanup code in the event is ignored.
-- Jac Goudsmit, May 30, 2001 on The Media Kit/TimedEventQueue.html

Power PC systems are on fire for one second every 256 seconds. Intel systems of course are never on fire... :)
-- , May 22, 2001 on The Kernel Kit/System.html

Don't call SetRunMode directly inside your node's code to change the current run mode. You need to call BMediaRoster::SetRunModeNode to do that. If you call your hook-function directly, the actual run mode will remain unchanged (calling hook-functions directly without help from the Media Roster is always a Bad Thing (TM)).
-- Jac Goudsmit, May 22, 2001 on The Media Kit/MediaNode.html

The notification messages received after calling BRoster::StartWatching() have the following fields:

be:signature be:team be:thread be:flags be:ref

-- , May 20, 2001 on The Application Kit/Roster.html

The GetNextOutput function must initialize the media_destination of the output to media_destination::null if the output is not connected to another media node. Just filling the media_destination with 0 is not sufficient.
-- Jac Goudsmit, May 17, 2001 on The Media Kit/BufferProducer.html

The GetNextInput function must initialize the media_source of the input to media_source::null if the input is not connected to another media node. Just filling the media_source with 0 is not sufficient.
-- Jac Goudsmit, May 17, 2001 on The Media Kit/BufferConsumer.html

The GetFreeInputsFor and GetFreeOutputsFor functions respectively check for inputs/outputs that have their source/destination set to media_source::null/media_destination::null. Note that media_source::null and media_destination::null (contrary to what their name suggests) are NOT equal to a media_source/media_destination filled with 0.
-- Jac Goudsmit, May 17, 2001 on The Media Kit/MediaRoster.html

The FormatProposal() function is not only called when connecting two nodes, but also when you call BMediaRoster::GetFormatFor with a media_output as parameter.

FormatSuggestionRequested() is called when you call BMediaRoster::GetFormatFor with a media_node as parameter. By the way, the media_audio_format::wildcard and media_video_format::wildcard that are mentioned in the documentation for this function are really data, not functions.

-- Jac Goudsmit, May 17, 2001 on The Media Kit/BufferProducer.html

The AcceptFormat function is not only called during connection of two nodes, but also when you call BMediaRoster::GetFormatFor() with a media_input as parameter.
-- Jac Goudsmit, May 17, 2001 on The Media Kit/BufferConsumer.html

Somewhere in the Be Book the BMediaRoster::SetOutputBuffersFor function is mentioned. This function has moved to BBufferConsumer
-- Jac Goudsmit, May 16, 2001 on The Media Kit/MediaRoster.html

In BBufferConsumer::BufferReceived(), it is mentioned that your node may receive small buffers and you should recycle them before the function returns. This is confusing; after all small buffers don't ever belong to a Buffer Group so why should you recycle them?

Answer: Small buffer objects that your BufferReceived hook-function receives, are destroyed after you return. So the remark really should be: if you receive a small buffer, you should handle it immediately before your BufferReceived function returns. If you derive from BMediaEventLooper, you cannot generate a B_HANDLE_BUFFER event and add it to the event queue, because the pointer to the buffer will be invalid once your HandleEvent function finds it. What you CAN do if you want to use HandleEvent to handle the buffer, is call DispatchEvent from your BufferReceived function if the incoming buffer is a small one. That function calls your HandleEvent hook-function so that small buffers can be handled in the same way as large ones. Before you call DispatchEvent, you need to use BTimeSource::SnoozeUntil to wait for the performance time of the buffer.

And for future compatibility, you should still call Recycle() on the buffer in BufferReceived, if it's a small buffer (like the Be Book says).

-- Jac Goudsmit, May 16, 2001 on The Media Kit/BufferConsumer.html

Something that the Be Book doesn't mention is that most hook-functions in the media kit are called with pointers that are guaranteed to be non-NULL. This is because the pointers that are passed to the functions, usually point into fixed-length structs that are used internally to pass data between nodes. In many code-examples on the Be website, almost no checks for NULL-pointers appear, and this is not just to simplify the example but also because it's not really necessary.
-- Jac Goudsmit, May 16, 2001 on The Media Kit/index.html

oops... here's that comment one more time...

The HandleMessage() function mentions that you should call the HandleMessage function of BBufferProducer, BBufferConsumer and BMediaNode, and call the HandleBadMessage function if no-one can handle the message.

Actually this is not really necessary if your control loop uses WaitForMessage() or if you subclass your node from BMediaEventLooper (which uses WaitForMessage it its control loop): the WaitForMessage function knows how to dispatch messages to media nodes; your media node will only have to handle messages that no other class that you derive your node from, understands.

Of course that also means you can't intercept messages that are meant to be received by other classes that you derive from.

-- Jac Goudsmit, May 16, 2001 on The Media Kit/MediaNode.html

The WaitForMessage() or if you subclass your node from BMediaEventLooper (which uses WaitForMessage it its control loop): the WaitForMessage function knows how to dispatch messages to media nodes; your media node will only have to handle messages that no other class that you derive your node from, understands.

Of course that also means you can't intercept messages that are meant to be received by other classes that you derive from.

-- Jac Goudsmit, May 16, 2001 on The Media Kit/MediaNode.html

BMediaNode::GetNodeAttributes() should really return the number of attributes that your hookup function filled in; returning B_OK would tell BeOS that you filled in 0 attributes.
-- Jac Goudsmit, May 16, 2001 on The Media Kit/MediaNode.html

DEBUG_ONLY( expression ) doesn't pay attention to whether SET_DEBUG_ENABLED() was set to true or false, so if this is your first time using this macro, you may be confused that "expression" is evaluated any time DEBUG is defined.

To allow DEBUG_ONLY to function when PRINT does, you need to write the code: DEBUG_ONLY( if(IS_DEBUG_ENABLED()) { expression } );

-- Scott Mann, May 11, 2001 on The Support Kit/Debugging.html

How does one change the font size of all the menu items in a menu? Do you have to derive a class, and redefine Draw() or something?
-- , May 11, 2001 on The Interface Kit/Menu.html

That didn't work out so well....

media_node is actually declared in MediaNode.h, not in MediaDefs.h

-- Oliver Sampson, May 8, 2001 on The Media Kit/misc_api.html

media_node is actually declared in not in
-- , May 8, 2001 on The Media Kit/misc_api.html

Beware, SetScale() seem to miswork when use on a bitmap child view.
-- Philippe Houdoin, April 26, 2001 on The Interface Kit/ViewGraphicsState.html

If you want to print 64 bit integers with dprintf, the printf standard "%qd" won't work, but you can use "%Ld" instead (note the capital L).
-- Alexander G. M. Smith , February 26, 2001 on Drivers/KernelFunctions.html

The sample code for GetSupportingApps is incorrect (although the documentation is correct). Instead of:

message.FindInt32("be:subs", &subs); message.FindInt32("be:supers", &supers);
it should be:

message.FindInt32("be:sub", &subs); message.FindInt32("be:super", &supers);

-- Billy Kakes, February 26, 2001 on The Storage Kit/MimeType.html

On german keyboards there is a key labelled "<" and ">" between the left shift key and the Y. Its code is 0x69.
-- Achim Blumensath , January 29, 2001 on Keyboard/KeyboardKeyCodes.html

Remember, you want to add a BView to a BTab then add the BTab to a BTabView .. I have seen people get caught on this many times.
-- , January 29, 2001 on The Interface Kit/Tab.html

GetInstalledSupertypes() actually return the types in the "super_types" field of the passed in BMessage.
-- Carlos Hasan , January 9, 2001 on The Storage Kit/MimeType.html

The network add-on API is at http://www-classic.be.com/documentation/be_book_r3/The%20Network%20Kit/. One warning: do NOT subclass BStandardPacket. If you do, bad things happen.
-- Nathan Whitehorn , January 8, 2001 on The Network Kit/index.html

After writing my AGMSDeviceTest program (see BeBits.com), I figured out what the standard IOCtl operations do and added descriptions. Here's the list:
Standard IOCtl Codes and Their Meanings
NameIOCtl #Data SizeDescription
B_GET_DEVICE_SIZE14Returns a size_t in *Data with the device size in bytes. Obsolete, not 64 bits! Use B_GET_GEOMETRY instead and do the 64 bit math.
B_SET_DEVICE_SIZE24Sets the device size (in bytes) to the size_t value pointed to by *Data. Probably obsolete since it's only 32 bits. Good for RAM disks I guess, since they use 32 bit pointers.
B_SET_NONBLOCKING_IO30Sets the device to use nonblocking I/O (calls return immediately rather than waiting for the IO operation to complete).
B_SET_BLOCKING_IO40Sets the device to use blocking I/O (calls to the driver return only once the operation is complete).
B_GET_READ_STATUS51Returns a true bool in *Data if the device can read without blocking, otherwise sets *Data to false. I presume for blocking mode, this means true if there is some data ready in the buffers for you to read.
B_GET_WRITE_STATUS61Returns a true bool in *Data if the device can write without blocking, otherwise sets *Data to false. I presume for blocking mode this means true if there are some empty intermediate buffers ready to receive your data.
B_GET_GEOMETRY720Gets the device geometry (sector size / sectors / tracks / heads) and other characteristics of the device and writes it into the device_geometry structure the caller provided at *Data. If media isn't present, sizes could be zero.
B_GET_DRIVER_FOR_DEVICE8256Writes the path of the driver executable handling this device into the buffer the caller provided in *Data. Note that the header defines a buffer smaller than B_PATH_NAME_LENGTH (1024) for some reason.
B_GET_PARTITION_INFO9284Returns a partition_info structure for the device in *Data, fortunately it uses 64 bit values. The DevFS does this for you, making fake devices for partitions, so the driver writer doesn't have to handle this message. Only works when you use it on the partition's file: if your device is */raw, then */S_P (S is session, P is partition) are the partition files. For example */0_0 for the first partition, */0_1 for the second and so on.
B_SET_PARTITION10284Finishes setting up a user-defined partition. *Data points to a partition_info structure, fortunately with 64 bit values. The DevFS makes fake devices for partitions, when you "creat()" the */S_P file, where S is a session number (mostly for multisession CD-ROMs, else 0) and P is the partition number (0 & upwards). Then use this IOCtl operation to set the size and offset of the partition, with the device name field set to your */raw device. Note that sizes may have to be a multiple of cylinder size. See the article http://www-classic.be.com/aboutbe/benewsletter/volume_II/Issue23.html for details.
B_FORMAT_DEVICE111Low level formats the device. This can erase everything, watch out! *Data points to a bool: true for full format, false for a quick format (device should test for presence of an existing format by attempting to read the first & last sectors, then do a full format if errors were encountered).
B_EJECT_DEVICE120Ejects the media from the device. For CD-ROMs this means opening the tray or otherwise popping out the CD. You can guess what this does for Internet toasters.
B_GET_ICON138Gets a graphic icon from the device. The device will use the device_icon structure pointed to by *Data to get the size desired (square icons this many pixels wide, usually 16 or 32) and the buffer to write the icon bitmap to (B_CMAP8 style bitmap).
B_GET_BIOS_GEOMETRY1420Fills out the device_geometry structure pointed to by *Data with a description of the device as the BIOS sees it. I presume it's mostly for disk type devices used during bootup, also may be needed when making partitions on a disk device.
B_GET_MEDIA_STATUS154Writes the media status (ready, empty drive, door open, ...) into the status_t pointed to by *Data. Also clears the media changed flag, so read / write calls will start working again rather than returning B_DEV_MEDIA_CHANGED.
B_LOAD_MEDIA160Loads the media into the drive. For CD-ROMs this closes the tray or sucks in the CD. May also be useful for Internet toaster appliances. Also see is_computer_on_fire().
B_GET_BIOS_DRIVE_ID171Returns the BIOS ID for disks in a single byte. $80 is usually the C: boot drive.
B_SET_UNINTERRUPTABLE_IO180Prevents control-C and I presume other signals from interrupting I/O (well, maybe not SIGTERM?). The call to read/write will return when it is finished, not any earlier.
B_SET_INTERRUPTABLE_IO190Allows control-C and I presume other signals to interrupt I/O. I presume that means that a call to read/write which is waiting for data can return with partial data or a B_INTERRUPTED error code or both (probably best to not do both since the C read() API can't represent both).
B_FLUSH_DRIVE_CACHE200Flushes cached data from internal caches and lower level hardware caches to the actual media, then returns. This guarantees that your data has actually been written. Useful to do just before shutting off the power.
B_GET_NEXT_OPEN_DEVICE1000260Iterates through open devices. *Data points to an open_device_iterator structure which gives you a name for each open thing. Set the cookie to zero to start. Seems to only work if you apply it to /dev, giving you a list of all loaded devices.
B_DEVICE_OP_CODES_END99990User defined control codes follow this one.

-- Alexander G. M. Smith , December 26, 2000 on Drivers/kernelAPI.html

The above reference should probably be to SetFontSize()...
-- Peter Folk , December 21, 2000 on The Interface Kit/Font.html

BFont::SetSize() makes a misleading refrence to "See also: BView::SetSize()", which, of course, does not exist. This will take about 10 minutes to find out using the BeBook (due to the whack nature of the BView section of the BeBook). If you look in the BView header, however, it is readily apparent.

Makes one wonder what it was really referring to...

-- Alan Ellis , December 20, 2000 on The Interface Kit/Font.html

There are other attributes that are understood (some even required) by Tracker:

-- Stephen van Egmond, December 17, 2000 on The Storage Kit/MimeType.html

The function tint_color() also seems to be undocumented.
-- Carlos Hasan , December 13, 2000 on The Interface Kit/functions.html

It'd be nice if the spawn_thread() description linked to the Thread Priority Values instead of just mentioning it...
-- Peter Folk , December 4, 2000 on The Kernel Kit/Threads.html

There appears to be a new undocumented function ItemAtFast(uint32).

This function looks to be doing unchecked access to items in the list, that is, it does not make sure that the index that you pass is valid before trying to give you back the item.

So use this when you know how big the list is and want quick access, but be careful, it could cause a crash if you spin off the end.

-- Alan Ellis , December 4, 2000 on The Support Kit/List.html

There's some nice information on kernel and device driver programming at BeDriven. Some of it is in a language I don't parse (much less understand) but most of it is good, useful information collected from many sources (bedevtalk, the Be Book, newsletter articles, etc).
-- Peter Folk , December 4, 2000 on The Kernel Kit/index.html

The description of write_hook() is misleading:

write_hook()'s final argument should be size_t *len, and it should say that you return B_OK AND set *len to the amount of data writen, unless an error occurs in which case you return an error.

The description is correct in stating that it is not an error to write fewer bytes than requested. In this case you return B_OK (not an error) and set *len to the amount of data actually writen.

-- Peter Folk , December 3, 2000 on Drivers/writing_drivers.html

#It is not discussed what value comes back when this function fails.
[...]
#What, in fact, happens, is that you are returned a negative value
#when it fails.

The standard idiom when dealing with most, if not all, functions in the Be kits is:

  ret = foo();
  if (ret < B_OK) fprintf(stderr, "Damn.  %s!", strerror(ret));
So checking for B_ERROR in particular is not the goal (as there are many errors other than the generic B_ERROR which must be somehow indicated); instead check if the return values was "less than OK". Really a rather nice idiom if you ask me...
-- Peter Folk , December 3, 2000 on The Kernel Kit/Images.html

Watch out! SetTarget() is documented as accepting new targets either before or after the control has been attached to a window. In my experience, the earliest you can set a control's target is in AttachedToWindow().

However, the control I'm working with is a liblayout class which derives from BTextControl, so perhaps I'm hitting a bug in liblayout.

-- Stephen van Egmond, December 3, 2000 on The Interface Kit/Control.html

Concerning load_add_on():

It is not discussed what value comes back when this function fails. A curory look at the documentation would suggest that B_ERROR would be returned, but this is not the case.

What, in fact, happens, is that you are returned a negative value when it fails.

What this value means is a mystery to me, if I find out, you will be the first to know.

-- Alan Ellis , December 1, 2000 on The Kernel Kit/Images.html

Regarding BFil::Seek().

So there are these constants SEEK_END etc. however they are not defined in File.h, or Node.h or PositionIO.h, and there is no mention on this page (that I can find) of where they might be.

They are, in fact, in stdio.h. Who knew?

-- Alan Ellis , November 29, 2000 on The Storage Kit/File.html

OK, last one, I promise.

The *WatchingAll() functions work in conjunction. That is, StartWatchingAll() will watch everything, and StopWatchingAll() will stop that operation.

It does not work to watch specific constants and then use StopWatchingAll() to stop. You have to explicitly stop watching any explicity specified constants.

-- Alan Ellis , November 27, 2000 on The Application Kit/Handler.html

More news on the *Watching set of functions. It appears that the semantics of the functions is reversed when dealing with BHandler vs BMessenger, so if you are wanting to use a BHandler pointer the description is correct and you have to use the watched BHandler's pointer to call the function and pass in the watcher's pointer. weird.

Information courtesy of Dianne Hackborn of Be Inc.

Any incorectness in this is my fault. =)

-- Alan Ellis , November 27, 2000 on The Application Kit/Handler.html

The function ui_color() seems undocumented, though obvious. Look in the global constants section of the UI refrence for the color_which constants.
-- Alan Ellis , November 25, 2000 on The Interface Kit/functions.html

There are a few things about the documentation for the Observer/Watcher functions that seem to need better clarification.

1) SendNotices()

Is only described in the Release Notes for some reason.

It says that the 'what' param of the message sent to SendNotices gets clobbered, this is only partly true, the _copy_ of the message's what param getts clobbered, the original is stays the same.

2) StartWatching()

The wording states" ... registers the BMessenger or BHandler specified by watche to be notified whenever the state specified by what changes."

What I really think this means is that this function registers this to be notified when the watcher uses SendNotices() specifying what.

I think perhps there should be a column in the BMessage describing this if there is not already.

-- Alan Ellis , November 24, 2000 on The Application Kit/Handler.html

You will need to lock your looper if its running. A better way to do this is to call SetDivider before AddChild.
-- Nathan Whitehorn , November 21, 2000 on The Interface Kit/MenuField.html

You will need to lock your looper if its running. A better way to do this is to call SetDivider before AddChild.
-- Nathan Whitehorn , November 21, 2000 on The Interface Kit/TextControl.html

How to make the string half of the TextControl not clip at high sizes:
--
BTextControl *field = new BTextControl(..., "Left Text", ...);
AddChild(field);
field->SetDivider(be_plain_font->StringWidth("Left Text##"));

--
Tip numero uno: NEVER use just a pixel value for SetDivider(). Always check against be_plain_font so that the user can change the font size at will and have nothing clip.
-- Brian Luft , November 20, 2000 on The Interface Kit/TextControl.html

How to make the string half of the MenuField not clip at high sizes: -- BMenuField *field = new BMenuField(..., "Left Text", ...); AddChild(field); field->SetDivider(be_plain_font->StringWidth("Left Text##")); -- Tip numero uno: NEVER use just a pixel value for SetDivider(). Always check against be_plain_font so that the user can change the font size at will and have nothing clip.
-- Brian Luft , November 20, 2000 on The Interface Kit/MenuField.html

In my expierence it has been shown that you cannot create a window in one thread, and then call the first Show() (for window startup) in another.

If you want to start up a window but not show it at the same time, use a Hide() call before the first Show() call, this will cause it to not show up, but still start.

-- Alan Ellis , November 20, 2000 on The Interface Kit/Window.html

The control hook function for a disk drive sometimes receives an unknown function, the value of the function equals 10199. I don't know it's purpose is, I just return a value of B_OK, and it seems to work fine.
-- Earl Colby Pottinger , November 15, 2000 on Drivers/writing_drivers.html

Watch out! One of the AddItem calls is deprecated. Take a look at the Release Notes.
-- Stephen van Egmond, November 14, 2000 on Deskbar/Deskbar.html

Trey Boudreau pointed out this useful bit of info:

Note a missing bit of info about create_pool(): it does NOT fix the size of the pool at creation time. The size parameter specifies the MINIMUM increase in the size of the pool when it can't satisfy a malloc() or realloc(). Since it allocates memory out of areas, and the kernel sizes areas in multiples of B_PAGE_SIZE (4096 bytes, currently), the module will round up the size increase to the next multiple of B_PAGE_SIZE.

-- Alexander G. M. Smith , November 13, 2000 on Drivers/area_malloc.html

When init_driver() returns an error, the driver is unloaded, without calling uninit_driver(). So free your resources before you return an error!
-- Peter Folk , November 11, 2000 on Drivers/writing_drivers.html

Ports don't work right (at all) between kernel and user space in my experience.
-- Nathan Whitehorn , November 7, 2000 on The Kernel Kit/PortConcepts.html

Keep in mind that BWindow Screen will probably be deprecated in a future BeOS release. The "de facto" API for high performance graphics will be OpenGL.
-- Bruno G. Albuquerque , November 7, 2000 on The Game Kit/WindowScreen.html

There is an inaccuracy on how to use the "Debug tools". It IS possible to "#define DEBUG" in the IDE. Just add "-DDEBUG" in the "Enter additional desired gcc options:" field.
-- Linus Almström , November 7, 2000 on The Support Kit/Debugging.html

Thanks to Tony "Zippy" Martinez for the excellent new transparent warning icons that appear throughout the Be Book.
-- Stephen van Egmond, November 7, 2000 on bebook/index.html

BFont::SetFace()

The B_UNDERSCORE_FACE and B_STRIKEOUT_FACE are not implemented. B_ITALIC_FACE and B_BOLD_FACE are. Not sure about the others.

You can however use values returned by BFont::GetHeight() to draw your own underline/strikeout.

-- Matthew Allen , November 6, 2000 on The Interface Kit/Font.html

BFont::BoundingBox() returns a BRect which corresponds to an idealized 1-point font. You have to multiply the Rect by the point size to use it for layout...
-- Dave Brubeck , November 6, 2000 on The Interface Kit/Font.html

Concerning the be_app_messenger global pointer. It is not a pointer.

From Application.h

extern _IMPEXP_BE BMEssenger be_app_messenger;

-- Alan Ellis , November 6, 2000 on The Application Kit/Messenger.html

One thing I have noticed about BView::SetViewCursor() is that it will not work in the constructor, AttachedToWindow(), AllAttached(), or WindowActivated(). Sheesh! In fact, the only place that it seems to work to use SetViewCursor() is in MouseMoved().
-- Alan Ellis , November 6, 2000 on The Interface Kit/View.html

This kit is very out of date. Please use the Midi2 Kit to ensure compatiablity with other midi applications. Sadly, we don't have any Midi2 Kit documentation, so look at the headers, and patchbay example on Be's ftp site.
-- Daniel Walton , November 6, 2000 on The Midi Kit/index.html

inspite of what the documentation for SetMenu says the menu actually used in the input server menu doesn't seem to be the menu you own if you change it(the menu you own) the change will not come into effect until you call SetMenu again - the only conclusion i came to is that the input server copies the menu
-- Eyal Bari , November 6, 2000 on The Input Server/InputServerMethod.html

Beware... as of yet, BTabView's tabs are not font-sensitive. You might want to look into a better, third-party solution that is font-sensitive instead of using this one.
-- Brian Luft , November 6, 2000 on The Interface Kit/TabView.html

Remember to always put your BTextViews inside BScrollViews. The BScrollView is what adds that cool-looking bevel to the outside. So, use BScrollView even if you don't want to have it scroll.
-- Brian Luft , November 6, 2000 on The Interface Kit/TextView.html

For a background view (which just is painted gray and holds other controls), try using a BBox. For the bounds, take the window Bounds() and InsetBy(-1, -1). Doing this will make your dialog look classier and more professional.
-- Brian Luft , November 6, 2000 on The Interface Kit/View.html

Make sure to ALWAYS call ResizeToPreferred() on your buttons so that the text doesn't clip and the buttons are the correct size. Nothing worse than a hard-coded button size.
-- Brian Luft , November 6, 2000 on The Interface Kit/Button.html

There is an extension to the BString class in the OpenTracker project, called TrackerString. It contains some pattern matching and more search facilities. It also fixes some bugs in the case-insensitive Find*() functions in R5.
-- Thorbjörn Jemander , November 6, 2000 on The Support Kit/String.html

minfo->configure(0, 10); Does not work for me. So far the code seem to needed to be written as: (*minfo->configure)(0, 10); Comments?
-- Earl Colby Pottinger , November 4, 2000 on Drivers/using_modules.html


Stephen van Egmond