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 3117 deletions
#include <stdio.h> // for fprintf, stderr, printf, etc
#include <stdlib.h> // for atoi, exit
#include <string.h> // for strcmp
#include <vrpn_Shared.h> // for vrpn_gettimeofday, vrpn_SleepMsecs, timeval
#include "vrpn_Configure.h" // for VRPN_CALLBACK
#include "vrpn_Poser.h" // for vrpn_Poser_Remote
#include "vrpn_Tracker.h" // for vrpn_TRACKERCB, etc
static bool g_verbose = false;
void Usage (const char * s)
{
fprintf(stderr,"Usage: %s [-v] [-millisleep n] [trackername [posername]]\n",s);
fprintf(stderr," -millisleep: Sleep n milliseconds each loop cycle\n");
fprintf(stderr," (if no option is specified, the Windows architecture\n");
fprintf(stderr," will free the rest of its time slice on each loop\n");
fprintf(stderr," but leave the processes available to be run immediately;\n");
fprintf(stderr," a 1ms sleep is the default on all other architectures).\n");
fprintf(stderr," -millisleep 0 is recommended when using this server and\n");
fprintf(stderr," a client on the same uniprocessor CPU Win32 PC.\n");
fprintf(stderr," -millisleep -1 will cause the server process to use the\n");
fprintf(stderr," whole CPU on any uniprocessor machine.\n");
fprintf(stderr," -v: Verbose.\n");
fprintf(stderr," trackername: String name of the tracker device (default Tracker0@localhost)\n");
fprintf(stderr," posername: String name of the poser device (default Poser0@localhost)\n");
exit(0);
}
//--------------------------------------------------------------------------------------
// This function takes the pose reported by the tracker and sends it
// directly to the poser, without changing it in any way. For this to
// work properly, the tracker must report translations in just the right
// space for the poser.
void VRPN_CALLBACK handle_tracker_update(void *userdata, const vrpn_TRACKERCB t)
{
// Turn the pointer into a poser pointer.
vrpn_Poser_Remote *psr= (vrpn_Poser_Remote*)userdata;
// Get the data from the tracker and send it to the poser.
struct timeval now;
vrpn_gettimeofday(&now, NULL);
psr->request_pose(now, t.pos, t.quat);
}
int main (int argc, char * argv[])
{
char default_tracker[] = "Tracker0@localhost";
char default_poser[] = "Poser0@localhost";
char *tracker_client_name = default_tracker;
char *poser_client_name = default_poser;
int realparams = 0;
int i;
#ifdef _WIN32
// On Windows, the millisleep with 0 option frees up the CPU time slice for other jobs
// but does not sleep for a specific time. On Unix, this returns immediately and does
// not do anything but waste cycles.
int milli_sleep_time = 0; // How long to sleep each iteration (default: free the timeslice but be runnable again immediately)
#else
int milli_sleep_time = 1; // How long to sleep each iteration (default: 1ms)
#endif
#ifdef WIN32
WSADATA wsaData;
int status;
if ((status = WSAStartup(MAKEWORD(1,1), &wsaData)) != 0) {
fprintf(stderr, "WSAStartup failed with %d\n", status);
return(1);
}
#endif // not WIN32
//--------------------------------------------------------------------------------------
// Parse the command line
i = 1;
while (i < argc) {
if (!strcmp(argv[i], "-v")) { // Specify config-file name
g_verbose = true;
} else if (!strcmp(argv[i], "-millisleep")) { // How long to sleep each loop?
if (++i > argc) { Usage(argv[0]); }
milli_sleep_time = atoi(argv[i]);
} else if (argv[i][0] == '-') { // Unknown flag
Usage(argv[0]);
} else switch (realparams) { // Non-flag parameters
case 0:
tracker_client_name = argv[i];
realparams++;
break;
case 1:
poser_client_name = argv[i];
realparams++;
break;
default:
Usage(argv[0]);
}
i++;
}
if (realparams > 2) {
Usage(argv[0]);
}
//--------------------------------------------------------------------------------------
// Open the tracker and poser objects that we're going to use.
if (g_verbose) {
printf("Opening tracker %s, poser %s\n", tracker_client_name, poser_client_name);
}
vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(tracker_client_name);
vrpn_Poser_Remote *psr = new vrpn_Poser_Remote(poser_client_name);
//--------------------------------------------------------------------------------------
// Set up the callback handler on the tracker object and pass it
// a pointer to the poser it is to use. Only ask for data from
// sensor 0.
tkr->register_change_handler(psr, handle_tracker_update, 0);
//--------------------------------------------------------------------------------------
// Loop forever until killed.
while (1) {
tkr->mainloop();
psr->mainloop();
vrpn_SleepMsecs(milli_sleep_time);
}
return 0;
}
# Microsoft Developer Studio Project File - Name="tracker_to_poser" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=tracker_to_poser - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "tracker_to_poser.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "tracker_to_poser.mak" CFG="tracker_to_poser - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "tracker_to_poser - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "tracker_to_poser - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "tracker_to_poser - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../quat" /I "../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c /Tp
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"../pc_win32/Release" /libpath:"../pc_win32/DLL/Release"
!ELSEIF "$(CFG)" == "tracker_to_poser - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../quat" /I "../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c /Tp
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../pc_win32/Debug" /libpath:"../pc_win32/DLL/Debug"
!ENDIF
# Begin Target
# Name "tracker_to_poser - Win32 Release"
# Name "tracker_to_poser - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\tracker_to_poser.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="tracker_to_poser"
ProjectGUID="{1AC1C1EB-400A-4838-AC5E-48F3F9CE7D5C}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/tracker_to_poser.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include,../quat,../"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/tracker_to_poser.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/tracker_to_poser.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib"
ProgramDatabaseFile=".\Release/tracker_to_poser.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/tracker_to_poser.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/tracker_to_poser.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include,../quat,../"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\Debug/tracker_to_poser.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/tracker_to_poser.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/tracker_to_poser.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/tracker_to_poser.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="tracker_to_poser.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
// Test code for vrpn_LamportClock
#ifdef VRPN_USE_OLD_STREAMS
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
#include <assert.h>
#include <vrpn_LamportClock.h>
vrpn_LamportClock * clockA;
vrpn_LamportClock * clockB;
void setUp (void) {
clockA = new vrpn_LamportClock (2, 0);
clockB = new vrpn_LamportClock (2, 1);
}
void tearDown (void) {
if (clockA) delete clockA;
if (clockB) delete clockB;
}
void test_one_getTimestampAndAdvance (void) {
vrpn_LamportTimestamp * t1 = clockA->getTimestampAndAdvance();
vrpn_LamportTimestamp tc (*t1);
assert(t1);
assert(t1->size() == 2);
assert((*t1)[0] == 1);
assert((*t1)[1] == 0);
assert(!(*t1 < *t1));
assert(!(tc < *t1));
assert(!(*t1 < tc));
vrpn_LamportTimestamp * t2 = clockA->getTimestampAndAdvance();
assert(t2);
assert((*t1)[0] == 1);
assert((*t1)[1] == 0);
assert(t2->size() == 2);
assert((*t2)[0] == 2);
assert((*t2)[1] == 0);
assert(*t1 < *t2);
assert(!(*t2 < *t1));
vrpn_LamportTimestamp * t3 = clockA->getTimestampAndAdvance();
vrpn_LamportTimestamp * t4 = clockA->getTimestampAndAdvance();
vrpn_LamportTimestamp * t5 = clockA->getTimestampAndAdvance();
assert(t5->size() == 2);
assert((*t5)[0] == 5);
assert((*t5)[1] == 0);
delete t1;
delete t2;
delete t3;
delete t4;
delete t5;
}
void test_two (void) {
vrpn_LamportTimestamp * ta1 = clockA->getTimestampAndAdvance();
vrpn_LamportTimestamp * tb1 = clockB->getTimestampAndAdvance();
clockA->receive(*tb1);
vrpn_LamportTimestamp * ta2 = clockA->getTimestampAndAdvance();
assert((*ta2)[0] == 2);
assert((*ta2)[1] == 1);
assert(*ta1 < *ta2);
assert(*tb1 < *ta2);
assert(!(*tb1 < *ta1));
assert(!(*ta1 < *tb1));
delete ta1;
delete tb1;
delete ta2;
}
int main (int argc, char ** argv) {
setUp();
test_one_getTimestampAndAdvance();
tearDown();
setUp();
test_two();
tearDown();
cout << "OK" << endl;
}
/* This program will ping a VRPN server and time how long it takes the server
that is being pinged to respond. It makes use of the VRPN ping/pong
mechanism by which objects detect if they have connected to servers.
It gives an indication of the round-trip time from a message at the user
level from a client through the user level at a server.
*/
#include <signal.h> // for signal, SIGINT
#include <stdio.h> // for NULL, printf
#include <stdlib.h> // for exit
#include <vrpn_Connection.h> // for vrpn_Connection, etc
#include <vrpn_Text.h> // for vrpn_Text_Receiver
#include "vrpn_Configure.h" // for VRPN_CALLBACK
#include "vrpn_Shared.h" // for timeval, vrpn_gettimeofday, etc
#include "vrpn_Types.h" // for vrpn_int32
vrpn_Text_Receiver *r;
vrpn_Connection *c;
vrpn_int32 ping_message_id;
vrpn_int32 pong_message_id;
vrpn_int32 sender;
struct timeval now;
struct timeval last_ping;
void handle_cntl_c(int) { exit(0); }
int VRPN_CALLBACK my_pong_handler(void *userdata, vrpn_HANDLERPARAM p)
{
static int count = 0;
static double min = 10000, max = 0, sum = 0;
// See how long it has been between the ping request and
// the pong response.
struct timeval diff;
vrpn_gettimeofday(&now, NULL);
double msecs;
diff = vrpn_TimevalDiff(now, last_ping);
msecs = vrpn_TimevalMsecs(vrpn_TimevalNormalize(diff));
// Keep statistics on the length (min, max, average)
if (msecs < min) {
min = msecs;
};
if (msecs > max) {
max = msecs;
};
sum += msecs;
// Print and reset the statistics every once in a while
if (++count == 500) {
printf("Min = %4.2g, Max = %4.2g, Mean = %4.2g\n", min, max,
sum / count);
count = 0;
min = 10000;
max = sum = 0.0;
}
// Send a new ping request, and record when we sent it.
// REMEMBER not to call mainloop() within the handler.
vrpn_gettimeofday(&last_ping, NULL);
c->pack_message(0, last_ping, ping_message_id, sender, NULL,
vrpn_CONNECTION_RELIABLE);
c->send_pending_reports();
return 0;
}
int main(int argc, char *argv[])
{
// Declare a new text receiver (all objects are text senders)
// and find out what connection it is using.
r = new vrpn_Text_Receiver(argv[1]);
c = r->connectionPtr();
// Declare the same sender and message types that the BaseClass
// will use for doing the ping/pong, so we can use the same
// mechanism. Register a handler for the pong message, so we
// can deal with them.
ping_message_id = c->register_message_type("Server, are you there?");
pong_message_id = c->register_message_type("Server is here!");
sender = c->register_sender(vrpn_copy_service_name(argv[1]));
c->register_handler(pong_message_id, my_pong_handler, NULL, sender);
// Let the user kill the program "nicely."
signal(SIGINT, handle_cntl_c);
// Wait a few seconds (spinning while we do) in order to allow the
// real pong message to clear from the system.
struct timeval then, diff;
vrpn_gettimeofday(&then, NULL);
do {
vrpn_gettimeofday(&now, NULL);
r->mainloop();
diff = vrpn_TimevalDiff(now, then);
} while (vrpn_TimevalMsecs(vrpn_TimevalNormalize(diff)) < 2000);
// Send a new ping request to the server, and start counting how
// long it takes to respond.
vrpn_gettimeofday(&last_ping, NULL);
c->pack_message(0, last_ping, ping_message_id, sender, NULL,
vrpn_CONNECTION_RELIABLE);
// Loop forever.
while (1) {
r->mainloop();
}
}
/* vrpn_print_devices.C
This is a VRPN client program that will connect to one or more VRPN
server devices and print out descriptions of any of a number of
message types. These include at least tracker, button, dial and analog
messages. It is useful for testing whether a server is up and running,
and perhaps for simple debugging.
*/
#include <stdio.h> // for printf, fprintf, NULL, etc
#include <stdlib.h> // for exit, atoi
#ifndef _WIN32_WCE
#include <signal.h> // for signal, SIGINT
#endif
#include <string.h> // for strcmp, strncpy
#include <vrpn_Analog.h> // for vrpn_ANALOGCB, etc
#include <vrpn_Button.h> // for vrpn_Button_Remote, etc
#include <vrpn_Dial.h> // for vrpn_Dial_Remote, etc
#include <vrpn_FileConnection.h> // For preload and accumulate settings
#include <vrpn_Shared.h> // for vrpn_SleepMsecs
#include <vrpn_Text.h> // for vrpn_Text_Receiver, etc
#include <vrpn_Tracker.h> // for vrpn_TRACKERACCCB, etc
#include <vector> // for vector
#include "vrpn_BaseClass.h" // for vrpn_System_TextPrinter, etc
#include "vrpn_Configure.h" // for VRPN_CALLBACK
#include "vrpn_Types.h" // for vrpn_float64, vrpn_int32
using namespace std;
int done = 0; // Signals that the program should exit
unsigned tracker_stride = 1; // Every nth report will be printed
//-------------------------------------
// This section contains the data structure that holds information on
// the devices that are created. For each named device, a remote of each
// type (tracker, button, analog, dial, text) is created. A particular device
// may only report a subset of these values, but that doesn't hurt anything --
// there simply will be no messages of the other types to receive and so
// nothing is printed.
class device_info {
public:
char *name;
vrpn_Tracker_Remote *tkr;
vrpn_Button_Remote *btn;
vrpn_Analog_Remote *ana;
vrpn_Dial_Remote *dial;
vrpn_Text_Receiver *text;
};
const unsigned MAX_DEVICES = 50;
//-------------------------------------
// This section contains the data structure that is used to determine how
// often to print a report for each sensor of each tracker. Each element
// contains a counter that is used by the callback routine to keep track
// of how many it has skipped. There is an element for each possible sensor.
// A new array of elements is created for each new tracker object, and a
// pointer to it is passed as the userdata pointer to the callback handlers.
// A separate array is kept for the position, velocity, and acceleration for
// each
// tracker. The structure passed to the callback handler also has a
// string that is the name of the tracker.
class t_user_callback {
public:
char t_name[vrpn_MAX_TEXT_LEN];
vector<unsigned> t_counts;
};
/*****************************************************************************
*
Callback handlers
*
*****************************************************************************/
void VRPN_CALLBACK
handle_tracker_pos_quat(void *userdata, const vrpn_TRACKERCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
// See if we have gotten enough reports from this sensor that we should
// print this one. If so, print and reset the count.
if (++t_data->t_counts[t.sensor] >= tracker_stride) {
t_data->t_counts[t.sensor] = 0;
printf("Tracker %s, sensor %d:\n pos (%5.2f, %5.2f, %5.2f); "
"quat (%5.2f, %5.2f, %5.2f, %5.2f)\n",
t_data->t_name, t.sensor, t.pos[0], t.pos[1], t.pos[2],
t.quat[0], t.quat[1], t.quat[2], t.quat[3]);
}
}
void VRPN_CALLBACK handle_tracker_vel(void *userdata, const vrpn_TRACKERVELCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
// See if we have gotten enough reports from this sensor that we should
// print this one. If so, print and reset the count.
if (++t_data->t_counts[t.sensor] >= tracker_stride) {
t_data->t_counts[t.sensor] = 0;
printf("Tracker %s, sensor %d:\n vel (%5.2f, %5.2f, %5.2f); "
"quatvel (%5.2f, %5.2f, %5.2f, %5.2f)\n",
t_data->t_name, t.sensor, t.vel[0], t.vel[1], t.vel[2],
t.vel_quat[0], t.vel_quat[1], t.vel_quat[2], t.vel_quat[3]);
}
}
void VRPN_CALLBACK handle_tracker_acc(void *userdata, const vrpn_TRACKERACCCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
// See if we have gotten enough reports from this sensor that we should
// print this one. If so, print and reset the count.
if (++t_data->t_counts[t.sensor] >= tracker_stride) {
t_data->t_counts[t.sensor] = 0;
printf("Tracker %s, sensor %d:\n acc (%5.2f, %5.2f, %5.2f); "
"quatacc (%5.2f, %5.2f, %5.2f, %5.2f)\n",
t_data->t_name, t.sensor, t.acc[0], t.acc[1], t.acc[2],
t.acc_quat[0], t.acc_quat[1], t.acc_quat[2], t.acc_quat[3]);
}
}
void VRPN_CALLBACK handle_button(void *userdata, const vrpn_BUTTONCB b)
{
const char *name = (const char *)userdata;
printf("##########################################\r\n"
"Button %s, number %d was just %s\n"
"##########################################\r\n",
name, b.button, b.state ? "pressed" : "released");
}
void VRPN_CALLBACK
handle_button_states(void *userdata, const vrpn_BUTTONSTATESCB b)
{
const char *name = (const char *)userdata;
printf("Button %s has %d buttons with states:", name, b.num_buttons);
int i;
for (i = 0; i < b.num_buttons; i++) {
printf(" %d", b.states[i]);
}
printf("\n");
}
void VRPN_CALLBACK handle_analog(void *userdata, const vrpn_ANALOGCB a)
{
int i;
const char *name = (const char *)userdata;
printf("Analog %s:\n %5.2f", name, a.channel[0]);
for (i = 1; i < a.num_channel; i++) {
printf(", %5.2f", a.channel[i]);
}
printf(" (%d chans)\n", a.num_channel);
}
void VRPN_CALLBACK handle_dial(void *userdata, const vrpn_DIALCB d)
{
const char *name = (const char *)userdata;
printf("Dial %s, number %d was moved by %5.2f\n", name, d.dial, d.change);
}
void VRPN_CALLBACK handle_text(void *userdata, const vrpn_TEXTCB t)
{
const char *name = (const char *)userdata;
// Warnings and errors are printed by the system text printer.
if (t.type == vrpn_TEXT_NORMAL) {
printf("%s: Text message: %s\n", name, t.message);
}
}
// WARNING: On Windows systems, this handler is called in a separate
// thread from the main program (this differs from Unix). To avoid all
// sorts of chaos as the main program continues to handle packets, we
// set a done flag here and let the main program shut down in its own
// thread by calling shutdown() to do all of the stuff we used to do in
// this handler.
void handle_cntl_c(int) { done = 1; }
void Usage(const char *arg0)
{
fprintf(
stderr,
"Usage: %s [-notracker] [-nobutton] [-noanalog] [-nodial]\n"
" [-trackerstride n]\n"
" [-notext] device1 [device2] [device3] [device4] [...]\n"
" -trackerstride: Print every nth report from each tracker sensor\n"
" -notracker: Don't print tracker reports for following devices\n"
" -nobutton: Don't print button reports for following devices\n"
" -noanalog: Don't print analog reports for following devices\n"
" -nodial: Don't print dial reports for following devices\n"
" -notext: Don't print text messages (warnings, errors) for "
"following devices\n"
" deviceX: VRPN name of device to connect to (eg: Tracker0@ioglab)\n"
" The default behavior is to print all message types for all devices "
"listed\n"
" The order of the parameters can be changed to suit\n",
arg0);
exit(0);
}
int main(int argc, char *argv[])
{
int print_for_tracker = 1; // Print tracker reports?
int print_for_button = 1; // Print button reports?
int print_for_analog = 1; // Print analog reports?
int print_for_dial = 1; // Print dial reports?
int print_for_text = 1; // Print warning/error messages?
// If we happen to open a file, neither preload nor accumulate the
// messages in memory, to avoid crashing for huge files.
vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD = false;
vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE = false;
device_info device_list[MAX_DEVICES];
unsigned num_devices = 0;
int i;
// Parse arguments, creating objects as we go. Arguments that
// change the way a device is treated affect all devices that
// follow on the command line.
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-notracker")) {
print_for_tracker = 0;
}
else if (!strcmp(argv[i], "-nobutton")) {
print_for_button = 0;
}
else if (!strcmp(argv[i], "-noanalog")) {
print_for_analog = 0;
}
else if (!strcmp(argv[i], "-nodial")) {
print_for_dial = 0;
}
else if (!strcmp(argv[i], "-notext")) {
print_for_text = 0;
}
else if (!strcmp(argv[i], "-trackerstride")) {
if (++i >= argc) {
Usage(argv[0]);
}
if (atoi(argv[i]) <= 0) {
fprintf(stderr,
"-trackerstride argument must be 1 or greater\n");
return -1;
}
tracker_stride = atoi(argv[i]);
}
else { // Create a device and connect to it.
device_info *dev;
// Make sure we have enough room for the new device
if (num_devices == MAX_DEVICES) {
fprintf(stderr, "Too many devices!\n");
exit(-1);
}
// Name the device and open it as everything
dev = &device_list[num_devices];
dev->name = argv[i];
dev->tkr = new vrpn_Tracker_Remote(dev->name);
dev->ana = new vrpn_Analog_Remote(dev->name);
dev->btn = new vrpn_Button_Remote(dev->name);
dev->dial = new vrpn_Dial_Remote(dev->name);
dev->text = new vrpn_Text_Receiver(dev->name);
if ((dev->ana == NULL) || (dev->btn == NULL) ||
(dev->dial == NULL) || (dev->tkr == NULL) ||
(dev->text == NULL)) {
fprintf(stderr, "Error opening %s\n", dev->name);
return -1;
}
else {
printf("Opened %s as:", dev->name);
}
// If we are printing the tracker reports, prepare the
// user-data callbacks and hook them up to be called with
// the correct data for this device.
if (print_for_tracker) {
vrpn_Tracker_Remote *tkr = dev->tkr;
t_user_callback *tc1 = new t_user_callback;
t_user_callback *tc2 = new t_user_callback;
t_user_callback *tc3 = new t_user_callback;
if ((tc1 == NULL) || (tc2 == NULL) || (tc3 == NULL)) {
fprintf(stderr, "Out of memory\n");
}
printf(" Tracker");
// Fill in the user-data callback information
strncpy(tc1->t_name, dev->name, sizeof(tc1->t_name));
strncpy(tc2->t_name, dev->name, sizeof(tc2->t_name));
strncpy(tc3->t_name, dev->name, sizeof(tc3->t_name));
// Set up the tracker callback handlers
tkr->register_change_handler(tc1, handle_tracker_pos_quat);
tkr->register_change_handler(tc2, handle_tracker_vel);
tkr->register_change_handler(tc3, handle_tracker_acc);
}
if (print_for_button) {
printf(" Button");
dev->btn->register_change_handler(dev->name, handle_button);
dev->btn->register_states_handler(dev->name,
handle_button_states);
}
if (print_for_analog) {
printf(" Analog");
dev->ana->register_change_handler(dev->name, handle_analog);
}
if (print_for_dial) {
printf(" Dial");
dev->dial->register_change_handler(dev->name, handle_dial);
}
if (print_for_text) {
printf(" Text");
dev->text->register_message_handler(dev->name, handle_text);
}
else {
vrpn_System_TextPrinter.remove_object(dev->tkr);
vrpn_System_TextPrinter.remove_object(dev->btn);
vrpn_System_TextPrinter.remove_object(dev->ana);
vrpn_System_TextPrinter.remove_object(dev->dial);
vrpn_System_TextPrinter.remove_object(dev->text);
}
printf(".\n");
num_devices++;
}
}
if (num_devices == 0) {
Usage(argv[0]);
}
#ifndef _WIN32_WCE
// signal handler so logfiles get closed right
signal(SIGINT, handle_cntl_c);
#endif
/*
* main interactive loop
*/
printf("Press ^C to exit.\n");
while (!done) {
unsigned i;
// Let all the devices do their things
for (i = 0; i < num_devices; i++) {
device_list[i].tkr->mainloop();
device_list[i].btn->mainloop();
device_list[i].ana->mainloop();
device_list[i].dial->mainloop();
device_list[i].text->mainloop();
}
// Sleep for 1ms so we don't eat the CPU
vrpn_SleepMsecs(1);
}
// Delete all devices.
{
unsigned i;
for (i = 0; i < num_devices; i++) {
delete device_list[i].tkr;
delete device_list[i].btn;
delete device_list[i].ana;
delete device_list[i].dial;
delete device_list[i].text;
}
}
return 0;
} /* main */
# Microsoft Developer Studio Project File - Name="vrpn_print_devices" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=vrpn_print_devices - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "vrpn_print_devices.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "vrpn_print_devices.mak" CFG="vrpn_print_devices - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "vrpn_print_devices - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "vrpn_print_devices - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "vrpn_print_devices - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../pc_win32/client_src/vrpn_print_devices/Release"
# PROP Intermediate_Dir "../pc_win32/client_src/vrpn_print_devices/Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /D "_CONSOLE" /D "NDEBUG" /D "_MBCS" /D "WIN32" /FR /YX /FD /c /Tp
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"../pc_win32/Release" /libpath:"../pc_win32/DLL/Release"
!ELSEIF "$(CFG)" == "vrpn_print_devices - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../pc_win32/client_src/vrpn_print_devices/Debug"
# PROP Intermediate_Dir "../pc_win32/client_src/vrpn_print_devices/Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I ".." /D "_CONSOLE" /D "_DEBUG" /D "_MBCS" /D "WIN32" /FR /YX /FD /GZ /c /Tp
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../pc_win32/Debug" /libpath:"../pc_win32/DLL/Debug"
!ENDIF
# Begin Target
# Name "vrpn_print_devices - Win32 Release"
# Name "vrpn_print_devices - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=vrpn_print_devices.C
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="vrpn_print_devices"
ProjectGUID="{AED1729B-0600-4ECD-BE20-9F1964FFD2C8}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\../pc_win32/client_src/vrpn_print_devices/Debug"
IntermediateDirectory=".\../pc_win32/client_src/vrpn_print_devices/Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\../pc_win32/client_src/vrpn_print_devices/Debug/vrpn_print_devices.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include&quot;;.."
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\../pc_win32/client_src/vrpn_print_devices/Debug/vrpn_print_devices.pch"
AssemblerListingLocation=".\../pc_win32/client_src/vrpn_print_devices/Debug/"
ObjectFile=".\../pc_win32/client_src/vrpn_print_devices/Debug/"
ProgramDataBaseFileName=".\../pc_win32/client_src/vrpn_print_devices/Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\../pc_win32/client_src/vrpn_print_devices/Debug/vrpn_print_devices.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\../pc_win32/client_src/vrpn_print_devices/Debug/vrpn_print_devices.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\../pc_win32/client_src/vrpn_print_devices/Debug/vrpn_print_devices.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\../pc_win32/client_src/vrpn_print_devices/Release"
IntermediateDirectory=".\../pc_win32/client_src/vrpn_print_devices/Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\../pc_win32/client_src/vrpn_print_devices/Release/vrpn_print_devices.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="&quot;$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include&quot;;.."
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\../pc_win32/client_src/vrpn_print_devices/Release/vrpn_print_devices.pch"
AssemblerListingLocation=".\../pc_win32/client_src/vrpn_print_devices/Release/"
ObjectFile=".\../pc_win32/client_src/vrpn_print_devices/Release/"
ProgramDataBaseFileName=".\../pc_win32/client_src/vrpn_print_devices/Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\../pc_win32/client_src/vrpn_print_devices/Release/vrpn_print_devices.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SYSTEMDRIVE)\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib"
ProgramDatabaseFile=".\../pc_win32/client_src/vrpn_print_devices/Release/vrpn_print_devices.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\../pc_win32/client_src/vrpn_print_devices/Release/vrpn_print_devices.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="vrpn_print_devices.C"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
CompileAs="2"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
// vrpn_print_message.C: Print out information about all the messages
// that come from a VRPN file or connection. Useful for seeing what
// is at a server or in a file.
// It uses the logging feature to get called even for messages that
// it has not registered senders for.
// XXX Does not work on files; nothing gets printed...
// XXX Bad side effect: It produces a file called vrpn_temp.deleteme
// in the current directory.
#include <stdio.h> // for fprintf, NULL, stderr, etc
#include <stdlib.h> // for exit
#include <vrpn_Configure.h> // for VRPN_CALLBACK
#include <vrpn_Shared.h> // for timeval
#include <vrpn_Connection.h> // for vrpn_HANDLERPARAM, etc
vrpn_Connection *conn; // Connection pointer
int Usage(char *s)
{
fprintf(stderr, "Usage: %s vrpn_connection_name\n", s);
fprintf(stderr, " (Note: file:filename can be connection name)\n");
return -1;
}
// This function does the work. It prints out the message type,
// sender, size and time for each message that comes in to the
// connection.
int VRPN_CALLBACK msg_handler(void *, vrpn_HANDLERPARAM p)
{
const char *sender_name = conn->sender_name(p.sender);
const char *type_name = conn->message_type_name(p.type);
// We'll need to adjust the sender and type if it was
// unknown.
if (sender_name == NULL) {
sender_name = "UNKNOWN_SENDER";
}
if (type_name == NULL) {
type_name = "UNKNOWN_TYPE";
}
printf("Time: %ld:%ld, Sender: %s, Type %s, Length %d\n",
static_cast<long>(p.msg_time.tv_sec),
static_cast<long>(p.msg_time.tv_usec), sender_name, type_name,
p.payload_len);
return -1; // Do not log the message
}
int main(int argc, char *argv[])
{
char *conn_name; // Name of the connection or file
// Parse the command line
if (argc != 2) {
return Usage(argv[0]);
}
else {
conn_name = argv[1];
}
// Open the connection, with a file for incoming log required for some
// reason.
// (I think it's so that there is a log that we can filter by displaying it)
conn = vrpn_get_connection_by_name(conn_name, "vrpn_temp.deleteme");
if (conn == NULL) {
fprintf(stderr, "ERROR: Can't get connection %s\n", conn_name);
return -1;
}
// Set up the callback for all message types
conn->register_log_filter(msg_handler, NULL);
// Mainloop until they kill us.
while (1) {
conn->mainloop();
}
return 0; // Sure!
}
/* vrpn_print_performance.C
This is a VRPN client program that will connect to one or more VRPN
server devices and print out the rate of any of a number of message types.
These include only tracker messages at this time, but the rest are easy.
While it doesn't (currently) attempt to consider latency, its measurement of
update rate might be informative to some.
*/
#include <stdio.h> // for printf, NULL, fprintf, etc
#include <stdlib.h> // for exit, atoi
#ifndef _WIN32_WCE
#include <signal.h> // for signal, SIGINT
#endif
#include <string.h> // for strcmp, strncpy
#include <vrpn_Analog.h> // for vrpn_Analog_Remote, etc
#include <vrpn_Button.h> // for vrpn_Button_Remote, etc
#include <vrpn_FileConnection.h> // For preload and accumulate settings
#include <vrpn_Shared.h> // for vrpn_gettimeofday, etc
#include <vrpn_Tracker.h> // for vrpn_TRACKERACCCB, etc
#include <vector> // for vector
#include "vrpn_BaseClass.h" // for vrpn_System_TextPrinter, etc
#include "vrpn_Configure.h" // for VRPN_CALLBACK
using namespace std;
int done = 0; // Signals that the program should exit
double report_interval = 1; // Every n seconds a report will be printed
//-------------------------------------
// This section contains the data structure that holds information on
// the devices that are created. For each named device, a remote of each
// type (tracker, button, analog, dial, text) is created. A particular device
// may only report a subset of these values, but that doesn't hurt anything --
// there simply will be no messages of the other types to receive and so
// nothing is printed.
class device_info {
public:
char *name;
vrpn_Tracker_Remote *tkr;
vrpn_Button_Remote *btn;
vrpn_Analog_Remote *ana;
};
const unsigned MAX_DEVICES = 50;
//-------------------------------------
// This section contains the data structure that is used to determine how
// often to print a report for each sensor of each tracker. Each element
// contains a counter that is used by the callback routine to keep track
// of how many it has skipped. There is an element for each possible sensor.
// A new array of elements is created for each new tracker object, and a
// pointer to it is passed as the userdata pointer to the callback handlers.
// A separate array is kept for the position, velocity, and acceleration for
// each
// tracker. The structure passed to the callback handler also has a
// string that is the name of the tracker.
class t_user_callback {
public:
char t_name[vrpn_MAX_TEXT_LEN];
vector<unsigned> t_counts;
vector<struct timeval> t_last_report;
};
struct timeval t_analog_last_report;
unsigned t_analog_count;
/*****************************************************************************
*
Callback handlers
*
*****************************************************************************/
void VRPN_CALLBACK
handle_tracker_pos_quat(void *userdata, const vrpn_TRACKERCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
struct timeval now;
double interval;
vrpn_gettimeofday(&now, NULL);
// Make sure we have a count value for this sensor
while (t_data->t_last_report.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_last_report.push_back(now);
}
interval =
vrpn_TimevalDurationSeconds(now, t_data->t_last_report[t.sensor]);
t_data->t_counts[t.sensor]++;
// See if it's been long enough to display a frequency notification
if (interval >= report_interval) {
double frequency = t_data->t_counts[t.sensor] / interval;
t_data->t_counts[t.sensor] = 0;
t_data->t_last_report[t.sensor] = now;
printf("Tracker %s, sensor %d:\t%5.2f Hz (%5.2f sec)\n", t_data->t_name,
t.sensor, frequency, interval);
}
}
void VRPN_CALLBACK handle_tracker_vel(void *userdata, const vrpn_TRACKERVELCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
struct timeval now;
double interval;
vrpn_gettimeofday(&now, NULL);
// Make sure we have a count value for this sensor
while (t_data->t_last_report.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_last_report.push_back(now);
}
interval =
vrpn_TimevalDurationSeconds(now, t_data->t_last_report[t.sensor]);
t_data->t_counts[t.sensor]++;
// See if it's been long enough to display a frequency notification
if (interval >= report_interval) {
double frequency = t_data->t_counts[t.sensor] / interval;
t_data->t_counts[t.sensor] = 0;
t_data->t_last_report[t.sensor] = now;
printf("Tracker %s, sensor %d:\t\t%5.2f messages per second averaged "
"over %5.2f seconds\n",
t_data->t_name, t.sensor, frequency, interval);
}
}
void VRPN_CALLBACK handle_tracker_acc(void *userdata, const vrpn_TRACKERACCCB t)
{
t_user_callback *t_data = static_cast<t_user_callback *>(userdata);
// Make sure we have a count value for this sensor
while (t_data->t_counts.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_counts.push_back(0);
}
struct timeval now;
double interval;
vrpn_gettimeofday(&now, NULL);
// Make sure we have a count value for this sensor
while (t_data->t_last_report.size() <= static_cast<unsigned>(t.sensor)) {
t_data->t_last_report.push_back(now);
}
interval =
vrpn_TimevalDurationSeconds(now, t_data->t_last_report[t.sensor]);
t_data->t_counts[t.sensor]++;
// See if it's been long enough to display a frequency notification
if (interval >= report_interval) {
double frequency = t_data->t_counts[t.sensor] / interval;
t_data->t_counts[t.sensor] = 0;
t_data->t_last_report[t.sensor] = now;
printf("Tracker %s, sensor %d:\t\t%5.2f messages per second averaged "
"over %5.2f seconds\n",
t_data->t_name, t.sensor, frequency, interval);
}
}
void VRPN_CALLBACK handle_button(void *userdata, const vrpn_BUTTONCB b)
{
const char *name = (const char *)userdata;
printf("Button %s, number %d was just %s\n", name, b.button,
b.state ? "pressed" : "released");
}
void VRPN_CALLBACK handle_analog(void *userdata, const vrpn_ANALOGCB /*a*/)
{
const char *name = (const char *)userdata;
struct timeval now;
double interval;
vrpn_gettimeofday(&now, NULL);
interval = vrpn_TimevalDurationSeconds(now, t_analog_last_report);
t_analog_count++;
// See if it's been long enough to display a frequency notification
if (interval >= report_interval) {
double frequency = t_analog_count / interval;
t_analog_count = 0;
t_analog_last_report = now;
printf("Analog %s:\t\t%5.2f messages per second averaged over %5.2f "
"seconds\n",
name, frequency, interval);
}
/*
const char *name = (const char *)userdata;
int i;
printf("Analog %s:\n %5.2f", name, a.channel[0]);
for (i = 1; i < a.num_channel; i++) {
printf(", %5.2f", a.channel[i]);
}
printf(" (%d chans)\n", a.num_channel);
*/
}
// WARNING: On Windows systems, this handler is called in a separate
// thread from the main program (this differs from Unix). To avoid all
// sorts of chaos as the main program continues to handle packets, we
// set a done flag here and let the main program shut down in its own
// thread by calling shutdown() to do all of the stuff we used to do in
// this handler.
void handle_cntl_c(int) { done = 1; }
void Usage(const char *arg0)
{
fprintf(
stderr,
"Usage: %s [--notracker] [--nobutton] [--noanalog] [--nodial]\n"
" [--reportinterval n]\n"
" [--notext] device1 [device2] [device3] [device4] [...]\n"
" -trackerstride: Print every nth report from each tracker sensor\n"
" -notracker: Don't print tracker reports for following devices\n"
" -nobutton: Don't print button reports for following devices\n"
" -noanalog: Don't print analog reports for following devices\n"
" deviceX: VRPN name of device to connect to (eg: Tracker0@ioglab)\n"
" The default behavior is to print all message types for all devices "
"listed\n"
" The order of the parameters can be changed to suit\n",
arg0);
exit(0);
}
int main(int argc, char *argv[])
{
int print_for_tracker = 1; // Print tracker reports?
int print_for_button = 1; // Print button reports?
int print_for_analog = 1; // Print analog reports?
// If we happen to open a file, neither preload nor accumulate the
// messages in memory, to avoid crashing for huge files.
vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD = false;
vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE = false;
device_info device_list[MAX_DEVICES];
int num_devices = 0;
int i;
// Parse arguments, creating objects as we go. Arguments that
// change the way a device is treated affect all devices that
// follow on the command line.
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-notracker")) {
print_for_tracker = 0;
}
else if (!strcmp(argv[i], "--nobutton")) {
print_for_button = 0;
}
else if (!strcmp(argv[i], "--noanalog")) {
print_for_analog = 0;
}
else if (!strcmp(argv[i], "--reportinterval")) {
if (++i >= argc) {
Usage(argv[0]);
}
report_interval = atoi(argv[i]);
if (report_interval <= 0) {
fprintf(stderr,
"--reportinterval argument must be 1 or greater\n");
return -1;
}
}
else { // Create a device and connect to it.
device_info *dev;
// Make sure we have enough room for the new device
if (num_devices == MAX_DEVICES) {
fprintf(stderr, "Too many devices!\n");
exit(-1);
}
// Name the device and open it as everything
dev = &device_list[num_devices];
dev->name = argv[i];
dev->tkr = new vrpn_Tracker_Remote(dev->name);
dev->ana = new vrpn_Analog_Remote(dev->name);
dev->btn = new vrpn_Button_Remote(dev->name);
if ((dev->tkr == NULL) || (dev->ana == NULL) ||
(dev->btn == NULL)) {
fprintf(stderr, "Error opening %s\n", dev->name);
return -1;
}
else {
printf("Opened %s as:", dev->name);
}
struct timeval now;
vrpn_gettimeofday(&now, NULL);
// If we are printing the tracker reports, prepare the
// user-data callbacks and hook them up to be called with
// the correct data for this device.
if (print_for_tracker) {
vrpn_Tracker_Remote *tkr = dev->tkr;
t_user_callback *tc1 = new t_user_callback;
t_user_callback *tc2 = new t_user_callback;
t_user_callback *tc3 = new t_user_callback;
if ((tc1 == NULL) || (tc2 == NULL) || (tc3 == NULL)) {
fprintf(stderr, "Out of memory\n");
}
printf(" Tracker");
// Fill in the user-data callback information
strncpy(tc1->t_name, dev->name, sizeof(tc1->t_name));
strncpy(tc2->t_name, dev->name, sizeof(tc2->t_name));
strncpy(tc3->t_name, dev->name, sizeof(tc3->t_name));
// Set up the tracker callback handlers
tkr->register_change_handler(tc1, handle_tracker_pos_quat);
tkr->register_change_handler(tc2, handle_tracker_vel);
tkr->register_change_handler(tc3, handle_tracker_acc);
}
if (print_for_button) {
printf(" Button");
dev->btn->register_change_handler(dev->name, handle_button);
}
if (print_for_analog) {
printf(" Analog");
t_analog_last_report = now;
t_analog_count = 0;
dev->ana->register_change_handler(dev->name, handle_analog);
}
printf(".\n");
num_devices++;
}
}
if (num_devices == 0) {
Usage(argv[0]);
}
#ifndef _WIN32_WCE
// signal handler so logfiles get closed right
signal(SIGINT, handle_cntl_c);
#endif
/*
* main interactive loop
*/
printf("Press ^C to exit.\n");
while (!done) {
int i;
// Let all the devices do their things
for (i = 0; i < num_devices; i++) {
device_list[i].tkr->mainloop();
device_list[i].btn->mainloop();
device_list[i].ana->mainloop();
}
// Sleep for 1ms so we don't eat the CPU
vrpn_SleepMsecs(1);
}
return 0;
} /* main */
# - Script to check if the signature for a mac HID callback uses UInt32 or uint32_t
# Requires that the associated CPP file be present: CheckMacHIDAPI.cpp.
#
# MACOSX_HID_UINT32T, set according to the results of our test.
#
# Use add_definitions(-DMACOSX_HID_UINT32T=${MACOSX_HID_UINT32T}) in your
# listfile and the following prototype for the function you'd like to
# register using setInterruptReportHandlerCallback:
# void ReaderReportCallback(
# void *target,
# IOReturn result,
# void *refcon,
# void *sender,
# MACOSX_HID_UINT32T size
# )
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(APPLE)
if(NOT MACOSX_HID_UINT32T)
get_filename_component(_moddir ${CMAKE_CURRENT_LIST_FILE} PATH)
try_compile(_HID_uint32t
${CMAKE_BINARY_DIR}
${_moddir}/CheckMacHIDAPI.cpp
OUTPUT_VARIABLE
_HID_uint32t_OUTPUT
COMPILE_DEFINITIONS
-DMACOSX_HID_UINT32T=uint32_t)
message(STATUS
"Checking uint32_t in HID callback signature... ${_HID_uint32t}")
try_compile(_HID_UInt32
${CMAKE_BINARY_DIR}
${_moddir}/CheckMacHIDAPI.cpp
OUTPUT_VARIABLE
_HID_UInt32_OUTPUT
COMPILE_DEFINITIONS
-DMACOSX_HID_UINT32T=UInt32)
message(STATUS
"Checking UInt32 in HID callback signature... ${_HID_UInt32}")
if(_HID_uint32t)
set(MACOSX_HID_UINT32T
"uint32_t"
CACHE
STRING
"The 32-bit uint type desired in the callback set by setInterruptReportHandlerCallback")
mark_as_advanced(MACOSX_HID_UINT32T)
elseif(_HID_UInt32)
set(MACOSX_HID_UINT32T
"UInt32"
CACHE
STRING
"The 32-bit uint type desired in the callback set by setInterruptReportHandlerCallback")
mark_as_advanced(MACOSX_HID_UINT32T)
else()
message(SEND_ERROR
"ERROR: Could not detect appropriate Mac HID uint32 type!")
endif()
endif()
endif()
/**
* \file CheckMacHIDAPI.cpp
* \brief C++ source file used by CMake module CheckMacHIDAPI.cmake
*
* \author
* Ryan Pavlik, 2009-2010
* <rpavlik@iastate.edu>
* http://academic.cleardefinition.com/
*
* \author
* Based on code extracted from VRPN 07.22 for use as a minimal test case
*
* Attempts to compile a difficult bit of code against the Mac
* HID API, as two different types have been required in the callback
* function (UInt32 and uint32_t) and testing is the best way to know
* which one is correct for a given system.
*
*/
#if defined(__APPLE__)
#include <stdio.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <CoreFoundation/CoreFoundation.h>
void ReaderReportCallback(
void *target, IOReturn result, void *refcon, void *sender, MACOSX_HID_UINT32T size
)
{}
#endif
int main(int argc, char* argv[]) {
#if defined(__APPLE__)
io_object_t _ioObject;
IOHIDDeviceInterface122 **_interface;
unsigned char _buffer[512];
IOReturn result = (*_interface)->setInterruptReportHandlerCallback(_interface,
_buffer, 512,
ReaderReportCallback,
NULL, 0);
#endif
return 0;
}
# - Removes duplicate entries and non-directories from a provided list
#
# clean_directory_list(<listvar> [<additional list items>...])
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__clean_directory_list)
return()
endif()
set(__clean_directory_list YES)
function(clean_directory_list _var)
# combine variable's current value with additional list items
set(_in ${${_var}} ${ARGN})
if(_in)
# Initial list cleaning
list(REMOVE_DUPLICATES _in)
# Grab the absolute path of each actual directory
set(_out)
foreach(_dir ${_in})
if(IS_DIRECTORY "${_dir}")
get_filename_component(_dir "${_dir}" ABSOLUTE)
file(TO_CMAKE_PATH "${_dir}" _dir)
list(APPEND _out "${_dir}")
endif()
endforeach()
if(_out)
# Clean up the output list now
list(REMOVE_DUPLICATES _out)
endif()
# return _out
set(${_var} "${_out}" PARENT_SCOPE)
endif()
endfunction()
# - A smarter replacement for list(REMOVE_DUPLICATES) for library lists
#
# Note that, in the case of cyclic link dependencies, you _do_ actually need
# a library in a list multiple times. So, only use this function when you know
# that the dependency graph is acyclic.
#
# clean_library_list(<listvar> [<additional list items>...]) - where
# listvar is the name of a destination variable, and also possibly a source, and
# it is followed by any number (including 0) of additional libraries to append
# to the list before processing.
#
# Removes duplicates from the list, leaving only the last instance, while
# preserving the meaning of the "optimized", "debug", and "general" labeling.
# (Libraries listed as general are listed in the result instead as optimized and
# debug)
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__clean_library_list)
return()
endif()
set(__clean_library_list YES)
function(clean_library_list _var)
# combine variable's current value with additional list items
set(_work ${${_var}} ${ARGN})
if(_work)
# Turn each of optimized, debug, and general into flags
# prefixed on their respective library (combining list items)
string(REGEX REPLACE "optimized;" "1CLL%O%" _work "${_work}")
string(REGEX REPLACE "debug;" "1CLL%D%" _work "${_work}")
string(REGEX REPLACE "general;" "1CLL%G%" _work "${_work}")
# Any library that doesn't have a prefix is general, and a general
# library is both debug and optimized so stdize it
set(_std)
foreach(_lib ${_work})
if(NOT "${_lib}" MATCHES "^1CLL%.%")
list(APPEND _std "1CLL%D%${_lib}" "1CLL%O%${_lib}")
elseif("${_lib}" MATCHES "^1CLL%G%")
string(REPLACE "1CLL%G%" "" _justlib "${_lib}")
list(APPEND _std "1CLL%D%${_justlib}" "1CLL%O%${_justlib}")
else()
list(APPEND _std "${_lib}")
endif()
endforeach()
# REMOVE_DUPLICATES leaves the first - so we reverse before and after
# to keep the last, instead
list(REVERSE _std)
list(REMOVE_DUPLICATES _std)
list(REVERSE _std)
# Split list items back out again: turn prefixes into the
# library type flags.
string(REGEX REPLACE "1CLL%D%" "debug;" _std "${_std}")
string(REGEX REPLACE "1CLL%O%" "optimized;" _std "${_std}")
# Return _std
set(${_var} ${_std} PARENT_SCOPE)
endif()
endfunction()
# - Run cppcheck on c++ source files as a custom target and a test
#
# include(CppcheckTargets)
# add_cppcheck(<target-name> [UNUSED_FUNCTIONS] [STYLE] [POSSIBLE_ERROR] [FORCE] [FAIL_ON_WARNINGS]) -
# Create a target to check a target's sources with cppcheck and the indicated options
# add_cppcheck_sources(<target-name> [UNUSED_FUNCTIONS] [STYLE] [POSSIBLE_ERROR] [FORCE] [FAIL_ON_WARNINGS]) -
# Create a target to check standalone sources with cppcheck and the indicated options
#
# Requires these CMake modules:
# Findcppcheck
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__add_cppcheck)
return()
endif()
set(__add_cppcheck YES)
if(NOT CPPCHECK_FOUND)
find_package(cppcheck QUIET)
endif()
if(CPPCHECK_FOUND)
if(NOT TARGET all_cppcheck)
add_custom_target(all_cppcheck)
set_target_properties(all_cppcheck PROPERTIES EXCLUDE_FROM_ALL TRUE)
endif()
endif()
function(add_cppcheck_sources _targetname)
if(CPPCHECK_FOUND)
set(_cppcheck_args)
set(_input ${ARGN})
list(FIND _input UNUSED_FUNCTIONS _unused_func)
if("${_unused_func}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_UNUSEDFUNC_ARG})
list(REMOVE_AT _input ${_unused_func})
endif()
list(FIND _input STYLE _style)
if("${_style}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_STYLE_ARG})
list(REMOVE_AT _input ${_style})
endif()
list(FIND _input POSSIBLE_ERROR _poss_err)
if("${_poss_err}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_POSSIBLEERROR_ARG})
list(REMOVE_AT _input ${_poss_err})
endif()
list(FIND _input FORCE _force)
if("${_force}" GREATER "-1")
list(APPEND _cppcheck_args "--force")
list(REMOVE_AT _input ${_force})
endif()
list(FIND _input FAIL_ON_WARNINGS _fail_on_warn)
if("${_fail_on_warn}" GREATER "-1")
list(APPEND
CPPCHECK_FAIL_REGULAR_EXPRESSION
${CPPCHECK_WARN_REGULAR_EXPRESSION})
list(REMOVE_AT _input ${_fail_on_warn})
endif()
set(_files)
foreach(_source ${_input})
get_source_file_property(_cppcheck_loc "${_source}" LOCATION)
if(_cppcheck_loc)
# This file has a source file property, carry on.
get_source_file_property(_cppcheck_lang "${_source}" LANGUAGE)
if("${_cppcheck_lang}" MATCHES "CXX")
list(APPEND _files "${_cppcheck_loc}")
endif()
else()
# This file doesn't have source file properties - figure it out.
get_filename_component(_cppcheck_loc "${_source}" ABSOLUTE)
if(EXISTS "${_cppcheck_loc}")
list(APPEND _files "${_cppcheck_loc}")
else()
message(FATAL_ERROR
"Adding CPPCHECK for file target ${_targetname}: "
"File ${_source} does not exist or needs a corrected path location "
"since we think its absolute path is ${_cppcheck_loc}")
endif()
endif()
endforeach()
if("1.${CMAKE_VERSION}" VERSION_LESS "1.2.8.0")
# Older than CMake 2.8.0
add_test(${_targetname}_cppcheck_test
"${CPPCHECK_EXECUTABLE}"
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files})
else()
# CMake 2.8.0 and newer
add_test(NAME
${_targetname}_cppcheck_test
COMMAND
"${CPPCHECK_EXECUTABLE}"
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files})
endif()
set_tests_properties(${_targetname}_cppcheck_test
PROPERTIES
FAIL_REGULAR_EXPRESSION
"${CPPCHECK_FAIL_REGULAR_EXPRESSION}")
add_custom_command(TARGET
all_cppcheck
PRE_BUILD
COMMAND
${CPPCHECK_EXECUTABLE}
${CPPCHECK_QUIET_ARG}
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT
"${_targetname}_cppcheck: Running cppcheck on target ${_targetname}..."
VERBATIM)
endif()
endfunction()
function(add_cppcheck _name)
if(NOT TARGET ${_name})
message(FATAL_ERROR
"add_cppcheck given a target name that does not exist: '${_name}' !")
endif()
if(CPPCHECK_FOUND)
set(_cppcheck_args)
list(FIND ARGN UNUSED_FUNCTIONS _unused_func)
if("${_unused_func}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_UNUSEDFUNC_ARG})
endif()
list(FIND ARGN STYLE _style)
if("${_style}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_STYLE_ARG})
endif()
list(FIND ARGN POSSIBLE_ERROR _poss_err)
if("${_poss_err}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_POSSIBLEERROR_ARG})
endif()
list(FIND ARGN FORCE _force)
if("${_force}" GREATER "-1")
list(APPEND _cppcheck_args "--force")
endif()
list(FIND _input FAIL_ON_WARNINGS _fail_on_warn)
if("${_fail_on_warn}" GREATER "-1")
list(APPEND
CPPCHECK_FAIL_REGULAR_EXPRESSION
${CPPCHECK_WARN_REGULAR_EXPRESSION})
list(REMOVE_AT _input ${_unused_func})
endif()
get_target_property(_cppcheck_includes "${_name}" INCLUDE_DIRECTORIES)
set(_includes)
foreach(_include ${_cppcheck_includes})
list(APPEND _includes "-I${_include}")
endforeach()
get_target_property(_cppcheck_sources "${_name}" SOURCES)
set(_files)
foreach(_source ${_cppcheck_sources})
get_source_file_property(_cppcheck_lang "${_source}" LANGUAGE)
get_source_file_property(_cppcheck_loc "${_source}" LOCATION)
if("${_cppcheck_lang}" MATCHES "CXX")
list(APPEND _files "${_cppcheck_loc}")
endif()
endforeach()
if("1.${CMAKE_VERSION}" VERSION_LESS "1.2.8.0")
# Older than CMake 2.8.0
add_test(${_name}_cppcheck_test
"${CPPCHECK_EXECUTABLE}"
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files})
else()
# CMake 2.8.0 and newer
add_test(NAME
${_name}_cppcheck_test
COMMAND
"${CPPCHECK_EXECUTABLE}"
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files})
endif()
set_tests_properties(${_name}_cppcheck_test
PROPERTIES
FAIL_REGULAR_EXPRESSION
"${CPPCHECK_FAIL_REGULAR_EXPRESSION}")
add_custom_command(TARGET
all_cppcheck
PRE_BUILD
COMMAND
${CPPCHECK_EXECUTABLE}
${CPPCHECK_QUIET_ARG}
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_includes}
${_files}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT
"${_name}_cppcheck: Running cppcheck on target ${_name}..."
VERBATIM)
endif()
endfunction()
# - Create ctest -S scripts to use to run dashboard builds
#
# include(CreateDashboardScripts)
# create_dashboard_scripts([<initialcachetemplatefilename>])
#
# If you need additional settings to persist from the "parent" CMake instance
# to the initial cache created by the dashboard script,
# you may pass a filename which will be configured into the initial cache.
#
# In the resulting DASHBOARDSCRIPT_BASE_DIRECTORY, an end-user
# may optionally create a file named
# CustomInitialCache.${DASHBOARDSCRIPT_SCRIPT_NAME}
# (by default, CustomInitialCache.go.cmake) containing set commands that use
# the CACHE option, to set up additional site-local cache variable values.
#
# Requires these CMake modules:
# GetCompilerInfoString
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Only do any of the prep work if not already in a dashboard script
if(NOT IN_DASHBOARD_SCRIPT)
# Hide a CTest variable
mark_as_advanced(DART_TESTING_TIMEOUT)
include(GetCompilerInfoString)
get_compiler_info_string(_COMPILERID)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_dashboardmoddir
${CMAKE_CURRENT_LIST_FILE}
PATH)
if(NOT "$ENV{USER}" MATCHES "^$")
set(_user "$ENV{USER}")
elseif(NOT "$ENV{USERNAME}" MATCHES "^$")
set(_user "$ENV{USERNAME}")
endif()
if(NOT _dashboardscript_machine)
if(NOT SITE)
site_name(SITE)
endif()
set(_dashboardscript_machine "${SITE}" CACHE INTERNAL "")
set(SITE
"${_user}@${_dashboardscript_machine}"
CACHE
STRING
"Human-readable site name"
FORCE)
endif()
set(DASHBOARDSCRIPT_BASE_DIRECTORY
"${CMAKE_BINARY_DIR}/Dashboards-${_dashboardscript_machine}-${_user}"
CACHE
PATH
"Directory to use as the root of all dashboard work")
mark_as_advanced(DASHBOARDSCRIPT_BASE_DIRECTORY)
set(DASHBOARDSCRIPT_SOURCE_DIRECTORY "${CMAKE_SOURCE_DIR}")
set(BUILDNAME
"${CMAKE_SYSTEM}-${CMAKE_SYSTEM_PROCESSOR}-${_COMPILERID}"
CACHE
STRING
"Human-readable build ID info")
set(DASHBOARDSCRIPT_CMAKE_COMMAND
"${CMAKE_COMMAND}"
CACHE
FILEPATH
"The cmake binary to use when configuring a dashboard build")
mark_as_advanced(DASHBOARDSCRIPT_CMAKE_COMMAND)
# Try to find CTest, preferably right next to the chosen CMake
if(DASHBOARDSCRIPT_CMAKE_COMMAND)
get_filename_component(_cmake_dir
${DASHBOARDSCRIPT_CMAKE_COMMAND}
PATH)
else()
get_filename_component(_cmake_dir ${CMAKE_COMMAND} PATH)
endif()
find_program(DASHBOARDSCRIPT_CTEST_EXECUTABLE
NAMES
ctest
HINTS
"${_cmake_dir}"
NO_DEFAULT_PATH)
find_program(DASHBOARDSCRIPT_CTEST_EXECUTABLE
NAMES
ctest
HINTS
"${_cmake_dir}")
set(DASHBOARDSCRIPT_CTEST_EXECUTABLE
"${DASHBOARDSCRIPT_CTEST_EXECUTABLE}"
CACHE
FILEPATH
"Path to the CTest executable to use for dashboard builds.")
mark_as_advanced(DASHBOARDSCRIPT_CTEST_EXECUTABLE)
# Optionals
if(NOT "1.${CMAKE_VERSION}" VERSION_LESS "1.2.8.0")
if(IS_DIRECTORY "${CMAKE_SOURCE_DIRECTORY}/.git")
find_program(DASHBOARDSCRIPT_GIT_EXECUTABLE NAMES git git.cmd)
if(DASHBOARDSCRIPT_GIT_EXECUTABLE)
set(UPDATE_TYPE "git")
set(UPDATE_COMMAND "${DASHBOARDSCRIPT_GIT_EXECUTABLE}")
set(UPDATE_OPTIONS "")
mark_as_advanced(DASHBOARDSCRIPT_GIT_EXECUTABLE)
endif()
endif()
endif()
else()
# IN_DASHBOARD_SCRIPT is YES
message(STATUS
"CreateDashboardScripts detected that we're in a dashboard script already.")
endif()
function(create_dashboard_scripts)
# Only create the script if we have all the required variables
# and are not already in it, and are at least 2.8.0.
if(DASHBOARDSCRIPT_BASE_DIRECTORY AND
DASHBOARDSCRIPT_SOURCE_DIRECTORY AND
DASHBOARDSCRIPT_BASE_DIRECTORY AND
BUILDNAME AND
DASHBOARDSCRIPT_CMAKE_COMMAND AND
DASHBOARDSCRIPT_CTEST_EXECUTABLE AND
NOT IN_DASHBOARD_SCRIPT AND
NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.0")
set(_Continuous_cron "15 * * * * ")
set(_Nightly_cron "15 0 * * * ")
set(_Experimental_cron
"\nor run this command for an one-off experimental test build:\n")
set(_Experimental_flags "-VV")
message(STATUS
"Dashboard scripts have been generated for automatic nightly and continuous builds.")
if(WIN32)
set(_Continuous_cron)
set(_Nightly_cron)
message(STATUS
"You can set up scheduled tasks to run these command lines:")
else()
message(STATUS "You can add these sample lines to your crontab:")
endif()
set(_msg)
if(NOT DASHBOARDSCRIPT_BUILD_CONFIGURATION)
set(DASHBOARDSCRIPT_BUILD_CONFIGURATION "RelWithDebInfo")
endif()
set(DASHBOARDSCRIPT_BUILD_CONFIGURATION "${DASHBOARDSCRIPT_BUILD_CONFIGURATION}" CACHE STRING "Build configuration to use for dashboard builds by default")
mark_as_advanced(DASHBOARDSCRIPT_BUILD_CONFIGURATION)
foreach(DASHBOARDSCRIPT_DASH_TYPE Nightly Continuous Experimental)
# If given a cache template, configure it
if(ARGN)
configure_file(${ARGN}
"${DASHBOARDSCRIPT_BASE_DIRECTORY}/GeneratedInitialCache.run${DASHBOARDSCRIPT_DASH_TYPE}.cmake"
@ONLY)
endif()
# Actually create the script file
configure_file(${_dashboardmoddir}/DashboardScript.cmake.in
"${DASHBOARDSCRIPT_BASE_DIRECTORY}/run${DASHBOARDSCRIPT_DASH_TYPE}.cmake"
@ONLY)
set(_msg
"${_msg}\n${_${DASHBOARDSCRIPT_DASH_TYPE}_cron}\"${DASHBOARDSCRIPT_CTEST_EXECUTABLE}\" -S \"${DASHBOARDSCRIPT_BASE_DIRECTORY}/run${DASHBOARDSCRIPT_DASH_TYPE}.cmake\" ${_${DASHBOARDSCRIPT_DASH_TYPE}_flags}")
endforeach()
message(STATUS "\n${_msg}\n")
message(STATUS "")
endif()
endfunction()
# - Dashboard driver script for use with ctest.
#
# Generated file processed by CreateDashboardScripts.cmake
# Run it like:
# ctest -S nameofthisfile
# with -V or -V -VV if you want more feedback.
#
# Generally you do not need to edit this file by hand!
#
# If this file isn't named DashboardScript.cmake.in and located
# in the same directory as CreateDashboardScripts.cmake, it has been
# auto-generated and will be overwritten every time CMake configures
# itself. (This may be every build!)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
set(CTEST_PROJECT_NAME "@PROJECT_NAME@")
set(CTEST_DASHBOARD_ROOT "@DASHBOARDSCRIPT_BASE_DIRECTORY@")
set(CTEST_SOURCE_DIRECTORY "@DASHBOARDSCRIPT_SOURCE_DIRECTORY@")
set(DASH_TYPE "@DASHBOARDSCRIPT_DASH_TYPE@")
set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/build-${DASH_TYPE}")
set(CTEST_NOTES_FILES
"${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}"
"${CTEST_DASHBOARD_ROOT}/GeneratedCombinedCache.${CTEST_SCRIPT_NAME}")
set(CTEST_BUILD_NAME "@BUILDNAME@")
set(CTEST_SITE "@SITE@")
set(CTEST_USE_LAUNCHERS TRUE)
set(CTEST_COMMAND "@DASHBOARDSCRIPT_CTEST_EXECUTABLE@")
set(CTEST_CMAKE_COMMAND "@DASHBOARDSCRIPT_CMAKE_COMMAND@")
set(CTEST_UPDATE_TYPE "@UPDATE_TYPE@")
set(CTEST_UPDATE_COMMAND "@UPDATE_COMMAND@")
set(CTEST_UPDATE_OPTIONS "@UPDATE_OPTIONS@")
if((NOT CTEST_CONFIGURATION_TYPE) OR (NOT CTEST_BUILD_CONFIGURATION))
set(CTEST_BUILD_CONFIGURATION "@DASHBOARDSCRIPT_BUILD_CONFIGURATION@")
set(CTEST_CONFIGURATION_TYPE "@DASHBOARDSCRIPT_BUILD_CONFIGURATION@")
endif()
# Avoid non-ascii characters in tool output.
set(ENV{LC_ALL} C)
if(EXISTS "${CTEST_DASHBOARD_ROOT}/GeneratedInitialCache.${CTEST_SCRIPT_NAME}")
file(READ "${CTEST_DASHBOARD_ROOT}/GeneratedInitialCache.${CTEST_SCRIPT_NAME}" _initcache)
else()
set(_initcache)
endif()
if(EXISTS "${CTEST_DASHBOARD_ROOT}/CustomInitialCache.cmake")
file(READ "${CTEST_DASHBOARD_ROOT}/CustomInitialCache.cmake" _customcache)
set(_initcache "${_initcache}
${_customcache}")
endif()
set(_initcache "# This file is automatically regenerated every dashboard build -
# Do not edit it directly!
# If you want to add initial cache values, you can create/modify
# the CustomInitialCache.cmake file in this directory.
# Pretty typical settings to preseve from the generating cache
set(BUILD_TESTING ON CACHE BOOL docstring)
set(IN_DASHBOARD_SCRIPT ON CACHE BOOL docstring)
set(CTEST_USE_LAUNCHERS ON CACHE BOOL docstring)
set(CMAKE_PREFIX_PATH \"@CMAKE_PREFIX_PATH@\" CACHE STRING docstring)
set(CMAKE_BUILD_TYPE \"@CMAKE_BUILD_TYPE@\" CACHE STRING docstring)
set(CTEST_CONFIGURATION_TYPE \"@CMAKE_BUILD_TYPE@\" CACHE STRING docstring)
# testing tool locations
# Saved here because the tools in the path might be outdated
set(CPPCHECK_EXECUTABLE \"@CPPCHECK_EXECUTABLE@\" CACHE FILEPATH docstring)
set(DOXYGEN_EXECUTABLE \"@DOXYGEN_EXECUTABLE@\" CACHE FILEPATH docstring)
${_initcache}")
file(WRITE "${CTEST_DASHBOARD_ROOT}/GeneratedCombinedCache.${CTEST_SCRIPT_NAME}" "${_initcache}")
ctest_empty_binary_directory("${CTEST_BINARY_DIRECTORY}")
ctest_start(${DASH_TYPE})
if(CTEST_UPDATE_COMMAND AND NOT DASH_TYPE STREQUAL "Experimental")
ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
endif()
# Only proceed if we updated a file or if we're not a continuous build
set(PROCEED NO)
if(res GREATER 0)
message(STATUS "One or more files were updated, so we will proceed to "
"and build")
set(PROCEED YES)
endif()
if(NOT DASH_TYPE STREQUAL "Continuous")
message(STATUS "We are not a continuous dashboard, so continuing regardless "
"of whether any files were updated")
set(PROCEED YES)
endif()
if(PROCEED)
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res
OPTIONS "-C${CTEST_DASHBOARD_ROOT}/GeneratedCombinedCache.${CTEST_SCRIPT_NAME}")
if(${res} EQUAL 0)
# Only try to build if we could configure
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
# Some tests, like cppcheck tests, don't depend on a successful build
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
endif()
endif()
# Always submit results
ctest_submit(RETURN_VALUE res)
# - Run doxygen on source files as a custom target
#
# include(DoxygenTargets)
# add_doxygen(<doxyfile> [OUTPUT_DIRECTORY <outputdir>]
# [EXTRA_INPUT <single path or quoted list of paths>]
# [EXTRA_STRIP_FROM_PATH <single path or quoted list of paths>]
# [EXTRA_STRIP_FROM_INC_PATH <single path or quoted list of paths>]
# [INSTALL_DESTINATION <installdir>
# [INSTALL_COMPONENT <installcomponent>]
# [INSTALL_PDF_NAME <installpdfname>] ]
# [DOC_TARGET <targetname>]
# [PROJECT_NUMBER <versionnumber>]
# [NO_WARNINGS]
# [NO_PDF])
#
# Requires these CMake modules:
# FindDoxygen
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__add_doxygen)
return()
endif()
set(__add_doxygen YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_doxygenmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
if(APPLE)
list(APPEND CMAKE_PREFIX_PATH "/usr/texbin")
endif()
if(NOT DOXYGEN_FOUND)
find_package(Doxygen QUIET)
endif()
set(DOXYGEN_LATEX "NO")
set(DOXYGEN_PDFLATEX "NO")
set(DOXYGEN_DOT "NO")
if(DOXYGEN_DOT_EXECUTABLE)
set(DOXYGEN_DOT "YES")
endif()
find_package(LATEX QUIET)
if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
set(DOXYGEN_LATEX "YES")
endif()
if(PDFLATEX_COMPILER)
set(DOXYGEN_PDFLATEX "YES")
endif()
# An optional single-file install that supports cmake older than 2.8.0
# For internal use
function(_dt_install_file target filename dest rename)
if(CMAKE_VER VERSION_LESS 2.8.0)
set(INSTALL_CODE "
if(EXISTS \"${filename}\")
message(STATUS \"Found: ${filename}\")
file(INSTALL
DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${dest}\"
TYPE FILE
RENAME \"${rename}\"
FILES \"${filename}\")
else()
message(STATUS \"Skipping (build '${target}' to create): ${filename}\")
endif()
")
if(NOT ARGN STREQUAL "")
set(INSTALL_COMPONENT "${ARGN}")
set(INSTALL_CODE "
if(NOT CMAKE_INSTALL_COMPONENT OR \"\${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"${INSTALL_COMPONENT}\")
${INSTALL_CODE}
endif()
")
endif()
install(CODE "${INSTALL_CODE}")
else()
set(COMPONENT_ARGS)
if(NOT ARGN STREQUAL "")
set(COMPONENT_ARGS COMPONENT "${ARGN}")
endif()
install(FILES
"${filename}"
DESTINATION
"${dest}"
RENAME "${rename}"
${COMPONENT_ARGS}
OPTIONAL)
endif()
endfunction()
# An optional single-directory install that supports cmake older than 2.8.0
# For internal use
function(_dt_install_dir target dir dest)
if(CMAKE_VER VERSION_LESS 2.8.0)
set(INSTALL_CODE "
if(EXISTS \"${dir}\")
message(STATUS \"Found: ${dir}\")
file(INSTALL
DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${dest}\"
TYPE DIRECTORY
FILES \"${dir}\")
else()
message(STATUS \"Skipping (build '${target}' to create): ${dir}\")
endif()
")
if(NOT ARGN STREQUAL "")
set(INSTALL_COMPONENT "${ARGN}")
set(INSTALL_CODE "
if(NOT CMAKE_INSTALL_COMPONENT OR \"\${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"${INSTALL_COMPONENT}\")
${INSTALL_CODE}
endif()
")
endif()
install(CODE "${INSTALL_CODE}")
else()
set(COMPONENT_ARGS)
if(NOT ARGN STREQUAL "")
set(COMPONENT_ARGS COMPONENT "${ARGN}")
endif()
install(DIRECTORY
"${dir}"
DESTINATION
"${dest}"
${COMPONENT_ARGS}
OPTIONAL)
endif()
endfunction()
function(add_doxygen _doxyfile)
# parse arguments
set(WARNINGS YES)
set(_nowhere)
set(_curdest _nowhere)
set(_val_args
OUTPUT_DIRECTORY
EXTRA_INPUT
EXTRA_STRIP_FROM_PATH
EXTRA_STRIP_FROM_INC_PATH
DOC_TARGET
INSTALL_DESTINATION
INSTALL_COMPONENT
INSTALL_PDF_NAME
PROJECT_NUMBER)
set(_bool_args
NO_WARNINGS
NO_PDF)
foreach(_arg ${_val_args} ${_bool_args})
set(${_arg})
endforeach()
foreach(_element ${ARGN})
list(FIND _val_args "${_element}" _val_arg_find)
list(FIND _bool_args "${_element}" _bool_arg_find)
if("${_val_arg_find}" GREATER "-1")
set(_curdest "${_element}")
elseif("${_bool_arg_find}" GREATER "-1")
set("${_element}" ON)
set(_curdest _nowhere)
else()
list(APPEND ${_curdest} "${_element}")
endif()
endforeach()
if(_nowhere)
message(FATAL_ERROR "Syntax error in use of add_doxygen!")
endif()
if(NO_WARNINGS)
set(WARNINGS NO)
endif()
if(NOT DOC_TARGET)
set(DOC_TARGET doc)
endif()
if(NOT OUTPUT_DIRECTORY)
set(OUTPUT_DIRECTORY "docs-generated")
endif()
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_DIRECTORY}")
if(NOT INSTALL_PDF_NAME)
set(INSTALL_PDF_NAME "docs-generated.pdf")
endif()
if(NOT PROJECT_NUMBER)
set(PROJECT_NUMBER "${CPACK_PACKAGE_VERSION}")
endif()
if(DOXYGEN_FOUND)
if(TARGET ${DOC_TARGET})
message(FATAL_ERROR "Documentation target ${DOC_TARGET} already exists!")
endif()
if(NOT IS_ABSOLUTE "${OUTPUT_DIRECTORY}")
get_filename_component(OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_DIRECTORY}"
ABSOLUTE)
endif()
set_property(DIRECTORY
APPEND
PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${OUTPUT_DIRECTORY}/html"
"${OUTPUT_DIRECTORY}/latex")
if(NOT TARGET ${DOC_TARGET}_open)
# Create a target to open the generated HTML file.
if(WIN32)
set(DOXYGEN_LAUNCHER_COMMAND start)
elseif(NOT APPLE)
set(DOXYGEN_LAUNCHER_COMMAND xdg-open)
endif()
if(DOXYGEN_LAUNCHER_COMMAND)
add_custom_target(${DOC_TARGET}_open
COMMAND ${DOXYGEN_LAUNCHER_COMMAND} "${OUTPUT_DIRECTORY}/html/index.html"
VERBATIM)
set_target_properties(${DOC_TARGET}_open
PROPERTIES
EXCLUDE_FROM_ALL
TRUE)
set_target_properties(${DOC_TARGET}_open
PROPERTIES
EXCLUDE_FROM_DEFAULT_BUILD
TRUE)
add_dependencies(${DOC_TARGET}_open ${DOC_TARGET})
endif()
endif()
get_filename_component(_doxyfileabs "${_doxyfile}" ABSOLUTE)
get_filename_component(INCLUDE_FILE "${_doxyfileabs}" NAME)
get_filename_component(INCLUDE_PATH "${_doxyfileabs}" PATH)
# Doesn't currently work on Windows, so don't bother
if(DOXYGEN_LATEX AND NOT NO_PDF AND NOT WIN32)
set(MAKE_PDF YES)
set(GENERATE_LATEX YES)
else()
set(MAKE_PDF NO)
set(GENERATE_LATEX NO)
endif()
if(DOXYGEN_PDFLATEX AND MAKE_PDF)
set(USE_PDFLATEX YES)
else()
set(USE_PDFLATEX NO)
endif()
if(DOXYGEN_DOT)
set(HAVE_DOT YES)
set(DOT_PATH ${DOXYGEN_DOT_PATH})
else()
set(HAVE_DOT NO)
set(DOT_PATH)
endif()
# See http://www.cmake.org/pipermail/cmake/2006-August/010786.html
# for info on this variable
if("${CMAKE_BUILD_TOOL}" MATCHES "(msdev|devenv)")
set(WARN_FORMAT "\"$file($line) : $text \"")
else()
set(WARN_FORMAT "\"$file:$line: $text \"")
endif()
configure_file("${_doxygenmoddir}/DoxygenTargets.doxyfile.in"
"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${DOC_TARGET}.additional"
@ONLY)
if(IN_DASHBOARD_SCRIPT)
set(ALL_IN_DASHBOARD ALL)
else()
set(ALL_IN_DASHBOARD)
endif()
add_custom_target(${DOC_TARGET} ${ALL_IN_DASHBOARD}
COMMAND
"${DOXYGEN_EXECUTABLE}"
"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${DOC_TARGET}.additional"
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
#MAIN_DEPENDENCY ${DOC_TARGET}
COMMENT
"Running Doxygen with configuration ${_doxyfile}..."
VERBATIM)
if(NOT IN_DASHBOARD_SCRIPT)
set_target_properties(${DOC_TARGET}
PROPERTIES
EXCLUDE_FROM_ALL
TRUE)
set_target_properties(${DOC_TARGET}
PROPERTIES
EXCLUDE_FROM_DEFAULT_BUILD
TRUE)
endif()
if(MAKE_PDF)
add_custom_command(TARGET
${DOC_TARGET}
POST_BUILD
COMMAND
${CMAKE_MAKE_PROGRAM}
WORKING_DIRECTORY
"${OUTPUT_DIRECTORY}/latex"
COMMENT
"Generating PDF using PDFLaTeX..."
VERBATIM)
endif()
if(INSTALL_DESTINATION)
if(INSTALL_COMPONENT)
_dt_install_dir("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/html" "${INSTALL_DESTINATION}" "${INSTALL_COMPONENT}")
if(MAKE_PDF)
_dt_install_file("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/latex/refman.pdf" "${INSTALL_DESTINATION}" "${INSTALL_PDF_NAME}" "${INSTALL_COMPONENT}")
endif()
else()
_dt_install_dir("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/html" "${INSTALL_DESTINATION}")
if(MAKE_PDF)
_dt_install_file("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/latex/refman.pdf" "${INSTALL_DESTINATION}" "${INSTALL_PDF_NAME}")
endif()
endif()
endif()
endif()
endfunction()
@INCLUDE_PATH = "@INCLUDE_PATH@"
@INCLUDE = "@INCLUDE_FILE@"
OUTPUT_DIRECTORY = "@OUTPUT_DIRECTORY@"
GENERATE_LATEX = "@GENERATE_LATEX@"
USE_PDFLATEX = @USE_PDFLATEX@
HAVE_DOT = @HAVE_DOT@
DOT_PATH = "@DOT_PATH@"
LATEX_CMD_NAME = "@LATEX_COMPILER@"
MAKEINDEX_CMD_NAME = "@MAKEINDEX_COMPILER@"
WARNINGS = @WARNINGS@
WARN_FORMAT = @WARN_FORMAT@
PROJECT_NUMBER = @PROJECT_NUMBER@
INPUT += @EXTRA_INPUT@
STRIP_FROM_PATH += @EXTRA_STRIP_FROM_PATH@
STRIP_FROM_INC_PATH += @EXTRA_STRIP_FROM_INC_PATH@
LATEX_BATCHMODE = YES
QUIET = YES
# - Add flags to compile with extra warnings
#
# enable_extra_compiler_warnings(<targetname>)
# globally_enable_extra_compiler_warnings() - to modify CMAKE_CXX_FLAGS, etc
# to change for all targets declared after the command, instead of per-command
#
#
# Original Author:
# 2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__enable_extra_compiler_warnings)
return()
endif()
set(__enable_extra_compiler_warnings YES)
macro(_enable_extra_compiler_warnings_flags)
set(_flags)
if(MSVC)
option(COMPILER_WARNINGS_EXTREME
"Use compiler warnings that are probably overkill."
off)
mark_as_advanced(COMPILER_WARNINGS_EXTREME)
set(_flags "/W4")
if(COMPILER_WARNINGS_EXTREME)
set(_flags "${_flags} /Wall /wd4619 /wd4668 /wd4820 /wd4571 /wd4710")
endif()
else()
include(CheckCXXCompilerFlag)
set(_flags)
check_cxx_compiler_flag(-W SUPPORTS_W_FLAG)
if(SUPPORTS_W_FLAG)
set(_flags "${_flags} -W")
endif()
check_cxx_compiler_flag(-Wall SUPPORTS_WALL_FLAG)
if(SUPPORTS_WALL_FLAG)
set(_flags "${_flags} -Wall")
endif()
check_cxx_compiler_flag(-Wextra SUPPORTS_WEXTRA_FLAG)
if(SUPPORTS_WEXTRA_FLAG)
set(_flags "${_flags} -Wextra")
endif()
endif()
endmacro()
function(enable_extra_compiler_warnings _target)
_enable_extra_compiler_warnings_flags()
get_target_property(_origflags ${_target} COMPILE_FLAGS)
if(_origflags)
set_property(TARGET
${_target}
PROPERTY
COMPILE_FLAGS
"${_flags} ${_origflags}")
else()
set_property(TARGET
${_target}
PROPERTY
COMPILE_FLAGS
"${_flags}")
endif()
endfunction()
function(globally_enable_extra_compiler_warnings)
_enable_extra_compiler_warnings_flags()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" PARENT_SCOPE)
endfunction()