Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • danc/MicroCART
  • snawerdt/MicroCART_17-18
  • bbartels/MicroCART_17-18
  • jonahu/MicroCART
4 results
Show changes
Showing
with 0 additions and 3355 deletions
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<!--
Edit the documentation here, then copy the contents of the <body> tag into package-info.java (without the tags) -->
<body>
This package include a set of widgets that are bound to a Vrpn server
buttons, analogs and trackers.
<h3>Create a simple application that uses the widgets</h3>
<p>
The following chapters describe how to create a simple application
with a {@link eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton} and
a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar}. An example
application project that contains these widgets and more can be found
in the <em>example_app</em> directory.
</p>
<h4>Create and configure the project</h4>
<p>
Refer to any Android documentation for instructions about how to
set-up the Android SDK and the Eclipse plugin. Do not forget to setup
the Android SDK in any new workspace (<em>Window</em> &gt; <em>Preferences</em>,
then go to the <em>Android</em> tab and configure the SDK location).
</p>
<p>
Import the <em>Vrpn_library</em> project into your Eclipse workspace.
Open the Android section of the project property page and verify that
<em>Is library</em> checked. If the build complains about "Android
requires .class compatibility set to 5.0", you need first to select
the project, right-click > <em>Properties</em> &gt; <em>Android
tools</em> &gt; <em>Fix project properties</em>, then open the project
properties, go to the <em>Java compiler</em> section, then deselect
<em>enable project specific settings</em>. You may need to clean and
rebuild (<em>Project</em> &gt; <em>Clean</em>) several times before
the project shows no errors.
</p>
<p>
Create a new Android project : <em>File</em> > <em>New</em> > <em>Other
...</em> , <em>Android</em> &gt; <em>Android Project</em>. On the first
page of the wizard, check <em>Create activity</em> and enter any name
you like for the main activity (for instance <em>MainActivity</em>).
</p>
<p>
Add the library to your project : open the properties of the project,
go to the <em>Android</em> page. In the <em>Library</em> pane, click <em>Add</em>
then select <em>vrpn_library</em>, apply the changes and close the
window. At this point, the Eclipse <em>Package Explorer</em> view of
your project should contain a <em>vrpn_library_src</em> folder and the
<em>gen</em> folder should contain a package entry named <em>eu.ensam.ii.vrpn</em>.
</p>
<p>
Open the
<code>AndroidManifest.xml</code>
file. On the <em>Application</em> tab, check <em>Define an
&lt;Application&gt; tag in the AndroidManifest.xml</em>. Then click on the
<em>Browse</em> button that is on the right of <em>Name</em> and
select <em>VrpnApplication</em>.
</p>
<h4>Modify the main activity</h4>
<p>Edit the main activity to define the binding to the Vrpn server
when the activity is created. The method {@link
android.app.Activity#onCreate onCreate} is called when the Activity is
created. The default version of this method contain only the first and
last lines :</p>
<pre>
super.onCreate(savedInstanceState);
....
setContentView(R.layout.main);
</pre>
<p>We need to define the binding with the Vrpn server. The method
becomes :</p>
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InetAddress vrpnServerAddress = null;
try {
// Replace the IP address
vrpnServerAddress = InetAddress.getByName("192.168.173.1");
} catch (UnknownHostException e) {
}
final int vrpnServerPort = 7777;
VrpnClient.getInstance().setupVrpnServer(vrpnServerAddress, vrpnServerPort);
setContentView(R.layout.main);
}
</pre>
<a name="vrpnids"></a>
<h4>Create a Vrpn Ids list</h4>
<p>
Before laying out your Vrpn widgets in your application, you should
create an XML configuration file that contains the IDs of the Vrpn
buttons and analog that you will be using. This allows you to keep a
unique list of Vrpn IDs, making it easier to avoid duplicate values
and reference this list from your application. Create this file with <em>File</em>
> <em>New</em> > <em>Other</em>, then <em>Android </em> > <em>Android
XML File</em>. In XML file dialog, type any file name you like, for
instance <em>vrpn.xml</em>, then select <em>Values</em> as the type of
resource to create.
</p>
<p>
Edit the resulting file, found at <em>res/values/vrpn.xml</em> to add
the numbers of the Vrpn Buttons and Analogs that you will be using.
</p>
<pre>
&lt;resources&gt;
&lt;item type="id" format="integer" name="VrpnAnalogLightIntensity"&gt;0&lt;/item&gt;
&lt;item type="id" format="integer" name="VrpnButtonLightsOn"&gt;0&lt;/item&gt;
&lt;/resources&gt;
</pre>
<p>
Note that <em>type</em> must be <em>id</em> and <em>format</em> must
be <em>integer</em>, but <em>name</em> can be anything you like.
</p>
<h4>Add your widgets to the main layout</h4>
<p>Say we want an Android application to control the lighting in
our VR application : turn the light on or off and also control the
light intensity. We will create an application with a {@link
eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton} as the light
switch and a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar} as a
light intensity controller.</p>
<p>
By default, the layout of the main Activity is described in <em>res/layout/main.xml</em>
and just displays <em>Hello</em>. Edit this file. The XML code looks
is something like :
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/&gt;
&lt;/LinearLayout&gt;
</pre>
<p>
The root element,
<code>LinearLayout</code>
, is a container for the other widgets, currently contains a
<code>TextView</code>
.
<p>
The basics about XML layouts are presented in <a
href="http://developer.android.com/guide/topics/ui/declaring-layout.html">Declaring
layout</a> SDK page.
</p>
<p>
Before the end tag
<code>&lt;/LinearLayout&gt;</code>
, include a {@link eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton}
to turn the lights on or off :
<pre>
&lt;eu.ensam.ii.vrpn.VrpnToggleButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:vrpnButton="@id/VrpnButtonLightsOn"
/&gt;
</pre>
The Vrpn widgets use so-called
<em>custom XML properties</em> , such as
<em>app:vrpnButton</em> . This custom property allows you to specify
the id of the target Vrpn button in the XML layout file rather than in
Java code. However, the use of this custom property requires the
addition of an XML namespace tag so that the build system can find
then. After the
<em>xmlns:android</em> line, add the following line :
<pre>
xmlns:app="http://schemas.android.com/apk/res/your.application.package.name.here"
</pre>
Different attributes exist for each widgets and the whole list is shown
when you unfold
<em>gen/eu/ensam.ii.vrpn/R.java/R/attr</em> in the Eclipse Package
View. Your layout is now ready for your to include the Vrpn widgets.
Now save the file to build your project. If there are build errors,
check the following :
<ul>
<li>you have added the <code>xmlns::app</code> line in the root
layout</li>
<li>the spelling of the <code>app:</code> attribute</li>
<li>the value of the Vrpn attributes</li>
<li>the spelling of the widget name</li>
</ul>
<p>
In most cases, the <em>Preview</em> tab of the XML layout is not
displayed properly as soon as you include one of the Vrpn widgets.
This is a known problem for which not solution has currently been
found. It prevents you from previewing the layout it wil be displayed
correctly in the application, either on a device or in the emulator.
</p>
<p>Now add a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar} to
control the light intensity :</p>
<pre>
&lt;eu.ensam.ii.vrpn.VrpnSeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:minValue="0"
app:maxValue="255"
app:defaultValue="128"
app:vrpnAnalog="@id/VrpnAnalogLightIntensity"
/&gt;
</pre>
Your Android application is now ready to run. Upload on a device and
run. There is not much to seen for the time being. However, if you run
a network sniffer on a machine connected to the same network as the
Android device, you should see UDP packets flowing out of the device.
If you are using the emulator instead of an actual device, see the
<a
href="
http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking">Emulator
networking</a> SDK page for the correct network setup.
<h4>Test your application</h4>
In order to test your application, you need a VRPN server built with
VRPN_USE_JSONNET. See the
<code>README.jsoncpp</code>
file for instructions to build this server. When you get this server
running, the easiest way to test the Android application is to use the
<code>vrpn_print_devices</code>
application provided with Vrpn. Type the command :
<pre>
vrpn_print_devices Jsonnet@localhost
</pre>
The command should then report the values of the Button and SeekBar as
they are changed.
<h3>Beyond the basics</h3>
<h4>Application with multiple tabs</h4>
If you want to create an application with more widgets that can be
placed on a single screen, using a {@link android.app.TabActivity
TabActivity} instead of a regular Activity may be the way to go. A
{@link android.app.TabActivity TabActivity} can display several
activities of view, each inside a tab. The Android SDK documentation
explains how to create a tabbed application with activities. However,
using activities require careful state management since the activities
may be terminated when the use switches from one tab to another. It is
therefore easier to manage a {@link android.app.TabActivity
TabActivity} that display
<em>views</em> intead of activities.
<p></p>
<p>First of all, your main activity must extend {@link
android.app.TabActivity TabActivity} intead of {@link
android.app.Activity Activity}.</p>
<p>
Then, create a layout for each tab in <em>res/layout</em> with <em>File</em>
> <em>New</em> > <em>Other...</em> , then <em>Android</em> > <em>New
XML file</em>. In the <em>New Android XML file</em> dialog, name the file
<em>tab_one.xml</em>, select <em>Layout</em> as the type of resource,
then select <em>LinearLayout</em> as the root element. Repeat the
process with a second tab layout named <em>tab_two.xml</em>. Update
each tab layout as described in <em>Add your widgets to the main
layout</em> above, paying attention not to forget the <em>xmlns:app</em>
line.
</p>
<p>
The next step is to create a new layout names <em>res/layout/tab_group.xml</em>for
the whole activity. This layout looks like :
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"&gt;
&lt;TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/&gt;
&lt;FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"&gt;
&lt;/FrameLayout&gt;
&lt;include layout="@layout/tab_one"&gt;&lt;/include&gt;
&lt;include layout="@layout/tab_two"&gt;&lt;/include&gt;
&lt;/TabHost&gt;
</pre>
<p>
Then edit the <em>onCreate</em> method of your activity. After the
line <em>super.onCreate()</em> add the <em>VrpnClient.getInstance().setUri(....)</em>
line, then add :
<pre>
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.tab_group, getTabHost().getTabContentView(), true);
TabHost.TabSpec spec;
spec = getTabHost().newTabSpec("1").setContent(R.id.tab_one);
getTabHost().addTab(spec)
spec = getTabHost().newTabSpec("2").setContent(R.id.tab_two);
getTabHost().addTab(spec);
getTabHost().setCurrentTab(0);
</pre>
<p>See in the SDK documentation how to use the {@link
android.widget.TabHost.TabSpec#setIndicator setIndicator} method in
order to display an icon in the tab headers.</p>
<h3>Updating the widget library</h3>
<h4>Create a new Widget</h4>
<p>To create a new Widget type you should look at the source code
of VrpnSeekBar, which is the more elaborate. The main steps are as
follows :</p>
<ul>
<li>Decide which Android widget class you want to extend and
which events will trigger Vrpn updates.</li>
<li>Decide whether your widget will send Vrpn button,analog or
tracker updates.</li>
<li>Decide whether your widget needs new custom XML attributes.
If this is the case, look at <code>res/values/attrs.xml</code> for
examples.</li>
<li>Implement a private <em>init</em> method that each
constructor will call. In this method, you must obtain the XML custom
attributes of the widget. You should also send a Vrpn update with the
initial value of the widget</li>
<li>Implement the appropriate change listener, according to which
event you want your widget to respond to. In the change listener,
call the appropriate method : {@link
eu.ensam.ii.vrpn.VrpnClient#sendAnalog(int,double) sendAnalog} or
{@link eu.ensam.ii.vrpn.VrpnClient#sendButton(int,boolean)
sendButton}. Note that a single widget can s end several updates,
like the {@link eu.ensam.ii.vrpn.VrpnSurface VrpnSurface} does or
like a <a
href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.html">color
picker</a>would do. There is currently no <em>sendTracker</em> method
although this may be useful to implement an Arcball for instance.</li>
</ul>
<p>Note that using the full path of the parent class such as in :
<pre>public class VrpnRadioButton extends android.widget.RadioButton</pre>
allows Javadoc to generate a link to the parent class.
</p>
<h4>Generate the documentation</h4>
<p>
Select the <em>vrpn_library/src</em> folder, then select the menu item
<em>Project</em> &gt; <em>Generate Javadoc</em>.
<p>
On the first page of the wizard, select the path of the <em>javadoc</em>
tool. Check that <em>vrpn_library/src</em> is selected, but not <em>vrpn_library/gen</em>,
then select an appropriate destination for the documentation.
</p>
<p>
On the second page of the wizard select <em>android.jar</em> in the <em>Referenced
archives</em> list and take note of the <em>android.jar</em> doc path
(like
<code>file:/E:/android/docs/reference</code>
).
</p>
<p>
On the third page of the wizard add the following line to the <em>Extra
javadoc options</em> text box :
<pre>
-linkoffline http://d.android.com/reference file:/E:/android/docs/reference
</pre>
but replace the
<code>file:/</code>
URL by your local Android SDK URL noted from the page two of the
wizard. This allows Javadoc to include full references to the on-line
Android documentation.
</body>
</html>
\ No newline at end of file
//
//
// Please edit package-info.html, then paste here
//
/**
*
This package include a set of widgets that are bound to a Vrpn server
buttons, analogs and trackers.
<h3>Create a simple application that uses the widgets</h3>
<p>
The following chapters describe how to create a simple application
with a {@link eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton} and
a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar}. An example
application project that contains these widgets and more can be found
in the <em>example_app</em> directory.
</p>
<h4>Create and configure the project</h4>
<p>
Refer to any Android documentation for instructions about how to
set-up the Android SDK and the Eclipse plugin. Do not forget to setup
the Android SDK in any new workspace (<em>Window</em> &gt; <em>Preferences</em>,
then go to the <em>Android</em> tab and configure the SDK location).
</p>
<p>
Import the <em>Vrpn_library</em> project into your Eclipse workspace.
Open the Android section of the project property page and verify that
<em>Is library</em> checked. If the build complains about "Android
requires .class compatibility set to 5.0", you need first to select
the project, right-click > <em>Properties</em> &gt; <em>Android
tools</em> &gt; <em>Fix project properties</em>, then open the project
properties, go to the <em>Java compiler</em> section, then deselect
<em>enable project specific settings</em>. You may need to clean and
rebuild (<em>Project</em> &gt; <em>Clean</em>) several times before
the project shows no errors.
</p>
<p>
Create a new Android project : <em>File</em> > <em>New</em> > <em>Other
...</em> , <em>Android</em> &gt; <em>Android Project</em>. On the first
page of the wizard, check <em>Create activity</em> and enter any name
you like for the main activity (for instance <em>MainActivity</em>).
</p>
<p>
Add the library to your project : open the properties of the project,
go to the <em>Android</em> page. In the <em>Library</em> pane, click <em>Add</em>
then select <em>vrpn_library</em>, apply the changes and close the
window. At this point, the Eclipse <em>Package Explorer</em> view of
your project should contain a <em>vrpn_library_src</em> folder and the
<em>gen</em> folder should contain a package entry named <em>eu.ensam.ii.vrpn</em>.
</p>
<p>
Open the
<code>AndroidManifest.xml</code>
file. On the <em>Application</em> tab, check <em>Define an
&lt;Application&gt; tag in the AndroidManifest.xml</em>. Then click on the
<em>Browse</em> button that is on the right of <em>Name</em> and
select <em>VrpnApplication</em>.
</p>
<h4>Modify the main activity</h4>
<p>Edit the main activity to define the binding to the Vrpn server
when the activity is created. The method {@link
android.app.Activity#onCreate onCreate} is called when the Activity is
created. The default version of this method contain only the first and
last lines :</p>
<pre>
super.onCreate(savedInstanceState);
....
setContentView(R.layout.main);
</pre>
<p>We need to define the binding with the Vrpn server. The method
becomes :</p>
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InetAddress vrpnServerAddress = null;
try {
// Replace the IP address
vrpnServerAddress = InetAddress.getByName("192.168.173.1");
} catch (UnknownHostException e) {
}
final int vrpnServerPort = 7777;
VrpnClient.getInstance().setupVrpnServer(vrpnServerAddress, vrpnServerPort);
setContentView(R.layout.main);
}
</pre>
<a name="vrpnids"></a>
<h4>Create a Vrpn Ids list</h4>
<p>
Before laying out your Vrpn widgets in your application, you should
create an XML configuration file that contains the IDs of the Vrpn
buttons and analog that you will be using. This allows you to keep a
unique list of Vrpn IDs, making it easier to avoid duplicate values
and reference this list from your application. Create this file with <em>File</em>
> <em>New</em> > <em>Other</em>, then <em>Android </em> > <em>Android
XML File</em>. In XML file dialog, type any file name you like, for
instance <em>vrpn.xml</em>, then select <em>Values</em> as the type of
resource to create.
</p>
<p>
Edit the resulting file, found at <em>res/values/vrpn.xml</em> to add
the numbers of the Vrpn Buttons and Analogs that you will be using.
</p>
<pre>
&lt;resources&gt;
&lt;item type="id" format="integer" name="VrpnAnalogLightIntensity"&gt;0&lt;/item&gt;
&lt;item type="id" format="integer" name="VrpnButtonLightsOn"&gt;0&lt;/item&gt;
&lt;/resources&gt;
</pre>
<p>
Note that <em>type</em> must be <em>id</em> and <em>format</em> must
be <em>integer</em>, but <em>name</em> can be anything you like.
</p>
<h4>Add your widgets to the main layout</h4>
<p>Say we want an Android application to control the lighting in
our VR application : turn the light on or off and also control the
light intensity. We will create an application with a {@link
eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton} as the light
switch and a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar} as a
light intensity controller.</p>
<p>
By default, the layout of the main Activity is described in <em>res/layout/main.xml</em>
and just displays <em>Hello</em>. Edit this file. The XML code looks
is something like :
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/&gt;
&lt;/LinearLayout&gt;
</pre>
<p>
The root element,
<code>LinearLayout</code>
, is a container for the other widgets, currently contains a
<code>TextView</code>
.
<p>
The basics about XML layouts are presented in <a
href="http://developer.android.com/guide/topics/ui/declaring-layout.html">Declaring
layout</a> SDK page.
</p>
<p>
Before the end tag
<code>&lt;/LinearLayout&gt;</code>
, include a {@link eu.ensam.ii.vrpn.VrpnToggleButton VrpnToggleButton}
to turn the lights on or off :
<pre>
&lt;eu.ensam.ii.vrpn.VrpnToggleButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:vrpnButton="@id/VrpnButtonLightsOn"
/&gt;
</pre>
The Vrpn widgets use so-called
<em>custom XML properties</em> , such as
<em>app:vrpnButton</em> . This custom property allows you to specify
the id of the target Vrpn button in the XML layout file rather than in
Java code. However, the use of this custom property requires the
addition of an XML namespace tag so that the build system can find
then. After the
<em>xmlns:android</em> line, add the following line :
<pre>
xmlns:app="http://schemas.android.com/apk/res/your.application.package.name.here"
</pre>
Different attributes exist for each widgets and the whole list is shown
when you unfold
<em>gen/eu/ensam.ii.vrpn/R.java/R/attr</em> in the Eclipse Package
View. Your layout is now ready for your to include the Vrpn widgets.
Now save the file to build your project. If there are build errors,
check the following :
<ul>
<li>you have added the <code>xmlns::app</code> line in the root
layout</li>
<li>the spelling of the <code>app:</code> attribute</li>
<li>the value of the Vrpn attributes</li>
<li>the spelling of the widget name</li>
</ul>
<p>
In most cases, the <em>Preview</em> tab of the XML layout is not
displayed properly as soon as you include one of the Vrpn widgets.
This is a known problem for which not solution has currently been
found. It prevents you from previewing the layout it wil be displayed
correctly in the application, either on a device or in the emulator.
</p>
<p>Now add a {@link eu.ensam.ii.vrpn.VrpnSeekBar VrpnSeekBar} to
control the light intensity :</p>
<pre>
&lt;eu.ensam.ii.vrpn.VrpnSeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:minValue="0"
app:maxValue="255"
app:defaultValue="128"
app:vrpnAnalog="@id/VrpnAnalogLightIntensity"
/&gt;
</pre>
Your Android application is now ready to run. Upload on a device and
run. There is not much to seen for the time being. However, if you run
a network sniffer on a machine connected to the same network as the
Android device, you should see UDP packets flowing out of the device.
If you are using the emulator instead of an actual device, see the
<a
href="
http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking">Emulator
networking</a> SDK page for the correct network setup.
<h4>Test your application</h4>
In order to test your application, you need a VRPN server built with
VRPN_USE_JSONNET. See the
<code>README.jsoncpp</code>
file for instructions to build this server. When you get this server
running, the easiest way to test the Android application is to use the
<code>vrpn_print_devices</code>
application provided with Vrpn. Type the command :
<pre>
vrpn_print_devices Jsonnet@localhost
</pre>
The command should then report the values of the Button and SeekBar as
they are changed.
<h3>Beyond the basics</h3>
<h4>Application with multiple tabs</h4>
If you want to create an application with more widgets that can be
placed on a single screen, using a {@link android.app.TabActivity
TabActivity} instead of a regular Activity may be the way to go. A
{@link android.app.TabActivity TabActivity} can display several
activities of view, each inside a tab. The Android SDK documentation
explains how to create a tabbed application with activities. However,
using activities require careful state management since the activities
may be terminated when the use switches from one tab to another. It is
therefore easier to manage a {@link android.app.TabActivity
TabActivity} that display
<em>views</em> intead of activities.
<p></p>
<p>First of all, your main activity must extend {@link
android.app.TabActivity TabActivity} intead of {@link
android.app.Activity Activity}.</p>
<p>
Then, create a layout for each tab in <em>res/layout</em> with <em>File</em>
> <em>New</em> > <em>Other...</em> , then <em>Android</em> > <em>New
XML file</em>. In the <em>New Android XML file</em> dialog, name the file
<em>tab_one.xml</em>, select <em>Layout</em> as the type of resource,
then select <em>LinearLayout</em> as the root element. Repeat the
process with a second tab layout named <em>tab_two.xml</em>. Update
each tab layout as described in <em>Add your widgets to the main
layout</em> above, paying attention not to forget the <em>xmlns:app</em>
line.
</p>
<p>
The next step is to create a new layout names <em>res/layout/tab_group.xml</em>for
the whole activity. This layout looks like :
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"&gt;
&lt;TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/&gt;
&lt;FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"&gt;
&lt;/FrameLayout&gt;
&lt;include layout="@layout/tab_one"&gt;&lt;/include&gt;
&lt;include layout="@layout/tab_two"&gt;&lt;/include&gt;
&lt;/TabHost&gt;
</pre>
<p>
Then edit the <em>onCreate</em> method of your activity. After the
line <em>super.onCreate()</em> add the <em>VrpnClient.getInstance().setUri(....)</em>
line, then add :
<pre>
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.tab_group, getTabHost().getTabContentView(), true);
TabHost.TabSpec spec;
spec = getTabHost().newTabSpec("1").setContent(R.id.tab_one);
getTabHost().addTab(spec)
spec = getTabHost().newTabSpec("2").setContent(R.id.tab_two);
getTabHost().addTab(spec);
getTabHost().setCurrentTab(0);
</pre>
<p>See in the SDK documentation how to use the {@link
android.widget.TabHost.TabSpec#setIndicator setIndicator} method in
order to display an icon in the tab headers.</p>
<h3>Updating the widget library</h3>
<h4>Create a new Widget</h4>
<p>To create a new Widget type you should look at the source code
of VrpnSeekBar, which is the more elaborate. The main steps are as
follows :</p>
<ul>
<li>Decide which Android widget class you want to extend and
which events will trigger Vrpn updates.</li>
<li>Decide whether your widget will send Vrpn button,analog or
tracker updates.</li>
<li>Decide whether your widget needs new custom XML attributes.
If this is the case, look at <code>res/values/attrs.xml</code> for
examples.</li>
<li>Implement a private <em>init</em> method that each
constructor will call. In this method, you must obtain the XML custom
attributes of the widget. You should also send a Vrpn update with the
initial value of the widget</li>
<li>Implement the appropriate change listener, according to which
event you want your widget to respond to. In the change listener,
call the appropriate method : {@link
eu.ensam.ii.vrpn.VrpnClient#sendAnalog(int,double) sendAnalog} or
{@link eu.ensam.ii.vrpn.VrpnClient#sendButton(int,boolean)
sendButton}. Note that a single widget can s end several updates,
like the {@link eu.ensam.ii.vrpn.VrpnSurface VrpnSurface} does or
like a <a
href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.html">color
picker</a>would do. There is currently no <em>sendTracker</em> method
although this may be useful to implement an Arcball for instance.</li>
</ul>
<p>Note that using the full path of the parent class such as in :
<pre>public class VrpnRadioButton extends android.widget.RadioButton</pre>
allows Javadoc to generate a link to the parent class.
</p>
<h4>Generate the documentation</h4>
<p>
Select the <em>vrpn_library/src</em> folder, then select the menu item
<em>Project</em> &gt; <em>Generate Javadoc</em>.
<p>
On the first page of the wizard, select the path of the <em>javadoc</em>
tool. Check that <em>vrpn_library/src</em> is selected, but not <em>vrpn_library/gen</em>,
then select an appropriate destination for the documentation.
</p>
<p>
On the second page of the wizard select <em>android.jar</em> in the <em>Referenced
archives</em> list and take note of the <em>android.jar</em> doc path
(like
<code>file:/E:/android/docs/reference</code>
).
</p>
<p>
On the third page of the wizard add the following line to the <em>Extra
javadoc options</em> text box :
<pre>
-linkoffline http://d.android.com/reference file:/E:/android/docs/reference
</pre>
but replace the
<code>file:/</code>
URL by your local Android SDK URL noted from the page two of the
wizard. This allows Javadoc to include full references to the on-line
Android documentation.
/*
********************************* End of paste Here
*/
package eu.ensam.ii.vrpn;
\ No newline at end of file
set(ATMELLIB_PUBLIC_HEADERS
vrpn_atmellib_errno.h
vrpn_atmellib.h)
set(ATMELLIB_SOURCES
vrpn_atmellib_helper.h
vrpn_atmellib_helper.C
vrpn_atmellib_iobasic.C
vrpn_atmellib_openclose.C
vrpn_atmellib_register.C
vrpn_atmellib_tester.C)
add_library(vrpn_atmel ${ATMELLIB_PUBLIC_HEADERS} ${ATMELLIB_SOURCES})
set_property(TARGET
vrpn_atmel
PROPERTY
PUBLIC_HEADER
${ATMELLIB_PUBLIC_HEADERS})
set_property(TARGET
vrpn_atmel
PROPERTY
FOLDER
"Library")
if(VRPN_INSTALL)
install(TARGETS
vrpn_atmel
ARCHIVE
DESTINATION
lib
COMPONENT
serversdk
PUBLIC_HEADER
DESTINATION
include
COMPONENT
serversdk)
endif()
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib.h */
/* project : vrpn_avango */
/* description: part of vrpn_avango_atmel_server */
/* */
/***************************************************************************************************/
/* */
/* */
/***************************************************************************************************/
#if !defined(VRPN_AVANGO_ATMELLIB_SERIAL_H)
#define VRPN_AVANGO_ATMELLIB_SERIAL_H
/* includes, system */
/* #include <> */
/* includes, project */
#include "vrpn_atmellib_errno.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*************************************************************************************************/
/* constants you have to remember */
/* maiximum time to wait for a new byte from the atmel */
#define VRPN_ATMELLIB_SELECT_WAIT_SEC 0
#define VRPN_ATMELLIB_SELECT_WAIT_USEC 150000
/*************************************************************************************************/
/* types, exported (enum, struct, union, typedef) */
/*************************************************************************************************/
/* the 2 bytes which defines a message from/to the microcontroller */
struct command_t {
unsigned char addr;
unsigned char value;
};
/*************************************************************************************************/
typedef int error_t;
typedef int handle_t;
/*************************************************************************************************/
/* for development purpose mainly
displays a value as Bits on the screen */
extern void outBit( unsigned char );
/*************************************************************************************************/
/* BASICS */
/*************************************************************************************************/
/* opens the the specified port (whole path needed) and sets the parameters
for the communication with the microcontroller
CAUTION: the return value is a program specific file handler and not the
system file handler */
extern handle_t openPort(const char*i, const int baud, struct termios * init_param);
/* close the specified port and reset all parameters */
extern error_t closePort (handle_t, struct termios * init_param);
/* checks if the given file handler is valid: returns 1 (true) if the handle is invalid otherwise
return 0 (false) */
extern error_t handle_invalid (int);
/* checks if the register is valid */
extern error_t register_invalid( unsigned char );
/*************************************************************************************************/
/* LOW LEVEL INTERFACE */
/*************************************************************************************************/
/* send one/more command(s) to the microcontroller which don't change the state of it
the return value of the command - i.e. the value of a register - is returned in the
second calling variable */
extern int getCmd (handle_t, struct command_t*);
/* send one/more command(s) to the microcontroller which change the state of the microcontrolle */
extern int setCmd (int, struct command_t*);
/* set the value of the specified register */
extern error_t
setRegister( handle_t Hd , const unsigned char Register , const unsigned char Val);
/* get the value of the specified register */
extern int getRegister( handle_t Hd , const unsigned char Register);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* #if !defined(VRPN_AVANGO_ATMELLIB_SERIAL_H) */
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : atmel_serial_errno.h */
/* project : atmellib */
/* description: error numbers of the lib */
/* */
/***************************************************************************************************/
#if !defined(ATMELLIB_SERIAL_ERRNO_H)
#define ATMELLIB_SERIAL_ERRNO_H
/* program specific error codes */
#define ATMELLIB_NOERROR 1 /* no error */
#define ATMELLIB_ERROR_GENERAL -1 /* general error */
#define ATMELLIB_ERROR_SEQTO -5 /* sequence to small */
#define ATMELLIB_ERROR_NORESPVAL -6 /* the mc didn't confirm the command */
#define ATMELLIB_ERROR_NOCOMVAL -7 /* no valid command (must be bigger than 127 ) */
#define ATMELLIB_ERROR_REGINV -10 /* the register is invalid */
#define ATMELLIB_ERROR_VALINV -11 /* the value register is invalid */
#define ATMELLIB_ERROR_RESINV -12 /* hardware ressource invalid */
#define ATMELLIB_ERROR_NOTINIT -13 /* the prequists are not ok: i.e. to put a
light on the pin must be in output mode */
#define ATMELLIB_ERROR_PARAMINV -14 /* functioncall with invalid parameter*/
#define ATMELLIB_ERROR_NOSTATEVAL -15 /* no valid state or not able to read it out */
#endif /* #if !defined(ATMELLIB_SERIAL_ERRNO_H) */
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_helper.C */
/* project : atmel-avango */
/* description: part of the serial lib for the Atmel */
/* miscellaneous functions */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for error_t
#include <stdio.h> // for printf
/* include i/f header */
#include "vrpn_atmellib.h" // for command_t, getCmd, setCmd, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_NOERROR, etc
#include "vrpn_atmellib_helper.h"
/***************************************************************************************************/
/* set the defined bit in the command to the expected value and leave the rest like it is */
/***************************************************************************************************/
error_t
setBitCmd( struct command_t * Cmd , const unsigned char Pos , unsigned char Val )
{
/* check if the parameter are valid */
if ((Val != 0) && (Val != 1))
return ATMELLIB_ERROR_VALINV;
if (Pos > 7)
return ATMELLIB_ERROR_VALINV;
/* check if the value for "our" pin is already correct else change it */
if (Pos == 7) {
/* bit seven is in byte one */
if (((*Cmd).addr) & 0x01) {
if (Val == 0)
(*Cmd).addr -= 1; /* it's 1 and it has to be 0*/
}
else {
if (Val == 1) /* it's 0 and it has to be 1 */
(*Cmd).addr += 1;
}
}
else { /* the bits in the second byte */
unsigned char Reference = 0x01 << Pos;
if ( ((*Cmd).value) & Reference ) {
if (Val == 0)
(*Cmd).value -= PowToTwo(Pos);
}
else { /* change necessary */
if (Val == 1)
(*Cmd).value += PowToTwo(Pos);
}
}
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* change only one bit of the value of the specified register */
/***************************************************************************************************/
error_t
setBitReg( const handle_t Hd , const unsigned char Reg , \
const unsigned char Pos , const unsigned char Val )
{
struct command_t Cmd;
error_t R;
unsigned char i;
/* check if the parameters are valid */
if ((Val != 0) && (Val != 1))
return ATMELLIB_ERROR_VALINV;
/* set the correct address for the register */
/* check if the first bit is already set or if it has to be done here */
if (Reg & 0x80)
Cmd.addr = Reg;
else {
Cmd.addr = Reg + 64;
Cmd.addr <<= 1;
}
Cmd.value = 0x00;
/* get the current setting of the register on the microcontroller */
/* if you get sth invalid try again */
for (i=0 ; i<10 ; ++i) {
if ( (R = getCmd( Hd , &Cmd )) != ATMELLIB_NOERROR )
return R;
if ( Cmd.value<128)
break;
}
if (i==10)
return ATMELLIB_ERROR_NOSTATEVAL;
if ( (R = setBitCmd( &Cmd , Pos , Val )) != ATMELLIB_NOERROR)
return R;
/* write the corrected value back to the microcontroller */
if ( (R = setCmd( Hd , &Cmd )) != ATMELLIB_NOERROR )
return R;
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* 2^Exponent */
/***************************************************************************************************/
unsigned int
PowToTwo( unsigned int Exponent )
{
unsigned int i;
unsigned int R = 1;
for( i=0 ; i<Exponent ; i++)
R *= 2;
return R;
}
/***************************************************************************************************/
/* valid address byte to the specified register */
/* the MSB data bit is set to zero */
/***************************************************************************************************/
unsigned char
getAddress( unsigned char Reg )
{
Reg += 64;
Reg <<= 1;
return Reg;
}
/***************************************************************************************************/
/* set the value in a two byte command */
/***************************************************************************************************/
void
setValue( struct command_t * Cmd , unsigned char Val)
{
if (Val>127) {
Val -= 128;
if ( ! ((*Cmd).addr & 0x01))
(*Cmd).addr +=1;
}
else
if ((*Cmd).addr & 0x01)
(*Cmd).addr -=1;
(*Cmd).value = Val;
}
/***************************************************************************************************/
/* helper function */
/***************************************************************************************************/
/* extern */ void
outBit( unsigned char Arg )
{
unsigned char Ref;
for ( Ref=0x80 ; Ref != 0x00 ; Ref >>= 1 ) {
if (Ref & Arg)
printf("1");
else
printf("0");
}
printf("\n");
}
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : lib */
/* project : atmellib */
/* description: private part of the header for internal use */
/* */
/***************************************************************************************************/
/* $Id: vrpn_atmellib_helper.h,v 1.1 2007/06/25 19:56:16 taylorr Exp $ */
#if !defined(ATMELLIB_SERIAL_HELPER_H)
#define ATMELLIB_SERIAL_HELPER_H
/* includes, system */
/* #include <> */
#include <errno.h> // for error_t
/* includes, project */
#include "vrpn_atmellib.h" // for handle_t
#if defined(__cplusplus)
extern "C" {
#endif
/*****************************************************************/
/* types, variables NOT exported, internal (static) */
/* internal functions */
/* set the specified bit in the given Command without interfering the other bits*/
error_t setBitCmd( struct command_t * Command , \
const unsigned char Position , unsigned char Value );
/* set the specified bit in the Register without interfering the other bits */
error_t setBitReg( const handle_t Handle , const unsigned char Register , \
const unsigned char Position , const unsigned char Value );
/* gives you the 2^Exponent */
unsigned int PowToTwo( unsigned int Exponent);
/* valid address byte for the specified Register
the MSB data bit is set to zero */
unsigned char getAddress( unsigned char Register );
/* set a value in an two byte command*/
void setValue( struct command_t * Command , unsigned char Value);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* #if !defined(ATMELLIB_SERIAL_HELPER_H) */
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmel_iobasic.C */
/* project : atmel-avango */
/* description: basic functions for serial io access on the tty */
/* */
/***************************************************************************************************/
//#define VRPN_ATMELLIB_VERBOSE_OUTBIT
//#define VRPN_ATMELLIB_VERBOSE
/* include system headers */
#include <errno.h> // for errno, ENXIO, error_t
#include <stddef.h> // for size_t
#include <stdio.h> // for fprintf, stderr, NULL, etc
#include <string.h> // for strerror
#include <sys/select.h> // for select, FD_SET, FD_ZERO, etc
#include <termios.h> // for tcflush, TCIOFLUSH
#include <unistd.h> // for read, write
/* include i/f header */
#include "vrpn_Shared.h" // for timeval
#include "vrpn_atmellib.h" // for command_t, handle_t, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_NORESPVAL, etc
/***************************************************************************************************/
/* read data from the tty */
/* returns the bytes read or one of the system wide error codes returned by read */
/***************************************************************************************************/
static int
read_wrapper (handle_t fd, void* buf, size_t len)
{
return read (fd, buf, len);
}
/***************************************************************************************************/
/* write data to the tty: return the byte written or one of the system
wide error codes returned by write */
/***************************************************************************************************/
static int
write_wrapper ( handle_t fd , const void* buf , size_t len )
{
return write (fd , buf , len );
}
/***************************************************************************************************/
/* make a select for lib-wide time and if this is successfully read one byte */
/***************************************************************************************************/
static int
select_read_wrapper(handle_t fd , struct timeval * time)
{
fd_set rdfs;
unsigned char byte;
int ret;
FD_ZERO( &rdfs );
FD_SET(fd , &rdfs);
ret = select( fd+1, &rdfs, NULL, NULL, time);
if (ret<0) {
fprintf(stderr, "select_read_wrapper:: error during select: %s (%i)\n",
strerror(errno) ,errno);
return ATMELLIB_ERROR_NORESPVAL;
}
else if (ret==0) {
// time expired
fprintf(stderr, "vrpn_atmellib::select_read_wrapper: select timed out\n" );
return ATMELLIB_ERROR_NORESPVAL;
}
// successful select -> read out one command
if ((ret = read_wrapper(fd , (void *) (&byte), 1)) <=0 )
return ret;
#ifdef VRPN_ATMELLIB_VERBOSE_OUTBIT
outBit(byte);
#endif
return byte;
}
/***************************************************************************************************/
/* make a select for lib-wide time and if this is successfully read one byte */
/***************************************************************************************************/
static int
select_write_wrapper(handle_t fd , struct timeval * time, unsigned char * data , int len)
{
fd_set wrfs;
int ret;
FD_ZERO( &wrfs );
FD_SET(fd , &wrfs);
ret = select( fd+1, NULL, &wrfs, NULL, time);
if (ret<0) {
fprintf(stderr,
"vrpn_atmellib::select_write_wrapper::error during waiting for writing permission: %s (%i)\n",
strerror(errno) ,errno);
return ATMELLIB_ERROR_NORESPVAL;
}
else if (ret==0) {
// time expired
fprintf(stderr, "vrpn_atmellib::select_write_wrapper: timed out in wrapper\n" );
return ATMELLIB_ERROR_NORESPVAL;
}
// successful select -> write down command
// write twice to ensure that the atmel receives it
//write_wrapper(fd , (void *) data, len);
return write_wrapper(fd , (void *) data, len);
}
/***************************************************************************************************/
/* PART OF THE BASIC INTERFACE: for explainations to the functions see the header file */
/***************************************************************************************************/
/***************************************************************************************************/
/* get the value of one register */
/***************************************************************************************************/
/* extern */ error_t
getCmd (handle_t fd, struct command_t* Cmd)
{
struct timeval time_wait;
int ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
unsigned char read_val;
#endif
// some adds to measure time for reading out
#ifdef VRPN_ATMELLIB_TIME_MEASURE
struct timeval start;
struct timeval end;
int sec, usec;
vrpn_gettimeofday( &start , 0);
#endif
unsigned char PossibilityOne;
unsigned char PossibilityTwo;
unsigned char Reference;
/* check if the given parameters are valid */
if (handle_invalid(fd))
return ENXIO;
if ((*Cmd).addr < 128)
return ATMELLIB_ERROR_NOCOMVAL;
PossibilityOne = (*Cmd).addr;
PossibilityTwo = (*Cmd).addr;
Reference = 0x01;
if (Reference & PossibilityTwo)
/* the LSB of the Address is 1 -> make 0 -> use XOR operator */
PossibilityTwo ^= Reference;
else
/* the LSB of the address is 0 -> make 1 -> use OR operator */
PossibilityTwo |= Reference;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_flush_input_buffer(fd);
vrpn_flush_output_buffer(fd);
#else
tcflush( fd , TCIOFLUSH );
#endif
time_wait.tv_sec = VRPN_ATMELLIB_SELECT_WAIT_SEC;
time_wait.tv_usec = VRPN_ATMELLIB_SELECT_WAIT_USEC;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_write_characters(fd, (&((*Cmd).addr)) , 1);
#else
/* you have to send the address first */
if ( (ret = select_write_wrapper( fd ,
&(time_wait),
(&((*Cmd).addr)) ,
1 ))
!= 1 ) {
fprintf(stderr, "\n vrpn_atmellib::getCmd: Error while writing down. error=%i\n",
ret);
return ret;
}
#endif
while (time_wait.tv_usec!=0) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error vrpn_read_available_characters for first byte\n");
break;
}
// else
ret = read_val;
#else
if ((ret = select_read_wrapper(fd, &time_wait)) < 0) {
fprintf(stderr, "vrpn_atmellib::getCmd:\
Error select_read_wrapper for first byte: %i\n" , ret);
break;
}
#endif
// found expected first byte
if ((ret==PossibilityOne) || (ret==PossibilityTwo )) {
(*Cmd).addr = ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
ret = select_read_wrapper(fd, &time_wait);
#endif
if ((ret < 0) || (ret > 128)) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error reading second byte: %i\n\n" , ret);
break;
}
(*Cmd).value = ret;
#ifdef VRPN_ATMELLIB_TIME_MEASURE
// display time for
vrpn_gettimeofday( &end , 0);
sec=end.tv_sec-start.tv_sec;
usec=end.tv_usec-start.tv_usec;
printf("Time for reading out: sec=%i , usec=%i\n", sec, usec);
#endif
return ATMELLIB_NOERROR;
}
}
return ATMELLIB_ERROR_NORESPVAL;
}
/***************************************************************************************************/
/* write one command to the mc and wait for confirmation */
/***************************************************************************************************/
/* extern */ error_t
setCmd (handle_t fd , struct command_t * Cmd)
{
struct timeval time_wait;
int ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
unsigned char read_val;
#endif
// some adds to measure time for reading out
#ifdef VRPN_ATMELLIB_TIME_MEASURE
struct timeval start;
struct timeval end;
int sec, usec;
vrpn_gettimeofday( &start , 0);
#endif
/* check if the given parameters are valid */
if (handle_invalid(fd))
return ENXIO;
if ((*Cmd).addr < 128)
return ATMELLIB_ERROR_NOCOMVAL;
time_wait.tv_sec = VRPN_ATMELLIB_SELECT_WAIT_SEC;
time_wait.tv_usec = VRPN_ATMELLIB_SELECT_WAIT_USEC;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_write_characters(fd, (unsigned char*) Cmd, 2);
#else
if ( (ret = select_write_wrapper( fd ,
&(time_wait),
(unsigned char*) Cmd ,
2 ))
!= 2 ) {
fprintf(stderr, "\n vrpn_atmellib::setCmd: Error while writing down. error=%i\n",
ret);
return ret;
}
#endif
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_flush_input_buffer(fd);
vrpn_flush_output_buffer(fd);
#else
tcflush( fd , TCIOFLUSH );
#endif
while (time_wait.tv_usec!=0) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::setCmd: Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
if ((ret = select_read_wrapper(fd, &time_wait)) < 0) {
fprintf(stderr, "vrpn_atmellib::setCmd: Error select_read_wrapper for first byte: %i\n" , ret);
break;
}
#endif
// found expected first byte
if (ret==(*Cmd).addr) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
printf("Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
ret = select_read_wrapper(fd, &time_wait);
#endif
if (ret!=(*Cmd).value) {
printf("vrpn_atmellib::setCmd: Error select_read_wrapper for second byte: %i\n" , ret);
break;
}
#ifdef ATMELLIB_TIME_MEASURE
// display time for
vrpn_gettimeofday( &end , 0);
sec=end.tv_sec-start.tv_sec;
usec=end.tv_usec-start.tv_usec;
printf("Time for writing down: sec=%i , usec=%i\n", sec, usec);
#endif
return ATMELLIB_NOERROR;
}
}
return ATMELLIB_ERROR_NORESPVAL;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_openclose.C */
/* project : atmel-avango */
/* description: handle open, close and initalization of the tty */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for ENXIO, error_t
#include <fcntl.h> // for open, O_NOCTTY, O_RDWR
#include <termios.h> // for termios, cfsetispeed, etc
#include <unistd.h> // for close, isatty
/* include i/f header */
#include "vrpn_atmellib.h" // for handle_t, handle_invalid
#include "vrpn_atmellib_errno.h" // for ATMELLIB_NOERROR
/***************************************************************************************************/
/* internal (static) functions */
/*****************************************************************/
/* set the parameter to communicate with the microcontroller */
/*****************************************************************/
static int
Set_Params( handle_t fd , const int baud, struct termios * init_param)
{
struct termios Params;
/* get the actual parameters of the tty */
tcgetattr( fd , &Params );
/* save the init values of the tty */
(*init_param) = Params;
/* wait time for new data */
Params.c_cc[VTIME] = 0;
Params.c_cc[VMIN] = 1;
if (baud==38400) {
Params.c_cflag = B38400 | CSIZE | CS8 | CREAD | CLOCAL | HUPCL;
cfsetospeed( &Params , B38400 );
cfsetispeed( &Params , B38400 );
}
else {
// 9600 baud is default
Params.c_cflag = B9600 | CSIZE | CS8 | CREAD | CLOCAL | HUPCL;
cfsetospeed( &Params , B9600 );
cfsetispeed( &Params , B9600 );
}
Params.c_iflag = (IGNBRK | IGNPAR);
Params.c_lflag = 0;
Params.c_oflag = 0;
/* activate the new settings */
tcsetattr( fd , TCSANOW , &Params );
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* PART OF THE BASIC INTERFACE: for explainations to the functions see the header file */
/***************************************************************************************************/
/***************************************************************************************************/
/* open the specified serial port and set the parameter that it's ready to communicate with the mc*/
/***************************************************************************************************/
/* extern */ handle_t
openPort (const char* tty , const int baud, struct termios * init_param)
{
handle_t fd;
/* try to open thespecified device */
if ( (fd = open( tty , O_RDWR | O_NOCTTY )) < 0)
return fd;
/* check if the open file is a tty */
if (!isatty( fd )) {
close (fd);
return -1;
}
/* set the correct serial parameter to communicate with the microcontroller */
if ( Set_Params( fd , baud, init_param ) < 0 )
{
close (fd);
return -1;
}
return fd;
}
/***************************************************************************************************/
/* close the specified port and reset the parameter to the initial values */
/***************************************************************************************************/
/* extern */ error_t
closePort (handle_t fd , struct termios * init_param)
{
if (handle_invalid(fd))
return ENXIO;
/* first reset the parameters and then close the port */
tcsetattr( fd , TCSADRAIN, init_param );
close( fd );
return ATMELLIB_NOERROR;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_register.C */
/* project : atmel-avango */
/* description: function of an easy high level interface for access to the registers */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for ENXIO, error_t
/* include i/f header */
#include "vrpn_atmellib.h" // for command_t, handle_invalid, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_REGINV, etc
#include "vrpn_atmellib_helper.h" // for getAddress, setValue
/***************************************************************************************************/
/* HIGH LEVEL INTERFACE */
/***************************************************************************************************/
/***************************************************************************************************/
/* write the value of the specified register and wait for confirmation */
/***************************************************************************************************/
/* extern */ error_t
setRegister( handle_t Handle , const unsigned char Register , const unsigned char Value)
{
struct command_t Cmd;
/* check if the arguments are valid */
if (handle_invalid(Handle))
return ENXIO;
if (register_invalid( Register ) != ATMELLIB_NOERROR)
return ATMELLIB_ERROR_REGINV;
/* combine the parameter to a valid commande */
Cmd.addr = getAddress( Register );
setValue( &Cmd , Value );
/* send the command to the microcontroller */
return ( setCmd( Handle , &Cmd ) );
}
/***************************************************************************************************/
/* read out the value of the specified register */
/***************************************************************************************************/
/*extern*/ int
getRegister( handle_t Handle , const unsigned char Register )
{
error_t R;
struct command_t Cmd;
/* check if the arguments are valid */
if (handle_invalid(Handle))
return ENXIO;
if (register_invalid( Register ) == ATMELLIB_ERROR_GENERAL)
return ATMELLIB_ERROR_REGINV;
/* make a valid command */
Cmd.addr = getAddress( Register );
/* Send the command to the microcontroller */
if ( (R = getCmd( Handle , &Cmd )) != ATMELLIB_NOERROR)
return R;
/* get the value */
if ( Cmd.addr & 0x01 ) Cmd.value += 128;
return (Cmd.value);
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_tester.C */
/* project : atmel-avango */
/* description: functions to test the state */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for error_t
/* include i/f header */
#include "vrpn_atmellib.h" // for handle_t
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_GENERAL, etc
/***************************************************************************************************/
/* internal (static) variables */
/* define a invalid handle */
const static int invalid_handle = -1;
/***************************************************************************************************/
/* test if the given handler is a valid handle */
/***************************************************************************************************/
/* extern */ error_t
handle_invalid (handle_t handle)
{
return (invalid_handle == handle);
}
/***************************************************************************************************/
/* test if the register is valid - if it exists on the mc */
/***************************************************************************************************/
/* extern */ error_t
register_invalid (unsigned char Register)
{
if (Register > 63) {
return ATMELLIB_ERROR_GENERAL;
}
return ATMELLIB_NOERROR;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
.depend
make.out
makefile
pc_cygwin
pc_linux
sgi_irix
sparc_solaris
powerpc_aix
*.vcproj.*.user
cmake_minimum_required(VERSION 2.6)
#-----------------------------------------------------------------------------
# XXX Things to make better.
#
# XXX clock_drift_estimator
# Move applications into subprojects in visual studio
# Make the files with ".c" extension also compile as C++.
# Make the c_interface_example work
#-----------------------------------------------------------------------------
# Build the client applications if we've been asked to.
if(VRPN_BUILD_CLIENTS)
if(NOT VRPN_CLIENT_LIBRARY)
message(FATAL_ERROR
"Cannot compile clients without either the client or full library. Enable one and try again.")
endif()
#-----------------------------------------------------------------------------
# Libraries we need to do our thing.
find_package(GLUT)
if(APPLE)
mark_as_advanced(GLUT_cocoa_LIBRARY)
endif()
find_package(OpenGL)
set(CLIENTS_SOURCES
vrpn_print_devices.C
vrpn_print_performance.C
vrpn_print_messages.C
)
set(TEST_SOURCES
add_vrpn_cookie.C
bdbox_client.C
clock_drift_estimator.C
ff_client.C
forcedevice_test_client.cpp
forwarderClient.C
#midi_client.C # XXX TODO No vrpn_Sound_Remote ever defined in this repository
#ohm_client.C # XXX TODO No vrpn_Ohmmeter (vrpn_Ohmmeter.h) defined in this repository
phan_client.C
printcereal.C
printvals.C
sound_client.C
sphere_client.C
testSharedObject.C
test_Zaber.C
test_imager.C
test_mutex.C
text.C
tracker_to_poser.cpp
vrpn_LamportClock.t.C
vrpn_ping.C
)
if(NOT WIN32)
# TODO: These need "open" calls modified to build on win.
list(APPEND
TEST_SOURCES
logfilesenders.C
logfiletypes.C
checklogfile.C)
endif()
###
# Tests
###
if(BUILD_TESTING)
foreach(SOURCE ${TEST_SOURCES})
get_filename_component(APP ${SOURCE} NAME_WE)
add_executable(${APP} ${SOURCE})
target_link_libraries(${APP} ${VRPN_CLIENT_LIBRARY})
set_target_properties(${APP} PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS ${APP} RUNTIME DESTINATION bin COMPONENT tests)
endif()
endforeach()
if(GLUT_FOUND AND OPENGL_FOUND)
include_directories(${GLUT_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
add_executable(testimager_client testimager_client.C)
target_link_libraries(testimager_client
${VRPN_CLIENT_LIBRARY}
${GLUT_glut_LIBRARY}
${OPENGL_LIBRARIES})
set_target_properties(testimager_client PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS
testimager_client
RUNTIME
DESTINATION
bin
COMPONENT
tests)
endif()
option(VRPN_GLUT_IS_STATIC_FREEGLUT
"Is the GLUT used for the imaging test client a static build of FreeGLUT?"
NO)
mark_as_advanced(VRPN_GLUT_IS_STATIC_FREEGLUT)
if(VRPN_GLUT_IS_STATIC_FREEGLUT)
set_property(TARGET
testimager_client
PROPERTY
COMPILE_DEFINITIONS
"FREEGLUT_STATIC")
endif()
endif()
endif()
add_executable(c_interface_example
c_interface_example.c
c_interface.h
c_interface.cpp)
target_link_libraries(c_interface_example ${VRPN_CLIENT_LIBRARY})
set_target_properties(c_interface_example PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS
c_interface_example
RUNTIME
DESTINATION
bin
COMPONENT
tests)
endif()
###
# Clients
###
foreach(SOURCE ${CLIENTS_SOURCES})
get_filename_component(APP ${SOURCE} NAME_WE)
add_executable(${APP} ${SOURCE})
target_link_libraries(${APP} ${VRPN_CLIENT_LIBRARY})
set_target_properties(${APP} PROPERTIES FOLDER Clients)
if(VRPN_INSTALL)
install(TARGETS ${APP} RUNTIME DESTINATION bin COMPONENT clients)
endif()
endforeach()
###
# Servers
###
add_executable(run_auxiliary_logger run_auxiliary_logger.C)
target_link_libraries(run_auxiliary_logger ${VRPN_CLIENT_LIBRARY})
set_target_properties(run_auxiliary_logger PROPERTIES FOLDER Servers)
if(VRPN_INSTALL)
install(TARGETS
run_auxiliary_logger
RUNTIME
DESTINATION
bin
COMPONENT
servers)
endif()
endif()
2009-12-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* c_interface_example.cpp : Gets rid of a compiler warning.
2009-12-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* CmakeLists.txt : Improvements by Ryan Pavlik to the Cmake files that
make them cleaner and use more modern constructions. Also various
bug fixes to make code compile on a number of architectures.
* bdbox_client.C : Compiles with modern VRPN.
* logfilesenders.c : Compiles on all architectures.
* logfiletypes.c : Same.
* testimager_client.C : Compiles on Apple.
* tracker_to_poser.cpp : Compiles on all architectures.
2009-11-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* CMakeLists.txt : Turning off testimager_client on all but Windows.
* testimager_client.C : Removing declarations that aren't needed but that
only worked on Windows.
2009-11-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* ff_client.C : Picking lint found by a new compiler (const declarations and
printf format descriptions.
* phan_client.C : Same.
* printceral.C : Same.
* sphere_client.C : Same.
* text.C : Same.
* vrpn_print_devices.C : Same.
2009-11-21 Russell M. Taylor II <taylorr@cs.unc.edu>
* CMakeLists.txt : File to describe to the Cmake build system how
to compile VRPN.
* ff_client.C : Upgrade to compile on Windows with recent VRPN.
* phan_client.C : same.
* testSharedObject.C : same.
* text.C : same.
* vrpn_ping.C : same.
2009-11-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* sound_client.c : Fixed it so that it compiles. There must
have been an inadvertent cutting out of some lines in
the code.
2009-09-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Turned "-g" flag into "$(DEBUG_FLAGS)" throughout.
2009-07-20 Russell M. Taylor II <taylorr@cs.unc.edu>
* run_auxiliary_logger.C : Added a test program that
lets you connect and ask for a log file for some
duration.
* run_auxiliary_logger.dsp : Same.
* run_auxiliary_logger.vcproj : Same.
2009_06_16 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removed UNC-specific include and library paths.
2009_04_17 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Patch from Hans Lambermont to make it compile under Linux.
* test_imager.C : Same.
2009_03_07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added entry to compile a C-interface example program.
* c_interface.cpp : Code to provide a C interface to remote classes.
* c_interface.h : Same.
* c_interface_example.c : Example C program using the interface.
2009_01_21 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.vcproj : Making it compile with quatlib
in expected location.
* sphere_client.vcproj : Same.
* vrpn_print_devices.C : Removed limit on the number of sensors per
tracker. Now uses a vector to keep track of counts, which
can add more until we run out of memory.
2008_07_02 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Has the code not preload or
accumulate in case of reading from a file.
2008_03_04 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Replaces vrpn_Connection
constructor with call to vrpn_create_server_connection()
* test_imager.C : Same.
* testimager_client.C : Whitespace changes
* vrpn_print_devices.C : Added Text_Receiver to the objects
being created, so you can print out text messages from an
object as well.
2007-12-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Has VRPN fileconnections neither preload
nor accumulate in case we open a logfile to read the
device.
2007-08-05 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Fixed a race-condition bug at startup that
would cause a crash when a Glut function was called before
Glut was initialized.
2007-06-28 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added linking with pthreads because of vrpn_Thread class.
2007-06-19 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding patch submitted by Patrick Hartling from
Infiscape.com for making this compile on MacOSX
to create universal binaries.
2007-03-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding a build environment for cross-compiling to
ARM from PCs running Cygwin
2007-03-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Making this code compile under pc_linux_arm.
2006-10-04 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.vcproj : Updated to use the August 2006 version
of the DirectX SDK and the Microsoft Platform SDK
for Windows Server 20003 R2.
* forcedevice_test_client.vcproj : Same.
* printcerial.vcproj : Same.
* printvals.vcproj : Same.
* sphere_client.vcproj : Same.
* test_imager.vcproj : Same.
* test_zaber.vcproj : Same.
* testimager_client.vcproj : Same.
* tracker_to_poser.vcproj : Same.
* vrpn_print_devices.vcproj : Same.
2006-08-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : It now renders when it gets the
end of a frame, which helps reduce the tearing in the
video being displayed.
2006-07-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Adding a call to make the connection limit
the number of messages it will handle before returning control
to the application. This prevents the server from choking the
whole program by continually filling the network with packets.
2006-06-21 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added install and uninstall.
2006-03-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* *.vcproj : Visual C++ 2005 project files for VRPN.
2006-02-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Switched to the more standard
GL/glut.h for the include.
* testimager_client.dsp : Modified so that it looks in
the NSRG buildime rather than a nearby local
directory.
2005-10-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.cpp : Modified to also include the
presentation of a cube using the triangle interface.
2005-10-04 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added target for 64-bit Intel-based SGI compilation.
2005-09-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.C : Modified to only put
in normalized directions.
2005-08-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Diff went crazy, so it is hard to
tell. Newer version.
2005-08-10 Ben Wilde <wilde@cs.unc.edu>
* forcedevice_test_client.cpp
-Added tests for the line and plane constraints. The plane
seems to work fine, but the line constraint has a strange
behavior. Either due to poor implementation or vrpn problem.
2005-07-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Application to estimate the drift between
the local machine's clock and another machine's clock using
the PING/PONG response from an arbitrary server object.
* clock_drift_estimator.dsp : Project file for this.
2005-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.cpp : Deleted objects before exiting.
* phan_client.C : Same.
* sphere_client.C : Same.
2005-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.dsp : Added include directories on $(SYSTEMDRIVE)
and lib directories also on $(SYSTEMDRIVE) so that the
apps can build correctly with only edits in the
vrpn_Configure.h file if things are installed in standard
locations.
* forcedevice_test_client.dsp : Same.
* printvals.h : Same.
* setrouter.dsp : Same.
* test_imager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2005-07-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_client.C : Removed.
* vrpnTrackerClient.cpp : Same.
* printcereal.C : Removed Synchronized.
* printvals.c : Same.
* sound_client.c : same.
* test_imager.C : Deleted objects that had been created, to
avoid reference-count warning at the end.
2005-04-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Clears image to black so that
anything not filled in has a definite value.
2005-02-25 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removed -LANG:std from compile, no streams
used in the code anymore.
2005-02-01 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added John Stone's definitions to make
things compile under 64-bit Linux.
2005-01-11 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Modified to handle red, green,
blue channels from client.
2004-12-14 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpnTrackerClient.cpp : Fixed compiler warnings.
2004-12-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Swapped out test_tempimager for test_imager.
* test_imager.dsp : Same.
* test_imager.C : Same.
* test_tempimager.dsp : Same.
* test_tempimager.C : Same.
2004-12-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Modified to use vrpn_Imager rather than vrpn_TempImager.
2004-11-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* Happy Birthday to me!
* Makefile : Added John Stone's additions to make it compile on
64-bit Solaris
2004-09-16 Russell M. Taylor II <taylorr@cs.unc.edu>
Adding Chris VanderKnyff's changes that enable DLL linkage
for applications. Heading towards enabling C# and other language
support.
* forcedevice_test_client.cpp : Adding VRPN_CALLBACK.
* printcereal.C : same.
* printvals.C : same.
* sphere_client.C : same.
* test_Zaber.C : same.
* test_tempimager.C : same.
* testimager_client.C : same.
* tracker_to_poser.cpp : same.
* vrpn_Router_Client_GUI.C : same.
* vrpn_print_devices.C : same.
* forcedevice_test_client.dsp : Making it depend on the project
that causes both VRPN and VRPNDLL projects to be built, rather
than on VRPN. If you try to make it depend on both
VRPN and VRPNDLL, you get linking trouble.
* printcereal.dsp : same.
* printvals.dsp : same.
* setrouter.dsp : same.
* sphere_client.dsp : same.
* test_tempimager.dsp : same.
* test_zaber.dsp : same.
* testimager_client.dsp : same.
* tracker_to_poser.dsp : same.
* vrpn_Router_Client_GUI.dsp : same.
* vrpn_print_devices.dsp : same.
2004-09-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.dsp : Changing code generation back to
DLL-based for all classes, like it was supposed to be in
the first place. Confusion over the cause for a crash led
us to incorrectly change it before.
* printcereal.dsp : Same.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_tempimager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2004-08-31 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.dsp : Changing code generation to use
multithreaded non-DLL for both debug and release. This turns
out to have always been the proper setting to use.
Unfortunately, all apps have to be rebuild with new settings,
and all libraries have to use the same setting.
* printcereal.dsp : Same.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_tempimager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2004-08-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C : Removed references to objects that were never
created.
2004-07-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding build rule for .cpp (Horrible Windows extension
that is the same as the default rule in Unix for running the
C-pre-processor). Adding rule to build force test client.
* forcedevice_test.client.cpp : Removing unused variables.
2004-07-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Changed default port number.
* test_force_device_client.cpp : Test program for vrpn_ForceDevice/
* test_force_device_client.dsp : Project file to build this.
2004-05-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* tracker_to_poser.cpp : Can specify name of tracker and poser
on command line.
2004-05-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* client_to_poser.cpp : New application to read from tracker
and send to poser.
* client_to_poser.dsp : Project file for this app.
2004-04-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding flag to SGI compile in the hope that it would
fix things and let us use the new streams libraries. It
got us part of the way there on my system.
* clock_client.C : Added Patrick Hartling's changes to make VRPN
compile with Visual Studio.NET, which required switching to
new streams, which required retrofitting SGIs to use old
streams (using yet another define in vrpn_Configure.h).
* test_tempimager.C : same.
* vrpnTrackerClient.cpp : Same.
* vrpn_LamportClock.t.C : Same.
2004-04-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Using vrpn_gettimeofday() not gettimeofday().
* testimager_client.C : Same.
* vrpn_ping.C : Same.
* vrpn_print_devices.C : Same.
2003-12-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Added #ifdef-ed out line to save log.
2003-07-24 Matt McCallus <mccallus@cs.unc.edu>
* sound_client.c : white space, include path removed.
2003-05-05 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C : main() now returns int like it should.
* printvals.C : Same.
* sphere_clien.C : Same.
* test_Zaber.C : Same.
* test_tempimager.C : Uses new interface to TempImager.
* test_tempimager.dsp : Release version compiles now.
* test_zaber.dsp : Same.
2002-12-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.dsp : DSP files have been modified to not do definitions
of VRPN_NO_STREAMS and other constants directly, rather these
are now set by editing vrpn_Configure.h. Also, made projects
compile in both debug and release versions.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_zaber.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
* testimager_client.C : Comment change.
2002-11-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Modified to use new vrpn_Tempimager class.
* testimager_client.dsp : Made os that Release version can be built
and is stored in the correct place.
2002-10-30 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Only post redisplay to Glut once before it
actually calls the display function. Otherwise, the calls
bunch up and the application even stops responding to windows
events.
* test_tempimager.dsp : Enables build for Release.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
2002-10-14 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Scales faster, puts in more timing info.
2002-09-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Displays TempImager server output in OpenGL/Glut.
* testimager_client.dsp : Project file for testimager_client.C.
2002-09-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Modified to use vrpn_Analog_Output. Not tested.
2002-09-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_tempimager.C : Test file for TempImager class.
* test_tempimager.dsp : build file.
* Makefile : same.
2002-07-09 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removing seldom-used clients that don't compile on
all architectures.
2002-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Added handlers for velocity and
acceleration to the tracker device.
2002-05-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* haptic : New directory with examples of using a Phantom.
2002-05-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Program to joj the Zaber back and forth once we have gotten
a response to see where it is.
* vrpn_zaber.dsp : Build file to make the test program.
2001-11-10 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Modify to compile under Windows CE development environment.
2001-06-26 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Updates to use cleaner Tracker code.
2001-06-02 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Program to print all message types from a list
of devices (Tracker, Button, Analog, Dial).
* Makefile : Changed to include building the new application.
2001-04-26 Russell M. Taylor II <taylorr@cs.unc.edu>
* sound_client.c : Changed to compile with more recent version.
2001-04-19 Adam Seeger <seeger@cs.unc.edu>
* phan_client.C, sphere_client.C (main): added while-loop to wait until
the connection is established before sending commands
2001-02-17 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (main) : remove code to Usage(), change command-line
parameters to work with new logging methods.
(init) : work with new logging methods.
(Usage) : new function.
2000-11-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printvals.c (handle_cntl_c) : The ^C handler in Windows is
multi-threaded, which means it is busy tearing down
the connections while the main loop is still going.
This fixes it so that a flag is set and the main thread
does the shutdown.
2000-10-18 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (init) : sometimes use vrpn_DelayedConnection instead
of a straight vrpn_(Synchronized_)Connection
(Usage) : new option -delay
(main) : parse new option -delay, fix set of redundant
transmission time
(handle_gotConnection) : fix set of redundant transmission time
2000-10-17 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (handle_gotConnection) : new function
(init) : register handle_gotConnection
2000-10-16 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added vrpn_ping test program
2000-10-11 Tom Hudson <hudson@cs.unc.edu>
* printvals.c : add vrpn_RedundantRemote, global parameters
(init) : create vrpn_RedundantRemote
(main) : add parameters -quiet, -red
2000-09-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added vrpn_ping compilation
* vrpn_ping.C : New file
2000-09-12 Tom Hudson <hudson@cs.unc.edu>
* testSharedObject : added more complete test of features
2000-08-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added AIX compile
2000-08-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* setrouter : New file
* vrpn_Router_Client_GUI : New file
* Makefile : Added two router test clients, one of which uses GLUT
2000-08-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C (handle_control_C) : fixed deletion bug
# Couldn't understand or usefully modify the former makefile.
# Copied the one from ../server_src here and put the former one
# in Makefile.old
##########################
# common definitions. For non-UNC sites, uncomment one of the lines
# that defines hw_os for the machine you are on in the section just
# below. Then, the code should compile in your environment.
#
#HW_OS := sgi_irix
#HW_OS := sparc_solaris
#HW_OS := sparc_solaris_64
#HW_OS := hp700_hpux10
#HW_OS := pc_linux
HW_OS := pc_linux64
#HW_OS := pc_linux_ia64
# Try using this to cross-compile for ARM on a PC running Linux
#HW_OS := pc_linux_arm
# Try using this to cross-compile for ARM on a PC running Cygwin
#HW_OS := pc_cygwin_arm
#HW_OS := pc_cygwin
#HW_OS := pc_FreeBSD
#HW_OS := powerpc_aix
#HW_OS := powerpc_macosx
#HW_OS := universal_macosx
#HW_OS := macosx_32_64
#HW_OS := macosx_64
##########################
INSTALL_DIR := /usr/local
BIN_DIR := $(INSTALL_DIR)/bin
INCLUDE_DIR := $(INSTALL_DIR)/include
LIB_DIR := $(INSTALL_DIR)/lib
ifndef HW_OS
# hw_os does not exist on FreeBSD at UNC
UNAME := $(shell uname -s)
ifeq ($(UNAME), FreeBSD)
HW_OS := pc_FreeBSD
else
# pc_cygwin doesn't have HW_OS
ifeq ($(UNAME), CYGWIN_NT-4.0)
HW_OS := pc_cygwin
else
ifeq ($(UNAME), CYGWIN_98-4.10)
HW_OS := pc_cygwin
else
HW_OS := $(shell hw_os)
endif
endif
endif
endif
# check if its for pxfl
ifdef PBASE_ROOT
HW_OS := hp_flow
ifeq ($(PXFL_COMPILER), aCC)
HW_OS = hp_flow_aCC
endif
endif
CC := g++
ARCH_LIBS := -lpthread -lquat -lm
ifeq ($(HW_OS),pc_linux)
CC := g++
endif
ifeq ($(HW_OS),pc_linux_ia64)
CC := g++
endif
ifeq ($(HW_OS), pc_linux_arm)
CC := arm-linux-g++
RANLIB := arm-linux-ranlib
AR := arm-linux-ar ruv
endif
ifeq ($(HW_OS), pc_cygwin_arm)
CC := arm-unknown-linux-gnu-g++
RANLIB := arm-unknown-linux-gnu-ranlib
AR := arm-unknown-linux-gnu-ar ruv
endif
ifeq ($(HW_OS),pc_linux64)
CC := g++ -m64
endif
ifeq ($(HW_OS),sgi_irix)
ifndef SGI_ABI
SGI_ABI := n32
endif
ifndef SGI_ARCH
SGI_ARCH := mips3
endif
OBJECT_DIR_SUFFIX := .$(SGI_ABI).$(SGI_ARCH)
CC := CC -$(SGI_ABI) -$(SGI_ARCH)
GLUTLIBS := -lglut -lGLU -lGL -lXmu -lXext -lX11
endif
ifeq ($(HW_OS),hp700_hpux10)
CC := CC +a1
endif
ifeq ($(HW_OS), hp_flow_aCC)
CC := /opt/aCC/bin/aCC
endif
ifeq ($(HW_OS),sparc_solaris)
CC := /opt/SUNWspro/bin/CC
ARCH_LIBS := -lsocket -lnsl $(ARCH_LIBS)
endif
ifeq ($(HW_OS),sparc_solaris_64)
CC := /opt/SUNWspro/bin/CC -xarch=v9a
AR := /opt/SUNWspro/bin/CC -xarch=v9a -xar -o
ARCH_LIBS := -lsocket -lnsl $(ARCH_LIBS)
endif
ifeq ($(HW_OS),powerpc_aix)
# CC := /usr/ibmcxx/bin/xlC_r -g -qarch=pwr3 -w -+
CC := /usr/ibmcxx/bin/xlC_r $(DEBUG_FLAGS) -qarch=pwr3 -w -+
endif
ifeq ($(HW_OS),pc_cygwin)
ARCH_LIBS := -lquat -lcygwin -luser32 -lgdi32 -lcomdlg32 -lwsock32
endif
#CFLAGS = -I../ -I../quat -g
override CFLAGS := -I../ -I../quat $(DEBUG_FLAGS) $(CFLAGS)
override CXXFLAGS := -I../ -I../quat $(DEBUG_FLAGS) $(CXXFLAGS)
.SUFFIXES: .cpp
.c.o:
$(CC) $(CFLAGS) -c $*.c
.C.o:
$(CC) $(CXXFLAGS) -c $*.C
.cpp.o:
$(CC) $(CXXFLAGS) -c $*.cpp
OBJ_DIR := $(HW_OS)$(OBJECT_DIR_SUFFIX)
LIB_DIR := ../$(OBJ_DIR)
#LFLAGS = -g -L$(LIB_DIR) -L../quat/$(HW_OS)$(OBJECT_DIR_SUFFIX)
override LFLAGS := -L$(LIB_DIR) -L../quat/$(HW_OS)$(OBJECT_DIR_SUFFIX) $(DEBUG_FLAGS) $(LDFLAGS)
$(OBJ_DIR)/%.o: %.c
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: %.C
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CXXFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: %.cpp
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CXXFLAGS) -o $@ -c $<
INSTALL_APPS := vrpn_print_devices forcedevice_test_client vrpn_ping \
add_vrpn_cookie vrpn_print_performance vrpn_print_messages
APPS := $(INSTALL_APPS) printvals printcereal checklogfile logfilesenders \
logfiletypes text forwarderClient bdbox_client ff_client phan_client \
sphere_client bdbox_client test_mutex test_imager c_interface_example
all: $(APPS)
.PHONY: vrpn_print_devices
vrpn_print_devices: $(OBJ_DIR)/vrpn_print_devices
.PHONY: vrpn_print_messages
vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages
.PHONY: vrpn_print_performance
vrpn_print_performance: $(OBJ_DIR)/vrpn_print_performance
.PHONY: forcedevice_test_client
forcedevice_test_client: $(OBJ_DIR)/forcedevice_test_client
.PHONY: printvals
printvals: $(OBJ_DIR)/printvals
.PHONY: printcereal
printcereal: $(OBJ_DIR)/printcereal
.PHONY: checklogfile
checklogfile: $(OBJ_DIR)/checklogfile
.PHONY: bdbox_client
bdbox_client: $(OBJ_DIR)/bdbox_client
.PHONY: ff_client
ff_client: $(OBJ_DIR)/ff_client
.PHONY: phan_client
phan_client: $(OBJ_DIR)/phan_client
.PHONY: sphere_client
sphere_client: $(OBJ_DIR)/sphere_client
.PHONY: forwarderClient
forwarderClient: $(OBJ_DIR)/forwarderClient
.PHONY: add_vrpn_cookie
add_vrpn_cookie: $(OBJ_DIR)/add_vrpn_cookie
.PHONY: testSharedObject
testSharedObject: $(OBJ_DIR)/testSharedObject
.PHONY: vrpn_ping
vrpn_ping: $(OBJ_DIR)/vrpn_ping
.PHONY: testLamport
testLamport: $(OBJ_DIR)/testLamport
.PHONY: test_mutex
test_mutex: $(OBJ_DIR)/test_mutex
.PHONY: test_imager
test_imager: $(OBJ_DIR)/test_imager
.PHONY: c_interface_example
c_interface_example: $(OBJ_DIR)/c_interface_example
.PHONY: text
text: $(OBJ_DIR)/text
$(OBJ_DIR)/sound_client: $(OBJ_DIR)/sound_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/sound_client \
$(OBJ_DIR)/sound_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_messages \
$(OBJ_DIR)/vrpn_print_messages.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/printvals: $(OBJ_DIR)/printvals.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/printvals \
$(OBJ_DIR)/printvals.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_devices: $(OBJ_DIR)/vrpn_print_devices.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_devices \
$(OBJ_DIR)/vrpn_print_devices.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_messages \
$(OBJ_DIR)/vrpn_print_messages.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_performance: $(OBJ_DIR)/vrpn_print_performance.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_performance \
$(OBJ_DIR)/vrpn_print_performance.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/printcereal: $(OBJ_DIR)/printcereal.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/printcereal \
$(OBJ_DIR)/printcereal.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/bdbox_client: $(OBJ_DIR)/bdbox_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/bdbox_client \
$(OBJ_DIR)/bdbox_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/ff_client: $(OBJ_DIR)/ff_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/ff_client \
$(OBJ_DIR)/ff_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/forcedevice_test_client: $(OBJ_DIR)/forcedevice_test_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/forcedevice_test_client \
$(OBJ_DIR)/forcedevice_test_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/phan_client: $(OBJ_DIR)/phan_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/phan_client \
$(OBJ_DIR)/phan_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/sphere_client: $(OBJ_DIR)/sphere_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/sphere_client \
$(OBJ_DIR)/sphere_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/listen_client: $(OBJ_DIR)/listen_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/listen_client \
$(OBJ_DIR)/listen_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/text: $(OBJ_DIR)/text.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/text \
$(OBJ_DIR)/text.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/forwarderClient: $(OBJ_DIR)/forwarderClient.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/forwarderClient \
$(OBJ_DIR)/forwarderClient.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/checklogfile: $(OBJ_DIR)/checklogfile.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/checklogfile \
$(OBJ_DIR)/checklogfile.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/add_vrpn_cookie: $(OBJ_DIR)/add_vrpn_cookie.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/add_vrpn_cookie \
$(OBJ_DIR)/add_vrpn_cookie.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/testSharedObject: $(OBJ_DIR)/testSharedObject.o \
$(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/testSharedObject \
$(OBJ_DIR)/testSharedObject.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_ping: $(OBJ_DIR)/vrpn_ping.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_ping \
$(OBJ_DIR)/vrpn_ping.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/testLamport: $(OBJ_DIR)/vrpn_LamportClock.t.o \
$(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/testLamport \
$(OBJ_DIR)/vrpn_LamportClock.t.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/test_mutex: $(OBJ_DIR)/test_mutex.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/test_mutex \
$(OBJ_DIR)/test_mutex.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/test_imager: $(OBJ_DIR)/test_imager.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/test_imager \
$(OBJ_DIR)/test_imager.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/c_interface_example: $(OBJ_DIR)/c_interface_example.o $(OBJ_DIR)/c_interface.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/c_interface_example \
$(OBJ_DIR)/c_interface_example.o $(OBJ_DIR)/c_interface.o -lvrpn $(ARCH_LIBS)
# These utilities actually DON'T use libvrpn
$(OBJ_DIR)/logfilesenders: $(OBJ_DIR)/logfilesenders.o
$(CC) $(LFLAGS) -o $(OBJ_DIR)/logfilesenders \
$(OBJ_DIR)/logfilesenders.o
$(OBJ_DIR)/logfiletypes: $(OBJ_DIR)/logfiletypes.o
$(CC) $(LFLAGS) -o $(OBJ_DIR)/logfiletypes $(OBJ_DIR)/logfiletypes.o
install: all
-mkdir -p $(BIN_DIR)
( cd $(BIN_DIR) ; rm -f $(INSTALL_APPS) )
( cd $(OBJ_DIR) ; cp $(INSTALL_APPS) $(BIN_DIR) )
( cd $(BIN_DIR) ; strip $(INSTALL_APPS) )
uninstall:
( cd $(BIN_DIR) ; rm -f $(INSTALL_APPS) )
clean:
rm -f $(OBJ_DIR)/*
$(LIB_DIR)/libvrpn.a:
#include <stdio.h> // for fprintf, fclose, fopen, etc
#include <stdlib.h> // for exit
#include <vrpn_Connection.h> // for vrpn_cookie_size, etc
static const char DESC[] = "Reads a vrpn log; writes out the same log with a (current-version) "
"magic cookie in front.";
// TODO:
// Smart checking of command-line arguments
// Check to see if there's already a magic cookie there.
// ? Allow the user to specify cookie version inserted (non-current)
void Usage (char * name) {
fprintf(stderr, "%s\n", DESC);
fprintf(stderr, "Usage: %s <input filename> <output filename>\n",
name);
}
int main (int argc, char ** argv) {
FILE * f_in;
FILE * f_out;
char magicbuf [733]; // HACK
char a;
char * in_name;
char * out_name;
int final_retval = 0;
int retval;
// parse command line arguments
if (argc != 3) {
Usage(argv[0]);
exit(0);
}
in_name = argv[1];
out_name = argv[2];
f_in = fopen(in_name, "rb");
if (!f_in) {
fprintf(stderr, "Couldn't open input file %s.\n", in_name);
exit(0);
}
// check to see if f_out exists
f_out = fopen(out_name, "rb");
if (f_out) {
fprintf(stderr, "Output file \"%s\" already exists.\n", out_name);
fclose(f_in);
exit(0);
}
f_out = fopen(out_name, "wb");
if (!f_out) {
fprintf(stderr, "Couldn't open output file (%s).\n", out_name);
fclose(f_in);
exit(0);
}
retval = write_vrpn_cookie(magicbuf, vrpn_cookie_size() + 1,
vrpn_LOG_NONE);
if (retval < 0) {
fprintf(stderr, "vrpn_Connection::close_log: "
"Couldn't create magic cookie.\n");
goto CLEANUP;
}
retval = static_cast<int>(fwrite(magicbuf, 1, vrpn_cookie_size(), f_out));
if (retval != vrpn_cookie_size()) {
fprintf(stderr, "vrpn_Connection::close_log: "
"Couldn't write magic cookie to log file "
"(got %d, expected %d).\n",
retval, static_cast<int>(vrpn_cookie_size()));
goto CLEANUP;
}
while (!final_retval && !feof(f_in)) {
a = fgetc(f_in);
fputc(a, f_out);
}
CLEANUP:
fclose(f_out);
fclose(f_in);
}
// test client for sgi button/dial box
/*
button layout:
00 01 02 03
04 05 06 07 08 09
10 11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27
28 29 30 31
dial layout:
06 07
04 05
02 03
00 01
*/
#include <stdio.h> // for printf, NULL
#include <vrpn_Analog.h> // for vrpn_ANALOGCB, etc
#include <vrpn_Button.h> // for vrpn_BUTTONCB, etc
#include "vrpn_Configure.h" // for VRPN_CALLBACK
#include "vrpn_Types.h" // for vrpn_float64
/*
// this is the one in the PIT area
#define BDBOX_SERVER "sgibox0@x-vrsh://152.2.128.163/~seeger/src/vrpn/server_src/sgi_irix/vrpn_server,-f,~seeger/src/config/sgibox.cfg,-q"
*/
#define BDBOX_SERVER "sgibox0@x-vrsh://nano//net/nano/nano1/bin/vrpn_server,-f,/net/nano/nano1/config/sgibdbox.cfg,-q,4501,>/dev/null"
/*****************************************************************************
*
Callback handler
*
*****************************************************************************/
void VRPN_CALLBACK handle_button_change(void *userdata, const vrpn_BUTTONCB b)
{
static int count=0;
static int buttonstate = 1;
if (b.state != buttonstate) {
printf("button #%d is in state %d\n", b.button, b.state);
buttonstate = b.state;
count++;
}
if (count > 20) {
*(int*)userdata = 1;
}
}
void VRPN_CALLBACK handle_dial_change(void *userdata, const vrpn_ANALOGCB info)
{
static double channel_values[vrpn_CHANNEL_MAX];
static bool initialized = false;
int i;
if (!initialized) {
for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
channel_values[i] = 0.0;
}
initialized = true;
}
for (i = 0; i < info.num_channel; i++){
if (channel_values[i] != info.channel[i]) {
printf("dial #%d has value %f\n", i, (float)(info.channel[i]));
}
channel_values[i] = info.channel[i];
}
}
int main(int argc, char *argv[])
{
int done = 0;
vrpn_Analog_Remote *bd_dials;
vrpn_Button_Remote *bd_buttons;
printf("Connecting to sgi button/dial box:\n" BDBOX_SERVER "\n");
// initialize the buttons
bd_buttons = new vrpn_Button_Remote(BDBOX_SERVER);
bd_buttons->register_change_handler(&done, handle_button_change);
// initialize the dials
bd_dials = new vrpn_Analog_Remote(BDBOX_SERVER);
bd_dials->register_change_handler(NULL, handle_dial_change);
// main loop
while (!done ){
bd_dials->mainloop();
bd_buttons->mainloop();
}
} /* main */
/* Example of providing an interface to VRPN client-side objects through C.
* Initially made to handle the Tracker and Button objects, for the purpose
* of connecting to a Spaceball through Fortran. If you know how to link
* C and C++ code into Fortran, then you should be able to use it to link.
* (Note, you may need to add an underscore to the name of the C functions.)
* Also note, the implementation code is C++ code, but exposes its functions using
* a C interface.
*/
#include <stddef.h> // for NULL
#include <vrpn_Button.h> // for vrpn_Button_Remote, etc
#include <vrpn_Tracker.h> // for vrpn_TRACKERCB, etc
#include "c_interface.h"
#include "vrpn_Configure.h" // for VRPN_CALLBACK
/* Helper function that receives the callback handler from the C++ Tracker
* remote, repackages the values, and calls the user callback function. */
void VRPN_CALLBACK handle_tracker_pos_quat (void *userdata, const vrpn_TRACKERCB t)
{
vrpn_c_tracker_callback_function f = (vrpn_c_tracker_callback_function)(userdata);
f(t.sensor, t.pos, t.quat);
};
/* Open a tracker device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the tracker device on success. The tracker
* pointer needs to be passed to the poll and close functions. */
extern "C" void *vrpn_c_open_tracker(const char *device_name, vrpn_c_tracker_callback_function callback)
{
vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(device_name);
if (tkr != NULL) {
/* Tell the callback handler what function to call. */
tkr->register_change_handler((void*)callback, handle_tracker_pos_quat);
}
return tkr;
};
/* Poll the tracker whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a sensor. Returns false if the device is not working. */
extern "C" vrpn_c_bool vrpn_c_poll_tracker(void *device)
{
if (device == NULL) { return false; }
vrpn_Tracker_Remote *tkr = (vrpn_Tracker_Remote *)device;
tkr->mainloop();
return true;
};
/* Close the tracker whose device pointer is passed in. Returns true on success,
* false on failure. */
extern "C" vrpn_c_bool vrpn_c_close_tracker(void *device)
{
if (device == NULL) { return false; }
vrpn_Tracker_Remote *tkr = (vrpn_Tracker_Remote *)device;
delete tkr;
return true;
};
/* Helper function that receives the callback handler from the C++ Button
* remote, repackages the values, and calls the user callback function. */
void VRPN_CALLBACK handle_button_event (void *userdata, const vrpn_BUTTONCB b)
{
vrpn_c_button_callback_function f = (vrpn_c_button_callback_function)(userdata);
f(b.button, (b.state != 0));
};
/* Open a button device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the button device on success. The button
* device pointer needs to be passed to the read and close functions. */
extern "C" void *vrpn_c_open_button(const char *device_name, vrpn_c_button_callback_function callback)
{
vrpn_Button_Remote *btn = new vrpn_Button_Remote(device_name);
if (btn != NULL) {
/* Tell the callback handler what function to call. */
btn->register_change_handler((void*)callback, handle_button_event);
}
return btn;
};
/* Poll the button whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a button. Returns false if the device is not working. */
extern "C" vrpn_c_bool vrpn_c_poll_button(void *device)
{
if (device == NULL) { return false; }
vrpn_Button_Remote *btn = (vrpn_Button_Remote *)device;
btn->mainloop();
return true;
};
/* Close the button whose device pointer is passed in. Returns true on success,
* false on failure. */
extern "C" vrpn_c_bool vrpn_c_close_button(void *device)
{
if (device == NULL) { return false; }
vrpn_Button_Remote *btn = (vrpn_Button_Remote *)device;
delete btn;
return true;
};
/* Example of providing an interface to VRPN client-side objects through C.
* Initially made to handle the Tracker and Button objects, for the purpose
* of connecting to a Spaceball through Fortran. If you know how to link
* C and C++ code into Fortran, then you should be able to use it to link.
* (Note, you may need to add an underscore to the name of the C functions.)
* Also note, the implementation code is C++ code, but exposes its functions using
* a C interface.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef char vrpn_c_bool;
/* Function prototype for the function that will be called whenever a tracker
* report comes in. */
typedef void (*vrpn_c_tracker_callback_function)(unsigned sensor, const double pos[3], const double quat[4]);
/* Open a tracker device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the tracker device on success. The tracker
* pointer needs to be passed to the poll and close functions. */
void *vrpn_c_open_tracker(const char *device_name, vrpn_c_tracker_callback_function callback);
/* Poll the tracker whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a sensor. Returns false if the device is not working. */
vrpn_c_bool vrpn_c_poll_tracker(void *device);
/* Close the tracker whose device pointer is passed in. Returns true on success,
* false on failure. */
vrpn_c_bool vrpn_c_close_tracker(void *device);
/* Function prototype for the function that will be called whenever a button
* report comes in. */
typedef void (*vrpn_c_button_callback_function)(const unsigned button, const vrpn_c_bool value);
/* Open a button device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the button device on success. The button
* device pointer needs to be passed to the read and close functions. */
void *vrpn_c_open_button(const char *device_name, vrpn_c_button_callback_function callback);
/* Poll the button whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a button. Returns false if the device is not working. */
vrpn_c_bool vrpn_c_poll_button(void *device);
/* Close the button whose device pointer is passed in. Returns true on success,
* false on failure. */
vrpn_c_bool vrpn_c_close_button(void *device);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#include <stdio.h> // for printf
#include "c_interface.h"
void tracker_callback(unsigned sensor, const double pos[3], const double quat[4])
{
printf("Tracker sensor %d at (%lf,%lf,%lf) with orientation (%lf,%lf,%lf,%lf)\n",
sensor, pos[0], pos[1], pos[2], quat[0], quat[1], quat[2], quat[3]);
}
void button_callback(unsigned button, vrpn_c_bool value)
{
const char *state = (value?"pressed":"released");
printf("Button %d %s\n", button, state);
}
int main()
{
void *tkr;
void *btn;
const char *device_name = "Spaceball0@localhost";
printf("This is just a simple dummy application to show how you could access VRPN from straight C with a C-style interface.\n");
printf("It will try to connect to a local tracker and button device %s\n", device_name);
tkr = vrpn_c_open_tracker(device_name, tracker_callback);
btn = vrpn_c_open_button(device_name, button_callback);
while (1) {
vrpn_c_poll_tracker(tkr);
vrpn_c_poll_button(btn);
}
return 0;
}