docs/develop: Mass directory restructure.

Now vaguely follows the tree structure of "src", with the exception of
directories that described subsystems spanning more than one "kit" or
"server" (e.g. "media", "midi", "bluetooth") -- these have been left as their
own top-level directory within docs/develop.
This commit is contained in:
Augustin Cavalier
2018-01-10 16:12:14 -05:00
parent cdf0ad6a80
commit e81a954787
60 changed files with 0 additions and 0 deletions
+193
View File
@@ -0,0 +1,193 @@
Message header:
Data Bytes Meaning
FOB1 4 version
4 checksum
4 flattened size
4 'what'
1 flags
Data field:
Data Bytes Meaning
1 flags
4 type
// Mini data (all data less than 256 bytes total)
1 item count (*if* there is more than one)
1 data length
// Maxi data (all data more than 255 bytes total)
4 item count (*if* there is more than one)
4 data length
1 name length
X name
// Single item
4 item size (*if* this is a variable sized item)
Y item data - NULL padded to 8-byte boundary
// Multiple items
4 item size (*if* this is a variable sized item)
Y item data - NULL padded to 8-byte boundary
//------------------------------------------------------------------------------
// An example
//------------------------------------------------------------------------------
// PrintToStream()
Data Bytes Meaning
//BMessage: what = (0x0, or 0)
FOB1 4 version
0x90010001 4 checksum
0x00000192 4 flattened size (402 bytes)
0x0 4 'what' (none specified)
0x01 1 flags
// entry ATTRIBUTE_MENU, type='LONG', c=5, size= 4,
0x07 1 flags
LONG 4 type
0x05 1 item count
0x14 1 data length
0x0e 1 name length
ATTRIBUTE_ 14 name (ATTRIBUTE_MENU)
// data[0]: 0x8 (8, '')
0x8 4 data[0]
// data[1]: 0x8 (8, '')
0x8 4 data[1]
// data[2]: 0x6 (6, '')
0x6 4 data[2]
// data[3]: 0x8 (8, '')
0x8 4 data[3]
// data[4]: 0x6 (6, '')
0x6 4 data[4]
// entry CRITERIA_MENU, type='LONG', c=5, size= 4,
0x07 1 flags
LONG 4 type
0x05 1 item count
0x14 1 data length
0x0d 1 name length
CRITERIA_ 13 name (CRITERIA_MENU)
// data[0]: 0x0 (0, '')
0x0 4 data[0]
// data[1]: 0x0 (0, '')
0x0 4 data[1]
// data[2]: 0x0 (0, '')
0x0 4 data[2]
// data[3]: 0x0 (0, '')
0x0 4 data[3]
// data[4]: 0x0 (0, '')
0x0 4 data[4]
// entry VALUE, type='CSTR', c=5,
0x03 1 flags
CSTR 4 type
0x5 1 item count
0x90 1 data length
0x5 1 name length
VALUE 5 name (VALUE)
// size=18, data[0]: "listar@freelists."
0x12 4 item size
listar@fre 18 data[0]
2 padding to 8-byte boundary
// size=27, data[1]: "freelists-users@freelists."
0x1b 4 item size
freelists@ 27 data[1]
1 padding to 8-byte boundary
// size=27, data[2]: "freelists-users@freelists."
0x1b 4 item size
freelists@ 27 data[2]
1 padding to 8-byte boundary
// size=19, data[3]: "ecartis@freelists."
0x13 4 item size
ecartis@fr 19 data[3]
1 padding to 8-byte boundary
// size=26, data[4]: "freelists-news@freelists."
0x1a 4 item size
freelists@ 26 data[4]
2 padding to 8-byte boundary
// entry AND_OR_MENU, type='LONG', c=5, size= 4,
0x07 1 flags
LONG 4 type
0x5 1 item count
0x14 1 data length
0x0b 1 name length
AND_OR_MEN 11 name (AND_OR_MENU)
// data[0]: 0x1 (1, '')
0x1 4 data[0]
// data[1]: 0x1 (1, '')
0x1 4 data[1]
// data[2]: 0x1 (1, '')
0x1 4 data[2]
// data[3]: 0x1 (1, '')
0x1 4 data[3]
// data[4]: 0x0 (0, '')
0x0 4 data[4]
// entry COUNT, type='LONG', c=1, size= 4, data[0]: 0x5 (5, '')
0x0f 1 flags
LONG 4 type
0x4 1 data length
0x5 1 name length
COUNT 5 name (COUNT)
0x5 4 data
// entry ACTION_MENU, type='LONG', c=1, size= 4, data[0]: 0x2 (2, '')
0x0f 1 flags
LONG 4 type
0x4 1 data length
0x0b 1 name length
ACTION_MEN 11 name (ACTION_MENU)
0x2 4 data
// entry ACTION_VALUE, type='CSTR', c=1, size=42, data[0]: "/boot/home/mail/Erik's Mail/freelists.org"
0x0b 1 flags
CSTR 4 type
0x30 1 data length
0x0c 1 name length
ACTION_VAL 12 name (ACTION_VALUE)
0x2a 4 item size
/boot/home 42 data
2 padding to 8-byte boundary
//------------------------------------------------------------------------------
// An old example
Data Bytes Meaning
1BOF(ascii) 4 version
?? 4 ??
0x76 4 flattened size
DPUQ 4 what(B_QUERY_UPDATE)
?? 1 ??
0F 1 flags (including fixed chunk size)
GNOL 4 type
04 1 chunk size
06 1 name length
opcode 6 name
1 4 data(B_ENTRY_CREATED)
0F 1 flags (including fixed chunk size)
GNOL 4 type
04 1 chunk size
06 1 name length
device 6 name
4 4 data
0F 1 flags (including fixed chunk size)
GNLL 4 type
08 1 chunk size
09 1 name length
directory 9 name
524992 8 data
0F 1 flags (including fixed chunk size)
GNLL 4 type
08 1 chunk size
04 1 name length
node 4 name
524295 8 data
0B 1 flags (including variable chunk size)
RTSC 4 type
08 1 chunk size
04 1 name length
name 4 name
08 1 chunk size?
8 padded string?
@@ -0,0 +1,169 @@
/* The Dano Message Format
0. Disclaimer
The information herein is based on reverse engeneering flattened BMessages.
The conclusions might be wrong in the details, and an implementation can
probably not be drawn right from this description, but the overall format
described here should come close to the one found on Dano based systems.
1. Concept
In the Dano message format, data is kept in a flat buffer and is organised
in multiple "sections". Each section has a header that identifies the type
of the section and it's size. Each section contains a field that then holds
more information on the data and the data itself. Everything is usually
padded to 8 byte boundaries.
2. Section Headers
The section header looks like this:
typedef struct section_header_s {
int32 code;
ssize_t size;
uint8 data[0];
} SectionHeader;
The code identifies the type of the data following the header. Valid types
are the following:
enum {
SECTION_MESSAGE_HEADER = 'FOB2',
SECTION_OFFSET_TABLE = 'STof',
SECTION_TARGET_INFORMATION = 'ENwh',
SECTION_SINGLE_ITEM_DATA = 'SGDa'
SECTION_FIXED_SIZE_ARRAY_DATA = 'FADa',
SECTION_VARIABLE_SIZE_ARRAY_DATA = 'VADa',
SECTION_SORTED_INDEX_TABLE = 'DXIn',
SECTION_END_OF_DATA = 'DDEn'
};
The size field includes the size of the header itself and its data.
3. Message Header Section
The message header section stores the what field of the message. Its code,
conveniently at the very first 4 bytes, also identifies the message as a
Dano message ('FOB2'). The layout is as follows:
typedef struct message_header_s {
int32 what;
int32 padding;
} MessageHeader;
4. Offset Table Section
The offset table stores the byte offsets to the sorted index table and to
the end of data section. It looks like this:
typedef struct offset_table_s {
int32 indexTable;
int32 endOfData;
int64 padding;
} OffsetTable;
The index table offset is important since we will usually insert new fields
before the index table. The end of data offset can be used to directly
know where the index table ends. It's also possible that the end of index
offset is actually the end of the index table.
Both offsets are based on the beginning of the first data section and not
from the top of the message.
5. Single Item Data Section
The single item data section holds information on exactly one data item.
Since when only dealing with one item it doesn't matter wether it is fixed
size or not we do not distinct between these two types. The format is as
follows:
typedef struct single_item_s {
type_code type;
ssize_t itemSize;
uint8 nameLength;
char name[0];
} SingleItem;
The the name is padded to the next 8 byte boundary. After nameLength + 1
bytes the item data begins. The nameLength field does not count the
terminating 0 of the name, but the name is actually 0 terminated.
6. Fixed Size Item Array Data
This type of section holds an array of fixed size items. Describing the
format of this section in a struct is a bit harder, since the count
variable is stored after the name field. In pseudo code it would look like
this:
typedef struct fixed_size_s {
type_code type;
ssize_t sizePerItem;
uint8 nameLength;
char name[pad_to_8(nameLength + 1)];
int32 count;
int32 padding;
uint8 data[0];
} FixedSize;
7. Variable Sized Item Array Data
The format is very similar to the one of the fixed size item array above.
Again in pseudo code:
typedef struct variable_size_s {
type_code type;
int32 padding;
uint8 nameLength;
char name[pad_to_8(nameLength + 1)];
int32 count;
ssize_t totalSize;
uint8 data[0];
} VariableSize;
The data itself is constructed of the variable sized items, each padded to
an eight byte boundary. Where they begin and where they end is not encoded
in the data itself but in an "endpoint table" following the data (at data
+ totalSize). The endpoint table is an array of int32 items each pointing
to the end of an item (not including padding). As an example we take an
array of three variable sized items layouted like this:
<data>
76 61 72 69 61 62 6c 65 variable
20 73 69 7a 65 64 20 64 sized d
61 74 61 00 00 00 00 00 ata..... (pad)
61 72 69 61 62 6c 65 20 ariable
73 69 7a 65 64 20 64 61 sized da
74 61 00 00 00 00 00 00 ta...... (pad)
6c 61 73 74 20 69 6e 20 last in
74 68 69 73 20 61 72 72 this arr
61 79 21 00 00 00 00 00 ay!..... (pad)
</data>
Then the endpoint table would look like this:
<endPointTable>
<endPoint 20 />
<endPoint 43 />
<endPoint 68 />
<endPointTable>
The first endpoint (20) means that the size of the first item is 20 bytes.
The second endpoint (43) is constructed from the start of the second item
which is at pad_to_8(endpoint[0]) plus the size of the item. In this case
pad_to_8(endpoint[0]) results in 24, this is where the second item begins.
So 43 - 24 gives us the unpadded length of item 2 (19). The third item
starts at pad_to_8(endpoint[1]) and is in our case 48. The length of item
three is therefor 68 - 48 = 20 bytes. Note that in this example we are
talking about strings where the 0 termination is included in the item size.
8. Sorted Index Table
The sorted index table is a list of direct offsets to the fields. It is
binary sorted using the field names. This means that we can use it for
name lookups with a O(log(n)) complexity instead of doing linear searches.
The section data is composed directly out of the int32 array of offsets.
No extra data is stored in this section. All offsets have the first data
section as their base.
9. End Of Data Section
This section terminates the section stream. No other data is stored in this
section.
10. Target Information Section
The target information section is used to hold the target team, handler,
port information for message delivery. As this data is not relevant when
handling disk stored messages only, the format of this section is not
discussed here.
*/
@@ -0,0 +1,154 @@
<HTML>
<HEAD>
<TITLE>BClipboard Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BClipboard Use Cases and Implementation Details:</H1>
<P>This document describes the BClipboard interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BClipboard Interface</A></LI>
<LI><A HREF="#usecases">BClipboard Use Cases</A></LI>
<LI><A HREF="#implement">BClipboard Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BClipboard Interface:</H2>
<P>The BClipboard class provides an interface to a named, system-wide, temporary storage resource.
Access to the system clipboard is provided by the be_clipboard variable provided by a BApplication object (or by constructing a clipboard with the name "system").
The best source of information for the BClipboard interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Clipboard.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BClipboard Use Cases:</H2>
<P>The following use cases cover the BClipboard functionality:</P>
<OL>
<LI><P><B>Construction:</B> A BClipboard will accept one or two arguments to construction.
A name is required for identifying the clipboard. The discard argument indicates whether the
clipboard data should be discarded between boots. Te discard argument defaults to false, however
this is meaningless since functionality has not been implemented to maintain clipboard data
between boots.
After construction, the queue is empty.</P></LI>
<LI><P><B>Destruction:</B> The destructor destroys the BClipboard object, however the system-wide clipboard itself is unaffected.</P></LI>
<LI><P><B>Writing to clipboard 1:</B>
The normal procedure for writing data consists of the following: locking the clipboard via Lock(), clearing the
data via Clear(), adding data to the clipboard message, committing the data via Commit(), and unlocking the
clipboard via Unlock().
</P></LI>
<LI><P><B>Writing to clipboard 2:</B>
The data which is to be written is not added directly to the BClipboard object, but is added to the data
message for the BClipboard. The message is obtained by calling BClipboard::Data(). Data is added in fields
of type B_MIME_TYPE. The name of the field corresponds to the MIME type of the data. If multiple fields are
added, they should contain the same data, but formatted for different MIME types.
</P></LI>
<LI><P><B>Writing to clipboard 3:</B>
In the event that one wishes to back out of writing process before calling Commit(), Revert() must be called.
Otherwise, the changes to the clipboard remain in the BClipboard object.
</P></LI>
<LI><P><B>Reading from clipboard 1:</B>
The normal procedure for reading data consists of the following: locking the clipboard via Lock(), obtaining
the data from the clipboards data message, and unlocking the clipboard via Unlock().
</P></LI>
<LI><P><B>Reading from clipboard 2:</B>
The data message is obtained from a call to BClipboard::Data(). Data is obtained from the message by using
BMessage::FindData for a specified MIME type.
</P></LI>
<LI><P><B>Reading from clipboard 3:</B>
The data is uploaded from the system when Lock() is called, therefore any data which is written to the clipboard
between the calls to Lock() and Data() will not be included in the data message.
</P></LI>
<LI><P><B>Reading from clipboard 4:</B>
It is permissible to Unlock() the clipboard before calling FindData on the data message.
</P></LI>
<LI><P><B>Clearing:</B>
The Clear() function is used to remove all data from the clipboard and is used before adding new data which is
to be written to the clipboard. Clear() returns B_ERROR if the BClipboard is not locked, and returns B_OK if
it is locked.
</P></LI>
<LI><P><B>Committing:</B>
The Commit() function is used to upload data from the BClipboard to the system. The data is immediately
available to other applications once Commit() has been called. Commit() returns B_ERROR if the BClipboard
is not locked, and returns B_OK if it is locked.
</P></LI>
<LI><P><B>Revert:</B>
The Revert() function is used to synchronize the data in the BClipboard to the system. This is only needed in
case one begins to modify the data message and wishes to back out of the changes. Revert() returns B_ERROR if
the BClipboard is not locked, and returns B_OK if it is locked.
</P></LI>
<LI><P><B>Accessing data:</B>
Data() is used to obtain a pointer to the BClipboard's data message. One is expected to read and write data
directly to the message, but the message must not be freed or dispatched. Data() returns NULL if the
BClipboard is not locked.
</P></LI>
<LI><P><B>Accessing a data source:</B>
DataSource() is used to obtain a BMessenger pointed at the BApplication which last committed data to the
clipboard. There is no requirement for the the BClipboard to be locked when calling DataSource().
</P></LI>
<LI><P><B>Obtaining a count:</B>
The count refers to the number of times that data has been uploaded to the clipboard.
There are two count functions. SystemCount() returns an up to date count which is obtained from the system.
Count() returns a cached count. The cached count is set to zero upon creation
of the BClipboard, and is updated when Lock() or Commit() is called.
</P></LI>
<LI><P><B>Locking:</B>
Lock() is used to upload data from the system into the BClipboard object and prevent other threads in the
application from using it. It must be called before reading or writing data to the BClipboard. It blocks
if the BClipboard is already locked. The return value is true if the BClipboard is successfully locked, or
false if the BClipboard was deleted while Lock() was blocked.
</P></LI>
<LI><P><B>Unlocking:</B>
Unlock() is used to unlock the BClipboard and allow other threads in the application to use it.
</P></LI>
<LI><P><B>Checking lock status:</B>
IsLocked() returns true if the BClipboard is locked by the current thread, and false if it is not lockedi or is locked by another thread.
</P></LI>
<LI><P><B>Checking clipboard name:</B>
Name() returns a string containing the name of the clipboard. It is not necessary for the BClipboard to be
locked when calling Name().
</P></LI>
<LI><P><B>Watching a clipboard:</B>
StartWatching and StopWatching are used to enable and disable watching of a clipboard. When the clipboard is
changed, a B_CLIPBOARD_CHANGED message is sent to the target specified in the call to StartWatching.
</P></LI>
</OL>
<A NAME="implement"></A><H2>BClipboard Implementation:</H2>
<P>
The BClipboard class is implemented via a message passing system between the BClipboard, the Registrar, and
the Clipboard Handler associated with the Registrar. Details of the message passing protocol are listed in the
Registrar documentation.
</P>
</BODY>
</HTML>
@@ -0,0 +1,50 @@
<HTML>
<HEAD>
<TITLE>BCursor Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BCursor Use Cases and Implementation Details:</H1>
<P>This document describes the BCursor interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BCursor Interface</A></LI>
<LI><A HREF="#usecases">BCursor Use Cases</A></LI>
<LI><A HREF="#implement">BCursor Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BCursor Interface:</H2>
<P>The BCursor class is a simple class used to represent a mouse cursor as an object instead of an array of pixel data. The best source of information for the BCursor interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Cursor.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BCursor Use Cases:</H2>
<P>The following use cases cover the BCursor functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> The first BCursor constructor requires a pointer to the pixel data. The format for the pixel data is described
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Cursor.html#Cursor_Data_Format">here in the Be Book</A>.
This pixel data is used to initialize the BCursor, but BCursor does not take ownership of the data, therefore you are responsible for freeing the memory after construction.</P></LI>
<LI><P><B>Construction 2:</B> The second BCursor constructor requires a BMessage as an archive, however BCursor does not currently support archiving. Do not use this constructor.</P></LI>
<LI><P><B>Destruction:</B> This releases all resources used by the BCursor.</P></LI>
<LI><P><B>Instantiate:</B> This always returns NULL since it relies on the second constructor (which is not currently supported). If it were implemented, this would return a new BArchivable consisting of a BCursor created from the archive passed in as an argument. </P></LI>
</OL>
<A NAME="implement"></A><H2>BCursor Implementation:</H2>
<P>All meaningful work of the BCursor is implemented in the first constructor. The constructor establishes a link with the app_server and sends it the pixel data. The app_server provides the BCursor with a token which identifies the pixel data. When BApplication::SetCursor(BCursor) is called, it must get the needed cursor data by obtaining the BCursor's token (BApplication is a friend of BCursor) and using the token to request the data from the app_server. Note that BCursor does not internally store the pixel data.</P>
</BODY>
</HTML>
@@ -0,0 +1,123 @@
<HTML>
<!-- $Id: BMessageFilterUseCases.html 449 2002-07-26 03:06:04Z jrand $ -->
<HEAD>
<TITLE>BMessageFilter Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMessageFilter Use Cases and Implementation Details:</H1>
<P>This document describes the BMessageFilter interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMessageFilter Interface</A></LI>
<LI><A HREF="#usecases">BMessageFilter Use Cases</A></LI>
<LI><A HREF="#implement">BMessageFilter Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMessageFilter Interface:</H2>
<P>The BMessageFilter class is a simple class for processing incoming BMessage's before
they are dispatched to a BLooper. The best source of information for the BMessageFilter interface
can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/MessageFilter.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMessageFilter Use Cases:</H2>
<P>The following use cases cover the BMessageFilter functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BMessageFilter can be created by specifying a message_delivery
option, a message_source option, a command code and an optional filter function. These
options are used to determine the messages on which the filter will act and the filter itself
(see the "Filter" use cases).</P></LI>
<LI><P><B>Construction 2:</B> A BMessageFilter can be created by specifying a message_delivery
option, a message_source option and an optional filter function. These options are used to
determine the messages on which the filter will act and the filter itself (see the "Filter" use
cases).</P></LI>
<LI><P><B>Construction 3:</B> A BMessageFilter can be created by specifying a command code
and an optional filter function. These options are used to determine the messages on which the
filter will act and the filter itself (see the "Filter" use cases).</P></LI>
<LI><P><B>Construction 4:</B> A BMessageFilter can be constructed by use of a copy constructor
which can take a reference to or a pointer to another BMessageFilter. The new BMessageFilter
will have all the options of the source BMessageFilter when that source filter was constructed.
Any other state of the source BMessageFilter that it has accumulated after construction is not
copied to the new filter.</P></LI>
<LI><P><B>Assignment:</B> A BMessageFilter can be assigned the attributes of a source
BMessageFilter by the use of the assignment operator. The target BMessageFilter will have all
the options of the source BMessageFilter when that source filter was constructed. Any other
state of the source BMessageFilter that it has accumulated after construction is not copied
to the new filter.</P></LI>
<LI><P><B>Destruction:</B> When a BMessageFilter is deconstructed, the BMessageFilter releases
any shared resources it may have allocated.</P></LI>
<LI><P><B>Command:</B> When Command() is used on a BMessageFilter, the command code specified
at construction time for this filter is returned. If a BMessageFilter was not constructed
with a specific command code, this member function does not return a valid result.</P></LI>
<LI><P><B>FiltersAnyCommand:</B> When FiltersAnyCommand() is called on a BMessageFilter, it
returns true if a command code was not specified at construction time for this filter. It
returns false if a command code was specified at construction time. The Command() member
function (see above use case) is only valid when FiltersAnyCommand() returns false.</P></LI>
<LI><P><B>Looper:</B> The Looper() member function returns a pointer to the BLooper (or BHandler)
to which this filter has been added. If the filter has not been added to a BLooper, NULL is
returned. The member functions BLooper::AddCommonFilter() or BHandler::AddFilter() can be
used to add the filter to a looper (see use cases for BLooper and BHandler for details about
adding a filter).</P></LI>
<LI><P><B>MessageDelivery:</B> The MessageDelivery() member function returns the message delivery
value that was specified at construction time for this filter. The possible values are
B_DROPPED_DELIVERY, B_PROGRAMMED_DELIVERY and B_ANY_DELIVERY. If no message delivery value
was specified at construction time, B_ANY_DELIVERY is returned.</P></LI>
<LI><P><B>MessageSource:</B> The MessageSource() member function returns the message source
value that was specified at construction time for this filter. The possible values are
B_LOCAL_SOURCE, B_REMOTE_SOURCE and B_ANY_SOURCE. If no message source value
was specified at construction time, B_ANY_SOURCE is returned.</P></LI>
<LI><P><B>Filter 1:</B> The filter can be applied for a message by passing the message and the
target BHandler which has received that message to the Filter() member function. This member
function returns B_DISPATCH_MESSAGE or B_SKIP_MESSAGE to the caller. The actual impact
of these filter results is dependent on the BLooper and BHandler behaviour (see the use cases for
these classes for more details).</P></LI>
<LI><P><B>Filter 2:</B> If a filter function was not supplied on construction of the
BMessageFilter, then the Filter() member function determines the result of the filter. If the
Filter() member has been overridden in a derived class, the result depends on the behaviour of
this derived class. If the class has not been overridden and no filter function was provided
on construction, the B_DISPATCH_MESSAGE is returned. If a filter function was provided on
construction, then the filter function will be called and the Filter() member will return what
this filter function returns.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMessageFilter Implementation:</H2>
<P>The implementation of the BMessageFilter is pretty simple. It is mainly a container for
properties of the filter itself and a few simple methods for getting and setting these
properties.</P>
<P>The actual act of dispatching or skipping the message as dictated by the filter is implemented
in BLooper or BHandler. The BMessageFilter just provides a mechanism for these classes to
determine which to do. Also the BLooper or BHandler decide whether to pass the message through
the filter on their own. The filter does not look at every message to see whether the source
and delivery of this message is such that it should pass through the filter. Instead, BLooper or
BHandler look at the filter, check the source and delivery options of the filter against the
message itself and call the filter if appropriate. So, the filter is really just a container for
these options and doesn't take action based on them.</P>
</BODY>
</HTML>
@@ -0,0 +1,147 @@
<HTML>
<!-- $Id: BMessageQueueUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
<HEAD>
<TITLE>BMessageQueue Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMessageQueue Use Cases and Implementation Details:</H1>
<P>This document describes the BMessageQueue interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMessageQueue Interface</A></LI>
<LI><A HREF="#usecases">BMessageQueue Use Cases</A></LI>
<LI><A HREF="#implement">BMessageQueue Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMessageQueue Interface:</H2>
<P>The BMessageQueue class is a simple class for managing a queue of BMessages. The best
source of information for the BMessageQueue interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/MessageQueue.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMessageQueue Use Cases:</H2>
<P>The following use cases cover the BMessageQueue functionality:</P>
<OL>
<LI><P><B>Construction:</B> A BMessageQueue does not take any arguments when it is constructed.
After construction, the queue is empty.</P></LI>
<LI><P><B>Destruction:</B> When a BMessageQueue is deconstructed, all BMessages on the queue are
deleted. This implies that all BMessages added to a BMessageQueue must be allocated on the heap
with the new operation. The BMessageQueue is locked before performing the delete to ensure
that the queue doesn't change while it is being deleted. The lock is never released from the
destructor to ensure that any AddMessage() or other members blocking for the lock never
succeed in getting the lock. They will fail once the BMessageQueue is completely deleted.</P></LI>
<LI><P><B>Add Message 1:</B> When AddMessage() is used to put a BMessage on the queue, the
BMessageQueue takes ownership of the BMessage. The BMessage should be created on the heap but
there is no checking to ensure that has happened. The BMessageQueue records the order in
which the BMessages are added to the queue.</P></LI>
<LI><P><B>Add Message 2:</B> No check is performed to see if the BMessage is already part of that
BMessageQueue or any other when AddMessage() is used to put a BMessage on a queue. An attempt to
add a BMessage to a BMessageQueue which already has that same BMessage in it (where equality is
based on the address of the BMessage) will corrupt the queue. An attempt to add a BMessage to a
BMessageQueue when that BMessage is already in another BMessageQueue will corrupt the original
BMessageQueue. It is up to the caller of AddMessage() to use RemoveMessage() to prevent
queue corruption.</P></LI>
<LI><P><B>Add Message 3:</B> BMessage's can be added using AddMessage() from multiple threads
at the same time with no risk of queue corruption. Similarly, RemoveMessage() or NextMessage()
can be executing from another thread while an AddMessage() is started without corrupting the queue.
An AddMessage() attempt will block if another thread has used the Lock() member to lock the
BMessageQueue.</P></LI>
<LI><P><B>Remove Message 1:</B> The RemoveMessage() member takes a BMessage pointer. The
BMessageQueue is searched for this BMessage pointer. If that pointer is in the queue, then it
is removed from the queue. The BMessage is not deleted (note the BeBook implies it is but in
fact it is not). If the BMessage pointer is not on this BMessageQueue, this call has no affect.
After this call completes successfully, it is as though AddMessage() was never called for
this BMessage pointer.</P></LI>
<LI><P><B>Remove Message 2:</B> BMessage's can be removed using RemoveMessage() from multiple
threads at the same time with no risk of queue corruption. Similarly, AddMessage() or
NextMessage() can be executing from another thread while a RemoveMessage() is started without
corrupting the queue. A RemoveMessage() attempt will block if another thread has used the Lock()
member to lock the BMessageQueue.</P></LI>
<LI><P><B>Count Messages:</B> The CountMessages() member function returns the number of BMessage's
in the BMessageQueue. If there are no messages on the queue (an example of this situation is just
after construction), the member returns 0. Note, it is possible for the count to become corrupted
if the situation in Add Message 2 occurs.</P></LI>
<LI><P><B>Is Empty:</B> The IsEmpty() member function returns true if there are no BMessages on the
BMessageQueue. If there are one or more BMessages on the BMessageQueue, it returns false.</P></LI>
<LI><P><B>Find Message 1:</B> The FindMessage() member function is overloaded. If the member
function takes a single int32 argument, it is used to return the BMessage on the queue at a
particular index as indicated by the argument. The first message is at index 0, the second
at index 1 etc. If no message is at that index, NULL is returned.</P></LI>
<LI><P><B>Find Message 2:</B> The other FindMessage() member function takes a single uint32
argument and an optional int32 argument. The first mandatory argument specifies the "what" code
for the BMessage being searched for. The second optional argument specifies what occurance of
that "what" code in a BMessage on the queue should be returned. If the second argument is not
provided, it is assumed to be 0. If the second argument is 0, the first BMessage that has the
what code provided is returned. If the second argument is 1, the second BMessage that has the
what code provided is returned, etc. If no match is found, NULL is returned.</P></LI>
<LI><P><B>Lock 1:</B> The Lock() member function blocks until this thread can acquire exclusive
access to the BMessageQueue. Only one thread can hold the lock at any one time. A thread can
acquire the Lock() multiple times but release it the same number of times. While a thread holds
the lock, other threads will not be able to perform AddMessage(), RemoveMessage() or NextMessage().
Any threads attempting to do so will block until the BMessageQueue is unlocked.</P></LI>
<LI><P><B>Lock 2:</B> The Lock() member function returns true if the lock has successfully been
acquired. It will return false if an unrecoverable error has occurred. An example of such an
error would be deleting the BMessageQueue.</P></LI>
<LI><P><B>Unlock:</B> The Unlock() member function releases a lock on the BMessageQueue. If the
thread no longer holds any locks on the BMessageQueue, other threads are free to acquire the
BMessageQueue lock or call member functions like AddMessage(), RemoveMessage(), NextMessage() or
delete the BMessageQueue.</P></LI>
<LI><P><B>Next Message 1:</B> The NextMessage() member function removes the BMessage which is the
oldest on the queue. It returns that BMessage to the caller. After the call completes, the
BMessage is no longer on the queue and the next oldest BMessage is at the front of the queue
(ie next to be returned by NextMessage()).</P></LI>
<LI><P><B>Next Message 2:</B> BMessage's can be removed using NextMessage() from multiple
threads at the same time with no risk of queue corruption. Similarly, AddMessage() or
RemoveMessage() can be executing from another thread while a NextMessage() is started without
corrupting the queue. A NextMessage() attempt will block if another thread has used the Lock()
member to lock the BMessageQueue.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMessageQueue Implementation:</H2>
<P>Internally, the BMessageQueue uses a BLocker to ensure that member functions like AddMessage(),
RemoveMessage() and NextMessage() do not corrupt the queue when used from multiple threads. The
same BLocker is used to implemented the Lock() and Unlock() members.</P>
<P>Testing with a debugger shows that the queue is implemented using a "link" pointer in the
BMessage class itself. Each BMessage is also a singly linked list which represents the queue.
All the BMessageQueue needs is a pointer to the BMessage which starts the list. For performance
reasons, it is worth maintaining a pointer to the BMessage at the end of the list and the count
of the number of elements in the list. If these are not maintained, adding an element to the
list will get slower as the number of elements grows and the cost to determine the number of
elements in the list will be high.</P>
<P>Because the BMessageQueue uses the link pointer which is a private part of the BMessage class,
the BMessageQueue must be a friend class of BMessage. Checking the headers, this is in fact the
case in Be's implementation. Although friendship in classes can cause some pretty serious long
term headaches if abused (and I am not convinced that this is an abuse), the OpenBeOS
implementation will follow the same implementation for now.</P>
</BODY>
</HTML>
@@ -0,0 +1,407 @@
<HTML>
<!-- $Id: BPropertyInfoUseCases.html 814 2002-08-19 05:26:56Z jrand $ -->
<HEAD>
<TITLE>BPropertyInfo Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BPropertyInfo Use Cases and Implementation Details:</H1>
<P>This document describes the BPropertyInfo interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BPropertyInfo Interface</A></LI>
<LI><A HREF="#usecases">BPropertyInfo Use Cases</A></LI>
<LI><A HREF="#implement">BPropertyInfo Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BPropertyInfo Interface:</H2>
<P>The BPropertyInfo class is a simple class for describing the scripting interface which a
BHandler provides. It makes implementing the ResolveSpecifier() hook function easier to implement.
One source of information for the BPropertyInfo interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/PropertyInfo.html">here in the Be Book</A>.
Unfortunately, details of some changes to this interface introduced in BeOS 4 does not seem to have
made it into the BeBook. For the latest, refer to the
<A HREF="file:///boot/develop/headers/be/app/PropertyInfo.h">PropertyInfo.h</A> header file or the
<A HREF="http://www.acm.uiuc.edu/bug/Be%20Book/Release_Notes/R4RN_AppKit.html">BeOS 4 Developer Release Notes</A>.
</P>
<A NAME="usecases"></A><H2>BPropertyInfo Use Cases:</H2>
<P>The following use cases cover the BPropertyInfo functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BPropertyInfo can be created with 0 arguments. In this case,
it will not have any property_info or value_info structures associated with it. The only
way to initialize it would be to Unflatten() a flattened BPropertyInfo instance (see Unflatten
use cases).</P></LI>
<LI><P><B>Construction 2:</B> A BPropertyInfo can be created with a single property_info argument.
In this case, there will be no value_info structure associated with it and the BPropertyInfo
will assume it does not need to de-allocate the property_info structure itself on
destruction.</P></LI>
<LI><P><B>Construction 3:</B> A BPropertyInfo can be created with a property_info argument and
a value_info argument. In this case, the BPropertyInfo will use both of these arguments to
determine its future behaviour. It will assume it does not need to de-allocate the property_info
structure or the value_info structure itself on destruction.</P></LI>
<LI><P><B>Construction 4:</B> A BPropertyInfo can be created with a property_info argument and
a value_info argument and a flag to indicate whether these structres were allocated on the heap.
If the flag is false, it will assume it does not need to de-allocate the property_info structure
or the value_info structure itself on destruction. If the flag is true, it will assume that
the property_info pointer and the value_info pointer and all pointers contained within them (ie
const char * instances) need to be free()'d when the BPropertyInfo is destructed.</P></LI>
<LI><P><B>Destruction:</B> On destruction, a BPropertyInfo class does nothing unless the third
argument (free_on_delete flag) at construction was true. If this argument was true, the
BPropertyInfo class performs a "free()" on the pointers passed in at construction time and all
pointers contained within these structures.</P></LI>
<LI><P><B>Properties:</B> The Properties() member function returns the first argument passed in
at construction time of the BPropertyInfo or NULL if it was constructed with no arguments.</P></LI>
<LI><P><B>Values:</B> The Values() member function returns the second argument passed in
at construction time of the BPropertyInfo or NULL if it was constructed with one or fewer
arguments.</P></LI>
<LI><P><B>Count Properties:</B> The CountProperties() member function returns the number of
elements in the NULL terminated array of property_info structures passed in as the first argument
at construction time. If the BPropertyInfo class was constructed with no arguments, 0 is
returned.</P></LI>
<LI><P><B>Count Values:</B> The CountValues() member function returns the number of
elements in the NULL terminated array of value_info structures passed in as the second argument
at construction time. If the BPropertyInfo class was constructed with one or fewer arguments, 0 is
returned.</P></LI>
<LI><P><B>Fixed Size:</B> The IsFixedSize() method always returns false indicating that a
BPropertyInfo class instance can be flattened but the size of that flattened instance depends on
the state of the BPropertyInfo class itself.</P></LI>
<LI><P><B>Type Code:</B> The TypeCode() method always returns B_PROPERTY_INFO_TYPE ('SCTD')
regardless of the state of the BPropertyInfo class instance indicating that the flattened instance
is of type B_PROPERTY_INFO_TYPE.</P></LI>
<LI><P><B>Allows Type Code:</B> The AllowsTypeCode() method returns false for all passed in type
codes unless B_PROPERTY_INFO_TYPE ('SCTD') is passed in when this method returns true. This
implies that a BPropertyInfo class instance can be unflattened from flattened data of
B_PROPERTY_INFO_TYPE only (NOTE: the Be implementation seems to return true for all values
passed in although that doesn't seem to make much sense).</P></LI>
<LI><P><B>Flattened Size:</B> The FlattenedSize() member function retures the number of bytes
required to store a flattened version of the BPropertyInfo instance. The size will be determined
by the description of the flattened data structure described in the "implementation" section
below.</P></LI>
<LI><P><B>Flatten:</B> The Flatten() member function turns the current BPropertyInfo instance into
a series of bytes which completely describes its state so it can be recreated from it later. The
actual description of this byte representation of BPropertyInfo is described in the "implementation"
section below.</P></LI>
<LI><P><B>Unflatten:</B> The Unflatten() member function takes a passed in series of bytes and
sets the current BPropertyInfo instance into a copy of the BPropertyInfo described by those
bytes (ie a flattened version of a previous BPropertyInfo). The old state of the current
BPropertyInfo is replaced by that described by the flattened representation. The actual description
of this byte representation of BPropertyInfo is described in the "implemenation" section
below.</P></LI>
<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the current state of
the BPropertyInfo instance to standard out for debugging purpose. The actual format of this output
isn't critical but it should describe the state of the object and be easy for a developer to
understand.</P></LI>
<LI><P><B>Find Match:</B> The FindMatch() member function takes a BMessage, a specifier (in the
form of a BMessage), a specifier type (called form, ie B_DIRECT_SPECIFIER), property name and an
index. The member returns -1 if no match can be found. A match will have the "what" code of the
message (not the specifier message) in its command list or have a wildcard command. It will also
have the property name as its property name. And, the specifier type will be listed as a valid
specifier, or the property will have a wildcard specifier. Note, if the index is non-zero, then
only properties with command wildcards will be a match (a wildcard is an empty list of commands,
similarly for specifier type). On a match, the result is a 0 based offset into the array of
properties.</P></LI>
</OL>
<A NAME="implement"></A><H2>BPropertyInfo Implementation:</H2>
<P>There is a key difference between the OpenBeOS BPropertyInfo class and the Be implementation
is support for BeOS R3 compiled executables. The elements in the property_info structure changed
in R4 versus the one which was used in R3. Be did the following to handle this:</P>
<UL>
<LI>The R3 constructor was made private. Existing R3 binaries would use this constructor. This
constructor would use static functions to convert between the old property_info structure passed
from the R3 binary to the new one.</LI>
<LI>A new constructor was introduced in R4. This constructor would be source code compatible with
existing code which compiled on R3. However, when that code was recompiled for R4, this new
constructor would be called because the old one was made private.</LI>
<LI>I expect that work was also done to ensure that the R4 BPropertyInfo class could unflatten
R3 based BPropertyInfo instances. I have not done serious checking on this however.</LI>
</UL>
<P>For the OpenBeOS implementation, we have decided not to implement this R3 compatibility at
this time but we are not going to rule it out. The header file for BPropertyInfo will be changed
to "remove" the R3 compatibility interfaces using an "ifdef R3_compatible". The interfaces will
still appear to the human reader but not be there as far as the compiler is concerned. If we
revise out decision in the future, it will be a simple matter of removing the ifdefs and implement
these R3 compatibility interfaces. For now, we have decided not to do this because:</P>
<UL>
<LI>There is no binary compatibility between R3 and R4 of BeOS Intel. The ability for OpenBeOS
to be binary compatible with these old R3 interfaces buys us nothing on Intel.</LI>
<LI>There is binary compatibility with R3 with R4 and R5 on BeOS PPC. Without these interfaces
implemented, it may not be possible for R3 compiled binaries for PPC to operate against the
OpenBeOS implementation. However, there are no specific plans to support PPC. Also, the informal
PPC ports that have been discussed were considering using the gcc toolset which I believe precludes
any backward compatibility, even with R5 binaries.</LI>
<LI>There is some risk that a flattened BPropertyInfo instance on someone's hard disk was created
against the old R3 implementation. The OpenBeOS implementation may not be able to read this
flattened BPropertyInfo. However, we believe the chance of this happening to be very low and
not worth the cost of the implementation.</LI>
</UL>
<P>The flattened format of BPropertyInfo looks like the following:</P>
<TABLE BORDER=1>
<TR><TH>Section</TH><TH>Size</TH><TH>Description</TH></TR>
<TR><TD ROWSPAN=3>Header</TD><TD>1</TD><TD>Endian flag, 1 for big endian, 0 for little
endian</TD></TR>
<TR><TD>4</TD><TD>Number of property_info elements in the flattened data.</TD></TR>
<TR><TD>4</TD><TD>Set to 3 if there are value_info in the flattened data, 1 otherwise</TD></TR>
<TR><TD ROWSPAN=5>property_info main section, one per property_info element</TD><TD>1 to n</TD><TD>NULL terminated property_name</TD></TR>
<TR><TD>1 to n</TD><TD>NULL terminated usage string.</TD></TR>
<TR><TD>4</TD><TD>The extra_data value</TD></TR>
<TR><TD>4 to 40</TD><TD>Up to 10 commands, each 4 bytes in size. A zero command indicates the end of
the commands.</TD></TR>
<TR><TD>4 to 40</TD><TD>Up to 10 specifiers, each 4 bytes in size. A zero specifier indicates the end of
the specifiers.</TD></TR>
<TR><TD ROWSPAN=2>property_info types section, one per property_info element</TD><TD>4 to 40</TD>
<TD>Up to 10 types, each 4 bytes in size. A zero type indicates the end of the types.</TD></TR>
<TR><TD>4 to n</TD><TD>A series of 0 to 15 name and type pairs from the "compound types" or ctypes
section of the property_info structure. Each is made up of a null terminated name followed by a
4 byte type. There are up to 15 because there is a three element array of five name/type pairs.
If fewer than 5 elements appear in any one set of the the three elements, four zero bytes are
in the stream where the "name" would be. Also, to indicate that there are fewer than three
compound types, four zero bytes are in the stream where the first name would be.</TD></TR>
<TR><TD ROWSPAN=1>value_info header, only appears if the flag in the header is set to "3"</TD>
<TD>2</TD><TD>Number of value_info elements in the flattened data.</TD></TR>
<TR><TD ROWSPAN=5>value_info section, one per value_info element</TD><TD>4</TD><TD>The "kind"
of this value_info element.</TD></TR>
<TR><TD>4</TD><TD>The "value" of this value_info element</TD></TR>
<TR><TD>1 to n</TD><TD>A NULL terminated name string</TD></TR>
<TR><TD>1 to n</TD><TD>A NULL terminated usage string</TD></TR>
<TR><TD>4</TD><TD>The "extra_data" of this value_info element</TD></TR>
</TABLE>
<P>The following is some information from Marc Flerackers sent in a series of emails which
describes his investigation into how BPropertyInfo instances are flattened. Note that the
implementation is very much based Marc's implementation elluded to in these messages, although
you will see some differences between the above description and Marc's messages. The above
table describes the actual format as it is implemented today and seems to match Be's
implementation. However, Marc's investigation, implementation and emails were critical to
getting this information and is therefore included here in this document:</P>
<H3>Message 1:</H3>
<P>I spend this morning some time to check how a BPropertyInfo is flattened,
here's the result for BControl (not such a good choice as there are no
compound types, however I added at the bottom how the layout looks if there
are). I'm implementing this now in my own BPropertyInfo class. How is the
OBOS BPropertyInfo class going BTW?<P>
<PRE>
// Header
4 6 chunk count
4 1 version
// Start of property_info chunks, without types
8 "Enabled" name
58 "" usage ("Returns whether or not the BControl is currently enabled.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
8 "Enabled" name
34 "" usage ("Enables or disables the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Label" name
30 "" usage ("Returns the BControl's label.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Label" name
32 "" usage ("Sets the label of the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Value" name
30 "" usage ("Returns the BControl's value.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Value" name
32 "" usage ("Sets the value of the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
// Start of property_info chunks, only types
4 BOOL type
4 0 end type list
4 0 end compound list
4 BOOL type
4 0 end type list
4 0 end compound list
4 CSTR type
4 0 end type list
4 0 end compound list
4 LONG type
4 0 end type list
4 0 end compound list
4 LONG type
4 0 end type list
4 0 end compound list
</PRE>
<P>If there would have been compound types, the layout of the type chunks would
be like this</P>
<PRE>
4 BOOL type
4 0 end type list
5 "name" compound name
4 LONG compound type
4 0 end compound list
</PRE>
<H3>Message 2:</H3>
<P>Layout of a flattened BPropertyInfo with compound members. Value info is
still missing, I will look at it when I implement support for it in my
BPropertyInfo class. BTabView and BRadioButton are coming to cvs soon BTW, I
only have to find some time to write decent Draw functions ^_^.</P>
<PRE>
// Header
4 3 chunk count
4 1 version
// Start of property_info chunks, without types
7 "Suites" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
10 "Messenger" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
13 "InternalName" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
// Start of property_info chunks, only types
4 0 end type list
7 "suites" compound name
4 CSTR compound type
4 0 end compound sub list
9 "messages" compound name
4 SCTD compound type
4 0 end compound sub list
4 0 end compound list
4 MSNG type
4 0 end type list
4 0 end compound list
4 CSTR type
4 0 end type list
4 0 end compound list
</PRE>
<H3>Message 3:</H3>
<P>Some updated information about the flattened BPropertyInfo layout for people
who are interested ^_^.</P>
<PRE>
The header contains flags, not a version
flattened header
4 count
4 flags
0x1 : property_info structs are present
0x2 : value_info structs are present
flattened value_info chunks are appended at the end as follows
a small header
4 count
for every value_info
2 kind
4 value
x name
x usage
4 extra_data
where x is strlen + 1 of course.
</PRE>
<P>Value info structs are used to publish information about non-Be types and
scripting commands btw.</P>
<P>I tested my code against the Be implementation, and the flattened data
matches.</P>
</BODY>
</HTML>
@@ -0,0 +1,48 @@
<HTML>
<HEAD>
<TITLE>PortLink Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>PortLink Use Cases:</H1>
<P>This document describes the PortLink interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">PortLink Interface</A></LI>
<LI><A HREF="#usecases">PortLink Use Cases</A></LI>
</OL>
<A NAME="interface"><H2>PortLink Interface:</H2>
<P>The PortLink class is a lightweight class designed to ease the pain of sending a message to a port. Normal use boils down to creating a PortLink object, setting the message code, attaching any extra data via Attach(), and calling Flush() to send it.
</P>
<P>While this class is designed to facilitate port-based messaging, it does not devise any protocols for such. The recipient will need to know if data is included in a message, for example. Likewise, all extra data must be freed by the recipient.
</P>
<A NAME="usecases"><H2>PortLink Use Cases:</H2>
<P>The following use cases cover the PortLink functionality:</P>
<OL>
<LI><P><B>Construction:</B> A PortLink is created by passing it a port ID. Error-checking is not performed on the port itself, so be sure it is a valid port.
</P></LI>
<LI><P><B>Destruction:</B> When a PortLink is destroyed, any data which is currently attached to a pending message is freed.</P></LI>
<LI><P><B>Creating a message:</B> Creating a message can be as simple as setting the message code (similar to BMessage's <i>what</i> member). Extra data is not required.</P></LI>
<LI><P><B>Attaching Data:</B> Adding extra data is as simple as calling the member function Attach(), which makes a copy of the parameter passed to it. B_ERROR is returned if the no more data can be attached before the message is sent or if the size is invalid. B_NO_MEMORY is returned when the attachments are larger than the target port's capacity.</P></LI>
<LI><P><B>Sending a message:</B> Call Flush(). Whatever opcode has been set will be sent to the target. Optionally, a timeout (in microseconds) of type bigtime_t can be specified. This can be useful in preventing deadlocks if the target has crashed and its port fills up. The function returns B_BAD_VALUE if the target port is invalid.</P></LI>
<LI><P><B>Synchronous Messaging:</B> This one requires a little more care in order to prevent deadlocks. Attachments may be used as with Flush(), but FlushWithReply() will wait until the target replies unless a timeout value is specified in microseconds of type bigtime_t. A return code of B_ERROR indicates an internal data error and your message is intact. If a reply times out, it will return B_TIMED_OUT. If the target port is invalid, B_BAD_VALUE is returned. Otherwise, it returns B_OK.
<P>
<i>Reply Protocol:</i> The target will receive the message with all attached data with one slight modification to the otherwise chosen message protocol - the first item will be a port_id which is the port to which the sender is to reply. All other attached data (if any) immediately follows this port id.
</li>
</OL>
<h6>HTML Documentation Format by Jeremy Rand</h6>
</BODY>
</HTML>
+14
View File
@@ -0,0 +1,14 @@
- Need the ability to save crash reports.
- CLI needs to be more fully implemented.
- General expression evaluation parser. Once implemented, should supplant the primitive one currently used for C/C++ typecasting support, as well as being exposed for user expression input.
- Conditional breakpoint/watchpoints. Contingent on above general expression parser.
- Remote debug interface support.
- Kernel debug support.
- Architecture needs to be able to report back the hardware debugging capabilities/limitations of the target platform.
- WatchpointManager needs to be able to use the aforementioned information from Architecture in order to more intelligently
manage/restrict watchpoint usage (especially once expression watchpoints come into play).
- More complete DWARF3/4 support.
- x86-64 support.
- Support for retrieving/displaying function return values (arch-specific).
- Syntax highlighting in source view.
- Detection of mouse hovering over a variable in SourceView and showing value in tooltip (probably requires expression parsing support).
@@ -0,0 +1,660 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>BPicture specifications</title>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<meta name="author" content="Marc Flerackers([email protected])">
<meta name="description"
content="BPicture specifications for OpenBeOS">
</head>
<body>
<span style="font-weight: bold; text-decoration: underline;"></span>Author:
Marc Flerackers<br>
Revision: 1.4<br>
<span style="font-weight: bold; text-decoration: underline;"></span><span
style="font-weight: bold; text-decoration: underline;"><br>
Picture data</span><br>
<br>
The data of a BPicture is composed of instructions.<br>
<br>
These instructions have a small header, which looks as follows:<br>
<br>
<table cellpadding="2" cellspacing="2" border="1"
style="text-align: left;">
<tbody>
<tr>
<td>int16</td>
<td valign="top">id</td>
<td valign="top">The instruction id</td>
</tr>
<tr>
<td valign="top">int32</td>
<td valign="top">size</td>
<td valign="top">The size of the data</td>
</tr>
</tbody>
</table>
<br>
After this header the data follows. There are two exceptions:
EnterStateChange and EnterFontState. These are used to enclose state and
font changes. For ExitStateChange and ExitFontState there are no
instructions, this is not needed as we know the size of the instruction
block in the header of the Enter* functions.<br>
<br>
These are the known instructions at the moment:<br>
<br>
<table cellpadding="2" cellspacing="2" border="1"
style="text-align: left; width: 100%;">
<tbody>
<tr>
<th valign="top">Id<br>
</th>
<th valign="top">Name<br>
</th>
<th valign="top">Size<br>
</th>
<th valign="top">Data<br>
</th>
</tr>
<tr>
<td valign="top">0x0010<br>
</td>
<td valign="top">MovePenBy<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">BPoint where<br>
</td>
</tr>
<tr>
<td valign="top">0x0100<br>
</td>
<td valign="top">StrokeLine<br>
</td>
<td valign="top">16<br>
</td>
<td valign="top">BPoint start<br>
BPoint end<br>
</td>
</tr>
<tr>
<td valign="top">0x0101<br>
</td>
<td valign="top">StrokeRect<br>
</td>
<td valign="top">16<br>
</td>
<td valign="top">BRect rect<br>
</td>
</tr>
<tr>
<td valign="top">0x0102<br>
</td>
<td valign="top">FillRect<br>
</td>
<td valign="top">16<br>
</td>
<td valign="top">BRect rect<br>
</td>
</tr>
<tr>
<td valign="top">0x0103<br>
</td>
<td valign="top">StrokeRoundRect<br>
</td>
<td valign="top">24</td>
<td valign="top">BRect rect<br>
BPoint radii<br>
</td>
</tr>
<tr>
<td valign="top">0x0104<br>
</td>
<td valign="top">FillRoundRect</td>
<td valign="top">24<br>
</td>
<td valign="top">BRect rect<br>
BPoint radii</td>
</tr>
<tr>
<td valign="top">0x0105<br>
</td>
<td valign="top">StrokeBezier<br>
</td>
<td valign="top">32<br>
</td>
<td valign="top">BPoint[4] control</td>
</tr>
<tr>
<td valign="top">0x0106<br>
</td>
<td valign="top">FillBezier<br>
</td>
<td valign="top">32<br>
</td>
<td valign="top">BPoint[4] control</td>
</tr>
<tr>
<td valign="top">0x010B<br>
</td>
<td valign="top">StrokePolygon<br>
</td>
<td valign="top">4 + point data size + 1<br>
</td>
<td valign="top">int32 numPoints<br>
BPoint *points<br>
bool isClosed<br>
</td>
</tr>
<tr>
<td valign="top">0x010C<br>
</td>
<td valign="top">FillPolygon<br>
</td>
<td valign="top">4 + point data size </td>
<td valign="top">int32 numPoints<br>
BPoint *points<br>
</td>
</tr>
<tr>
<td valign="top">0x010D<br>
</td>
<td valign="top">StrokeShape<br>
</td>
<td valign="top">shape data size<br>
</td>
<td valign="top">shape data, see below </td>
</tr>
<tr>
<td valign="top">0x010E </td>
<td valign="top">FillShape </td>
<td valign="top">shape data size </td>
<td valign="top">shape data, see below </td>
</tr>
<tr>
<td valign="top">0x010F<br>
</td>
<td valign="top">DrawString<br>
</td>
<td valign="top">4 + string data size + 8<br>
</td>
<td valign="top">strlen<br>
char *string<br>
float deltax<br>
float deltay<br>
</td>
</tr>
<tr>
<td valign="top">0x0110 </td>
<td valign="top">DrawPixels<br>
</td>
<td valign="top">56 + pixel data size<br>
</td>
<td valign="top">BRect src<br>
BRect dest<br>
int32 width<br>
int32 height<br>
int32 bytesPerRow<br>
int32 pixelFormat<br>
int32 flags<br>
int32 length of pixel data<br>
pixel data<br>
</td>
</tr>
<tr>
<td valign="top">0x0112<br>
</td>
<td valign="top">DrawPicture<br>
</td>
<td valign="top">12<br>
</td>
<td valign="top">BPoint where?<br>
????<br>
</td>
</tr>
<tr>
<td valign="top">0x0113</td>
<td valign="top">StrokeArc<br>
</td>
<td valign="top">24<br>
</td>
<td valign="top">BPoint center<br>
BPoint radii<br>
float startTheta<br>
float arcTheta<br>
</td>
</tr>
<tr>
<td valign="top">0x0114<br>
</td>
<td valign="top">FillArc<br>
</td>
<td valign="top">24<br>
</td>
<td valign="top">BPoint center<br>
BPoint radii<br>
float startTheta<br>
float arcTheta</td>
</tr>
<tr>
<td valign="top">0x0115<br>
</td>
<td valign="top">StrokeEllipse<br>
</td>
<td valign="top">16<br>
</td>
<td valign="top">BRect rect<br>
</td>
</tr>
<tr>
<td valign="top">0x0116</td>
<td valign="top">FillEllipse</td>
<td valign="top">16<br>
</td>
<td valign="top">BRect rect</td>
</tr>
<tr>
<td valign="top">0x0200<br>
</td>
<td valign="top">EnterStateChange<br>
</td>
<td valign="top">size of state instructions<br>
</td>
<td valign="top">state instructions</td>
</tr>
<tr>
<td valign="top">0x0201</td>
<td valign="top">SetClippingRects</td>
<td valign="top">16 + size of rects<br>
</td>
<td valign="top">clipping_rect bound<br>
clipping_rect *rect</td>
</tr>
<tr>
<td valign="top">0x0202</td>
<td valign="top">ClipToPicture</td>
<td valign="top">7 + 8 + 1 </td>
<td valign="top">zero bytes<br>
BPoint pt<br>
bool clip_to_inverse_picture<br>
</td>
</tr>
<tr>
<td valign="top">0x0203<br>
</td>
<td valign="top">PushState<br>
</td>
<td valign="top">0<br>
</td>
<td valign="top"><br>
</td>
</tr>
<tr>
<td valign="top">0x0204</td>
<td valign="top">PopState</td>
<td valign="top">0<br>
</td>
<td valign="top"><br>
</td>
</tr>
<tr>
<td valign="top">0x0205<br>
</td>
<td valign="top">SetClippingRects </td>
<td valign="top">0 </td>
<td valign="top">This is a shorter instruction for 0 clipping
rects.<br>
</td>
</tr>
<tr>
<td valign="top">0x0300<br>
</td>
<td valign="top">SetOrigin<br>
</td>
<td valign="top">8<br>
</td>
<td valign="top">BPoint pt<br>
</td>
</tr>
<tr>
<td valign="top">0x0301<br>
</td>
<td valign="top">SetPenLocation<br>
</td>
<td valign="top">8<br>
</td>
<td valign="top">BPoint pt<br>
</td>
</tr>
<tr>
<td valign="top">0x0302<br>
</td>
<td valign="top">SetDrawingMode<br>
</td>
<td valign="top">2<br>
</td>
<td valign="top">drawing_mode mode<br>
</td>
</tr>
<tr>
<td valign="top">0x0303</td>
<td valign="top">SetLineMode<br>
</td>
<td valign="top">2 + 2 + 4<br>
</td>
<td valign="top">cap_mode capMode<br>
join_mode joinMode<br>
float miterLimit<br>
</td>
</tr>
<tr>
<td valign="top">0x0304<br>
</td>
<td valign="top">SetPenSize</td>
<td valign="top">4<br>
</td>
<td valign="top">float size<br>
</td>
</tr>
<tr>
<td valign="top">0x0305<br>
</td>
<td valign="top">SetScale<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">float scale</td>
</tr>
<tr>
<td valign="top">0x0306<br>
</td>
<td valign="top">SetForeColor<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">rgb_color color<br>
</td>
</tr>
<tr>
<td valign="top">0x0307<br>
</td>
<td valign="top">SetBackColor<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">rgb_color color</td>
</tr>
<tr>
<td valign="top">0x0308<br>
</td>
<td valign="top">SetStipplePattern<br>
</td>
<td valign="top">8<br>
</td>
<td valign="top">pattern p<br>
</td>
</tr>
<tr>
<td valign="top">0x0309<br>
</td>
<td valign="top">EnterFontState<br>
</td>
<td valign="top">size of font instructions</td>
<td valign="top">font instructions</td>
</tr>
<tr>
<td valign="top">0x030A<br>
</td>
<td valign="top">SetBlendingMode<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">source_alpha alphaSrcMode<br>
alpha_function alphaFncMode<br>
</td>
</tr>
<tr>
<td valign="top">0x0380<br>
</td>
<td valign="top">SetFontFamily<br>
</td>
<td valign="top">4 + string data size</td>
<td valign="top">strlen<br>
char *family<br>
</td>
</tr>
<tr>
<td valign="top">0x0381<br>
</td>
<td valign="top">SetFontStyle<br>
</td>
<td valign="top">4 + string data size</td>
<td valign="top">strlen<br>
char style</td>
</tr>
<tr>
<td valign="top">0x0382<br>
</td>
<td valign="top">SetFontSpacing<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">int32 spacing<br>
</td>
</tr>
<tr>
<td valign="top">0x0383<br>
</td>
<td valign="top">SetFontEncoding<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">int32 encoding<br>
</td>
</tr>
<tr>
<td valign="top">0x0384<br>
</td>
<td valign="top">SetFontFlags<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">int32 flags<br>
</td>
</tr>
<tr>
<td valign="top">0x0385<br>
</td>
<td valign="top">SetFontSize<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">float size<br>
</td>
</tr>
<tr>
<td valign="top">0x0386<br>
</td>
<td valign="top">SetFontRotate<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">float rotation<br>
</td>
</tr>
<tr>
<td valign="top">0x0387<br>
</td>
<td valign="top">SetFontShear<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">float shear(is 0 instead of 90?)<br>
</td>
</tr>
<tr>
<td valign="top">0x0389<br>
</td>
<td valign="top">SetFontFace<br>
</td>
<td valign="top">4<br>
</td>
<td valign="top">int32 flags<br>
</td>
</tr>
</tbody>
</table>
<br>
There are a few undocumented instructions:<br>
<br>
<table cellpadding="2" cellspacing="2" border="1"
style="text-align: left;" width="100%">
<tbody>
<tr>
<td valign="top">0x0388<br>
</td>
<td valign="top">SetFontBPP </td>
<td valign="top">4<br>
</td>
<td valign="top"> int32 bpp (default 8)<br>
</td>
</tr>
</tbody>
</table>
<br>
Not all instructions where checked yet. The SetClippingRects has still
to be documented.<br>
<br>
DrawPicture and ClipToPicture have an index to the sub-picture. In
flattened data, these sub-pictures are stored in front of the main
picture data, when archived to a BMessage, the sub-pictures are
contained in a field called "piclib".<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Shape data</span><br>
<br>
The shape data contained in a BPicture is stored as follows:<br>
<br>
<table cellpadding="2" cellspacing="2" border="1"
style="text-align: left;" width="100%">
<tbody>
<tr>
<td valign="top">int32<br>
</td>
<td valign="top">instruction count<br>
</td>
</tr>
<tr>
<td valign="top" rowspan="1" colspan="1">uint32 *instructions<br>
</td>
<td valign="top" rowspan="1" colspan="1">Each instruction looks
like:<br>
First byte is the instruction id<br>
The next three bytes is the amount of points used*<br>
</td>
</tr>
<tr>
</tr>
<tr>
<td valign="top">int32<br>
</td>
<td valign="top">point count<br>
</td>
</tr>
<tr>
<td valign="top">BPoint *points </td>
<td valign="top">points<br>
</td>
</tr>
</tbody>
</table>
<br>
<table cellpadding="2" cellspacing="2" border="1"
style="text-align: left; width: 100%;">
<tbody>
<tr>
<th valign="top">Id<br>
</th>
<th valign="top">Name<br>
</th>
<th valign="top">Points*<br>
</th>
<th valign="top">Notes<br>
</th>
</tr>
<tr>
<td valign="top">0x80</td>
<td valign="top">MoveTo</td>
<td valign="top"><br>
</td>
<td valign="top">
<ul>
<li>A "MoveTo" instruction doesn't stand alone, but is OR-ed
with a "LineTo" or "BezierTo" instruction<br>
</li>
</ul>
</td>
</tr>
<tr>
<td valign="top">0x10 </td>
<td valign="top">LineTo</td>
<td valign="top">point count in instruction<br>
</td>
<td valign="top">
<ul>
<li>One "LineTo" instruction draws "count" lines</li>
</ul>
</td>
</tr>
<tr>
<td valign="top">0x90 </td>
<td valign="top">MoveTo LineTo</td>
<td valign="top">point count in instruction + 1</td>
<td valign="top">
<ul>
<li>There is one extra point for the "MoveTo", which is not
counted in the instruction.<br>
</li>
</ul>
</td>
</tr>
<tr>
<td valign="top">0x20 </td>
<td valign="top">BezierTo</td>
<td valign="top">point count in instruction</td>
<td valign="top">
<ul>
<li>One "BezierTo" instruction draws "count" lines</li>
</ul>
</td>
</tr>
<tr>
<td valign="top">0xA0 </td>
<td valign="top">MoveTo&nbsp;BezierTo</td>
<td valign="top">point count in instruction + 1</td>
<td valign="top">
<ul>
<li>There is one extra point for the "MoveTo", which is not
counted in the instruction.<br>
</li>
</ul>
</td>
</tr>
<tr>
<td valign="top">0x40 </td>
<td valign="top">Close</td>
<td valign="top">0 </td>
<td valign="top">
<ul>
<li>"Close" can only follow a "LineTo" or "BezierTo" instruction</li>
<li>If an instruction follows "Close", the new instruction is
OR-ed with "Close" and replaces it instruction</li>
<li>A&nbsp;shape never starts with "Close"</li>
</ul>
</td>
</tr>
</tbody>
</table>
<br>
</body>
</html>
@@ -0,0 +1,34 @@
Tests executed on a Duron 1200
ikki:~/projects/current# tests/UnitTester BRegion
------------------------------------------------------------------------------
Tests
------------------------------------------------------------------------------
BRegion::Construction Test
+ PASSED
Clock time: 0 ms
BRegion::Exclude Test
+ PASSED
Clock time: 251 ms
BRegion::Include Test
+ PASSED
Clock time: 260 ms
BRegion::Intersect Test
+ PASSED
Clock time: 102 ms
BRegion::OffsetBy Test
+ PASSED
Clock time: 0 ms
------------------------------------------------------------------------------
Results
------------------------------------------------------------------------------
+ PASSED
As you can see, it may be worth optimizing especially the Exclude and Include methods.
See RegionSupport.cpp (in particular RSub() and ROr()) for more info.
@@ -0,0 +1,30 @@
Tests executed on a Duron 1200
ikki:~/projects/current# tests/UnitTester -r5 BRegion
------------------------------------------------------------------------------
Tests
------------------------------------------------------------------------------
BRegion::Construction Test
+ PASSED
Clock time: 0 ms
BRegion::Exclude Test
+ PASSED
Clock time: 284 ms
BRegion::Include Test
+ PASSED
Clock time: 265 ms
BRegion::Intersect Test
+ PASSED
Clock time: 113 ms
BRegion::OffsetBy Test
+ PASSED
Clock time: 0 ms
------------------------------------------------------------------------------
Results
------------------------------------------------------------------------------
+ PASSED
@@ -0,0 +1,391 @@
<HTML>
<!-- $Id: UnitTestingInfo.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
<HEAD>
<TITLE>Unit Testing Information</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>Unit Testing Information:</H1>
<P>This document describes the "why's" and "how's" of unit testing for the AppKit team of the
OpenBeOS project. Although it is intended for the AppKit team, there is no reason other teams
couldn't use this information to develop a similar unit testing strategy.</P>
<P>The document has the following sections:</P>
<OL>
<LI><A HREF="#what">What is unit testing?</A></LI>
<LI><A HREF="#why">Why is unit testing important?</A></LI>
<LI><A HREF="#when">When should I write my unit tests?</A></LI>
<LI><A HREF="#whattests">What kinds of tests should be in a unit test?</A></LI>
<LI><A HREF="#testframework">What framework is being used to do unit testing for the AppKit?</A></LI>
<LI><A HREF="#frameworkmods">What AppKit specific modifications have been made to this framework?</A></LI>
<LI><A HREF="#futuremods">What framework modifications might be required in the future?</A></LI>
<LI><A HREF="#buildingtests">How do I build the framework and current tests for the AppKit?</A></LI>
<LI><A HREF="#runningtests">How do I run tests?</A></LI>
<LI><A HREF="#writingtests">How do I write tests for my component?</A></LI>
<LI><A HREF="#exampletests">Are there example tests to base mine on?</A></LI>
<LI><A HREF="#threadedtests">How do I write a test with multiple threads?</A></LI>
</OL>
<A NAME="what"></A><H2>What is unit testing?</H2>
<P>Unit testing is the process of showing that a part of a software system works as far as the
requirements created for that part of the system. Unit testing is best if it has the following
characteristics:</P>
<UL>
<LI>The software component is tested in isolation with as little interaction with other software
components as possible.</LI>
<LI>The software component is tested using automated tools so that unit tests can be run with
every build of the software if required.</LI>
<LI>All requirements of the software component are tested as part of the unit tests.</LI>
</UL>
<P>Unit testing is not the only type of testing but is definitely a very important part of any
testing strategy. Following unit testing, software should go through "integration testing" to
show that the components work as expected when put together.</P>
<A NAME="why"></A><H2>Why is unit testing important?</H2>
<P>A basic concept of software engineering is that the cost of fixing a bug goes up by a factor
of 2-10x (depending on the source of the information) the later in the development process it is
found. Unit testing is critical to finding implementation bugs within a particular component as
quickly as possible.</P>
<P>Unit testing will also help to find requirements problems also. If you write the requirements
(or use cases) for your component from the BeBook, hopefully the BeBook and your use cases will
match the actual Be implementation. A good way to confirm that the BeBook documentation matches
Be's implementation is to write your unit tests and run them against the original Be code.</P>
<P>Unit tests will also continue to be maintained and run in the future also. As the mailing
lists obviously show, many people are looking forward to OpenBeOS post-R1 when new features
will be introduced above and beyond BeOS R5. These unit tests will be critical to ensuring that
any new feature or even just a bug fix doesn't break existing functionality.</P>
<P>Speaking of bug fixes, consider adding unit tests for any bugs you identify that slipped
through your original unit test suite. This will ensure that this bug or a similar one is not
re-introduced in the future.</P>
<P>Finally, unit testing is not the be all, end all of testing. As mentioned above, integration
testing must be done to show that software components work together. If all unit tests cover
all requirements and have run successfully against all components, then a failure has to be
due to a bug in the interaction of two or more known working software components.</P>
<A NAME="when"></A><H2>When should I write my unit tests?</H2></LI>
<P>As the AppKit process document describes the recommended order for implementing a component
is:</P>
<OL>
<LI>Write an interface specification</LI>
<LI>Write the use case specifications</LI>
<LI>Write the unit tests</LI>
<LI>Write an implementation plan</LI>
<LI>Write the code</LI>
</OL>
<P>Please see the AppKit process document for more details about the entire sequence. The unit
test are to be written once the use cases are written and before any implementation work is
done. The use cases must be done because they determine what the tests will be. You need to
write as many tests are required so that all use cases for that component are tested. The use
cases should be detailed enough that you can write your unit tests from them.</P>
<P>The unit tests are to be done before implementation for a very good reason. You should be able
to run these unit tests against the Be implementation and confirm that they all pass. If they do
not pass, then either there is a bug in the unit test itself or you have found a difference
between your use cases and the actual implementation. Even if your use cases match the BeBook,
if that is not how the actual Be implementation works, we must match the current implementation and
not the BeBook. You should go back and modify the use case. Change the use case so that it
matches Be's implementation and consider adding a note indicating this doesn't match the
BeBook.</P>
<P>Imagine if you completed the implementation and then wrote and ran the unit tests. If you run
the tests against your implementation and Be's implementation, you will notice the test passes
for your code but fails on Be's. At this point, you will have to change the implementation, change
the unit test and change the use case which is more work that if you write the unit tests before
the implementation. Worse, if you only ran the unit tests against your implementation and not
Be's, you may not notice the problem at all.</P>
<A NAME="whattest"></A><H2>What kinds of tests should be in a unit test?</H2>
<P>The unit tests you write should cover all the functionality of your software module. That
means your unit tests should include:</P>
<UL>
<LI>All standard expected functionality of the software component</LI>
<LI>All error conditions handled by the software component</LI>
<LI>Interaction with software components which cannot be decoupled from the target software
component</LI>
<LI>Concurrency tests to show that a software component which is expected to be thread safe (most
things are under BeOS) is safe and free from deadlocks.</LI>
</UL>
<A NAME="testframework"></A><H2>What framework is being used to do unit testing for the AppKit?</H2>
<P>The AppKit team has chosen to use CppUnit version 1.5 as the basis of all of our unit tests.
This framework provides very useful features and ensures that all unit tests for AppKit code
are consistent and can be executed from a single environment.</P>
<P>There are two key components to the framework. First, there is a library called libCppUnit.so
which provides all the C++ classes for defining your own testcases. Secondly, there is an
executable called "TestRunner" which is capable of executing a set of testcases.</P>
<P>For more information on CppUnit, please refer to
<A HREF="http://cppunit.sourceforge.net/">this website</A>
<A NAME="frameworkmods"></A><H2>What AppKit specific modifications have been made to this framework?</H2>
<P>The following are the modifications that have been introduced into the CppUnit v1.5
framework:</P>
<UL>
<LI>A makefile has been added for the library and the TestRunner.</LI>
<LI>Some "bugs" in CppUnit v1.5 which lead to it not compiling under BeOS v5.</LI>
<LI>The TestRunner has been modified to support BeOS based addons. Each test which you can
select from the TestRunner is found in the "add-ons" directory at runtime. The original
TestRunner required you to change the TestRunner when new tests were added to it.</LI>
<LI>Changed the output from TestRunner. The output includes a name of the test being run and
a run time for the test in microseconds.</LI>
<LI>Changed the arguments of the assert functions in the TestCase class from std::string to
const char *'s due to apparent concurrency problems with std::string under BeOS when testing
threaded tests.</LI>
<LI>Added locking to the TestResults class so that multiple threads can safely add result
information at the same time for a single test.</LI>
<LI>The ThreadedTestCaller class was written to allow us to write tests which contain multiple
threads. This is an important class because many BeOS components are thread safe and we need
to confirm that the OpenBeOS implementation is also thread safe.</LI>
</UL>
<P>This is the list of the important modifications done to CppUnit v1.5 at the time this document
is being written. For the latest information about modifications to CppUnit, check the code
which can be found in the OpenBeOS CVS repository.</P>
<A NAME="futuremods"></A><H2>What framework modifications might be required in the future?</H2>
<P>This framework will have to evolve as our needs grow. The main issues I think we need to
solve are:</P>
<UL>
<LI>The format of the test name is an encoded string representing the class definition of the
test class from gcc. It is not a very readable format but given that the test class is often
a template class and you would like different names for different instances of the template,
this seemed the best compromise. Suggestions welcome.</LI>
<LI>The threaded test support added into CppUnit forces you to specify the entry point for each
thread in your test. If you are doing a test with a BLooper or a BWindow, these classes start
a thread of their own. This thread will not be started through the standard entry point so
doing "assert's" from one of these threads will not work. Perhaps we need TestBLooper and
TestBWindow classes which will work with the assert's.</LI>
</UL>
<P>If you find you need some other features, feel free to add them to CppUnit.</P>
<A NAME="buildingtests"></A><H2>How do I build the framework and current tests for the AppKit?</H2>
<P>As of writing this document, you can build the framework and all the current AppKit tests
by performing the following steps:</P>
<OL>
<LI>Checkout the "app_kit" sources or the entire repository from the OpenBeOS CVS repository.
There is information at the OpenBeOS site about how to access the CVS repository.</LI>
<LI>In a terminal, "cd" into the "app_kit" directory in the CVS files you checked out.</LI>
<LI>Type "make".</LI>
</OL>
<P>Note that the build system for OpenBeOS is moving to jam so these steps may become obsolete.
When you the make has finished, you should find the following files:</P>
<UL>
<LI><CODE>app_kit/test/CppUnit/TestRunner</CODE> - this is the executable to use to execute
tests.</LI>
<LI><CODE>app_kit/test/CppUnit/lib/libCppUnit.so</CODE> - this is CppUnit library which your tests
must link against.</LI>
<LI><CODE>app_kit/test/CppUnit/lib/libopenbeos.so</CODE> - this is library which contains OpenBeOS
implementation of some Be classes (usually found in libbe.so, called libopenbeos.so to avoid a name
clash at runtime).</LI>
<LI><CODE>app_kit/test/add-ons/BAutolockTests</CODE> - this is the addon which contains the tests
which are run against the Be and OpenBeOS implementation of BAutolock.</LI>
<LI><CODE>app_kit/test/add-ons/BLockerTests</CODE> - this is the addon which contains the tests
which are run against the Be and OpenBeOS implementation of BLocker.</LI>
<LI><CODE>app_kit/test/add-ons/BMessageQueueTests</CODE> - this is the addon which contains the tests
which are run against the Be and OpenBeOS implementation of BMessageQueue.</LI>
</UL>
<P>These are the key files which ensure that the tests can be run.</P>
<A NAME="runningtests"></A><H2>How do I run tests?</H2>
<P>You have a few different options for how you run a test or a series of tests. Before you start
however, you must build the code as describe <A HREF="#buildingtests">in this section</A>. Once
it is built, you can run tests any of these ways:</P>
<UL>
<LI>Run "make test" from the app_kit directory. This will lead to all of the tests defined in
app_kit/test/add-ons directory to be run.</LI>
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner -all". This will
lead to all of the tests defined in the app_kit/test/add-ons directory to be run and is the same
as what happens in the "make" example above. However, recompile any code that has changed in the
process.</LI>
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner &lt;TestName&gt;"
where &lt;TestName&gt; is one of the addons found in the "app_kit/test/add-ons" directory. Only
the tests defined in that add-on will be run.</LI>
</UL>
<A NAME="writingtests"></A><H2>How do I write tests for my component?</H2>
<P>The first step to writing your tests is to develop a plan for how you will test the
functionality. For ideas of the kinds of tests you may want to consider, you should reference
<A HREF="#whattests">this section</A>.</P>
<P>Once you know the kinds of tests you want, you need to:</P>
<UL>
<LI><P>For every test you want, define a class which derives from the "TestCase" class in the
CppUnit framework.</P></LI>
<LI><P>Within each test class you define, create a "void setUp(void)" and "void tearDown(void)"
member function if required. If before executing your test, you need to perform some actions,
put those actions in the "setUp()" member. If you need to cleanup after your test, put those
actions in the "tearDown()" member.</P></LI>
<LI><P>Within each test class you define, create a member function which takes "void" and
returns "void". Within this member function, write the code to execute the test. Whenever you
want to ensure that some condition is true during your test, add a line within the member function
that looks like "assert(condition)". For example, if the variable "result" must have the value
B_OK at a particular point in your test, you should add a line which reads
"assert(result = B_OK)".</P></LI>
<LI><P>Create a constructor for all of your test classes that takes a "std::string name" argument
and pass that onto the TestCase parent class. Add whatever actions you need to take in the
constructor.</P></LI>
<LI><P>Create a destructor for all of your test classes and take whatever actions are
appropriate.</P></LI>
<LI><P>Within each test class you define, create a member with the signature
"static Test *suite(void)". For a simple test where only one test needs to be run for this class,
the contents of this member should look like:</P>
<PRE>
return(new TestCaller&lt;ClassName&gt;("", &amp;ClassName::MemberName));
</PRE>
<P>Replace "ClassName" with the name of your test class and "MemberName" with the name
of the member function you defined your test in. If you need to define more than one test to run
from this class, refer to instructions below on how to use the TestSuite class of CppUnit. If you
are creating a threaded test, refer to <A HREF="#threadedtests">this section</A>.</P></LI>
<LI><P>Create one ".cpp" file for defining the "addonTestFunc()" function. This function must
exist in global scope within your test addon. The contents of this ".cpp" file will look something
like:</P>
<PRE>
#include "TestAddon.h"
Test *addonTestFunc(void)
{
TestSuite *testSuite = new TestSuite("&lt;TestSuiteName&gt;");
testSuite-&gt;addTest(&lt;ClassName1&gt;::suite());
testSuite-&gt;addTest(&lt;ClassName2&gt;::suite());
/* etc */
return(testSuite);
}
</PRE>
<P>In the above example, replace &lt;TestSuiteName&gt; with an appropriate name for the group of
tests and &lt;ClassName1&gt; and &lt;ClassName2&gt; with the names of the test classes you have
defined.</P></LI>
<LI><P>Create a build system around a BeIDE project, Makefile or preferrably a jam file which
builds all the necessary code you have written into an addon.</P></LI>
<LI><P>Put this addon into the app_kit/test/add-ons directory and follow the above instructions
for how to run your tests.</P></LI>
</UL>
<A NAME="exampletests"></A><H2>Are there example tests to base mine on?</H2>
<P>There are example tests which you can find in the following directories:</P>
<UL>
<LI><CODE>app_kit/test/lib/application/BMessageQueue</CODE></LI>
<LI><CODE>app_kit/test/lib/support/BAutolock</CODE></LI>
<LI><CODE>app_kit/test/lib/support/BLocker</CODE></LI>
</UL>
<P>There are some things done in these tests which make things a bit more complex, but you may
want to do similar things:</P>
<UL>
<LI>Most tests use a ThreadedTestCaller class even in some situations when there aren't actually
more than one thread in the test.</LI>
<LI>All tests are defined as a template class. The test class is a template of the class to test
(if that makes sense to you). For example, to test both the Be and OpenBeOS BLocker and not
end up with a symbol conflict, the OpenBeOS implementation of BLocker is actually in a namespace
called "OpenBeOS". So, the tests must be run against the classes "::BLocker" and
"OpenBeOS::BLocker". The easiest way to do this was to make the class to be tested a template
and define it for both "::BLocker" and "OpenBeOS::BLocker".</LI>
</UL>
<P>Even with the complexity, I think this code provides a pretty good example of how to write
your tests.</P>
<A NAME="threadedtests"></A><H2>How do I write a test with multiple threads?</H2>
<P>If you have a test which you want to define that requires more than one thread of execution
(most likely a concurrency test of you code), you need to use the ThreadedTestCaller class.
The steps which differ from the above description on how to write a test case are:</P>
<UL>
<LI><P>In your test class, define a member function for each thread you will be starting. All of
these member functions must take "void" and return "void". If all the threads in your test
perform the exact same actions, it is OK to just define one member function. Usually in the
tests I have written, I have called these member functions "TestThread1()", "TestThread2()",
etc.</P></LI>
<LI><P>If your "static Test *suite()" function for your test class, you must return a
ThreadedTestCaller. Imagine that the test class name is "MyTestClass" and you want two threads
which run member functions "TestThread1()" and "TestThread2()". That code would look like:</P>
<PRE>
Test *MyTestClass::suite(void)
{
MyTestClass *theTest = new MyTestClass("");
ThreadedTestCaller&lt;MyTestClass&gt; *threadedTest = new TreadedTestCaller&lt;MyTestClass&gt;("", theTest);
threadedTest-&gt;addThread(":Thread1", &amp;MyTestClass::TestThread1);
threadedTest-&gt;addThread(":Thread2", &amp;MyTestClass::TestThread2);
return(threadedTest);
}
</PRE>
<P>If you need to, you can put a number of ThreadedTestCaller instances into a TestSuite and return
them in the suite() member function. Examples of this can be found in the BLocker and
BMessageQueue test examples.</P></LI>
</UL>
<P>Otherwise the steps are the same as for other tests. The code gets much more complex if you
define your test classes as templates as the examples do.</P>
</FONT>
</BODY>
</HTML>
@@ -0,0 +1,341 @@
<HTML>
<!-- $Id: BDeskbarUseCases.html 1185 2002-09-26 02:21:31Z jrand $ -->
<HEAD>
<TITLE>BDeskbar Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BDeskbar Use Cases and Implementation Details:</H1>
<P>This document describes the BDeskbar interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BDeskbar Interface</A></LI>
<LI><A HREF="#usecases">BDeskbar Use Cases</A></LI>
<LI><A HREF="#implement">BDeskbar Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BDeskbar Interface:</H2>
<P>The BDeskbar class is a simple class for getting information from the deskbar and for modifying
it from your application. The best source of source of information for the BDeskbar interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/Deskbar/Deskbar.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BDeskbar Use Cases:</H2>
<P>The following use cases cover the BDeskbar functionality:</P>
<OL>
<LI><P><B>Construction:</B> A BDeskbar does not take any arguments when it is constructed. The
BDeskbar instance creates a connection to the deskbar in order to get and change its state.</P></LI>
<LI><P><B>Destruction:</B> When a BDeskbar is deconstructed, the application's connection to the
deskbar is closed. However any change to the deskbar's state made through the BDeskbar instance
persists.</P></LI>
<LI><P><B>Add Item 1:</B> The AddItem() member function can be used to take a passed in pointer to
a BView and send it to the deskbar for inclusion in its shelf. This BView must be archivable
and must be exported by the application (for details on how to do this,
<A HREF="http://bedriven.be-in.org/articles/replicant/III_027-stepping%20up%20to%20the%20deskbar.html">this article</A>
may help). The item will be added and the id of the new item will be passed back to the caller
through a pointer to an int32.</P></LI>
<LI><P><B>Add Item 2:</B> The AddItem() member function can be used to add an item to the deskbar
shelf by passing a pointer to an entry_ref. The file pointed to by this entry_ref should be
an addon that exports the symbol "BView *instantiate_deskbar_item()". This entry point is used to
get a BView which it can display in the shelf. More information on this mechanism can be found in
the <A HREF="file:///boot/beos/documentation/Be%20Book/Release%20Notes/Deskbar.html">Deskbar Release Notes</A>
but not in the Be Book proper. The item id of the added item is passed back in an int32 pointer
provided by the caller. NOTE: The source code for the deskbar found in
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/StatusView.cpp?rev=1.5&content-type=text/vnd.viewcvs-markup">TReplicantTray::LoadAddon()</A>
indicates that it also looks for a symbol called "BView *instantiate_deskbar_entry(image_id, entry_ref *)"
first, but there is no documentation on this.</P></LI>
<LI><P><B>Remove Item 1:</B> The RemoveItem() member function takes an integer id and removes it
from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
not running or some communication failure occurs). A B_OK result does not mean that an item was
actually removed.</P></LI>
<LI><P><B>Remove Item 2:</B> The RemoveItem() member function also takes a string name and removes
it from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
not running or some communication failure occurs). A B_OK result does not mean that an item was
actually removed.</P></LI>
<LI><P><B>Count Items:</B> The CountItems() member function takes no arguments. It returns the
number of "items" in the deskbar shelf. For example, the small email icon often found in the
deskbar is one such item.</P></LI>
<LI><P><B>Has Item 1:</B> The HasItem() member function takes a integer id and returns a true or
false value which indicates whether or not an item exists in the deskbar shelf on that id. For
example, the small email icon often found in the deskbar is one such item.</P></LI>
<LI><P><B>Has Item 2:</B> The HasItem() member function also takes a string name parameter and
returns a true or false value which indicates whether or not an item by than name exists in
the deskbar shelf. For example, the small email icon often found in the deskbar is named
"mail".</P></LI>
<LI><P><B>Get Item Info 1:</B> The GetItemInfo() member function takes an integer id and a pointer
to a const char * (ie a string). It checks to see if the id passed in exists in the deskbar and
sets the value of the const char * to point to a allocated buffer which contains the name of the
item which corresponds to this id and the function returns B_OK. Ownership of this allocated
buffer is assigned to the caller of this member function so it is up to the caller to free the
memory. If the id doesn't exist, then it still returns B_OK but the pointer to the string is set
to NULL. If the pointer to the string passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
<LI><P><B>Get Item Info 2:</B> The GetItemInfo() member also takes a string (const char *) name
and a pointer to an int. If the name matches an item in the deskbar shelf, the id of this
item is returned at the location pointed to by the integer pointer and the member returns B_OK.
If the name doesn't match an item in the deskbar shelf, the id is set to -1. If the pointer
passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
<LI><P><B>Frame:</B> The Frame() member function returns a BRect which describes the location and
size of the deskbar on the screen.</P></LI>
<LI><P><B>Location:</B> The Location() member function returns one of B_DESKBAR_TOP,
B_DESKBAR_BOTTOM, B_DESKBAR_LEFT_BOTTOM, B_DESKBAR_RIGHT_BOTTOM, B_DESKBAR_LEFT_TOP or
B_DESKBAR_RIGHT_TOP. The return value describes where the deskbar currently is located. Also,
the Location() member function takes an optional argument which is a pointer to a boolean.
If supplied, the boolean which is pointed to is set to true if the deskbar is expanded and false
otherwise. A deskbar can only be contracted (ie not expanded) when in the left or right top
position.</P></LI>
<LI><P><B>Is Expanded:</B> The IsExpanded() member function returns true if the deskbar is
expanded and false if it is contracted. Note, the deskbar can only be contracted when in
left or right top position.</P></LI>
<LI><P><B>Set Location:</B> The SetLocation() member function takes the same values returned
by the Location() member. The value passed in the first argument sets the position of the deskbar.
If the optional second argument is supplied, it is a boolean which indicates whether or not the
deskbar is expanded (true) or contracted (false). Note, the deskbar can only be contracted when in
left or right top position.</P></LI>
<LI><P><B>Expand:</B> The Expand() member function takes a single boolean argument which sets the
deskbar to expanded (true) or contracted (false) mode. Note, the deskbar can only be contracted
when in left or right top position.</P></LI>
</OL>
<A NAME="implement"></A><H2>BDeskbar Implementation:</H2>
<P>Internally, the BDeskbar uses a BMessenger to communicate with the deskbar itself.
The source code from the OpenTracker project will be used as a reference for this effort.
You can find the deskbar source code here:</P>
<BLOCKQUOTE>
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/</A>
</BLOCKQUOTE>
<P>Specifically, the code which handles communicating with the BDeskbar class can be found
here:</P>
<BLOCKQUOTE>
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&amp;content-type=text/vnd.viewcvs-markup</A>
</BLOCKQUOTE>
<P>The following describes the messages used to communicate between BDeskbar and the deskbar
itself.</P>
<H3>AddItem:</H3>
<P>The AddItem() member sends the following message to the deskbar to add an item from an
archived BView:</P>
<PRE>
BMessage theMsg;
BMessage viewMsg;
theView.Archive(&amp;viewMsg); // This takes the target BView to place in the shelf and archives it into viewMsg
theMsg.what = 'icon'
theMsg.AddMessage("view", &amp;viewMsg); // This puts the archived view in the viewMsg and puts it in the message to the deskbar
</PRE>
<P>Or, the AddItem() member sends the following message to the deskbar to add an item from a file
that exports the "BView *instantiate_deskbar_item(void)" function:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'adon'
theMsg.AddRef("addon", &amp;theAddonRef); // This is the addon which contains the hook function to get the view to add
</PRE>
<P>The /boot/app/Pulse application exports the necessary symbol for this mechanism to work and
is a good candidate to test with.</P>
<P>In either case, the deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.AddInt32("id", theID); // This is the id of the new item
</PRE>
<P>Note that in both cases, the deskbar does not set the what code of the reply. Checking the
source code for
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::AddItem()</A>
confirms this.
<H3>HasItem:</H3>
<P>The HasItem() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'exst'
theMsg.AddInt32("id", theID); // This is the id to check for
// OR, only one of id or name should be in the message
theMsg.AddString("name", theName); // This is the name to check for
</PRE>
<P>The deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.AddBool("exists", IDorNameExists()); // This is a true/false value which indicates whether or not the name/id exists in the shelf
</PRE>
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
for
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemExists()</A>
confirms this.</P>
<H3>GetItemInfo:</H3>
<P>The GetItemInfo() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'info'
theMsg.AddInt32("id", theID); // This is the id to check for
// OR, only one of id or name should be in the message
theMsg.AddString("name", theName); // This is the name to check for
</PRE>
<P>The deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.AddString("name", theName); // This is the name corresponding to the id of the original request
// OR, only one of id or name should be in the response message depending on the request sent
theMsg.AddInt32("id", theID); // This is the id corresponding to the name of the original request
</PRE>
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
for
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemInfo()</A>
confirms this.</P>
<H3>CountItems:</H3>
<P>The CountItems() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'cwnt'
</PRE>
<P>The deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'rply'; // This means reply
theMsg.AddInt32("count", ItemCount()); // This is the number of items in the deskbar shelf
</PRE>
<H3>RemoveItem:</H3>
<P>The RemoveItem() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'remv'
theMsg.AddInt32("id", theID); // This is the id to remove
// OR, only one of id or name should be in the message
theMsg.AddString("name", theName); // This is the name to remove
</PRE>
<P>The deskbar does not send a response.</P>
<H3>Frame:</H3>
<P>The Frame() member sends a standard scripting message to get the frame from the deskbar. It
sends a B_GET_PROPERTY message to the deskbar asking for the "Frame" property specifying the
window by name. The window name is "Deskbar".</P>
<P>The response from deskbar has a what code of B_REPLY and a BRect describing the frame in a
value called "result". This is standard BeOS scripting.</P>
<H3>Location:</H3>
<P>The Location() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'gloc'; // This means get location
</PRE>
<P>The deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'rply'; // This means reply
theMsg.AddInt32("location", DeskbarLocation()); // This is the number which represents the location of the deskbar
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
</PRE>
<H3>IsExpanded:</H3>
<P>The IsExpanded() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'gexp'; // This means get expanded state
</PRE>
<P>The deskbar responds with a message which looks like:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'rply'; // This means reply
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
</PRE>
<H3>SetLocation:</H3>
<P>The SetLocation() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'sloc'; // This means set location
theMsg.AddInt32("location", newLocation); // This is the number which represents the location of the deskbar
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
</PRE>
<P>The deskbar does not send a reply to this message.</P>
<H3>Expand:</H3>
<P>The Expand() member sends the following message to the deskbar:</P>
<PRE>
BMessage theMsg;
theMsg.what = 'sexp'; // This means set expanded state
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
</PRE>
<P>The deskbar does not send a reply to this message.</P>
</BODY>
</HTML>
@@ -0,0 +1,89 @@
<HTML>
<!-- $Id: BPolygonUseCases.html 1727 2002-10-28 02:50:08Z jrand $ -->
<HEAD>
<TITLE>BPolygon Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BPolygon Use Cases and Implementation Details:</H1>
<P>This document describes the BPolygon interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BPolygon Interface</A></LI>
<LI><A HREF="#usecases">BPolygon Use Cases</A></LI>
<LI><A HREF="#implement">BPolygon Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BPolygon Interface:</H2>
<P>The BPolygon class is used to hold information about a shape composed of a series of straight
lines (ie a polygon). On its own, it just describes the shape and can only be drawn by passing
it to a BView. The best source of source of information for the BPolygon interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Interface%20Kit/Polygon.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BPolygon Use Cases:</H2>
<P>The following use cases cover the BPolygon functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BPolygon can be constructed without passing it any arguments. When
this is done, the polygon will have no points in it (ie no shape) until they are added through
AddPoints().</P></LI>
<LI><P><B>Construction 2:</B> A BPolygon can be constructed by passing it a pointer to an existing
BPolygon (ie a copy constructor). The resulting copy will have the exact same state as the
one passed in. That means it will have the same number of points in the same locations resulting
in the same shape.</P></LI>
<LI><P><B>Construction 3:</B> A BPolygon can be constructed by passing it a pointer to an array of
BPoints and an integer which describes the number of points in that array. The BPolygon will be
constructed such that it holds the shape described by that array of points.</P></LI>
<LI><P><B>Destruction:</B> When a BPolygon is deconstructed any memory allocated in order to hold
the state of the BPolygon is freed and the state of the polygon is lost.</P></LI>
<LI><P><B>Add Points:</B> The AddPoints() member function appends a number of passed in points to
the existing set of points already in the polygon. It takes a pointer to an array of BPoints and
an integer count of the number of points to append. This is similar to the "Construction 3" use
case except in that case there is no existing points so the passed in points describe the entire
polygon.</P></LI>
<LI><P><B>Count Points:</B> The CountPoints() member function returns the number of points which
describe the polygon. The result is an integer.</P></LI>
<LI><P><B>Frame:</B> The Frame() member function returns the smallest BRect which contains all of
the points which describes the BPolygon.</P></LI>
<LI><P><B>Map To:</B> The MapTo() member function applies a translation (ie move) and a scale (ie
grow/shrink) operation to the existing polygon, adjusting all points according to the passed in
rule. The operation to apply depends on two passed in BRect's. The translation and scale
adjustment which turns the first BRect into the second BRect is applied to all points in the
BPolygon.</P></LI>
<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the set of points which
make up the BPolygon to standard output. It does so by performing a PrintToStream() on the
individual BPoint's which make up the polygon. This member is generally used for debugging and
the output is primarily human readable and not sensitive to changes which could risk backward
compatibility.</P></LI>
<LI><P><B>Assignment Operator</B> The operator=() operator is defined for BPolygon's. It takes
a source BPolygon and assigns it to another existing BPolygon target. The state of the target
BPolygon is lost and replaced with that of the source. The source retains its state so the outcome
is two BPolygons with the same state (ie set of points).</P></LI>
</OL>
<A NAME="implement"></A><H2>BPolygon Implementation:</H2>
<P>Internally, the BPolygon contains an array of BPoint's which it uses to track the shape it
holds. The implementation of BPolygon is fairly simple since it is a fairly basic container
class for a set of points.</P>
</BODY>
</HTML>
@@ -0,0 +1,136 @@
Posted by Rudolf Nov 22, 2005 to the haiku-appsever ML:
http://www.freelists.org/post/haiku-appserver/new-drawing-bug-Rudolf-some-stuff-for-you,10
More good info @ http://www.freelists.org/archive/haiku-appserver
Be Docs (file: R4_Graphics_Driver_Docs):
Engine Synchronization
B_ACCELERANT_ENGINE_COUNT - No feature specific data required.
Return the number of acceleration engines that the device may operate in parallel.
It's not required for all engines to be equally capable (i.e. support the same
acceleration features).
B_ACQUIRE_ENGINE - No feature specific data required.
Request exclusive ownership of an acceleration engine with the capabilities mask specified.
The caller is willing to wait up to max_wait micro(milli?)-seconds. If the request can't be
fullfilled before that time expires, the accelerant should return B_WOULD_BLOCK immediatly.
If non-zero, sync_token points to a synchronization token retrieved from either
release_engine() or get_sync_token() to which the engine should be synchronized before
engine acquisition succeeds. See B_SYNC_TO_TOKEN for more details. The engine_token for
the successfully acquired engine is returned in engine_token **et.
B_RELEASE_ENGINE - No feature specific data required.
Relinquish exclusive ownership of the engine specified by engine_token et. If
sync_token *st is non-zero, return a sync_token which can be utilized to ensure that the
specified engine has completed all acceleration operations issued up this point in time.
B_WAIT_ENGINE_IDLE - No feature specific data required.
Wait for the graphics device to be completely idle (i.e. no current running or pending
acceleration primitives, DMA transfers, etc.).
B_GET_SYNC_TOKEN - No feature specific data required.
Return a synchronization token for the specified engine. sync_token *st must point at
a sync_token which will be updated with the information required to ensure that a call to
sync_to_token() will be able to ensure that the specified engine has completed all of the
acceleration primitives, DMA transfers, etc. that have been issued up to this point in time.
B_SYNC_TO_TOKEN - No feature specific data required.
Ensure that the engine specified in sync_token *st has completed the acceleration
primitives, DMA transfers, etc., issued up to the point in time specified in the sync_token.
Rudolf's notes.
info on engine_token:
uint32 ACCELERANT_ENGINE_COUNT(void)
exists because in theory a single card can have multiple independant acceleration engines.
For instance one that can do 2D, and one that can do 3D (or combinations). See
'engine capabilities' flags in Accelerant.h.
(note: never seen multiple engines per card yet though. Was this meant for some very old
hardware with seperate 2D and 3D 'blocks'? Although I guess it's thinkable that multiple
equally capable engines would exist as well..)
In order to distinquish between multiple engines all acceleration commands are given along
with an engine_token *et, aquired when
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et)
was called.
status_t SYNC_TO_TOKEN(sync_token *st)
is an exeption: here the engine is ID'd by member: (defined in Accelerant.h)
uint32 engine_id.
void WAIT_ENGINE_IDLE(void)
is an exeption also because this function returns only when *ALL* engines are completely
idle. Hence no need for distinction.
Furthermore the absense of the use of engine_token in both SYNC_TO_TOKEN and WAIT_ENGINE_IDLE
would seem to indicate these hooks may be used *without having acquired the engine*. (?).
info on sync_token:
-- How does the acceleration cmd interface work? There's a circular buffer that stores cmd's.
There's a hardware pointer that points 'at' the command currently being executed (think
of stacks: some architectures point to the first 'free' location, some to the 'last used'
location.)
There's also a second pointer which points at the first free location, i.e. where new cmd's
will be stored pending execution. This second pointer is a software maintained pointer (in
the driver).
-- What's a sync_token? A Sync_token in nothing more than a extra pointer (one per token). This
pointer points at the first free location in the cmd buffer at that point in time the
sync_token was 'filled'. In theory it doesn't change during the (rest of the) life-time of
the token, although the driver-implementation could (?) do that anyway for some internal
reason.
Driver users (i.e. app_server) are responsible for reserving memory for a sync_token. They
pass a pointer to it to the driver (if they want to use it). The driver in turns fills it
with the needed info. Driver users may never modify the content of the sync_token(s).
-- When would a user be interested in a sync_token? If multiple independant (so non-overlapping)
'regions' require multiple updates each alternatingly done by software and acceleration engine,
it might be interesting to use sync_tokens (for instance).
It would be possible to issue all engine commands concerning area #1, ask for a sync token,
issue all engine commands concerning area #2, and then do this:
- SYNC_TO_TOKEN (so waiting until all engine commands concerning area #1 are done);
- Draw in area #1 using software (while the acc engine is in the process of updating area #2:
(so some 'parallel processing' is done here).
If no sync token would be used, instead of syncing to token, wait_engine_idle would be used.
This of course would mean that no 'parallel processing' could be done...
Worse yet: if some seperate user is also using the engine (between RELEASE and AQUIRE engine
done by 'user #1' (i.e. app_server), the acc engine might *never* become fully idle.
A nice example here would be 3D acceleration: as long as no non-accelerated drawing has to be
done there, there's no reason the engine would need to be idle at all for this (apart from
processing 'user-input' like joystick controls).
You see: an acceleration engine automatically serializes it's cmd processing so update errors
because of out-of-order execution wouldn't happen.
-- Why didn't I implement sync_token stuff in the matrox, nvidia and neomagic drivers?
Lack of 'known specs' yet. You see, even if the pointers in the cmd buffer are known: that's
not enough yet:
- The fact that an command is fetched from the buffer does *not* mean it's
execution is completely done.
- The implementation via just a pointer is not enough: if you wait too long, the current
free pointer might have cycled around the buffer. This means a simple compare to that
pointer is not conclusive. Much better would be actually inserting 'dummy commands' inside
the command buffer at the place a sync_token is generated. This dummy commands would be
executed just once, when we reached our goal. If the dummy command clears a variable
especially setup for the sync_token in question: we would have a conclusive result without
even the use of an actual pointer in the sync_token. AND: updating the tokens would have no
software overhead, as the acc engine would do it. (via 'pointers only' some invalidation
code has to be executed once the hardware pointer cycles around).
NOTE PLEASE:
This information is based upon my understanding of hardware inner workings. As this
understanding grows and is corrected over time, I might contradict myself later on if
asked again. :-)
//actual hooks:
uint32 ACCELERANT_ENGINE_COUNT(void);
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait,
sync_token *st, engine_token **et);
status_t RELEASE_ENGINE(engine_token *et, sync_token *st);
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st);
status_t SYNC_TO_TOKEN(sync_token *st);
void WAIT_ENGINE_IDLE(void);
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

