427 lines
33 KiB
HTML
427 lines
33 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Be Newsletters - Volume 4: 1999</title><link rel="stylesheet" href="be_newsletter.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
|
||
<link rel="stylesheet" type="text/css" href="be_newsletter_ie.css" />
|
||
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="Be Newsletters" /><link rel="up" href="volume4.html" title="Volume 4: 1999" /><link rel="prev" href="Issue4-31.html" title="Issue 4-31, August 4, 1999" /><link rel="next" href="Issue4-33.html" title="Issue 4-33, August 18, 1999" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="Issue4-31.html" title="Issue 4-31, August 4, 1999"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="volume4.html" title="Volume 4: 1999"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="Issue4-33.html" title="Issue 4-33, August 18, 1999"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">Be Newsletters - Volume 4: 1999</div></div><div id="headerB">Prev: <a href="Issue4-31.html">Issue 4-31, August 4, 1999</a> Up: <a href="volume4.html">Volume 4: 1999</a> Next: <a href="Issue4-33.html">Issue 4-33, August 18, 1999</a></div><hr /></div><div class="article"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="Issue4-32"></a>Issue 4-32, August 11, 1999</h2></div></div></div><div class="sect1"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="Engineering4-32"></a>Be Engineering Insights:<br />
|
||
I. Making Your BLoopers More Responsive<br />
|
||
II. Gamma Correction
|
||
</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Jean-Baptiste</span> <span class="surname">Queru</span></span></div></div></div><p>
|
||
Some of my fellow engineers tell me that I'm lucky to have so many ideas
|
||
for my newsletter articles. They couldn't be more wrong. Having to choose
|
||
between two ideas is much harder (at least for me) than having to find
|
||
one idea. After whittling a pile of ideas down to just two, I couldn't
|
||
choose between them, so I'm using both for this article.
|
||
</p><p>
|
||
You can find the source for them here:
|
||
ftp://ftp.be.com/pub/samples/graphics/gamma.zip
|
||
</p><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id807993"></a>Part I: Responsive BLoopers</h3></div></div></div><p>
|
||
Something that BeOS developers must keep in mind when programming their
|
||
user interface is that users don't like interfaces to feel slow or
|
||
sluggish. One key to interface responsiveness is to let the <code class="classname">BLooper</code> run
|
||
freely and process messages. To achieve this goal, you must make sure
|
||
that your program doesn't spend too much time sitting in the various
|
||
virtual functions that the <code class="classname">BLooper</code> will call
|
||
in its <code class="classname">BHandler</code>s. The sample
|
||
code for this article shows two techniques that should cover a reasonable
|
||
number of common cases.
|
||
</p><div class="sect3"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id808022"></a>Use Asynchronous Controls</h4></div></div></div><p>
|
||
In older versions of BeOS, the only way to track the mouse to dynamically
|
||
change a control was to repeatedly call <code class="methodname">GetMouse()</code> in a loop. The BeBook
|
||
mistakenly suggested doing this in <code class="methodname">MouseMoved()</code>, which would prevent the
|
||
BLooper from processing message as long as the mouse button was held
|
||
down, which could be a very long time. The correct way to do this was to
|
||
poll in a separate thread, a tricky thing to set up and to tear down
|
||
without deadlocking.
|
||
</p><p>
|
||
Fortunately, R4 added an elegant way to solve the problem: the view event
|
||
mask, which lets you create asynchronous controls. Since this has already
|
||
been explained in other Newsletter articles, I won't say much about it,
|
||
but you can look at the sample code to see one of those beasts in action.
|
||
For more information,
|
||
</p><p>
|
||
see: <a class="xref" href="Issue3-45.html#Engineering3-45" title="Be Engineering Insights: That BeOS is one baaad mother-[Shut your mouth!] ...just talking 'bout BeOS">Be Engineering Insights: That BeOS is one baaad mother-[Shut your mouth!]
|
||
...just talking 'bout BeOS</a><br />
|
||
and<br />
|
||
<a class="xref" href="Issue3-46.html#Engineering3-46" title="Be Engineering Insights: The Kitchen Sink">Be Engineering Insights: The Kitchen Sink</a>
|
||
</p></div><div class="sect3"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id808073"></a>Use Other Threads to Do the Actual Work</h4></div></div></div><p>
|
||
We're now reaching the heart of the problem. The naive way to implement
|
||
real time user feedback with asynchronous controls is to redraw the
|
||
display each time <code class="methodname">MouseMoved()</code> is called.
|
||
Change the <code class="code">#if</code> in the sample
|
||
code to see what happens in that case. This is not what a user wants to
|
||
see, and it gets worse as the processing time gets longer. A temporary
|
||
solution might be to eliminate some of the <code class="constant">B_MOUSE_MOVED</code> messages by hand
|
||
in the <code class="classname">BMessageQueue</code> before they're dispatched; this only works if the
|
||
processing stays reasonably short and if the <code class="classname">BLooper</code>
|
||
is a <code class="classname">BWindow</code>.
|
||
</p><p>
|
||
A more general solution is to have another thread do the work for the
|
||
<code class="classname">BLooper</code>, so the <code class="classname">BLooper</code>
|
||
can continue processing messages (e.g., update
|
||
messages) as they come along. Since setting up and tearing down threads
|
||
can be painful, and can easily create deadlocks and other race
|
||
conditions, I've encapsulated all that work in two classes—called
|
||
<code class="classname">SignalSender</code> and <code class="classname">SignalCatcher</code> --
|
||
that I hope will be reasonably easy to
|
||
use. Those classes are an example of how easy it is to create your own
|
||
synchronization classes, and you might even find them useful in their
|
||
current state.
|
||
</p></div></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id808143"></a>Part II: Gamma correction.</h3></div></div></div><p>
|
||
The sample code is not only interesting because of the programming
|
||
techniques it uses, but also because of what it does. This small program
|
||
is actually intended to calibrate a gamma correction system and to use
|
||
this system to draw anti-aliased lines.
|
||
</p><p>
|
||
Gamma is a very simple process. The intensity of light created by a CRT
|
||
is a nonlinear function of its input voltage. Gamma is a parameter that
|
||
represents this nonlinearity, and gamma correction is the process of
|
||
compensating for this nonlinearity. Surprisingly, this nonlinearity is
|
||
the same for all CRTs: the intensity of light produced by the CRT is
|
||
proportional to the input voltage raised to the power 2.5. You can thus
|
||
repeat after me: "Gamma is 2.5."
|
||
</p><p>
|
||
There are, however, many components between the framebuffer (or, more
|
||
precisely, the DAC) and the CRT's input: various amplifiers, filters,
|
||
brighness/contrast controls. Overall, those components scale and offset
|
||
the signal between the DAC and the CRT.
|
||
</p><p>
|
||
All the math is done in a <code class="classname">GammaCorrect</code> class, so you don't have to know
|
||
exactly how it works if you don't want to.
|
||
</p><p>
|
||
The patterns displayed by the program are these:
|
||
</p><ul class="itemizedlist"><li><p>
|
||
In the top-left corner, a median blend of black and white (note that
|
||
I'm using lines, because some monitors, although expensive, have some
|
||
limitations that make other patterns yield incorrect results).
|
||
</p></li><li><p>
|
||
In the top-right corner, a plain gray that you can select using the
|
||
control in the bottom of the screen and that you must try to adjust to
|
||
the brightness of the black and white pattern.
|
||
</p></li><li><p>
|
||
In the bottom-left corner, a system of high-frequency ripples that
|
||
show some circular moire patterns if the gamma correction is not
|
||
properly calibrated.
|
||
</p></li><li><p>
|
||
In the bottom-right corner, some gamma-corrected anti-aliased lines,
|
||
compared to the standard lines.
|
||
</p></li></ul><p>
|
||
Right now, nothing is done by the OS, and everything has to be done by
|
||
the applications. This will probably change in a future release, but this
|
||
sample code shows how to use some gamma correction without any OS support.
|
||
</p><p>
|
||
If you want to know more about how it really works, here's the beginning
|
||
of an explanation. If we call <code class="literal">f</code> the value for a pixel in the
|
||
framebuffer and <code class="literal">l</code> the lightness on the screen for this pixel, we can
|
||
write that <code class="literal">l</code> is proportional to
|
||
<code class="literal">(f+e)^2.5</code>. Since it's more convenient to
|
||
use values between 0 and 1, we'll renormalize <code class="literal">l</code> in that range with to
|
||
renormalization factors that we'll call <code class="literal">a</code> and
|
||
<code class="literal">b</code>, so that <code class="literal">l=a*l'+b</code> (<code class="literal">l'</code> is
|
||
the normalized version of <code class="literal">l</code>). We can finally write that
|
||
<code class="literal">f=((l'-b)/a)^0.4-e</code>, where <code class="literal">f</code> will
|
||
vary between 0 and 1 when <code class="literal">l'</code> varies
|
||
between 0 and 1.
|
||
</p><p>
|
||
The sample code will compute <code class="literal">a</code>, <code class="literal">b</code>,
|
||
and <code class="literal">e</code> from another value <code class="literal">m</code> that I call
|
||
the "mid-light" value; i.e., the gray level that is as light as a median
|
||
blend of black and white. With ideal monitor settings, <code class="literal">m</code> should be
|
||
approximately 3/4, so that we get <code class="literal">a=1</code>, <code class="literal">b=0</code>
|
||
and <code class="literal">e=0</code>.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id808327"></a>Part III: Conclusion</h3></div></div></div><p>
|
||
I hope this article casts some light on a few useful programming tricks.
|
||
Please send your feedback to jbq@be.com
|
||
</p></div></div><hr class="pagebreak" /><div class="sect1"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="Engineering4-32-2"></a>Be Engineering Insights: Common ioctls and Error codes for Drivers</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Arve</span> <span class="surname">Hjønnevåg</span></span></div></div></div><p>
|
||
If you look in the file <code class="filename">be/drivers/Drivers.h</code>
|
||
in your system headers,
|
||
you'll find a list of Be-defined opcodes for ioctls. A driver may choose
|
||
to implement any of these, but all implemented ioctls need to behave as
|
||
defined by us. Some ioctls are required for certain types of devices.
|
||
Let's go through the opcodes defined for Release 4.5.
|
||
</p><p>
|
||
<code class="constant">B_GET_DRIVER_FOR_DEVICE</code>, <code class="constant">B_GET_PARTITION_INFO</code>,
|
||
and <code class="constant">B_SET_PARTITION</code> are
|
||
implemented in devfs. You should not implement any of these.
|
||
</p><p>
|
||
<code class="constant">B_GET_DEVICE_SIZE</code> and <code class="constant">B_SET_DEVICE_SIZE</code>
|
||
are obsolete calls that operate
|
||
on 32-bit numbers.
|
||
</p><p>
|
||
<code class="constant">B_SET_NONBLOCKING_IO</code> and <code class="constant">B_SET_BLOCKING_IO</code>, are used to change a file
|
||
descriptor to blocking or nonblocking mode. Devices where a read or write
|
||
operation depends on other events to complete should implement these. The
|
||
driver also sets the mode on open according to the <code class="constant">O_NONBLOCK</code> flag.
|
||
</p><p>
|
||
<code class="constant">B_GET_READ_STATUS</code> and <code class="constant">B_GET_WRITE_STATUS</code>
|
||
are used, in blocking IO mode,
|
||
to determine if a following read or write will block. A pointer to a bool
|
||
is passed as the argument, and the driver writes set the value to false
|
||
if the operation will block, and true if not.
|
||
</p><p>
|
||
<code class="constant">B_GET_GEOMETRY</code> is used to get information about a disk device. All
|
||
drivers that publish their device under /dev/disk/ should implement this.
|
||
The argument to this call is a pointer to the following structure:
|
||
</p><pre class="programlisting c">
|
||
typedef struct {
|
||
<span class="type">uint32</span> <code class="varname">bytes_per_sector</code>; <span class="comment">/* sector size in bytes */</span>
|
||
<span class="type">uint32</span> <code class="varname">sectors_per_track</code>; <span class="comment">/* # sectors per track */</span>
|
||
<span class="type">uint32</span> <code class="varname">cylinder_count</code>; <span class="comment">/* # cylinders */</span>
|
||
<span class="type">uint32</span> <code class="varname">head_count</code>; <span class="comment">/* # heads */</span>
|
||
<span class="type">uchar</span> <code class="varname">device_type</code>; <span class="comment">/* type */</span>
|
||
<span class="type">bool</span> <code class="varname">removable</code>; <span class="comment">/* non-zero if removable */</span>
|
||
<span class="type">bool</span> <code class="varname">read_only</code>; <span class="comment">/* non-zero if read only */</span>
|
||
<span class="type">bool</span> <code class="varname">write_once</code>; <span class="comment">/* non-zero if write-once */</span>
|
||
} <span class="type">device_geometry</span>;
|
||
</pre><p>
|
||
For block devices, bytes per sector should match the block size of the
|
||
physical device. A file system mounted on your device will not try to
|
||
read partial blocks. Most devices do not expose accurate information
|
||
about the relation of cylinders, heads, and sectors, but the number of
|
||
usable blocks in the device should match sectors per track*cylinder
|
||
count*head count.
|
||
</p><p>
|
||
When using this call to determine the size of a device, make sure to use
|
||
64-bit precision for the calculation.
|
||
</p><pre class="programlisting c">
|
||
<span class="type">device_geometry</span> <code class="varname">g</code>;
|
||
<span class="type">off_t</span> <code class="varname">devsize</code>;
|
||
if(<code class="function">ioctl</code>(<code class="varname">devfd</code>, <code class="constant">B_GET_GEOMETRY</code>, &<code class="varname">g</code>) >= 0) {
|
||
<code class="varname">devsize</code> = (<span class="type">off_t</span>)<code class="varname">g</code>.<code class="varname">bytes_per_sector</code> *
|
||
(<span class="type">off_t</span>)<code class="varname">g</code>.<code class="varname">sectors_per_track</code> *
|
||
(<span class="type">off_t</span>)<code class="varname">g</code>.<code class="varname">cylinder_count</code> * (<span class="type">off_t</span>)<code class="varname">g</code>.<code class="varname">head_count</code>;
|
||
}
|
||
</pre><p>
|
||
The device type field indicates the type of the device. The most common
|
||
values here are <code class="constant">B_DISK</code> for hard drives and
|
||
<code class="constant">B_CD</code> for CD-ROMs.
|
||
</p><p>
|
||
If the media in the device is removable, the removable field should be
|
||
true. Some devices support media of different size and block size. If
|
||
there is no media in the drive, report a size and block size of 0.
|
||
</p><p>
|
||
The read only field is set if the driver knows that the media is not
|
||
writeable. Some devices may not be able to determine this, so make sure
|
||
your application deals with write operations failing.
|
||
</p><p>
|
||
write_once should normally be set to false.
|
||
</p><p>
|
||
<code class="constant">B_GET_BIOS_GEOMETRY</code>, <code class="constant">B_GET_BIOS_DRIVE_ID</code>: On the x86 platform, hard
|
||
drives can be accessed though the bios at boot time and from other
|
||
operating systems. <code class="constant">B_GET_BIOS_GEOMETRY</code> will fill in the same structure as
|
||
<code class="constant">B_GET_GEOMETRY</code>, but sectors per track, cylinder count, and head count
|
||
need to match the numbers used by the bios. This information is needed to
|
||
create a partition table that the bios can use. <code class="constant">B_GET_BIOS_DRIVE_ID</code> will
|
||
return the drive number the bios uses for this drive. This information is
|
||
needed when adding a disk to the boot menu.
|
||
</p><p>
|
||
<code class="constant">B_FORMAT_DEVICE</code> is used to format the media in the device. If your device
|
||
needs to prepare the media before it can be read and written to,
|
||
implement <code class="constant">B_FORMAT_DEVICE</code>.
|
||
</p><p>
|
||
<code class="constant">B_GET_ICON</code> allows a device to have a custom icon. Currently, our disk
|
||
drivers have the Be disk and CD-ROM icons built in, but we will provide a
|
||
simple way to specify standard icons in the future.
|
||
</p><p>
|
||
<code class="constant">B_EJECT_DEVICE</code> and <code class="constant">B_LOAD_MEDIA</code> are used to eject or load media.
|
||
</p><p>
|
||
B GET MEDIA STATUS is used to determine the state of the media in the
|
||
drive. This is described in detail in my article "Removable Media"
|
||
<http://www-classic.be.com/aboutbe/benewsletter/volume
|
||
II/Issue44.html#Insight>.
|
||
</p><p>
|
||
<code class="constant">B_SET_UNINTERRUPTABLE_IO</code> and
|
||
<code class="constant">B_SET_INTERRUPTABLE_IO</code> change how the driver
|
||
responds to signals. By default a driver should return to user space as
|
||
soon as possible when it receives <code class="constant">SIGINT</code>. A driver can use the
|
||
<code class="constant">B_CAN_INTERRUPT</code> flag when acquiring semaphores and can abort its operation if
|
||
<code class="constant">B_INTERRUPTED</code> is returned. However, when using the file system cache, a
|
||
read or write operation may carry data that doesn't belong to the current
|
||
thread. The file system uses <code class="constant">B_SET_UNINTERRUPTABLE_IO</code> to tell the driver
|
||
not to abort any operations. <code class="constant">B_SET_INTERRUPTABLE_IO</code> restores the default
|
||
state. A disk driver that wants to abort IO operations on signals needs
|
||
to implement these ioctls.
|
||
</p><p>
|
||
<code class="constant">B_FLUSH_DRIVE_CACHE</code> needs to be implemented by disk drivers if the device
|
||
has a write cache. If the device has a write cache, either a software
|
||
cache or hardware cache, a call to <code class="constant">B_FLUSH_DRIVE_CACHE</code> should not return
|
||
until all data in the cache has been written to the media.
|
||
</p><p>
|
||
If an opcode is not supported by your driver, return <code class="constant">B_DEV_INVALID_IOCTL</code>.
|
||
This will cause the ioctl call to return -1 with errno set to
|
||
<code class="constant">B_DEV_INVALID_IOCTL</code>. For all opcodes above you
|
||
should return <code class="constant">B_OK</code> or <code class="constant">B_NO_ERROR</code>
|
||
if the operation was successful. If the operation failed you need to
|
||
return an error. In the file be/support/Errors.h under your system
|
||
headers, you'll find error codes for a variety of error conditions. You
|
||
should try to pick the error code that best describes why the operation
|
||
failed. Let's look at the most common cases for drivers.
|
||
</p><p>
|
||
If you don't know why an operation failed, return <code class="constant">B_ERROR</code>.
|
||
</p><p>
|
||
If an operation failed because you could not allocate memory, return
|
||
<code class="constant">B_NO_MEMORY</code>.
|
||
</p><p>
|
||
If an IO operation fails, return <code class="constant">B_IO_ERROR</code>, or if your device has
|
||
additional information you can return more specific errors such as
|
||
<code class="constant">B_DEV_NO_MEDIA</code>, <code class="constant">B_DEV_UNREADABLE</code>,
|
||
<code class="constant">B_DEV_FORMAT_ERROR</code>, <code class="constant">B_DEV_TIMEOUT</code>,
|
||
<code class="constant">B_DEV_RECALIBRATE_ERROR</code>, <code class="constant">B_DEV_SEEK_ERROR</code>,
|
||
<code class="constant">B_DEV_READ_ERROR</code>, <code class="constant">B_DEV_WRITE_ERROR</code>,
|
||
<code class="constant">B_DEV_NOT_READY</code>, and <code class="constant">B_READ_ONLY_DEVICE</code>.
|
||
</p><p>
|
||
If someone tries to write to a read-only device or to write-protected
|
||
media, return <code class="constant">B_READ_ONLY_DEVICE</code>.
|
||
</p><p>
|
||
For devices with removable media it's also important that
|
||
<code class="constant">B_DEV_NO_MEDIA</code>
|
||
and <code class="constant">B_DEV_MEDIA_CHANGED</code> are returned when appropriate. Once opened, read
|
||
and write operations should fail with <code class="constant">B_DEV_MEDIA_CHANGED</code> if the media
|
||
changes. See the article "<a class="xref" href="Issue3-44.html#Engineering3-44" title="Be Engineering Insights: Removable Media">Be Engineering Insights: Removable Media</a>" for more info on how this
|
||
should be implemented.
|
||
</p></div><hr class="pagebreak" /><div class="sect1"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="DevWorkshop4-32"></a>Developers' Workshop: What's Going On in Documentation Land?</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Ken</span> <span class="surname">McDonald</span></span></div></div></div><p>
|
||
Recently, the DTS oraA long time ago, in an office far, far away (or at least, on the other
|
||
side of the building), I wrote a newsletter article about making and
|
||
using menus in BeOS GUI applications. One of the goals of that article
|
||
was to see how people responded to a more tutorial style of
|
||
documentation--something that didn't necessarily go into every last,
|
||
cotton-pickin' finicky little detail, but that did provide the basic
|
||
information necessary to use a class or classes in your program, in a
|
||
compact, easy -to-read form.
|
||
</p><p>
|
||
We were rather surprised at the number of responses generated by that
|
||
article, almost all of them positive. Well, it's been a while, and other
|
||
things came up of course, but now we're back in the tutorial game. In
|
||
fact, there will hopefully be quite a few more tutorial style documents
|
||
coming down the pipe in the future.
|
||
</p><p>
|
||
In light of this (and due to the fact that I didn't have the time or the
|
||
imagination to do anything else), it seemed apropos to do a sequel to my
|
||
previous newsletter tutorial. Think of this one as "Looking for Tutorial
|
||
Feedback II: Nightmare on BView Street". The first writeup in this new
|
||
tutorial series will be about the BView class, and the first part of this
|
||
writeup is a short, very high-level introduction located here:
|
||
</p><p>
|
||
<http://www-classic.be.com/aboutbe/benewsletter/volume_III/resources/articl
|
||
e.htm l>
|
||
</p><p>
|
||
I hope the technical content is useful, but the main purpose of
|
||
presenting this here is to elicit comments from you, the reader. We
|
||
expect to put quite a bit of effort into this series (hopefully resulting
|
||
in a complete tutorial for programming the BeOS), and given this, it
|
||
makes sense to develop a format which will make the information as useful
|
||
as possible. For example, one of the things I've done in the tutorial is
|
||
to include a sidebar on the left, giving easy access to the section and
|
||
subsection headings within the document. Is this a good idea? Can you
|
||
suggest other features which might be better, or complementary? As the
|
||
series progresses, I will be locked in to a certain format and approach,
|
||
in order to maintain consistency--but right now, the sky is the limit.
|
||
(Well, subject to resource constraints, of course :-) ) So suggest away!
|
||
</p><p>
|
||
And, of course, please make comments on the writing style and content
|
||
also. If nothing else, please tell me:
|
||
</p><div class="orderedlist"><ol><li><p>
|
||
What I'm doing right in the tutorial.
|
||
</p></li><li><p>
|
||
What I'm doing wrong.
|
||
</p></li><li><p>
|
||
What most needs to be covered by this sort of documentation.
|
||
</p></li></ol></div><p>
|
||
You can email directly to me, ken@be.com. (Nope, you don't get my home
|
||
phone number :-) ). If you could begin the subject line of any feedback
|
||
with the words "TUTORIAL COMMENTS", it would let me use the cool indexing
|
||
features of the Be file system to keep responses nicely sorted.
|
||
</p></div><hr class="pagebreak" /><div class="sect1"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BitByBit4-32"></a>Bit By Bit: Introducing <span class="application">Rephrase</span></h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Stephen</span> <span class="surname">Beaulieu</span></span></div></div></div><p>
|
||
Our application-building exercise begins with <span class="application"><span class="application">Rephrase</span></span>,
|
||
a <code class="classname">BTextView</code> based
|
||
text-processing application. Over the next few months, I'll add features
|
||
in each installment, and explain the BeOS coding philosophy behind them.
|
||
</p><p>
|
||
You'll find the first version of <span class="application">Rephrase</span> at
|
||
</p><p>
|
||
<ftp://ftp.be.com/pub/samples/tutorials/rephrase/rephrase0.1d1.zip>
|
||
</p><div class="blockquote"><blockquote class="blockquote"><p>
|
||
<span class="application">Rephrase</span> 0.1d1<br />
|
||
New Features:<br />
|
||
Edit text within the window.
|
||
Drag and drop for open and save.
|
||
About box.
|
||
</p></blockquote></div><p>
|
||
This limited version of <span class="application">Rephrase</span> is essentially an application wrapped
|
||
around a standard <code class="classname">BTextView</code>. It
|
||
has a <code class="classname">BApplication</code> and a <code class="classname">BWindow</code> for the
|
||
text view to live in. There is an About window, with a basic set of menu
|
||
items in the main window to bring up the about window, quit the
|
||
application, and edit the text.
|
||
</p><p>
|
||
The application's real functionality (limited as it is) comes from the
|
||
<code class="classname">BTextView</code>. It lets you cut, copy, paste, and select the text. It even
|
||
provides limited file i/o through inherent drag and drop capabilites:
|
||
select text and drag it to the Tracker to save a text clipping, or drag a
|
||
file to the view to paste in its contents.
|
||
</p><p>
|
||
Although it has only 164 lines of code (many of them blank or comments),
|
||
the application is surprisingly functional. With the addition of
|
||
resizing, scrollbars and real open and save capabilities, <span class="application">Rephrase</span> could
|
||
even be useful.
|
||
</p><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id809190"></a>Programming Concepts</h3></div></div></div><p>
|
||
BeOS uses a system of messaging to manage most aspects of communication
|
||
and event handling. <code class="classname">BLooper</code>s run an event loop in a thread that receives
|
||
incoming messages and dispatches them to associated <code class="classname">BHandler</code>s to be acted
|
||
on.
|
||
</p><p>
|
||
<code class="classname">BApplication</code> provides a connection to the Application Server, which
|
||
enables the messaging system for the app. It also serves as the main
|
||
looper for interapplication communication and application global
|
||
services, such as displaying an About window. A global pointer to the
|
||
<code class="classname">BApplication</code> object (<code class="varname">be_app</code>),
|
||
is available throughout the application.
|
||
</p><p>
|
||
<code class="classname">BWindow</code>s and <code class="classname">BView</code>s
|
||
are the specialized loopers and handlers for managing
|
||
the graphical user interface. When visible, a <code class="classname">BWindow</code> represents an area
|
||
on screen. A <code class="classname">BWindow</code> maintains a hierarchy of
|
||
<code class="classname">BView</code>s that draw in and
|
||
handle messages for sections of that area. User interaction generates
|
||
messages that are delivered to the window, which passes them to the
|
||
<code class="classname">BView</code>s to handle as appropriate.
|
||
</p><p>
|
||
For example, when you select a menu item in <span class="application">Rephrase</span>, a message is sent
|
||
to the <code class="classname">BMenuItem</code>'s target. The menu item's window is the default target.
|
||
However, the menu item can be told to send its message elsewhere. For
|
||
instance, when "About <span class="application">Rephrase</span>" is selected from the File menu, a message
|
||
is sent to the <code class="classname">BApplication</code>. All the menu items in the Edit menu send
|
||
their messages to the <code class="classname">BTextView</code>.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id809293"></a>Implementation Details</h3></div></div></div><div class="orderedlist"><ol><li><p>
|
||
In <code class="function">main()</code>, create the application on the stack, call
|
||
<code class="methodname">Run()</code> and
|
||
return after run completes.
|
||
</p></li><li><p>
|
||
Don't hard-code your interface details. Some views resize
|
||
themselves to match their contents. Menus, for example, resize to
|
||
match the size of the characters in their font. After you create and
|
||
add the menu, determine its size and use that information to place the
|
||
rest of your views. Change the size of your font in the Menu
|
||
preferences panel, run <span class="application">Rephrase</span> and see.
|
||
</p></li><li><p>
|
||
Do not delete a <code class="classname">BLooper</code>. Send it a
|
||
<code class="constant">B_QUIT_REQUESTED</code> message
|
||
instead. This calls its <code class="methodname">QuitRequested()</code> hook function, and if that
|
||
returns <code class="constant">true</code>, will call the <code class="methodname">Quit()</code> function which tears down the
|
||
looper.
|
||
</p></li><li><p>
|
||
Windows own their child views and will properly delete them when
|
||
destroyed. Only delete a view if you have already called <code class="methodname">RemoveChild()</code>
|
||
to remove it from its parent.
|
||
</p></li><li><p>
|
||
Invokers own their model messages and will properly delete them
|
||
when destroyed.
|
||
</p></li><li><p>
|
||
When an app's last window is asked to quit, it should request the
|
||
app to quit as well. If not, the application may hang around in the
|
||
Deskbar with no windows.
|
||
</p></li></ol></div></div><p>
|
||
Next week: Opening a file.
|
||
</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="Issue4-31.html">Issue 4-31, August 4, 1999</a> Up: <a href="volume4.html">Volume 4: 1999</a> Next: <a href="Issue4-33.html">Issue 4-33, August 18, 1999</a> </div><div id="footerB"><div id="footerBL"><a href="Issue4-31.html" title="Issue 4-31, August 4, 1999"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="volume4.html" title="Volume 4: 1999"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="Issue4-33.html" title="Issue 4-33, August 18, 1999"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
|
||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
|
||
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>
|