haiku-website/static/legacy-docs/benewsletter/Issue3-9.html

594 lines
44 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 3: 1998</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="volume3.html" title="Volume 3: 1998" /><link rel="prev" href="Issue3-8.html" title="Issue 3-8, February 25, 1998" /><link rel="next" href="Issue3-10.html" title="Issue 3-10, March 11, 1998" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="Issue3-8.html" title="Issue 3-8, February 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="Issue3-10.html" title="Issue 3-10, March 11, 1998"><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 3: 1998</div></div><div id="headerB">Prev: <a href="Issue3-8.html">Issue 3-8, February 25, 1998</a>  Up: <a href="volume3.html">Volume 3: 1998</a>  Next: <a href="Issue3-10.html">Issue 3-10, March 11, 1998</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="Issue3-9"></a>Issue 3-9, March 4, 1998</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="Engineering3-9"></a>Be Engineering Insights: Fun with Tabs and Sliders</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Robert</span> <span class="surname">Chinn</span></span></div></div></div><p>
When you receive Release 3 of the BeOS, among other grander and more
important advances, you'll find that the Interface Kit now contains two
more classes, <code class="classname">BTabView</code> and
<code class="classname">BSlider</code>. Since they're new I'd like to
introduce them and discuss how to use them.
</p><p>
A tabview is a simple container object that allows you to separate and
present information in a clean, easily accessed fashion. Instead of using
a pop-up menu to toggle between pages of information, you can use a
tabview to provide an interface that presents topics and focused
information to the user.
</p><p>
<code class="classname">BTabView</code> is a simple and pretty much self-contained class that doesn't
require a lot of maintenance once it has been constructed. In its most
basic form there are only two things you need to do to use a <code class="classname">BTabView</code>:
construct it and add views to it.
</p><pre class="programlisting cpp">
<span class="type"><code class="classname">BTabView</code>*</span> <code class="varname">tab_container</code> = new <code class="classname">BTabView</code>( <code class="classname">BRect</code>(0,0,320,240),
"tab container",
<code class="constant">B_WIDTH_AS_USUAL</code>,
<code class="constant">B_FOLLOW_LEFT</code> | <code class="constant">B_FOLLOW_RIGHT</code>,
<code class="constant">B_WILL_DRAW</code> | <code class="constant">B_NAVIGABLE</code>);
</pre><p>
This constructs an empty tab container and shows no tabs. As with most
other simple <code class="classname">BView</code> derivatives, you pass in the
<code class="parameter">frame</code>, <code class="parameter">name</code>,
<code class="parameter">resizing_mode</code>, and view <code class="parameter">flags</code>.
The only other item in the constructor for a
tabview is the <code class="parameter">button_width</code> parameter, which configures the width of each
tab that the tabview presents. This parameter has three options, which
are identical to those used in a <code class="classname">BAlert</code>:
</p><pre class="screen">
<code class="constant">B_WIDTH_AS_USUAL</code> —sets the tab width to the
default of 100
<code class="constant">B_WIDTH_FROM_WIDEST</code>—bases all tab widths on the
longest tab name
<code class="constant">B_WIDTH_FROM_LABEL</code> —bases each tab width on
its related name
</pre><p>
To add a tab to the tabview you need to call the following:
</p><pre class="programlisting cpp">
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>(<code class="varname">tab_view_1</code>, <code class="constant">NULL</code>);
</pre><p>
where <code class="varname">tab_view_1</code> is a <code class="classname">BView</code> that contains the rest of the objects you
want to present in this "page." The name of the tab associated with the
page is the name of the view that you add in the <code class="methodname">AddTab()</code> call. Also, the
location of the view to be added, if set to 0,0, will be the left edge of
the tab, just below and inside the box drawn by the tabview.
</p><p>
The optional parameter to the <code class="methodname">AddTab()</code>
method, in this case <code class="constant">NULL</code>, is a <code class="classname">BTab</code>
pointer. The <code class="classname">BTab</code> class is a simple non-view class that simply draws to a
target view. Using this parameter you can override the default <code class="classname">BTab</code>
object and perform custom drawing for each individual tab.
</p><p>
As you make successive calls to <code class="methodname">AddTab()</code>,
</p><pre class="programlisting cpp">
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>( <code class="varname">tab_view_2</code> );
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>( <code class="varname">tab_view_3</code> );
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>( <code class="varname">tab_view_4</code> );
</pre><p>
more tabs are added to the tabview. When the user clicks on any of these
tabs, the view it is associated with is added to the tabview via
<code class="methodname">AddChild()</code>, and made visible, while the previous visible view is hidden as
a result of <code class="methodname">RemoveChild()</code>. That's all it takes to make a tabview functional
in an application.
</p><p>
The second class I'd like to introduce is <code class="classname">BSlider</code>.
Like <code class="classname">BTabView</code>, this is
also a simple class, based on <code class="classname">BControl</code>, that presents itself as a slider
control. As with any other <code class="classname">BControl</code>-based objects the construction is
quite simple:
</p><pre class="programlisting cpp">
<span class="type"><code class="classname">BSlider</code>*</span> <code class="varname">slider</code> = new <code class="classname">BSlider</code> ( <code class="classname">BRect</code> (0,0,100,10),
"slider",
"Some value:",
new <code class="classname">BMessage</code>('slde'),
0, 255,
<code class="constant">B_BLOCK_THUMB</code>);
</pre><p>
The first four parameters are the standard <code class="classname">BControl</code> parameters:
<code class="parameter">frame</code>,
<code class="parameter">name</code>, <code class="parameter">label</code>, and <code class="parameter">message</code>.
The message is sent when you move the slider
and release it. The fifth and sixth parameters are the <code class="parameter">minimum</code> and
<code class="parameter">maximum</code> values for the slider. The last parameter is the thumb style,
which can be set to one of two built-in thumbs, a rectangle (as used in
the Keyboard preferences) or a triangle (as used in the Fonts
preferences).
</p><p>
If you take a look at the <span class="application">VirtualMemory</span> preferences application you'll
notice that the bar color to the left of the thumb is different from the
color to the right. To accomplish this, simply do the following:
</p><pre class="programlisting cpp">
<span class="type">rgb_color</span> <code class="varname">color</code>;
<code class="varname">color</code>.<code class="varname">red</code> = <code class="varname">color</code>.<code class="varname">green</code> = 102;
<code class="varname">color</code>.<code class="varname">blue</code> = 152;
<code class="varname">color</code>.<code class="varname">alpha</code> = 255;
<code class="varname">slider</code>-&gt;<code class="methodname">UseFillColor</code>(<code class="constant">true</code>, &amp;<code class="varname">color</code>);
</pre><p>
The callback method <code class="methodname">UpdateText()</code> provides live updating of information. In
this method you can call <code class="methodname">Value()</code> or
<code class="methodname">Position()</code> to obtain information relating
to the slider and return a string of text to present to the user; in its
default state it simply returns <code class="constant">NULL</code>.
</p><pre class="programlisting cpp">
<span class="type">char*</span>
<code class="classname">DemoSlider</code>::<code class="varname">UpdateText</code>()
{
<span class="type">char</span> <code class="varname">msg</code>[32];
<code class="function">sprintf</code>(<code class="varname">msg</code>, "The current value is: %i.", <code class="methodname">Value</code>());
return <code class="varname">msg</code>;
}
</pre><p>
The slider can have as many as four different labels or none. The
standard <code class="classname">BControl</code> label is drawn at the top
left; set via <code class="methodname">SetLimitLabels()</code>
(the minimum and maximum labels) in the bottom left and right; and the
string returned from <code class="methodname">UpdateText()</code> in the top right. If any of these labels
is set to <code class="constant">NULL</code>, it will not be drawn.
</p><p>
To recap, here is a bit of code that builds two sliders in a two-tab
tabview. The second slider is a custom slider to demonstrate use of the
<code class="methodname">UpdateText()</code> callback.
</p><pre class="programlisting cpp">
class <code class="classname">DemoSlider</code> : public <code class="classname">BSlider</code> {
public:
<code class="methodname">DemoSlider</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">char *</span><code class="parameter">label</code>, <span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">msg</code>,
<span class="type">int32</span> <code class="parameter">min</code>, <span class="type">int32</span> <code class="parameter">max</code>, <span class="type">thumb_style</span> <code class="parameter">t</code>);
<code class="methodname">~DemoSlider</code>();
<span class="type">char*</span> <code class="methodname">UpdateText</code>() const;
private:
<span class="type">char*</span> <code class="varname">fStatus</code>;
};
<code class="classname">DemoSlider</code>::<code class="methodname">DemoSlider</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">char *</span><code class="parameter">label</code>,
<span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">msg</code>, <span class="type">int32</span> <code class="parameter">min</code>, <span class="type">int32</span> <code class="parameter">max</code>, <span class="type">thumb_style</span> <code class="parameter">t</code>)
: <code class="classname">BSlider</code>(frame,"demo slider",label,msg, min, max, t)
{
<span class="comment">// allocate some space for the string to be returned in</span>
<span class="comment">// UpdateText. use malloc so that Pavel will yell at me</span>
<code class="varname">fStatus</code> = (<span class="type">char*</span>)<code class="function">malloc</code>(64);
}
<code class="classname">DemoSlider</code>::<code class="methodname">~DemoSlider</code>()
{
if (<code class="varname">fStatus</code>)
<code class="function">free</code>(<code class="varname">fStatus</code>);
}
<span class="comment">// When the slider's Draw method is called, this method</span>
<span class="comment">// will also be called. If its return value is non-NULL,</span>
<span class="comment">// then it will be drawn with the rest of the slider</span>
<span class="type">char*</span>
<code class="classname">DemoSlider</code>::<code class="methodname">UpdateText</code>() const
{
if (<code class="varname">fStatus</code> &amp;&amp; <code class="methodname">Window</code>()-&gt;<code class="methodname">Lock</code>()) {
<code class="function">sprintf</code>(<code class="varname">fStatus</code>,"Current value is %i",<code class="methodname">Value</code>());
<code class="methodname">Window</code>()-&gt;<code class="methodname">Unlock</code>();
return <code class="varname">fStatus</code>;
} else
return <code class="constant">NULL</code>;
}
static <span class="type">void</span>
<code class="function">DoMe</code>()
{
<span class="comment">// construct a simple window</span>
<span class="type"><code class="classname">BWindow</code>*</span> <code class="varname">a_window</code> = new <code class="classname">BWindow</code>(<code class="classname">BRect</code>(25, 25, 345, 165),
"New Control Demo",
<code class="constant">B_TITLED_WINDOW</code>,
<code class="constant">B_NOT_ZOOMABLE</code> | <code class="constant">B_NOT_RESIZABLE</code>);
<span class="comment">// construct a tabview</span>
<span class="comment">// make the tab width based on the widest label</span>
<span class="type"><code class="classname">BTabView</code>*</span> <code class="varname">tab_container</code> = new <code class="classname">BTabView</code>(
<code class="classname">BRect</code>(0, 0, 320, 140), "tab container",
<code class="constant">B_WIDTH_FROM_WIDEST</code>);
<code class="varname">a_window</code>-&gt;<code class="methodname">AddChild</code>(<code class="varname">tab_container</code>);
<span class="comment">// do a quick calculation to determine the height of the</span>
<span class="comment">// content region of the tabview</span>
<span class="type">float</span> <code class="varname">contents_height</code> =
<code class="varname">tab_container</code>-&gt;<code class="methodname">Bounds</code>().<code class="methodname">Height</code>() -
<code class="varname">tab_container</code>-&gt;<code class="methodname">TabHeight</code>();
<code class="classname">BRect</code> <code class="varname">contents_rect</code>(0, 0, <code class="varname">tab_container</code>-&gt;<code class="methodname">Bounds</code>().<code class="methodname">Width</code>(),
<code class="varname">contents_height</code>);
<code class="classname">BRect</code> <code class="varname">slider_rect</code>(<code class="varname">contents_rect</code>);
<code class="varname">slider_rect</code>.<code class="methodname">InsetBy</code>(25,25);
<span class="comment">// construct a view to hold the first control</span>
<span class="comment">// the name of the tab associated with this view</span>
<span class="comment">// will be the name of this view</span>
<span class="type"><code class="classname">BView</code>*</span> <code class="varname">bg_1</code> = new <code class="classname">BView</code>(<code class="varname">contents_rect</code>,
"Slider with Block Thumb", <code class="constant">B_FOLLOW_NONE</code>, <code class="constant">B_WILL_DRAW</code>);
<span class="comment">// set the view to this control so that is blends in</span>
<span class="comment">// with the tabview</span>
<span class="comment">// set the alpha component so Hiroshi won't yell at you</span>
<code class="varname">bg_1</code>-&gt;<code class="methodname">SetViewColor</code>(216,216,216,255);
<span class="comment">// construct a slider with a block thumb</span>
<span class="comment">// the message that it will send will have a 'what' of 'blok'</span>
<span class="comment">// the minimum setting will be 0, the maximum will be 300</span>
<span class="type"><code class="classname">BSlider</code>*</span> <code class="varname">block_thumb_slider</code> = new <code class="classname">BSlider</code>(<code class="varname">slider_rect</code>,
"block thumb", "Slider Label", new <code class="classname">BMessage</code>('blok'), 0,
300, <code class="constant">B_BLOCK_THUMB</code>);
<span class="comment">// if this slider has the focus (set by tabbing to it),</span>
<span class="comment">// the left and right arrows will move it by 10</span>
<code class="varname">block_thumb_slider</code>-&gt;<code class="methodname">SetKeyIncrementValue</code>(10);
<span class="comment">// add some labels</span>
<code class="varname">block_thumb_slider</code>-&gt;<code class="methodname">SetLimitLabels</code>("minimum", "maximum");
<span class="comment">// add some hash marks</span>
<code class="varname">block_thumb_slider</code>-&gt;<code class="methodname">SetHashMarkCount</code>(5);
<code class="varname">block_thumb_slider</code>-&gt;<code class="methodname">SetHashMarks</code>(<code class="constant">B_HASH_MARKS_BOTH</code>);
<code class="varname">bg_1</code>-&gt;<code class="methodname">AddChild</code>(<code class="varname">block_thumb_slider</code>);
<span class="comment">// make this view (and control) a tab of the tabview</span>
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>(<code class="varname">bg_1</code>);
<span class="comment">// construct a second view</span>
<span class="type"><code class="classname">BView</code>*</span> <code class="varname">bg_2</code> = new <code class="classname">BView</code>(<code class="varname">contents_rect</code>,
"Slider with Triangle Thumb", <code class="constant">B_FOLLOW_NONE</code>, <code class="constant">B_WILL_DRAW</code>);
<code class="varname">bg_2</code>-&gt;<code class="methodname">SetViewColor</code>(216,216,216,255);
<span class="comment">// construct a custom slider with a triangle thumb</span>
<span class="comment">// when this slider is drawn, the text returned</span>
<span class="comment">// from UpdateText will be drawn in the</span>
<span class="comment">// upper right corner of the slider</span>
<span class="type"><code class="classname">DemoSlider</code>*</span> <code class="varname">triangle_thumb_slider</code> =
new <code class="classname">DemoSlider</code>(<code class="varname">slider_rect</code>,"", new <code class="classname">BMessage</code>('tri '), 1, 7,
<code class="constant">B_TRIANGLE_THUMB</code>);
<code class="varname">triangle_thumb_slider</code>-&gt;<code class="methodname">SetKeyIncrementValue</code>(1);
<code class="varname">triangle_thumb_slider</code>-&gt;<code class="methodname">SetLimitLabels</code>("one", "seven");
<code class="varname">triangle_thumb_slider</code>-&gt;<code class="methodname">SetHashMarkCount</code>(7);
<code class="varname">triangle_thumb_slider</code>-&gt;<code class="methodname">SetHashMarks</code>(<code class="constant">B_HASH_MARKS_BOTTOM</code>);
<span class="comment">// set the fill for left of thumb color</span>
<span class="type">rgb_color</span> <code class="varname">c</code>;
<code class="varname">c</code>.<code class="varname">green</code> = 102;
<code class="varname">c</code>.<code class="varname">red</code> = 102;
<code class="varname">c</code>.<code class="varname">blue</code> = 152;
<code class="varname">triangle_thumb_slider</code>-&gt;<code class="methodname">UseFillColor</code>(<code class="constant">true</code>,&amp;<code class="varname">c</code>);
<code class="varname">bg_2</code>-&gt;<code class="methodname">AddChild</code>(<code class="varname">triangle_thumb_slider</code>);
<code class="varname">tab_container</code>-&gt;<code class="methodname">AddTab</code>(<code class="varname">bg_2</code>);
<span class="comment">// the list of tabs is 0 based, make the first tab active</span>
<code class="varname">tab_container</code>-&gt;<code class="methodname">Select</code>(0);
<span class="comment">// make the window visible</span>
<code class="varname">a_window</code>-&gt;<code class="methodname">Show</code>();
}
</pre><p>
Both <code class="classname">BSlider</code> and <code class="classname">BTabView</code> are fairly simple. The goal was to make them
not difficult to use or overbearing and complex objects. I hope that both
of these objects suffice and that programmers find them useful. An
example of the use of <code class="classname">BTabView</code> can be found in the Fonts preferences
application. Examples of <code class="classname">BSlider</code> can be found in Keyboard, Mouse, and
many other preference applications.
</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="Marketing3-9"></a>Making Money</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Dave</span> <span class="surname">Johnson</span></span></div></div></div><p>
Good news: The BeOS is beginning to be noticed in the PC press.
</p><p>
More good news: Most of the "media" companies I talk to tell me they
realize that media applications will eventually HAVE TO be on the BeOS to
be competitive, and sooner rather than later.
</p><p>
Every day it looks more and more like the BeOS will emerge as the OS of
choice for media development. If you're writing a media application and
you're reading this Newsletter, you are in the right place.
</p><p>
You're also in the right place to make money writing software that is not
media-oriented. One good bet right now is developer tools: the BeOS for
Intel offers you a fresh shot at the same developers you're trying to
sell to right now. Another wide-open area to consider is utilities of all
kinds.
</p><p>
Here are some tips on making money selling software for the BeOS:
</p><p>
Be offers BeOS software developers a unique opportunity to reach their
potential market through our BeWare listings. The web orientation of our
CDs and downloadable OS make it a safe bet that most BeOS users will
visit the BeWare site. This immediate visibility to the user base of an
OS is a new concept that gives BeOS software developers a terrific—and
inexpensive—head start at reaching a market.
</p><p>
Need proof that this concept works? BeWare had 36,000 hits last week and
18,791 files were downloaded. Keep in mind that's for the Power Mac BeOS
only, with the Mac at 2.6% market share.
</p><p>
So get something up on BeWare! Make sure that your BeWare listings are up
to date, informative, benefit-oriented, and that they SELL your products.
If you're not up on BeWare yet, you're missing out.
</p><p>
There's another reason to get your product up on BeWare: publishers are
entering the BeOS market and they're looking for products and
programmers. What better way to reach them than via BeWare? Read my
article "How to Finish a Product,"
http://www.be.com/aboutbe/benewsletter/Issue98.html#Developer. Stop
adding features and ship what you have to BeWare! (You can always put the
rest in version 2.)
</p><p>
At your end of the sales process, do you have a web site ready? Your own
web site is your primary BeOS sales tool after BeWare! The BeWare site
will send many software-hungry customers your way, so you should have
your web site ready to accommodate them. Is the entry page of your web
site clear, informative, and sales oriented? Does your web site direct
the customer to product information? Do you have clear, benefit-oriented
descriptions of your products? Benefits, benefits, benefits—stress
benefits. Repeat your message, repeatedly.
</p><p>
Do you have order forms? Do you accept credit cards? Do you quickly send
the software to customers who order it? Do you sell through BeDepot? If
you do, get the customers interested in your product and send them where
they can place the order right now. Getting the order should be an
immediate part of the process. The excitement you generate for your
product will fade, so it's important to provide the ordering opportunity
immediately.
</p><p>
If you're not sales-oriented, take heart. This isn't a huckster approach
to ripping off the customer. Look at it as an opportunity to place your
fine product in the hands of more and more people.
</p><p>
Acquiring a sales orientation is difficult for many of us. I came by mine
the hard way in a past life running a software company. After years of
struggling, we tried actually selling something to customers using direct
mail, and learned that it works. It changed the culture of the company.
Gosh, offering products to customers in a sales-oriented way actually
works!
</p><p>
It's surprising how many smaller software companies don't understand
that. I know how hard it was for me, coming from primarily an engineering
background, to become sales-oriented. It seemed pushy, obnoxious, and
aggressive but it turned out that it works. (Now I'm pushy, obnoxious,
and aggressive, and I work...)
</p><p>
So before you get revolted at the thought of selling your product,
remember that those sales types wouldn't be doing what they do if it
didn't work. As much as you hate the thought, it might be a good idea to
infect your offices with one of those sales types—checkered sport
jacket, slick hair, suspenders, and all the rest—because if your
background is engineering, the world of sales may be another planet to
you, but it's very necessary to making money.
</p><p>
But wait, there's more! Accept this free gift as a token of my
appreciation for reading this article! Check out the web sites of
companies that are sales-oriented, and blatantly steal ideas from them.
Two that come to mind are Intuit
(<a class="ulink" href="http://www.intuit.com/">http://www.intuit.com/</a>) and Berkeley
Systems (http://www.berksys.com/).
</p><p>
Here's a very important tip: Make the press aware of your products. My
next article will discuss getting press for your products. The very best
way to get people interested in your software is by getting press
attention, so start thinking about it now and we'll compare notes.
Getting press for your BeOS products helps us get the Be ball rolling,
and that helps you, too.
</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="DevWorkshop3-9"></a>Developers' Workshop: Welcome to x86</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Doug</span> <span class="surname">Wright</span></span></div></div></div><p>
This week we'd like to present a laundry list of issues you should be
aware of when moving to the brave new world of x86 development.
</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="id670014"></a>Endianness</h3></div></div></div><p>
Incompatibilities between the x86 and PowerPC releases stem primarily
from the opposing endianness of the processors. This topic has been
covered exhaustively in previous Newsletter articles. For specifics,
reread:
</p><p>
"<a class="link" href="">Swapping Bytes, Part III</a>"<br />
By Peter Potrebic - Issue 3-#8
</p><p>
"<a class="link" href="">YABSA—Yet Another Byte-swapping Article</a>"<br />
By Bradley Taylor - Issue 2-#45
</p><p>
"<a class="link" href="">Will Your DATA Look Like ATAD?</a>"<br />
By Bradley Taylor - Issue 2-#9
</p><p>
The new header <code class="filename">support/ByteOrder.h</code> contains a slew of handy-dandy
functions and macros to help you sex, resex, and neuter your data.
</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="id670079"></a>Filesystem and Resource File Incompatibility</h3></div></div></div><p>
Although we successfully eliminated many of the endian problems
encountered in porting the BeOS to x86, there are still a few that will
linger at least through Release 3.
</p><p>
The internal BFS structures are endian opposite on the different
platforms: big-endian on PowerPC and little-endian on x86. We currently
do not have any tools that allow a BeOS machine to read a disk in the
opposite endian format. This does not mean there is no way to transfer
information across platforms; ftp still works as advertised, and, when
combined with zip, will even correctly transfer the filesystem attributes.
</p><p>
The BFS endian issues have to do with BFS's internal structures for
storing data, not the data itself. If your data is endian-independent, it
will be usable on both platforms without changes. Otherwise, you may have
problems if you don't check the endianness of the data before using it.
</p><p>
The majority of the persistent data formats in the BeOS are endian-
independent; in particular, both filesystem attributes and flattened
<code class="classname">BMessage</code>s are endian-agnostic. The resource file format is a notable
exception to this rule. You cannot use PowerPC resource files while
building a x86 application (and vice versa)—you need new x86 resources.
</p><p>
Release 3 ships with several tools to help translate resources, but their
abilities are limited: They convert only a few resource types, and are
unable to translate many of the data types found in a resource file.
Custom resource formats, of course, need to be translated manually. In
most cases, it's easier to create separate PowerPC and Intel resource
files from scratch and use the appropriate one as needed.
</p><p>
We are working on solutions to both of these problems, but at this time
we can't say exactly when they will be available.
</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="id670141"></a>Compiling</h3></div></div></div><p>
The biggest change to compiling is in the creation of shared libraries
(and consequently add-ons). In the PowerPC world, symbols are exported
from a shared library through the use of the <code class="code">#pragma export on</code> and
<code class="code">#pragma export off</code> pair. Additionally, you don't have to do anything
special to import symbols.
</p><p>
The x86 release understands different semantics for importing and
exporting symbols. It is still necessary to explicitly export a symbol
from a library, but you also must explicitly import the symbol into your
applications. Importing symbols from add-ons doesn't change; the symbol
is still resolved with <code class="function">find_image_symbol()</code>. However, if you are linking
against a shared library, you need to import the symbols.
</p><p>
The Intel release uses the traditional x86 methods for importing and
exporting symbols:
</p><pre class="programlisting c">
__declspec(dllexport) type name for exporting
__declspec(dllimport) type name for importing
</pre><p>
In both cases, type specifies what is being exported, and name specifies
its name. The new header file
<code class="filename">BeBuild.h</code> selectively exports or imports
the system classes and global functions, depending on whether the
libraries are being built or linked against.
</p><p>
We recommend following a similar pattern in your own header files, rather
than having separate header files for importing and exporting. Please see
the "Moving from PR2 to Release 3: Development Layout" section of the
Release 3 Release Notes for a more detailed look at this issue.
</p><p>
A related note: The Metrowerks x86 compiler allows the use of <code class="code">#pragma
export</code> and <code class="code">#pragma import</code> to export and import symbols on the x86.
However, we strongly recommend use of the more traditional (if ugly)
<code class="code">__declspec()</code> system, as it is more likely to be supported by future
compilers.
</p><p>
Finally, with the recent codification of the ANSI C++ spec, Metrowerks
has removed the inherited keyword from their compilers. This is a good
thing. If you use this keyword in your code, we strongly urge you to
replace it with a specific call to the appropriate parent member.
Meanwhile, you can use the compiler switch -pragma "def_inherited on" to
accept the old method. This switch will not be supported indefinitely, so
it's best to take the time and replace those calls to inherited.
</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="id670242"></a>Linking</h3></div></div></div><p>
Linking with shared libraries is a bit different on the x86. Instead of
linking with the library itself, you now link with a special
<code class="filename">.LIB</code> file (a
"linkable library"). For example, you now link with the linkable library
<code class="filename">libbe.so.LIB</code>, instead of the shared library
<code class="filename">libbe.so</code>. The system-linkable
libraries may be found in <code class="filename">/boot/develop/lib/x86</code>. On the PowerPC, nothing
changes: You still link with the shared library itself.
</p><p>
On a similar note, if you are linking against either the kernel (for
drivers) or the current application (for add-ons), you must link against
either <code class="filename">_KERNEL_.LIB</code> or
<code class="filename">_APP_.LIB</code>, as appropriate.
<code class="filename">_KERNEL_.LIB</code> may be
found in the same directory as the other system linkable libraries, while
<code class="filename">_APP_.LIB</code> must be culled from the appropriate application. The compiler
automatically generates a <code class="filename">.LIB</code> file for an x86 image—be it an
application, a static library, or a dynamic library—if any symbols are
exported (via <code class="code">__declspec(export)</code>).
</p><p>
There are a few new objects in
<code class="filename">/boot/develop/lib/x86</code>, notably
<code class="filename">glue-noinit.a</code>, <code class="filename">init_term_dyn.o</code>,
and <code class="filename">start_dyn.o</code>. All programs need these
objects. Normally, you shouldn't notice them since they're pulled in
automatically by the linker. However, if you run into problems with
unresolved symbols, try explicitly linking these files into your object.
The same drill applies to the PowerPC release as well.
</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="id670337"></a>Stephen Makes Life Easier</h3></div></div></div><p>
In an effort to make things easier for our developers, I've developed a
fairly basic, but usable, cross-platform makefile. The current
incarnation can be found at
ftp://ftp.be.com/pub/samples/intro/obsolete/Makefile. This is a generic
makefile that allows a developer to specify whether an application or
static or shared library is being created; what files, libraries, and
resources are needed to create it; and what its final name will be. This
makefile will continue to be upgraded as time allows, and as needed.
</p><p>
If you are an experienced makefile builder, and you have suggestions on
how to improve it, I'd like to hear from you. If you are unfamiliar with
makefiles in general (as I was when I started this), take a look. They
really aren't that terrible to deal with. Send all reports directly to
Developer Support via the online form in the Registered Developer Area.
</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="id670358"></a>The BeDC</h3></div></div></div><p>
Finally, please realize that the Newsletter format doesn't permit an
exhaustive look at all the issues arising from the x86 port of the BeOS.
For a more thorough presentation, be sure to attend the BeDC, where two
sessions will be devoted to the x86 port: Approaching a Cross Platform
OS; and in the extended track, Working with Intel. Bring your comments,
questions, and concerns to these sessions, and we'll try to get you the
answers you need.
</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="Gassee3-9"></a>The Newton Experience</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-Louis</span> <span class="surname">Gassée</span></span></div></div></div><p>
The Newton is no more. This is a little sad for the few people at Be who
once worked on that project in an earlier life, people such as Bob
Herold, Peter Potrebic, Steve Sakoman and yours truly. But we live on and
we are grateful for a few lessons which found their way into our work
here at Be.
</p><p>
The Newton story started late Spring of 1987. After successfully
directing the engineering efforts resulting in the Mac Plus, the Mac SE
and the Mac II (the Open Mac), Steve Sakoman sat in my office in the De
Anza III building in Cupertino and calmly told me he was going to leave
Apple.
</p><p>
To do what? To start a company that would build a new portable computer.
The size of a notebook, you'd write on the screen with a stylus and the
computer would recognize your handwriting. I asked Steve if he would hire
me as a CEO for his venture, he said yes, and we started looking for
money.
</p><p>
I'll cut a convoluted story to the known next milestone, we stayed at
Apple, Steve started what became known as the Newton project in a
building on Bubb Road. We liked the Newton concept very much, we saw the
Newton as "scalable": the idea of a computing device capable of
recognizing handwriting could be implemented, in theory, on a product as
small as a checkbook, or as large as a drafting table or even a networked
whiteboard.
</p><p>
Furthermore, the Newton concept did not threaten to cannibalize desktop
sales. As a result, we could develop a complete hardware and software
architecture and, if the market graft "took"—that is, if we succeeded
in attracting enough developers and customers—we could mutate a
version of the new platform into a more classical desktop product.
</p><p>
The latter thought was directed at our concern over the limitations of
the Macintosh architecture and the perceived need to, first, develop a
replacement in case it would age prematurely and, second, to do so
without wrecking the existing desktop business, without, in other words,
"osborning" the Mac.
</p><p>
We liked the Newton so much that when John Sculley gave me the benevolent
physical and financial kick to get in business on my own, I offered to
lead an effort to "claris" the Newton into an independent subsidiary.
Benevolently again, the offer was turned down. Still, for several years,
as we kept our work at Be under wraps, many were convinced we were
developing some PDA, as the term gained currency after the Go/Eo, Winpad,
Zoomer and finally Newton were announced.
</p><p>
We started collecting the benefits of the Newton's lessons early. One of
several reasons we didn't start a PDA company was we had grown
disenchanted with handwriting recognition. We had started to suspect
recognition would never reach "transparency." By this I mean the kind of
performance that never stands between you and your goal, your task. Most
of the time, error correction on a hard disk or a CD is transparent, it
takes place but stays out of the way. At Be, we decided our project would
only integrate known technologies, there were enough other kinds of risk
in it already.
</p><p>
The other lesson we learned, we hope, was setting expectations. The
Newton was announced with the greatest of fanfares, with proclamations of
trillion dollar turn-of-the-century markets. Imagine for a moment a
different kind of announcement: This is from our advance technology
division, this is only for the hardiest of explorers, this is not yet a
product for the mainstream.
</p><p>
Instead of becoming the butt of Doonesbury cartoons, not necessarily bad
publicity, the Newton could have iterated towards a nice PDA with the
support of the early adopter community. In other words, the Surgeon
General warnings and pocket protectors we associated with our product
come from our concern to represent our product as we think it is, good
genes, but not an adult yet, not ready for the mainstream.
</p><p>
We hope you'll join us at our Developer Conference in two weeks to check
on the young OS's progress.
</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="Issue3-8.html">Issue 3-8, February 25, 1998</a>  Up: <a href="volume3.html">Volume 3: 1998</a>  Next: <a href="Issue3-10.html">Issue 3-10, March 11, 1998</a> </div><div id="footerB"><div id="footerBL"><a href="Issue3-8.html" title="Issue 3-8, February 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="Issue3-10.html" title="Issue 3-10, March 11, 1998"><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>