+66
View File
@@ -0,0 +1,66 @@
Haiku OpenGL kit developers introduction
The Haiku OpenGL kit is made up of the folwing pieces:
* The "OpenGL Kit" aka libGL.so and supporting libraries.
This is what the user applications interact with.
* The "OpenGL Add-ons" (which do the real work)
These are chosen by the OpenGL kit and utilized
In the traditional BeOS sense, the OpenGL Add-ons are the
vendor provided OpenGL drivers. This actually doesn't
mesh well with the current open source OpenGL stack.
Our "OpenGL Add-ons" are really self contained Mesa and
Gallium renderers. On the old Mesa side of the house,
swrast is a bunch of wrapper code. On the Gallium side,
swpipe is a Gallium target.
Mesa drivers are the classical Mesa software rasterizers,
Gallium drivers are the new-school software and hardware
drivers.
**********
Mesa versions
The Haiku project uses two different versions of Mesa.
* Mesa 7.9.2 for gcc2 OpenGL Add-ons
* Mesa 10.2.0+ for gcc4 OpenGL Add-ons.
The reasoning behind this is that any version of Mesa
above 7.9.2 will require a *massive* porting effort to
make it compile under gcc2. Given this fact, it makes
sense to bump the gcc2 version of Mesa as far as it will
go and set it there statically. Think of Mesa 7.9.2
as the "stable" version Haiku R1 will use :)
Hardware 3D rendering and llvm-based software rendering
will never work for legacy gcc2 applications. Period.
However! If you're running a gcc2 hybrid version of
Haiku, llvm or hardware based rendering should be possible
on gcc4 applications.
It's essential someone from the Haiku project keeps up
with the upstream Mesa changes pushing build fixes to
upstream Mesa to keep Haiku relevant.
**********
The packages
Haiku has several packages for Mesa:
mesa-x.x.x-x-x86.hpkg Core Mesa package, provides libGL
mesa_devel-x.x.x-x-x86.hpkg Provides development headers and "OpenGL kit"
mesa_swrast-x.x.x-x-x86.hpkg Mesa "Software Rasterization" renderer
mesa_swpipe-x.x.x-x-x86.hpkg Gallium "Software pipe" LLVM enhanced renderer
Future :3
mesa_radeonhd-x.x.x-x-x86.hpkg Gallium "Radeon HD" hardware renderer
mesa_intel-x.x.x-x-x86.hpkg Gallium "Intel" hardware renderer
mesa_nvidia-x.x.x-x-x86.hpkg Gallium "nVidia" hardware renderer (unlikely)
@@ -0,0 +1,6 @@
PrintServerApp::MessageReceived(): BMessage: what = selp (0x73656c70, or 1936026736)
entry driver, type='CSTR', c=1, size=17, data[0]: "EPSON C40 Series"
entry transport, type='CSTR', c=1, size=12, data[0]: "Serial Port"
entry transport path, type='CSTR', c=1, size=8, data[0]: "serial1"
entry printer name, type='CSTR', c=1, size=8, data[0]: "my_test"
entry connection, type='CSTR', c=1, size=6, data[0]: "Local"
+19
View File
@@ -0,0 +1,19 @@
2x PageSetup
1x Print
config_page((null),0x80013478)
BMessage: what = pgst (0x70677374, or 1885827956)
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
config_page((null),0x80013478)
BMessage: what = pgst (0x70677374, or 1885827956)
entry current_printer, type='CSTR', c=1, size=12, data[0]: "DemoPrinter"
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
config_job((null),0x80013478)
BMessage: what = ppst (0x70707374, or 1886417780)
entry current_printer, type='CSTR', c=1, size=12, data[0]: "DemoPrinter"
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
@@ -0,0 +1,72 @@
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
entry printer, type='LONG', c=1, size= 4, data[0]: 0x8003b390 (-2147241072, ೐')
entry page_format, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:18.0, t:18.0, r:594.0, b:774.0)
entry current_printer, type='CSTR', c=1, size=27, data[0]: "HPLaserJetPCL3Driver_BeInc"
BMessage: what = GOOD (0x474f4f44, or 1196379972)
entry printer, type='LONG', c=1, size= 4, data[0]: 0x800131a8 (-2147405400, ী౨')
entry EPST_copies, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
entry EPST_dst_idx_page, type='LONG', c=1, size= 4, data[0]: 0x5 (5, '')
entry EPST_src_idx_page, type='LONG', c=1, size= 4, data[0]: 0x7 (7, '')
entry EPST_orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_page_order, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_centered, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_extended, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_rotate180, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_page_state, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_logic_userdef_width, type='FLOT', c=1, size= 4, data[0]: 0.0000
entry EPST_logic_userdef_height, type='FLOT', c=1, size= 4, data[0]: 0.0000
entry EPST_page_name, type='CSTR', c=1, size=3, data[0]: "A4"
entry EPST_scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:595.2, b:841.8)
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:8.4, t:8.4, r:586.8, b:802.2)
entry EPST_page_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:2976.0, b:4209.0)
entry EPST_printer_rect, type='RECT', c=1, size=16, data[0]: BRect(l:42.0, t:42.0, r:2934.0, b:4011.0)
entry EPST_page_settings_dpi, type='FLOT', c=1, size= 4, data[0]: 72.0000
entry EPST_printer_settings_dpi, type='FLOT', c=1, size= 4, data[0]: 360.0000
entry EPST_paper_feed, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_quality, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
entry EPST_resolution, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_paper_type, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_color, type='LONG', c=1, size= 4, data[0]: 0x6 (6, '')
entry EPST_microweave, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry EPST_unidirectionnal, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry xres, type='LONG', c=1, size= 4, data[0]: 0x168 (360, '')
entry yres, type='LONG', c=1, size= 4, data[0]: 0x168 (360, '')
entry EPST_BEATWARE, type='BOOL', c=1, size= 1, data[0]: 0
entry first_page, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
entry last_page, type='LONG', c=1, size= 4, data[0]: 0x7fffffff (2147483647, '')
entry EPST_preview, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry current_printer, type='CSTR', c=1, size=24, data[0]: "EPSONStylusDriver_BeInc"
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
entry printer, type='LONG', c=1, size= 4, data[0]: 0x8003b498 (-2147240808, ഘ')
entry bitmap, type='BOOL', c=1, size= 1, data[0]: 0
entry HighQuality, type='BOOL', c=1, size= 1, data[0]: 0
entry in_color, type='BOOL', c=1, size= 1, data[0]: 0
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry page size, type='CSTR', c=1, size=7, data[0]: "Letter"
entry ppd_item, type='MSGG', c=1, size= 0,
entry xres, type='LLNG', c=1, size= 8, data[0]: 0x12c (300, '')
entry yres, type='LLNG', c=1, size= 8, data[0]: 0x12c (300, '')
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry units, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:14.4, t:21.6, r:597.6, b:784.8)
entry first up, type='BOOL', c=1, size= 1, data[0]: 1
entry current_printer, type='CSTR', c=1, size=23, data[0]: "PostScriptDriver_BeInc"
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80018af0 (-2147382544, 瀊')
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry current_printer, type='CSTR', c=1, size=20, data[0]: "PreviewDriver_BeInc"

After

Width:  |  Height:  |  Size: 5.3 KiB

@@ -0,0 +1,40 @@
$ print_server
----------------------------------------------------------------------------------------------------------------------------------------------------
PAGE SETUP.........
----------------------------------------------------------------------------------------------------------------------------------------------------
PrintServerApp::MessageReceived(): BMessage: what = pgst (0x70677374, or 1885827956)
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
entry active, type='BOOL', c=1, size= 1, data[0]: 1
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
entry active, type='BOOL', c=1, size= 1, data[0]: 0
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
----------------------------------------------------------------------------------------------------------------------------------------------------
PRINT.........
----------------------------------------------------------------------------------------------------------------------------------------------------
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
PrintServerApp::MessageReceived(): BMessage: what = ppst (0x70707374, or 1886417780)
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
entry current_printer, type='CSTR', c=1, size=20, data[0]: "PreviewDriver_BeInc"
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
entry active, type='BOOL', c=1, size= 1, data[0]: 1
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
entry active, type='BOOL', c=1, size= 1, data[0]: 0
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
----------------------------------------------------------------------------------------------------------------------------------------------------
After spooling:
----------------------------------------------------------------------------------------------------------------------------------------------------
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
PrintServerApp::MessageReceived(): BMessage: what = psns (0x70736e73, or 1886613107)
entry JobName, type='CSTR', c=1, size=15, data[0]: "InterestFields"
entry Spool File, type='CSTR', c=1, size=79, data[0]: "/boot/home/config/settings/printers/PreviewDriver_BeInc/InterestFields@8257001"
@@ -0,0 +1 @@
BRect(78.0, 71.0, 561.0, 409.0)
@@ -0,0 +1,5 @@
Information from BeOS R5 implementation:
BPrintJob::ConfigPage()
BPrintJob::ConfigJob()
BPrintJob::TakeJob()
Binary file not shown.
@@ -0,0 +1,18 @@
$ print_server
Loaded addon /boot/home/config/add-ons/Print/DemoDriver
Loaded addon /boot/beos/system/add-ons/Print/transport/Serial Port
Loaded addon /boot/beos/system/add-ons/Print/EPSON Stylus Driver
Loaded addon /boot/beos/system/add-ons/Print/transport/Parallel Port
Loaded addon /boot/beos/system/add-ons/Print/HP PCL3 LaserJet Compatible
Loaded addon /boot/beos/system/add-ons/Print/transport/USB Port
Loaded addon /boot/beos/system/add-ons/Print/PostScript
Loaded addon /boot/beos/system/add-ons/Print/transport/Print To File
Loaded addon /boot/beos/system/add-ons/Print/Preview
BMessage: what = pgst (0x70677374, or 1885827956)
BMessage: what = pgcp (0x70676370, or 1885823856)
-------------------------------------------------
BMessage: what = pgcp (0x70676370, or 1885823856)
BMessage: what = ppst (0x70707374, or 1886417780)
entry current_printer, type='CSTR', c=1, size=24, data[0]: "EPSONStylusDriver_BeInc"
BMessage: what = pdef (0x70646566, or 1885627750)
BMessage: what = pgcp (0x70676370, or 1885823856)
Binary file not shown.
+542
View File
@@ -0,0 +1,542 @@
# Annotations
# ===========
#
# This file contains a list of miscellaneous annotations.
# An entry has the following tags:
# * OS: the concerned "operating system" (BeOS R5, OBOS POSIX)
# * Module: the concerned class or file
# * Location: a more precise location, e.g. a function
# * Description: a description of the item
OS: BeOS R5
Module: BEntry
Location: BEntry(const BDirectory*, const char*),
SetTo(const BDirectory*, const char*)
Description: Crash when passing a NULL BDirectory.
OS: BeOS R5
Module: BEntry
Location: MoveTo()
Description: Crashs when passing a NULL BDirectory.
OS: BeOS R5
Module: BPath
Location: BPath(const BDirectory*, const char*, bool),
SetTo(const BDirectory*, const char*, bool)
Description: Crash when passing a NULL BDirectory.
OS: BeOS R5
Module: BPath
Location: GetParent()
Description: Crashs when called on an uninitialized object or when passing
a NULL BPath.
OS: BeOS R5
Module: BPath
Location: operator==(), operator!=()
Description: Uninitialized paths are not equal. An initialized path equals
a (const char*)NULL, an uninitialized path does not.
OS: BeOS R5
Module: BPath
Location: Flatten()
Description: Crashs when passing a NULL buffer and doesn't check the buffer
size.
OS: BeOS R5
Module: BStatable
Location: destructor
Description: Is not virtual.
OS: BeOS R5
Module: BStatable
Location: GetAccessTime(), SetAccessTime()
Description: Access time unused.
OS: BeOS R5
Module: BStatable
Location: GetPermissions()
Description: Doesn't filter the mode flags, thus not only the permissions are
returned.
OS: BeOS R5
Module: BStatable
Location: Get*()
Description: Crash when passing a NULL pointer.
OS: OBOS POSIX
Module: BStatable
Location: SetPermissions/ModificationTime/CreationTime()
Description: Don't work due to set_stat(FileDescriptor, StatMember)
limitations.
OS: OBOS POSIX
Module: kernel_interface
Location: set_stat(FileDescriptor, StatMember)
Description: WSTAT_MODE, WSTAT_*TIME can't be implemented due to missing
fchmod()/FD time setters.
OS: BeOS R5
Module: libroot
Location: fchown()
Description: fchown(file, 0xFFFFFFFF, gid) sets the UID to 0xFFFFFFFF, which
is a bug.
OS: BeOS R5
Module: libroot
Location: readdir(), fs_read_attr_dir()
Description: The d_reclen field of a dirent structure does not contain the
length of the whole structure (unlike stated in
BeBook::BEntryList), but only the length of the d_name field.
If the terminating '\0' is counted or not seems to depend on the
file system.
OS: OBOS POSIX
Module: kernel_interface
Location: read_link(FileDescriptor, char*, size_t)
Description: Can't be implemented due to the lack of an FD readlink() version.
OS: BeOS R5
Module: BSymLink
Location: MakeLinkedPath(const char*, BPath*)
Description: The dirPath seems to be converted into a BDirectory, which
causes links to be resolved, i.e. a "/tmp" dirPath expands to
"/boot/var/tmp". That does also mean, that the dirPath must
exists!
OS: BeOS R5
Module: BSymLink
Location: MakeLinkedPath()
Description: Crashs when passing a NULL const char* or BDirectory.
OS: BeOS R5
Module: BNode
Location: GetNextAttrName()
Description: Crashs when passing a NULL buffer.
OS: BeOS R5
Module: BNode
Location: Read/WriteAttrString()
Description: Crash when passing a NULL BString.
OS: BeOS R5
Module: BNode
Location: Lock()
Description: Given two BNode objects initialized to the same node, it is
possible to Lock() one of them, although the BeBook says it isn't.
OS: BeOS R5
Module: BDirectory
Location: BDirectory(const node_ref*), SetTo(const node_ref*)
Description: Crash when passing a NULL node_ref.
OS: BeOS R5
Module: BDirectory
Location: GetEntry()
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5
Module: BDirectory
Location: FindEntry()
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5 (OBOS)
Module: BDirectory
Location: Contains(const char*, int32)
Description: If the supplied path is absolute and refers to an existing
entry, true is returned, even if the directory does not contain
the entry or is not even initialized.
(The OBOS implementation makes the behavior more consistent
with the BEntry* version, which returns false when the
directory is not initialized and true only if the directory
actually contains the entry.)
OS: BeOS R5
Module: BDirectory
Location: Contains(const BEntry*, int32)
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5
Module: BDirectory
Location: Contains(const BEntry*, bool)
Description: Bug: Tests with a directory, contained file/dir/symlink and
the respective node kind (B_FILE_NODE/B_DIRECTORY_NODE/
B_SYMLINK_NODE) result false.
OS: BeOS R5
Module: BDirectory
Location: GetNextDirents()
Description: Crashs when passing a NULL buffer.
OS: OBOS
Module: BQuery
Location: Push*()
Description: Return status_t instead of void. Fail, if Fetch() has already
been called.
OS: BeOS R5
Module: BQuery
Location: PushOp()
Description: Crashs when pushing B_CONTAINS/B_BEGINS/ENDS_WITH on an empty
stack.
OS: BeOS R5
Module: BQuery
Location: PushUInt64()
Description: Doesn't work. Predicates constructed using it are invalid.
OS: BeOS R5
Module: BQuery
Location: Get/SetPredicate()
Description: Crash when passing a NULL BString/char*.
OS: BeOS R5
Module: BQuery
Location: SetVolume()
Description: Crashs when passing a NULL BVolume.
OS: BeOS R5
Module: BQuery
Location: GetNextEntry/Ref()
Description: Crash when passing a NULL BEntry/entry_ref.
OS: BeOS R5
Module: BMimeType
Location: {Get,Set}LongDescription()
Description: Crashes when passed a NULL description
OS: BeOS R5
Module: BMimeType
Location: GetLongDescription()
Description: The contents of the description string are modified even if
the function fails.
OS: BeOS R5
Module: BMimeType
Location: SetShortDescription()
Description: When passed a NULL description, doesn't crash, but does
appear to make the result of following calls to SetShortDescription
unreliable (sometimes they work, sometimes they don't).
OS: BeOS R5 vs. OBOS
Module: BMimeType
Location:
Description: R5: The maximal MIME string length, BMimeType accepts is
B_MIME_TYPE_LENGTH *not* including terminating null. Note, that
app_info reserves only B_MIME_TYPE_LENGTH chars for the
signature field.
OBOS: That's why we support strings that fit into a buffer of
size B_MIME_TYPE_LENGTH only. This is consistent with the use
of the other *_LENGTH constants.
OS: BeOS R5
Module: BMimeType
Location: SetAppHint()
Description: The entry_ref passed to SetAppHint() must be valid but is not
required to refer to a file that actually exists; furthermore,
if it does exist, the MIME type of the file is not required to
match the BMimeType object's type.
OS: BeOS R5
Module: BMimeType
Location: SetIcon()
Description: The BBitmap passed to BMimeType::SetIcon() must be in the B_CMAP8
color space, or the application will crash. We should remember
to be smarter about this.
OS: BeOS R5
Module: BMimeType
Location: GetIcon()
Description: The BBitmap passed to BMimeType::GetIcon() must be in the B_CMAP8
color space. If not, the call returns B_OK but doesn't actually
modify the bitmap. We should remember to be smarter about this.
OS: BeOS R5
Module: BMimeType
Location: IsValid(const char*), GetSupertype(), Contains()
Description: Crash when passing NULL.
OS: BeOS R5
Module: BMimeType
Location: {Get,Set}IconForType(char*, BBitmap*, icon_size)
Description: Passing NULL as the first parameter is the same as calling
{Get,Set}Icon() with the second two parameters (i.e. {gets,sets}
the icon for the type itself).
OS: BeOS R5
Module: BMimeType
Location: SetFileExtensions()
Description: Passing a NULL message does not clear the File Extensions field
for the MIME type as indicated by the Be Book; instead, it crashes
the application :-)
OS: BeOS R5
Module: BMimeType
Location: GetFileExtensions()
Description: A B_STRING_TYPE field of name "type" is *added* to the result
containing the MIME type of the BMimeType object. Since the
BMessage passed to SetFileExtensions() appears to be simply
flattened into the appropriate attribute, the "type" field is
appended to any such "type" fields that may already exist in
the original BMessage.
OS: BeOS R5
Module: BMimeType
Location: Install()
Description: From the Be Book: "Currently, Install() may return a random value
if the object is already installed."
OS: BeOS R5
Module: BMimeType
Location:
Description: MIME Type strings are converted to lowercase before being used
as filenames in the MIME database.
OS: BeOS R5
Module: BMimeType
Location: Start/StopWatching()
Description: An invalid messenger (BMessenger::Invalid()) is fine as parameter.
OS: BeOS R5
Module: Mime.h/cpp
Location: get_device_icon()
Description: KDL when passing a NULL buffer!
OS: BeOS R5
Module: BMimeType
Location: CheckSnifferRule()
Description: Crashes when passing a NULL rule.
OS: BeOS R5
Module: BMimeType
Location: GetSnifferRule()
Description: Crashes when passing a NULL BString.
OS: BeOS R5
Module: BMimeType
Location: Check/Get/SetSnifferRule()
Description: The sniffer rules description in the BeBook deviates considerably
from the actual implementation:
- + masks
- + top level ORs: (patterns...) | (patterns...) | ...
- - range overriding: [range1] ([range2]pattern)
- either no or complete ranges: (pattern1 | pattern2)
or ([range1]pattern1 | [range2]pattern2), but not
([range1]pattern1 | pattern2)
- CheckSnifferRule() doesn't check some of the values, e.g.
ranges (negative values, or begin > end) or 0 <= priority <= 1.
OS: BeOS R5
Module: BMimeType
Location: GuessMimeType(const entry_ref *, BMimeType *)
Description: When passing an uninitialized entry_ref, B_OK and
"application/octet-stream" are returned.
OS: BeOS R5
Module: BMimeType
Location: SetAttrInfo
Description: Crashes when passed a NULL BMessage.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledTypes(BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All *entries* (files, dirs, or symlinks) in the root MIME database
directory treated as MIME types, except those that begin with an
underscore; only dirs are treated as supertypes (unless the dir's
META:TYPE attribute is different than its filename, in which case
it's not treated as a supertype).
+ For each supertype, all *entries* (files, dirs, or symlinks) in the
corresponding supertype subdirectory are treated as a MIME type, except
those that begin with an underscore.
+ The MIME type for supertypes is taken from the name of the supertype
subdirectory.
+ The MIME type for non-supertypes is take from the entry's META:TYPE
attribute. If the entry has no META:TYPE attribute, the MIME type is
derived by concatentating the name of the supertype directory to the
name of the entry, separated by a "/" character. Either way, the MIME
string returned is not checked to be valid.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledTypes(char *super, BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All *entries* (files, dirs, or symlinks) in the MIME database directory
corresponding to the "super" argument are treated as subtypes, *except*
those whose filenames begin with an underscore. It does not matter if
the supertype directory has a META:TYPE attribute or not.
+ The MIME type is taken from the entry's META:TYPE attribute. If the entry
has no such attribute, the MIME type is derived by concatentating the name
of the supertype directory (the directory's META:TYPE attribute is ignored
if present) to the name of the entry, separated by a "/" character. Either
way, the MIME string returned is not checked to be valid.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledSupertypes(BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All directories in the root MIME database directory are treated as
supertypes (even directories beginning with an underscore).
+ The MIME type is derived from the directory name, which is not
checked to be a valid MIME string.
OS: BeOS R5
Module: BMimeType
Location: GetWildcardApps()
Description: This code:
BMessage msg;
status_t error = BMimeType::GetWildcardApps(&msg);
is the same as:
BMessage msg;
BMimeType mime("application/octet-stream");
status_t error = mime.InitCheck();
if (!error)
error = mime.GetSupportingApps(&msg);
OS: BeOS R5
Module: BNodeInfo
Location: {Set,Get}AppHint()
Description: The file attribute the path of the "app hint" application
("BEOS:PPATH") is of type B_MIME_STRING_TYPE instead of
B_STRING_TYPE.
OS: BeOS R5
Module: BNodeInfo
Location: GetType()
Description: When the string stored in the "BEOS:TYPE" attribute is longer
than B_MIME_TYPE_LENGTH, the returned string is one character
shorter than the actual string.
OS: BeOS R5
Module: BNodeInfo
Location: GetIcon()
Description: Crashes when passing a NULL BBitmap.
OS: BeOS R5
Module: BNodeInfo
Location: GetIcon()
Description: Crashes when getting B_LARGE_ICON and passing a BBitmap with
B_RGB32 color space. B_MINI_ICON works just fine.
OS: BeOS R5
Module: BAppFileInfo
Location: GetSupportedTypes()
Description: Crashes when passing a NULL BMessage.
OS: BeOS R5
Module: BAppFileInfo
Location: Supports()
Description: Crashes when passing a NULL BMimeType.
OS: BeOS R5
Module: BAppFileInfo
Location: SetSupportedTypes(const BMessage *types, bool syncAll)
Description: Crashes when passing a NULL BMessage and syncAll = true.
OS: BeOS R5
Module: BAppFileInfo
Location: SetSupportedTypes()
Description: Sometimes installs a supported type, also when the file's
signature is not installed in the MIME database. This happens
e.g. when setting two supported types and then setting two
different types. The second of the new types is installed.
OS: BeOS R5
Module: BAppFileInfo
Location: SetSupportedTypes(const BMessage *types)
Description: Returns B_ENTRY_NOT_FOUND when the file's signature is not
installed in the MIME database, although the operation is
carried out successfully.
OS: BeOS R5
Module: BAppFileInfo
Location: SetSupportedTypes()
Description: Don't check whether the supplied types are valid MIME types. And
don't fail, if they are not. OBOS checks them.
OS: BeOS R5
Module: BAppFileInfo
Location: GetIcon(), GetIconForType()
Description: Crashes when getting B_LARGE_ICON and passing a BBitmap with
B_RGB32 color space. B_MINI_ICON works just fine.
OS: BeOS R5
Module: BAppFileInfo
Location: GetVersionInfo(), SetVersionInfo()
Description: Crash when passing a NULL version_info.
Module: BTest
Location: SetName()
Description: Should also rename the mount point.
Priority: medium
+159
View File
@@ -0,0 +1,159 @@
# Completed
# =========
#
# This file contains completed ToDo items.
Module: BEntry
Location: SetTo(const BDirectory *, const char *, bool)
Description: Reimplement! Concatenating dir and leaf to an absolute path
prevents the user from accessing entries with longer absolute
path. R5 handles this without problems.
Priority: medium
Requires: - OBOS kernel?
Module: BEntry
Location: SetTo(const BDirectory *, const char *, bool)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BVolume
Location: operator==()
Description: Implement.
Priority: high
Module: StatableTest
Location: GetXYZTest()
Description: Uncomment GetVolume() test, when BVolume::==() is implemented.
Priority: low
Requires: - implementation of BVolume::operator==()
Module: kernel_interface
Location: set_stat(const char*, StatMember)
Description: Implement WSTAT_CRTIME.
Priority: medium
Comment: not longer necessary as we use the Haiku kernel syscalls now
Module: BeOS R5::libroot
Location:
Description: Propose a project wide common handling of the
B_FILE/PATH_NAME_LENGTH (+ 1?) issue.
Priority: low
Comment: B_FILE/PATH_NAME_LENGTH already include the terminating null
Module: BSymLink
Location:
Description: Remove the work-around introduced because of the missing FD
version of readlink().
Priority: medium
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const entry_ref *)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const BEntry *)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*).
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const BDirectory*, const char*)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*).
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: Lock(), Unlock()
Description: Implement when kernel support is available.
Priority: medium
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const entry_ref *, uint32)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const BEntry *, uint32)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*, uint32).
Priority: low
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const BDirectory*, const char*, uint32)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*, uint32).
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: SetTo(const entry_ref *)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: SetTo(const BEntry *)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*).
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: SetTo(const BDirectory*, const char*)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*).
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: GetEntry()
Description: Check if necessary to reimplement! Implemented using
StorageKit::dir_to_self_entry_ref().
Priority: low
Requires: - OBOS kernel
Module: BQuery
Location: SetTarget()
Description: Used a bad hack to get port and token of the BMessenger. Fix it.
Priority: low
Requires: - respective function(s) to be provided by the IK team
Module: kernel_interface
Location: remove_attr()
Description: Verify return behavior of fs_remove_attr().
Priority: medium
Comment: not longer necessary as we use the Haiku kernel syscalls now
Module: BVolume
Location: SetName()
Description: Should also rename the mount point.
Priority: medium
@@ -0,0 +1,90 @@
Disk Device Protocols
=====================
disk device job scheduled message
target: Registered job update BMessengers
message: B_DISK_DEVICE_JOB_SCHEDULED
"job_id": B_INT32_TYPE
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
-----------------------------------------------------------------------
disk device job initiated message
target: Registered job update BMessengers
message: B_DISK_DEVICE_JOB_INITIATED
"job_id": B_INT32_TYPE
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
-----------------------------------------------------------------------
disk device job canceled message
target: Registered job update BMessengers
message: B_DISK_DEVICE_JOB_CANCELED
"job_id": B_INT32_TYPE
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
-----------------------------------------------------------------------
disk device job finished message
target: Registered job update BMessengers
message: B_DISK_DEVICE_JOB_FINISHED
"job_id": B_INT32_TYPE
"succeeded": B_BOOL_TYPE
[ "info": B_STRING_TYPE ]
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
- info: Optional description of success or failure
notes:
A separate job finished message is needed, as rounding error in
the computation of job progress may result in multiple
B_DISK_DEVICE_JOB_UPDATE messages with "progress" fields of 100.
-----------------------------------------------------------------------
disk device job simple progress update message
target: Registered job simple progress update BMessengers
message: B_DISK_DEVICE_JOB_SIMPLE_PROGRESS
"job_id": B_INT32_TYPE
"progress": B_UINT8_TYPE
"info": B_STRING_TYPE
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
- progress: Percent of job completed (0 to 100)
- info: Description of current action being taken, i.e.
"allocating inodes", "writing superblock", etc.
-----------------------------------------------------------------------
disk device job extra progress update message
target: Registered job extra progress update BMessengers
message: B_DISK_DEVICE_JOB_EXTRA_PROGRESS
"job_id": B_INT32_TYPE
"info": B_STRING_TYPE
reply: none (asynchronous message)
message fields:
- job_id: Unique job identifier
- info: Extended progress info string, i.e. "block 123: found
invalid inode; fixing"
-----------------------------------------------------------------------
@@ -0,0 +1,102 @@
<html>
<head>
<title>Registrar Notes</title>
</head>
<body bgcolor='#ffffff'>
<font face='Tahoma,Arial,SansSerif'>
<!-- Tasks -->
<hr>
<b>Registrar Tasks:</b>
<ul>
<li> MIME Database chores (note that BMimeType appears to read from the database directly for <code>Get*()</code> calls.)<br>
<ul>
<li> Writes to the database -- <code>SetLongDescription(), SetPreferredApp(), create_app_meta_mime(), etc</code>
<li> Monitoring of the database -- <code>{Start,Stop}Watching()</code> <br>
<li> Sniffer duties -- Sniffer code plus <code>{Get,Set,Check}SnifferRule()</code>
</ul>
<br>
<li> Timing chores
<ul>
<li> BMessageRunner functionality
</ul>
<li> System Shutdown chores <br>
<ul>
<li> Shutdown cycle
<li> System shutdown window
</ul>
<li> Roster chores
<ul>
<li> Recent documents, folders, and apps
<li> Info about running applications
<li> etc...
</ul>
</ul>
<!-- Internals -->
<hr>
<b>Registrar Internals:</b><br>
<br>
The registrar is a non-standard <code>BApplication</code>. It has a shadow app in the <code>app_server</code>
like a normal <code>BApplication</code>, but one of its ports is slightly different:
<ul>
<li> Standard ports -- snd, rcv, AppLooperPort
<li> Registrar ports -- snd, rcv, _roster_port_
</ul>
Since <code>BLooper::port_id</code> is private to <code>BLooper</code> (to whom <code>BApplication</code>
is a friend), and since you can't rename a port after it's been created,
it's likely that the only way to rename the <code>AppLooperPort</code> and have the registrar
still be a <code>BApplication</code> is to have <code>BApplication</code> check if it's the
registrar when it's created, and use <code>_roster_port_</code> as the name for what would
otherwise be its <code>AppLooperPort</code>.
<br>
<br>
The rationale behind having a port with a specific name is that the registrar
implements the roster functionality. Thus one can't address it using the app signature
constructor of BMessenger, but rather must send the message directly to
a named port (for example, upon creation, a BApplication object must find and contact
the registrar to notify it of another running application; if the registrar
cannot be found, the application putzes out).
<br>
<br>
The Registrar has three threads:
<ul>
<li> _roster_thread_
<li> timer_thread
<li> main_mime
</ul>
<!-- BMimeType Notes -->
<hr>
<b>BMimeType Notes:</b>
<ul>
<li> The <code>Get*()</code> methods directly access the MIME database.
<li> The <code>Set*()</code> methods send a message to another entity which does the job.
The function that does the sending is called <code>_send_to_roster_()</code>, so I
suppose the roster is the one. Since the registrar has a thread named
<code>_roster_thread_</code>, I assume the roster lives in the registrar.
<li> <code>Start/StopWatching()</code> call <code>BRoster::_Start/_StopWatching()</code>.
<li>Adding/removing a MIME type file in <code>~/config/settings/beos_mime/*/</code> does
not trigger a notification message. So obviously no node monitoring is
done and changes to the database are supposed to be done using the API.
</ul>
<!-- Links -->
<hr>
<b>Links:</b>
<ul>
<li> <a href='http://www.beatjapan.org/mirror/www.be.com/users/iconworld/icon5.html'>Icon World -- The Registrar</a>
<li> <a href='http://www.beosbible.com/exc_filetype.html'>The BeOS Bible -- File Typing and The Registrar</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Application.html'>BApplication</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Storage%20Kit/MimeType.html'>BMimeType</a>
<li> <a href='http://bang.dhs.org/be/bebook/Release%20Notes/StorageKit.html'>BMimeType (sniffer docs)</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Roster.html'>BRoster</a>
</font>
</body>
</html>
+96
View File
@@ -0,0 +1,96 @@
# ToDo
# ====
#
# This file lists items that have to be worked on.
# An entry for an item has the following tags:
# * Module: the concerned class or file
# * Location: a more precise location, e.g. a function
# * Description: a description of the item
# * Priority: the priority of the item, may be
# deferrable: of no/little relevance for OBOS R1 (to be future compatible:
# the next release)
# low: of relevance for the next release, but not needed in the
# near future
# medium: of relevance for the next release, needed in the near future
# high: of relevance for the next release, needed as soon as possible
# urgent: of relevance for the next release, needed yesterday, i.e.
# some people depend on it being finished and can't continue
# with their tasks otherwise
#
# * Requires: a list of prerequisites needed for the item to be worked on,
# omitted, when empty
# * Responsible: a list of people working on the item, omitted, when empty
#
Module: BEntry
Location: Entry.cpp
Description: Definition of SYMLINK_MAX belongs to some header file. Remove it.
Priority: low
Module: EntryTest
Location: InitTest1(), InitTest2()
Description: Enable tests with strlen(dir + leaf) > B_PATH_NAME_LENGTH.
Priority: low
Requires: - reimpl. of SetTo(const BDirectory *, const char *, bool)
Module: BPath
Location: Flatten()
Description: Reimplement for performance reasons. Don't call FlattenedSize().
Priority: low
Module: NodeTest
Location: SyncTest()
Description: Add more thorough tests.
Priority: low
Requires: - OBOS kernel
Module: NodeTest
Location: LockTest()
Description: Implement when kernel support is available.
Priority: medium
Requires: - OBOS kernel
Module: BFile
Location: Read/Write[At]()
Description: Verify behavior of B_OPEN_AT_END.
Priority: medium
Module: FileTest
Location: PositionTest()
Description: Uncomment test, when B_OPEN_AT_END behavior is understood.
Priority: medium
Requires: - verification of B_OPEN_AT_END behavior
Module: fs_info.h
Location: struct fs_info
Description: Change "char device_name[128]" to "char device_name[B_DEV_NAME_LENGTH]"
whenever appropriate, since B_DEV_NAME_LENGTH is now declared in
StorageDefs.h.
Priority: low
Requires: - filesystem support files in the source hierarchy
Module: BMimeType/MimeTypeTest
Location: update_mime_info(), create_app_meta_mime()
Description: Find out, what is the meaning of the force parameter. It does
obviously not mean, that calling the function twice, the second
time with force, has the same effect as calling it only at the
second time. At least the tests indicate, that the second call,
though with force, does not have any effect at all.
Priority: medium
Requires:
Module: VolumeTest
Location: SetNameTest()
Description: Check whether the mount point is renamed properly.
Priority: low
+691
View File
@@ -0,0 +1,691 @@
# Doxyfile 1.2.1
# This file describes the settings to be used by doxygen for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "OpenBeOS Storage Kit"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
# Spanish, Russian, Croatian, Polish, and Portuguese.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH = /cvsroot/open-beos/current
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a class diagram (in Html and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off.
CLASS_DIAGRAMS = YES
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
# will only generate file names in lower case letters. If set to
# YES upper case letters are also allowed. This is useful if you have
# classes or files whose names only differ in case and if your file system
# supports case sensitive file names.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the Javadoc-style will
# behave just like the Qt-style comments.
JAVADOC_AUTOBRIEF = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
# The ENABLE_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../../../src/kits/storage ../../../headers/os/storage ../../../headers/private/storage
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
FILE_PATTERNS = *.cpp *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using a WORD or other.
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Warning: This feature
# is still experimental and very incomplete.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other
# documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented header file showing
# the documented files that directly or indirectly include this file
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =
@@ -0,0 +1,614 @@
\documentclass[12pt, a4paper]{article}
\usepackage{amssymb,amsmath,latexsym}
\usepackage[english]{babel}
\usepackage{hhline}
\newcommand{\code}[1]{{\tt #1}}
\newenvironment{nitemize}{
\newdimen\oldparindent
\oldparindent=\parindent
\begin{itemize}
\itemindent=-\oldparindent
}{
\end{itemize}
}
%\newcommand{\codeblockspace}{\vspace{12pt}}
% begin/end a code block
\newcommand{\codeblockbegin}{\begin{flushleft}\begin{minipage}{\textwidth}}
\newcommand{\codeblockend}{\end{minipage}\end{flushleft}}
\begin{document}
\sloppy
\title{The Resources Format}
%\date{}
\author{Ingo Weinhold ([email protected])}
\maketitle
\tableofcontents
\section{Introduction}
\label{introduction}
Resources provide a means to store structured but flat data in files. Unlike
attributes resources are part of the file contents and thus do not require a
special file system handling, but rather a special file format.
On the one hand there are formats of files that exclusively contain resources
(resource files), on the other hand these are file formats extended to
additionally contain resources -- namely the ELF and PEF object formats.
In either case the format of the chunk of data that frames the resources
themselves is the same. We call it the resources format.
Section \ref{file-formats} explains how the resources format is embedded in
different file formats. Section \ref{resources-format} discusses the resources
format itself. In section \ref{implementations} we focus on robustness of
resources reading/writing implementations.
The final section says some words about the status of the information provided
by this document.
\section{File Formats}
\label{file-formats}
In all file formats described in this section the resources are being located
at the end of the files. They are completely independent of their location.
\subsection{x86 Resource Files}
x86 resource files introduce the least overhead. The resources start directly
after the magic number identifying the file format:
%
\codeblockbegin
\begin{verbatim}
const char kX86ResourceFileMagic[4] = { 'R', 'S', 0, 0 };
const uint32 kX86ResourcesOffset = 0x00000004;
\end{verbatim}
\codeblockend
%
The resources start at \code{kX86ResourcesOffset}.
\subsection{PPC Resource Files}
PPC resource files begin with a PEF container header, after which the
resources start.
%
\codeblockbegin
\begin{verbatim}
typedef char PefOSType[4];
struct PEFContainerHeader {
PefOSType tag1;
PefOSType tag2;
PefOSType architecture;
uint32 formatVersion;
uint32 dateTimeStamp;
uint32 oldDefVersion;
uint32 oldImpVersion;
uint32 currentVersion;
uint16 sectionCount;
uint16 instSectionCount;
uint32 reservedA;
};
\end{verbatim}
\codeblockend
%
\codeblockbegin
\begin{verbatim}
const char kPEFFileMagic1[4] = { 'J', 'o', 'y', '!' };
const char kPPCResourceFileMagic[4] = { 'r', 'e', 's', 'f' };
const uint32 kPPCResourcesOffset = 0x00000028;
\end{verbatim}
\codeblockend
\begin{nitemize}
\item{\code{tag1}:
Must be \code{kPEFFileMagic1}.}
\item{\code{tag2}:
Must be \code{kPPCResourceFileMagic}.}
\item{All other fields must be set to 0.}
\end{nitemize}
\noindent
The resources start at \code{kPPCResourcesOffset}.
\subsection{ELF Object Files}
In an ELF file, resources are appended to rather than contained in the
regular data of the file. That is adding resources to an existing ELF file
will not cause any modification to its data (i.e. ELF header, program header
table, section header table or sections), but will enlarge the file by some
alignment padding and, of course, the resources themselves.
Therefore two values have to be known: The size of the actual ELF file and the
block size to which the resources must be aligned. As ELF files do not contain
a size field, it has to be deduced, where the file ends. This end offset is
supposed to be the maximum of the end offsets of ELF header, program header
table (if any), section header table (if any), sections and segments.
The block size to which the resources have to be aligned is the maximum of
\code{kELFMinResourceAlignment} and the alignments of the segments in the file.
%
\begin{verbatim}
const uint32 kELFMinResourceAlignment = 32;
\end{verbatim}
%
The data used for the padding between the end of the actual ELF data and the
beginning of the resources may be arbitrary.
\subsection{PEF Object Files}
Similar to ELF files the resources are simply appended to the regular data of
a PEF file, but they are not aligned to any value. That is the resources
start directly after the last PEF section without any padding.
As no field exists, that tells about the size of the PEF container (the
regular data), it has to be deduced by iterating through the PEF section
headers.
\section{The Resources Format}
\label{resources-format}
This section describes the resources format. After a subsection that outlines
their general layout, it follow subsections discussing the major parts.
A general remark regarding the byte ordering: Resources have no standard
endianess, that is the resources created by little endian and big endian
machines differ. Usually it should be possible, to deduce the used endianess
from the type of the file. x86 resource files contain little endian, PPC
resource files big endian data. The endianess of an ELF file is encoded in
its header.
As there is in fact no good reason to have different resource file formats,
even if they differ only in the format of the header (see section
\ref{file-formats}), it may be decided to use the x86 resource file format
also for big endian machines. Therefore the endianess may be deduced by the
first field of the resources header (\code{rh\_resources\_magic}, see
subsection \ref{resources-header}).
\subsection{Resources Layout}
The layout of the resources in a file is shown in figure
\ref{fig:resources-layout}.
\begin{figure}[h!tb]
\begin{center}
\begin{tabular}{|c|c|c|}
\hline
& \multicolumn{2}{c|}{resources header}\\
\hhline{|~==|}
admin section & & index section header \\
\hhline{~~|-|}
& index section & resource index \\
\hhline{~~|-|}
& & padding \\
\hhline{:===:}
\multicolumn{3}{|c|}{unknown section}\\
\hhline{:===:}
\multicolumn{3}{|c|}{data section}\\
\hhline{|~~~|}
\hhline{:===:}
\multicolumn{3}{|c|}{info section}\\
\hline
\end{tabular}
\end{center}
\caption{The Resources Layout.}
\label{fig:resources-layout}
\end{figure}
\noindent
There are four sections:
%
\begin{itemize}
\item{An administrative section which comprises the resources header and the
resource index subsection. The latter locates all other data in the file.
}
\item{An unknown section, whose purpose is (unsurprisingly) unknown, but which
seems to be unused, always containing the same data.
}
\item{A data section holding the actual resource data.
}
\item{An info section, which provides aditional information for each resource,
such as type, id and name.
}
\end{itemize}
\subsection{Resources Header}
\label{resources-header}
The resources header has the following structure:
%
\codeblockbegin
\begin{verbatim}
struct resources_header {
uint32 rh_resources_magic;
uint32 rh_resource_count;
uint32 rh_index_section_offset;
uint32 rh_admin_section_size;
uint32 rh_pad[13];
};
\end{verbatim}
\codeblockend
%
\codeblockbegin
\begin{verbatim}
const uint32 kResourcesHeaderMagic = 0x444f1000;
const uint32 kResourceIndexSectionOffset = 0x00000044;
const uint32 kResourceIndexSectionAlignment = 0x00000600;
\end{verbatim}
\codeblockend
\begin{nitemize}
\item{\code{rh\_resources\_magic}:
Must be \code{kResourcesHeaderMagic}.
}
\item{\code{rh\_resource\_count}:
Specifies the number of resources stored in this file. May be 0.
}
\item{\code{rh\_index\_section\_offset}:
Specifies the offset of the resource index section relative to the beginning
of the resources. An alternative interpretation may be the size of the
resources header.
Must be \code{kResourceIndexSectionOffset}.
}
\item{\code{rh\_admin\_section\_size}:
Specifies the size of the administrative section.
Must be \code{kResourceIndexSectionOffset} plus a multiple of
\code{kResourceIndexSectionAlignment}.
}
\item{\code{rh\_pad}:
Padding. \code{0x00000000} words.
}
\end{nitemize}
\subsection{Resource Index Section}
\label{resources-index}
The resource index section starts with a header, it follows a table of
\code{resource\_index\_entry} structures, that locates the data of each
resource, and the section ends with a special padding.
\noindent
The resource index header has the following structure:
%
\codeblockbegin
\begin{verbatim}
struct resource_index_section_header {
uint32 rish_index_section_offset;
uint32 rish_index_section_size;
uint32 rish_unused_data1;
uint32 rish_unknown_section_offset;
uint32 rish_unknown_section_size;
uint32 rish_unused_data2[25];
uint32 rish_info_table_offset;
uint32 rish_info_table_size;
uint32 rish_unused_data3;
};
\end{verbatim}
\codeblockend
\begin{verbatim}
const uint32 kUnknownResourceSectionSize = 0x00000168;
\end{verbatim}
%
\begin{nitemize}
\item{\code{rish\_index\_section\_offset}:
Specifies the offset of the resource index section relative to the beginning
of the resources. An alternative interpretation may be the size of the
resources header.
Must be \code{kResourceIndexSectionOffset}.
}
\item{\code{rish\_index\_section\_size}:
Specifies the size of the resource index section.
Must be a multiple of \code{kResourceIndexSectionAlignment}.
}
\item{\code{rish\_unused\_data1}:
Contains special data as described in section \ref{resources-unknown}.
}
\item{\code{rish\_unknown\_section\_offset}:
Specifies the offset of the unknown section relative to the beginning
of the resources.
Must be the same value as given in the resources header for
\code{rh\_admin\_section\_size}.
}
\item{\code{rish\_unknown\_section\_size}:
Specifies the offset of the unknown section relative to the beginning
of the resources.
Must be \code{kUnknownResourceSectionSize};
}
\item{\code{rish\_unused\_data2}:
Contains special data as described in section \ref{resources-unknown}.
}
\item{\code{rish\_info\_table\_offset}:
Specifies the offset of the resource info table relative to the beginning
of the resources.
}
\item{\code{rish\_info\_table\_size}:
Specifies the size of the resource info table.
}
\item{\code{rish\_unused\_data3}:
Contains special data as described in section \ref{resources-unknown}.
}
\end{nitemize}
Directly, without padding, it follows a table of \code{resource\_index\_entry}
structures. The number of entries in the table is the number of resources
stored in the file, that is the value specified by the
\code{rh\_resource\_count} member of the resources header. Since the entries
are stored without padding, the size of the table is exactly the product of
the size of \code{resource\_index\_entry} and the number of resources.
If the latter is 0, the table takes no space.
%
\codeblockbegin
\begin{verbatim}
struct resource_index_entry {
uint32 rie_offset;
uint32 rie_size;
uint32 rie_pad;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rie\_offset}:
Specifies the offset of the resource data relative to the beginning
of the resources.
}
\item{\code{rie\_size}:
Specifies the size of the resource data.
}
\item{\code{rie\_pad}:
Padding. Must be \code{0x00000000}.
}
\end{nitemize}
Since the size of the resource index section must be a multiple of
\code{kResourceIndexSectionAlignment}, some padding may be needed at the end
of this section. How this padding looks like is described in section
\ref{resources-unknown}.
\subsection{Unknown Section}
\label{resources-unknown}
The meaning of this section is unknown. It does not seem to be used at all.
It always contains the same data given by \code{kUnusedResourceDataPattern}:
%
\codeblockbegin
\begin{verbatim}
const uint32 kUnusedResourceDataPattern[3] = {
0xffffffff, 0x000003e9, 0x00000000
};
\end{verbatim}
\codeblockend
%
In section \ref{resources-index} some members where named \code{unused\_data}.
These fields contain the same kind of data. To understand what the value for a
certain field of this type is, it may help to imagine, that before the
resources are written to a file, the space they will take is filled with the
pattern specified by \code{kUnusedResourceDataPattern}, and that only those
fields are written that are not unused. Thus the original pattern can be seen
through at the unused locations.
To be precise: Let \verb|uint32 resources[]| be the resources and
\code{index} the index of an unused field in \code{resources}, then it holds:
%
\begin{verbatim}
resources[index] == kUnusedResourceDataPattern[index % 3];
\end{verbatim}
%
\subsection{Resource Info Table}
\label{resources-infotable}
The resource info table features exactly one entry for each resource.
Such an entry (resource info) specifies the ID and name of a
resource. Subsequent infos for resources of the same type are collected in
a block that starts with a type field.
The following grammar specifies the layout of the resource info table.
Nonterminals start with an upper case, terminals with a lower case letter.
%
\begin{verbatim}
ResourceInfoTable ::= [ ResourceBlockList ]
ResourceInfoSeparator
ResourceInfoTableEnd
ResourceBlockList ::= ResourceBlock
[ ResourceInfoSeparator
ResourceBlockList ]
ResourceBlock ::= type ResourceInfoList
ResourceInfoList ::= ResourceInfo [ ResourceInfoList ]
ResourceInfo ::= id index name_size name
ResourceInfoSeparator ::= 0xffffffff 0xffffffff
ResourceInfoTableEnd ::= check_sum 0x00000000
\end{verbatim}
%
The relevant structures follow:
%
\codeblockbegin
\begin{verbatim}
struct resource_info_block {
type_code rib_type;
resource_info rib_info[1];
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rib\_type}:
Specifies the type of the resources in the block.
}
\item{\code{rib\_info}:
Is the first resource info of the block. More infos may follow.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info {
int32 ri_id;
int32 ri_index;
uint16 ri_name_size;
char ri_name[1];
};
\end{verbatim}
\codeblockend
\begin{verbatim}
const uint32 kMinResourceInfoSize = 10;
\end{verbatim}
%
\begin{nitemize}
\item{\code{ri\_id}:
Specifies the ID of the resource.
}
\item{\code{ri\_index}:
Specifies the index of the resource this resource info refers to.
}
\item{\code{ri\_name\_size}:
Specifies the size of the resource name. May be 0 -- then the resource does
not have a name and \code{ri\_name} has a size of 0.
}
\item{\code{ri\_name}:
Specifies the name of the resource. The name must be null terminated.
\code{ri\_name\_size} specifies the size of this field (including the
terminating null). If it is 0, the resource does not have a name and
\code{ri\_name} is empty, i.e. has size 0.
}
\item{\code{kMinResourceInfoSize}:
Is the minimal size of a resource info. That is the size it has, if the
resource does not have a name.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info_separator {
uint32 ris_value1;
uint32 ris_value2;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{ris\_value1}:
Specifies the first word of the separator.
Must be \code{0xffffffff}.
}
\item{\code{ris\_value2}:
Specifies the second word of the separator.
Must be \code{0xffffffff}.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info_table_end {
uint32 rite_check_sum;
uint32 rite_terminator;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rite\_check\_sum}:
Contains the check sum for the resource info table. The check sum is
calculated from all bytes of the resource info table not including
\code{rite\_check\_sum} and \code{rite\_terminator}. The data are grouped
into four byte blocks, which are interpreted as big endian unsigned words
and summed up, ignoring carry. If the number of bytes to be considered is
not dividable by four, the remaining bytes are interpreted as the lower
bytes of a big endian unsigned word (the upper byte(s) set to 0).
}
\item{\code{rite\_terminator}:
Terminates the resource info table.
Must be \code{0x00000000}.
}
\end{nitemize}
\section{Implementations}
\label{implementations}
Code that writes resources should strictly stick to the specification
presented in the preceding sections to achieve maximal compatibility.
Resources reading implementations may tolerate certain deviations that
for instance happen to occur in several files of the BeOS R5 distribution
and that are handled gracefully by xres and QuickRes. It follows a, possibly
incomplete, list:
%
\begin{itemize}
\item{The third and fourth byte of the x86 resource file magic (the 0 bytes)
may be arbitrary bytes.}
\item{\code{rh\_resource\_count} may be unreliable. The resource index table
should be read until its end, which is either marked by the unused data
pattern (see section \ref{resources-unknown}) or at the latest by the
beginning of the unknown section.}
\item{The resource info table may contain entries for indices that are out
of range, i.e. greater than the number of resources induced by the resource
index table. Those entries should be ignored.}
\item{The resource info table may contain multiple entries for an index.
Any such entry after the first one should be ignored.}
\item{The resource info table may not contain an entry for an index.
The respective resource should be ignored.}
\item{The resource info table may not contain a \code{ResourceInfoTableEnd}
(see section \ref{resources-infotable}) and thus no check sum. The table
should be accepted nevertheless. Note, that a table containing a wrong check
sum is {\em not} to be accepted.}
\end{itemize}
\section{Status of this Document}
\label{status}
The information contained in this document are obtained by analyzing
resources-containing files created or modified by tools available for BeOS R5,
namely QuickRes and xres. They are incomplete and may even be partially wrong,
where being based on incorrect assumptions.
\noindent
It follows a list of items with a low degree of reliance:
\begin{itemize}
\item{Resources alignment in ELF files: Several tests with linker object files
have shown, that QuickRes aligns their resources offset to 32 bytes.
For executables on the other hand the alignment was always 4096, which is
the usual memory page size of current x86 architectures and therefore the
preferred program segment alignment. From these two information it has been
deduced, that the alignment is, if present, the maximum of
the segment alignments to be found in the program header table,
but at minimum 32.}
\item{The resources layout: The general layout of the resources is not very
well understood. The layout presented in figure \ref{fig:resources-layout}
resulted from the attempt to assign all the fields a reasonable meaning, but
in fact not even the exact length and meaning of the fields of the resources
header is unclear. The same holds for the resource index section header.}
\item{The unknown section: The contents of the unknown section and of unknown
fields is base on educated guesses.}
\end{itemize}
\end{document}
+691
View File
@@ -0,0 +1,691 @@
# Doxyfile 1.2.1
# This file describes the settings to be used by doxygen for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "OpenBeOS Support Kit"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
# Spanish, Russian, Croatian, Polish, and Portuguese.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH = /cvsroot/open-beos/current
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a class diagram (in Html and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off.
CLASS_DIAGRAMS = YES
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
# will only generate file names in lower case letters. If set to
# YES upper case letters are also allowed. This is useful if you have
# classes or files whose names only differ in case and if your file system
# supports case sensitive file names.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the Javadoc-style will
# behave just like the Qt-style comments.
JAVADOC_AUTOBRIEF = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
# The ENABLE_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../../../src/kits/support ../../../headers/os/support
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
FILE_PATTERNS = *.cpp *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using a WORD or other.
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Warning: This feature
# is still experimental and very incomplete.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other
# documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented header file showing
# the documented files that directly or indirectly include this file
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =
@@ -0,0 +1,79 @@
<HTML>
<!-- $Id: BAutolockUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
<HEAD>
<TITLE>BAutolock Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BAutolock Use Cases and Implementation Details:</H1>
<P>This document describes the BAutolock interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BAutolock Interface</A></LI>
<LI><A HREF="#usecases">BAutolock Use Cases</A></LI>
<LI><A HREF="#implement">BAutolock Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BAutolock Interface:</H2>
<P>The BAutolock class is a simple class for handling synchronization between threads. The best
source of information for the BAutolock interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/Autolock.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BAutolock Use Cases:</H2>
<P>The following use cases cover the BAutolock functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BAutolock can be created by passing a pointer to a BLocker object.
An attempt will be made to Lock() this BLocker during the construction of the BAutolock object.
</P></LI>
<LI><P><B>Construction 2:</B> A BAutolock can be created by passing a reference to a BLocker object.
An attempt will be made to Lock() this BLocker during the construction of the BAutolock object.
</P></LI>
<LI><P><B>Construction 3:</B> A BAutolock can be created by passing a pointer to a BLooper object.
An attempt will be made to Lock() this BLooper during the construction of the BAutolock object.
</P></LI>
<LI><P><B>Is Locked:</B> When the BAutolock is constructed, a lock is attempted on the BLocker or
BLooper passed in. The result of that lock attempt is returned by calling IsLocked() on the
BAutolock. The result is a boolean. True is returned if the lock was successfully acquired.
False is returned if the lock could not be acquired. See the docs for BLocker and BLooper to
find out why the lock acquisition may fail.</P></LI>
<LI><P><B>Destruction 1:</B> If the lock acquisition on the BLocker or BLooper was successful at
construction time, when the BAutolock is destructed, the lock will be released by calling Unlock()
on the BLocker or BLooper.</P></LI>
<LI><P><B>Destruction 2:</B> If the lock acquisition on the BLocker or BLooper failed at
construction time, when the BAutolock is destructed, nothing is done to the BLocker or the BLooper.
An Unlock() is not attempted because the lock at construction time failed.</P></LI>
</OL>
<A NAME="implement"></A><H2>BAutolock Implementation:</H2>
<P>The entire BAutolock implementation is inline. Because BAutolock is implemented inline, there
is no code for BAutolock in libbe.so. The code is all in Be's Autolock.h header file and compiled
at build time directly into any object being built.</P>
<P>This has some interesting implications from a backwards compatibility perspective. Because
there are no references from existing non-Be executables and libraries to libbe.so expecting
to find the BAutolock class, the entire definition of BAutolock can be changed almost without risk
of breaking compatibility. This gives anyone wishing to expand and build on the current BAutolock
class a great deal of flexibility.</P>
<P>However, it may be worthwhile when changing BAutolock in the future to try and stay source
compatible. That way, existing source code will continue to compile without having to update
it.</P>
</BODY>
</HTML>
@@ -0,0 +1,130 @@
<HTML>
<!-- $Id: BLockerUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
<HEAD>
<TITLE>BLocker Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BLocker Use Cases and Implementation Details:</H1>
<P>This document describes the BLocker interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BLocker Interface</A></LI>
<LI><A HREF="#usecases">BLocker Use Cases</A></LI>
<LI><A HREF="#implement">BLocker Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BLocker Interface:</H2>
<P>The BLocker class is a simple class for handling synchronization between threads. The best
source of information for the BLocker interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/Locker.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BLocker Use Cases:</H2>
<P>The following use cases cover the BLocker functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BLocker can be created by specifying a name for the semaphore used
internally. If a name is specified during construction, then that name is given to the internal
semaphore. If no name is given at construction, the semaphore is given the name "some BLocker".
</P></LI>
<LI><P><B>Construction 2:</B> A BLocker can use a semaphore or a "benaphore" internally depending
on a flag passed when the BLocker is created. If the flag is false, the BLocker uses a semaphore
to do synchronization. If the flag is true, the BLocker uses a benaphore internally to do
synchronization. If no flag is specified, the BLocker uses a benaphore internally.</P></LI>
<LI><P><B>Destruction:</B> When a BLocker is destructed, any threads waiting for the lock are
immediately unblocked. The threads are notified by the return code of the locking member function
that the lock was not successfully acquired. Any threads blocked on Lock() will return with
a false value. Any threads blocked on LockWithTimeout() will return with B_BAD_SEM_ID.</P></LI>
<LI><P><B>Locking 1:</B> When a thread acquires the BLocker using the Lock() or LockWithTimeout()
member functions, no other thread can acquire the lock until this thread releases it.</P></LI>
<LI><P><B>Locking 2:</B> When a thread holds the BLocker and it calls Lock() or LockWithTimeout(),
the member function returns immediately. The thread must call Unlock() the same number of times
it calls Lock...() before the BLocker is released. At any time, the thread can call CountLocks()
to get the number of times it must call Unlock() to release the BLocker.</P></LI>
<LI><P><B>Locking 3:</B> When a thread calls Lock(), the thread blocks until it can acquire the
lock. Once the lock has been acquired or an unrecoverable error has occurred, the Lock() member
function completes. If the lock has been acquired, Lock() returns true. If the lock has not
been acquired, Lock() returns false.</P></LI>
<LI><P><B>Locking 4:</B> When a thread calls LockWithTimeout(), the thread blocks until it can
acquire the lock, the time specified in microseconds expires, or an unrecoverable error occurs.
If the timeout specified is B_INFINTE_TIMEOUT, there is no timeout and the member function will
either acquire the lock or fail due to an unrecoverable error. If the lock is acquired, the
member function returns B_OK. If the timeout is reached, B_TIMED_OUT is returned and the lock is
not acquired. If a serious error occurs, a non B_OK code is returned.</P></LI>
<LI><P><B>Unlocking:</B> The Unlock() member function takes no arguments and returns no value.
If the thread currently holds the lock, the lock count is reduced by the call to Unlock(). If
the lock count reaches zero, then another thread may acquire the lock. If the thread does not
hold the lock and it calls Unlock(), the call will have no affect at all on the BLocker.</P></LI>
<LI><P><B>Locking Thread:</B> The LockingThread() member function returns the thread_id of the
thread that is holding the lock. If no thread holds the lock, then B_ERROR is returned.</P></LI>
<LI><P><B>Is Locked:</B> The IsLocked() member function returns true if the BLocker is currently
held by the calling thread. If the BLocker is not acquired by any thread or it is acquired by a
different thread, IsLocked() returns false.</P></LI>
<LI><P><B>Count Locks:</B> The CountLocks() member function returns the number of times the lock
has been acquired by the thread which holds the lock. If no thread holds the lock, then 0 is
returned. If the BLocker is held by any thread, including a thread which is not the thread
making the CountLocks() request, the number of times the lock has been acquired by the thread which
holds the lock is returned.</P></LI>
<LI><P><B>Count Lock Requests:</B> The CountLockRequests() member function returns the number of
threads currently attempting to lock the BLocker. If no thread holds the lock and no thread is
waiting for the lock, then 0 is returned. If one thread holds the lock and no other threads
are waiting for the lock, then 1 is returned. If one thread holds the lock and x threads are
waiting for the lock, then x+1 is returned. The call to CountLockRequests() can be made by any
thread including threads which do not have the lock.</P>
<P><B>NOTE:</B> Reading the Be Book, that would seem like what is returned by this member
function. In actuality, the value returned is just the "benaphore count" for the BLocker.
If the BLocker is semaphore style, then the benaphore count is set to 1 at construction time
to ensure that the semaphore is always tested when a lock is acquired. The return value is
just this count. So, the return value for benaphore style is:</P>
<PRE>
numThreadsWaitingForTheLock + numThreadsHoldingTheLock + numOfTimeoutsOccuredOnTheLock
</PRE>
<P>The return value for a semaphore style is:</P>
<PRE>
numThreadsWaitingForTheLock + numThreadsHoldingTheLock + numOfTimeoutsOccuredOnTheLock + 1
</PRE>
<P>Again, this is what we are implementing but the above description is what appears in the
BeBook as far as I understand it.</P>
</LI>
<LI><P><B>Sem:</B> The Sem() member function returns the sem_id of the semaphore used by the
BLocker. If the BLocker is a benaphore, then the sem_id returned is the semaphore used to
implement the benaphore. If the BLocker is a not a benaphore, then the sem_id returned is the
semaphore which the BLocker represents.</P></LI>
</OL>
<A NAME="implement"></A><H2>BLocker Implementation:</H2>
<P>For more information about how to implement a benaphore, you can reference an implementation
found on Be's website at
<A HREF="http://www-classic.be.com/aboutbe/benewsletter/Issue26.html">http://www-classic.be.com/aboutbe/benewsletter/Issue26.html</A>.</P>
</BODY>
</HTML>
@@ -0,0 +1,104 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<HTML>
<HEAD>
<TITLE>BMallocIO Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMallocIO Use Cases and Implementation Details:</H1>
<P>This document describes the BMallocIO interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMallocIO Interface</A></LI>
<LI><A HREF="#usecases">BMallocIO Use Cases</A></LI>
<LI><A HREF="#implement">BMallocIO Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMallocIO Interface:</H2>
<P>The BMallocIO class represent a buffer of dynamically allocated memory. The buffer is
automatically allocated by multiplies of a blocksize you can specify, so it will always be
big enough to contain the data. The best source of information for the BMallocIO interface
can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/MemoryIO.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMallocIO Use Cases:</H2>
<P>The following use cases cover the BMallocIO functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> The BMallocIO constructor set the blocksize to 256.</P></LI>
<LI><P><B>Destruction:</B> The BMallocIO destructor frees the allocated memory.</P></LI>
<LI><P><B>Reading 1:</B> When ReadAt() is called, the BMallocIO returns the number of bytes read from the specified
position. ReadAt() takes three arguments: the position where to begin the read operation, the buffer where to put the read data,
and the number of bytes to read. This function does not read outside of the buffer.
If the specified position is invalid (i.e. outside bounds) this function returns 0. If the read operation
begins at a valid position, but the sum of position and bytes to read is bigger than the size of the buffer, BMallocIO
returns just the available data.</P></LI>
<LI><P><B>Reading 2.</B> BMallocIO inherits the Read() function from BPositionIO. This function read the specified amount
of data from the current position, and put it into the specified buffer, then it moves the I/O index forward of the number of read bytes.
This function behaves like the above. </P></LI>
<LI><P><B>Writing 1:</B> When WriteAt() is called, BMallocIO returns the number of bytes written to the specified position.
WriteAt() takes three arguments: the position where to begin the write operation, the buffer from which to read the data to write, and the
number of bytes to write.
If the write position is beyond the buffer length, BMallocIO enlarges the buffer to accomodate the data. If enlarging fails, the function
returns B_NO_MEMORY.
</P></LI>
<LI><P><B>Writing 2.</B> BMallocIO inherits the Write() function from BPositionIO. This function write the specified amount
of data to the current position of the BMallocIO object, reading from the specified buffer, then it moves the I/O index forward
of the number of read bytes.
This function behaves like the above. </P></LI>
<LI><P><B>Size Changes:</B> The SetSize() member function enlarges or shrink the amount of data which can be read/write.
Shrinking the buffer is always possible, and the function returns B_OK. Zero frees the memory, while negative values are
not allowed, and the function returns B_ERROR.
</P></LI>
<LI><P><B>Seeking.</B> Seek() sets the position in the data buffer where the Read() and Write() functions (inherited from
BPositionIO) begin reading and writing. How the position argument is understood depends on the mode flag. There are three possible modes:
<UL>
<LI><P>
SEEK_SET. The position passed is an offset from the beginning of allocated memory; in other
words, the current position is set to position. For this mode, position should be a positive
value.
</P></LI>
<LI><P>
SEEK_CUR. The position argument is an offset from the current position; the value of the
argument is added to the current position. </P></LI>
<LI><P>
SEEK_END. The position argument is an offset from the end of the buffer for a BMallocIO
object. Positive values seek beyond the end of the buffer or data; negative
values seek backwards into the data. </P></LI>
</UL>
Seek() Always return the new position.
</P></LI>
<LI><P><B>Position:</B> The Position() call always return the current position.</P></LI>
<LI><P><B>Setting the BlockSize:</B> The SetBlockSize() call let you specify
the blocksize which BMallocIO uses to allocate memory.</P></LI>
<LI><P><B>Getting the Buffer:</B> The Buffer() call returns the buffer used internally
by BMallocIO.</P></LI>
<LI><P><B>Getting the Buffer Lenght:</B> The BufferLength() call returns the length
of the buffer.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMallocIO Implementation:</H2>
</BODY>
</HTML>
@@ -0,0 +1,106 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<HTML>
<HEAD>
<TITLE>BMemoryIO Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMemoryIO Use Cases and Implementation Details:</H1>
<P>This document describes the BMemoryIO interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMemoryIO Interface</A></LI>
<LI><A HREF="#usecases">BMemoryIO Use Cases</A></LI>
<LI><A HREF="#implement">BMemoryIO Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMemoryIO Interface:</H2>
<P>The BMemoryIO class represent a buffer of dynamically allocated memory. You assign the
buffer to a BMemoryIO object on construction. The best source of information for the BMemoryIO interface
can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/MemoryIO.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMemoryIO Use Cases:</H2>
<P>The following use cases cover the BMemoryIO functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BMemoryIO can be created by specifying a void pointer
and a ssize_t option. These options are used to determine the buffer to assign to the BMemoryIO object and its
size. No check is done to determine if the buffer is valid or if it contains at least the number of byte specified.</P></LI>
<LI><P><B>Construction 2:</B> As the one above, but the buffer is specified with a const void pointer.
The BMemoryIO object becomes read only, and every subsequent Write(), WriteAt() and SetSize() calls will
return B_NOT_ALLOWED.</P></LI>
<LI><P><B>Destruction:</B> The BMemoryIO destructor does nothing. It's up to the caller the responsibility
to free the buffer assigned on construction.</P></LI>
<LI><P><B>Reading 1:</B> When ReadAt() is called, the BMemoryIO returns the number of bytes read from the specified
position. ReadAt() takes three arguments: the position where to begin the read operation, the buffer where to put the read data,
and the number of bytes to read. This function does not read outside of the buffer.
If the specified position is invalid (i.e. outside bounds) this function returns 0. If the read operation
begins at a valid position, but the sum of position and bytes to read is bigger than the max size (specified on construction), BMemoryIO
returns just the available data.</P></LI>
<LI><P><B>Reading 2.</B> BMemoryIO inherits the Read() function from BPositionIO. This function read the specified amount
of data from the current position, and put it into the specified buffer, then it moves the I/O index forward of the number of read bytes.
This function behaves like the above. </P></LI>
<LI><P><B>Writing 1:</B> When WriteAt() is called, BMemoryIO returns the number of bytes written to the specified position.
WriteAt() takes three arguments: the position where to begin the write operation, the buffer from which to read the data to write, and the
number of bytes to write. If the BMemoryIO object was constructed with the const constructor, this function returns B_NOT_ALLOWED.
This function does not write outside of the buffer bounds. If the specified position is invalid (i.e. outside bounds) this function returns 0. If the write operation begins at a valid position, but the sum of position and bytes to write is bigger than the max size (specified on construction), BMemoryIO
returns just the amount of data which can be written.
If the BMemoryIO object has been shrunk (see the Size Change case), and the write operation is outside the current bounds (but inside the
bounds specified on construction) this function re-enlarge it to accomodate the data.</P></LI>
<LI><P><B>Writing 2.</B> BMemoryIO inherits the Write() function from BPositionIO. This function write the specified amount
of data to the current position of the BMemoryIO object, reading from the specified buffer, then it moves the I/O index forward
of the number of read bytes.
This function behaves like the above. </P></LI>
<LI><P><B>Size Changes:</B> The SetSize() member function enlarges or shrink the amount of data which can be read/write.
If the BMemoryIO object was constructed with the const constructor, this function always returns B_NOT_ALLOWED.
Any SetSize call with a size parameter bigger than the size specified on construction will fail and return B_ERROR. Shrinking the buffer
is always possible, and the function returns B_OK. Negative values are not allowed, and the function returns B_ERROR.
</P></LI>
<LI><P><B>Seeking.</B> Seek() sets the position in the data buffer where the Read() and Write() functions (inherited from
BPositionIO) begin reading and writing. How the position argument is understood depends on the mode flag. There are three possible modes:
<UL>
<LI><P>
SEEK_SET. The position passed is an offset from the beginning of allocated memory; in other
words, the current position is set to position. For this mode, position should be a positive
value.
</P></LI>
<LI><P>
SEEK_CUR. The position argument is an offset from the current position; the value of the
argument is added to the current position. </P></LI>
<LI><P>
SEEK_END. The position argument is an offset from the end of the buffer for a BMemoryIO
object. Positive values seek beyond the end of the buffer or data; negative
values seek backwards into the data. </P></LI>
</UL>
Seek() Always return the new position.
</P></LI>
<LI><P><B>Position:</B> The Position() call always return the current position.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMemoryIO Implementation:</H2>
<P>The implementation of the BMemoryIO is simple. It consist in implementing memory read/write on a buffer
with an index.</P>
</BODY>
</HTML>
@@ -0,0 +1,61 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<HTML>
<HEAD>
<TITLE>BString Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BString Use Cases and Implementation Details:</H1>
<P>This document describes the BString interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BString Interface</A></LI>
<LI><A HREF="#usecases">BString Use Cases</A></LI>
<LI><A HREF="#implement">BString Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BString Interface:</H2>
<P>The BString is as string allocation and manipulation class. The object allocates and deallocates
memory for you so the buffer will always be "big enough" to contain the data.
BString provides a number of charachter search, comparison, and manipulation functions in
a variety of flavors. The best source of information about the BString class can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/String.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BString Use Cases:</H2>
<P>The following use cases cover the BString functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BString can be created with an empty constructor.
This way the created BString is empty.</P></LI>
<LI><P><B>Construction 2:</B> You can create a BString object with a const char pointer as
parameter. After the construction, the BString object contains a copy of the string pointed
by the const char pointer.</P></LI>
<LI><P><B>Construction 3:</B> BString can be created using a copy constructor.
The parameter is another BString. After the construction, your BString will contain a
copy of the other BString.</P></LI>
<LI><P><B>Construction 4:</B> You can create a BString object with a const char pointer as
parameter and an int32 parameter, which specifies the maximum bytes BString will consider.
After the construction, the BString object contains a maximum of bytes (specified by the int32
parameter) of the string pointed by the pointer.</P></LI>
<LI><P><B>Destruction:</B> The BString destructor frees the allocated memory.</P></LI>
</OL>
<A NAME="implement"></A><H2>BString Implementation:</H2>
</BODY>
</HTML>