Vrui change log
===============

Vrui-1.0-030:
- Beginning of history file

Vrui-1.0-031:
- Added image handling library (libImages) with PNG and JPEG support
- Added vislet plug-in API to Vrui to handle dynamic loading of
  visualization plug-ins into unaware Vrui applications.
- Added prototype offset tool to translate the position of any input
  device by a fixed vector and replicate one device button to the offset
  device.

Vrui-1.0-032:
- Changed build system and some sources to provide preliminary support
  for Mac OS X.
  - Requires OS version 10.4.
  - Requires X11 emulation.
  - Can be configured to use Apple's OpenAL package.
  - Can be configured to use libpng for PNG image file support and
    libjpeg for JPEG image file support.
- Removed plug-in handling from Misc library and moved it to Plugins
  library to remove dependency of Misc on libdl.
  - Factory and FactoryManager moved from namespace Misc to namespace
    Plugins.

Vrui-1.0-033:
- Changed behavior of Vrui windows to provide a consistent window into
  the virtual world by panning their viewports across the maximum
  viewport defined by the display containing the window.
  - Still need to fix MouseNavigationTool such that it rotates/scales
    around the current window center instead of the display center.
  - Should change panning behavior to move a VRScreen inside the bounds
    of the screen given in the configuration file instead of moving the
    window inside the screen -- will simplify integrating moving windows
    with other parts of Vrui.
- Changed behavior of modifier keys inside InputDeviceAdapterMouse such
  that buttons and button keys are "sticky" when changing the current
  button set with a modifier key.
- Added navigation/virtual device tool to better integrate SpaceBall
  input devices into Vrui.
  - Should implement generic HIDNavigationTool to convert valuators into
    arbitrary translational/rotational axes.

Vrui-1.0-034:
- Improved build system to better handle debug and release versions of
  the toolkit in the same installation directory; example application
  makefiles now respect DEBUG make parameter.
- Started adding a very preliminary user's manual and library
  documentation in HTML format in the Documentation directory.

Vrui-1.0-035:
- Added new barrier class to Threads library.
- Initial support for multi-threaded rendering to optimally use shared-
  memory multipipe rendering systems such as SGI PRISMs.
  - New windowsMultithreaded flag in Vrui root section to switch from
    sequential multiwindow to parallel multiwindow rendering.
- Fixed OpenGL extension handling for the Mac OS X version.
- Improved behavior of panning viewport windows by relating mouse
  navigation to the current window center.
- Fixed long-standing bug in font rendering when using convolution to
  perform antialiasing.

Vrui-1.0-036:
- Added Mac OS X support to Misc::LargeFile class.
- Changed plug-in interface to use generic creator/destructor function
  names instead of class-specific names.
- Added cross-platform support to create plug-in modules to makefile
  fragment.
- Added several OpenGL extensions to GLExtensionManager.
- Added example program showing how to create application-specific tool
  classes and register them with the Vrui tool manager.

Vrui-1.0-037:
- Changed API of GLFont to report average character width.
- Changed API of GLMotif::TextField to automatically format numerical-
  value fields.
- Temporarily changed RayMenuTool and RayScreenMenuTool to double as
  widget tools by setting interactWithWidgets to true in their
  configuration file sections.
- Added new lower-resolution fonts (*12.fnt) that look better on low-
  resolution displays and in desktop environments.

Vrui-1.0-038:
- Small improvements in Vrui's desktop embedding.

Vrui-1.0-039:
- Fixed typo in error message strings for Threads::Thread exception
  classes.
- Added support for thread-local storage using POSIX TLS mechanism to
  Threads library.
- Fixed bug in multithreaded rendering: current GLContextData object and
  current GL extension objects were stored process-global instead of
  local to each rendering thread.
  - Seems to fix crashes when using OpenGL extensions and lock-ups when
    exiting Vrui applications in multithreaded environments.
- Changed destination directory for plug-ins during build from Share to
  library directory.
- Updated Vrui.cfg and VRDevices.cfg to most recent settings from IDAV
  and KeckCAVES VR environments. Supported environments:
  - Power wall in IDAV main lab (anaglyphic stereo or mono, with
    spaceball)
  - Tiled display wall in IDAV VR lab (with optional VR binoculars)
  - Responsive workbench in IDAV VR lab (with new low-cost DLP
    projector)
  - KeckCAVES
  - Desktop simulator with optional spaceball, optimized for 20" LCD
 
Vrui-1.0-040:
- Fixed bulk data transfer in Comm::MulticastPipeMultiplexer. Can now
  reliably send large amounts of data across the broadcast/multicast
  connection. Throughput for 100Mb/s Ethernet is stable at 11.34MB/s,
  throughput for 1Gb/s Ethernet is fluctuating up to 91.4MB/s.
- Changed SpaceBallNavigationTool to additionally allow zooming.
- Changed build system to allow per-package compiler flags.
- Improved desktop embedding:
  - Windows in panningViewport can be configured to keep the tool kill
    zone in a fixed user-specified position when moved/resized.
  - Windows in panningViewport moved can be configured to move the 3D
    scene along with them.
  - Mouse navigation in panningViewport windows zooms around the window
    center and dollys in a line from the eye to the window center
- Changed API of Vrui::ToolManager and Vrui::ToolKillZone.
- Added function to Vrui.h to concatenate navigation transformations
  from the left.
- Added function to Vrui.h to detect whether the local node is the
  master (i.e., a single node or the head node of a cluster).
- Added Laserpointer tool to simplify pointing out features in 3D
  displays (no more need to abuse the ray menu tool).
- Provided new navigation tool for desktop input devices such as
  joysticks and spaceballs. Supercedes previous JoystickNavigationTool
  and SpaceballNavigationTool.
- Fixed bug in VRWindow that reported a wrong window center in
  SplitViewportStereo windows.
- Added option that InputDeviceTools create their own virtual input
  devices when created.
- Rolled in most recent Mac OS X changed provided by Braden Pellett.
  - Now supports HID devices using Mac OS X's HID API.

Vrui-1.0-041:
- Added library interdependencies to makefile to allow parallel build
  using make -j <numjobs>.
- Added required environment variable for Mac OS X builds to Vrui
  makefile fragment.
- Fixed bug in Comm::MulticastPipeMultiplexer causing a segmentation
  fault when slaves are waiting on an empty send queue.
- Added new method to class Rotation that creates a rotation
  transforming a "from" vector into a "to" vector.
- Added ValueCoder class for class Plane to geometry library.
- Added forward direction to Vrui environment state to help applications
  that need a general direction pointing "into" the VR environment. Can
  be queried using the Vrui::getForwardDirection() function.
- Added floor plane equation to Vrui environment state to help
  applications that want to have a user walk on a virtual environment,
  for example. Can be queried using the Vrui::getFloorPlane() function.
- Added WalkNavigationTool class to navigate immersive VR environments
  by walking and gaze direction.
- Added accessor methods to Vrui::Glyph.
- Added generic waldo tool to scale translations and rotations of 6-DOF
  input devices (generalization of WaldoLocatorTool and
  WaldoDraggingTool).
- Added facilities for automatic garbage collection using reference
  counting to Misc library (classes RefCounted and Autopointer), and
  a thread-safe version of RefCounted class to Threads library.
- Added code to Vrui.General.cpp to re-normalize navigation
  transformation on every set... and concatenate... call.
- Fixed a leftover bug in Misc::MulticastPipeMultiplexer that prohibited
  opening/closing pipes dynamically and broadcasting high-bandwidth bulk
  data. Multicast pipes now get average transfer rates of about 70MB/s
  on 1Gb/s Ethernet, and are reliable to use for application-level data
  streaming.
- Added shift() method to Geometry::Box to shift boxes by a given offset
  vector.
- Fixed synchronization bug in Vrui: application time was only
  synchronized after the first complete frame.
- Added isJoined() method to Threads::Thread.
- Added Vrui::Rotation class to Vrui/Geometry.h, to create a shortcut
  when writing rotation code.
- Added Misc/Utility.h header file containing basic helper functions.
- Improved Geometry::Polygon class. Now has robust point-in-polygon test
  for 2- and 3-dimensional general polygons.
- Improved Comm::TCPSocket class (reduced latency/increased through-put)
  by adding methods to enable/disable TCP_NODELAY or TCP_CORK. TCP_CORK
  momentarily only supported by Linux kernels >= 2.4.
- Added configuration file setting to specify the UDP port to use on a
  multicast master, to simplify getting through firewalls. Still
  defaults to dynamic port assignment by the OS.
- Changed Vislet API to allow vislet classes to read default settings
  from the Vislet manager's section in the Vrui configuration file.
  - CAVERenderer vislet class now reads texture file names and
    rendering settings from configuration file; can still be overridden
    by command line parameters.
  - Added Vrui::getVisletManager(void) function to Vrui kernel
    interface in Vrui/Vrui.h.
- Added shutdown method to Comm::TCPSocket to selectively close the
  read or write direction of a connected socket.
- Slightly changed error handling in Comm::TCPSocket blocking read and
  write to more reliably detect unexpected socket closures.
- Fixed Mac OS X version of HIDDevice input device driver module by
  filtering out non-axis device capabilities (fix by Braden Pellett).
- Added clarification comment about Vrui::openPipe() returning NULL in
  non-cluster environments to Vrui/Vrui.h
- Added header file Vrui/ClusterSupport.h with helper functions to
  simplify writing cluster-aware applications.
- Finally fixed Vrui::WaldoTool to behave as expected.
- Fixed access privilege bug in converting copy constructor of
  Geometry::AffineTransformation.
- Fixed several bugs in Comm::MulticastPipeMultiplexer, but still not
  working reliably.
- Changed Vrui's shutdown behavior. Previous implementation destroyed
  Vrui state before an application object's destructor was called,
  leading to persistent crashes on shutdown. New approach has explicit
  deinit() function. This change is transparent to applications using
  the application object interface.
- Changed Vrui's internal cluster communication protocol to flush the
  internal multicast pipe as early in the frame as possible to increase
  parallelism between the master and the slaves.
- Added "multipipeRemoteCommand" setting to Vrui configuration file to
  select the command used to start slave application instances
  (defaults to "ssh").
- Changed order of Vrui state elements and initialization from
  configuration file. Now properly reads physical unit size before
  reading other sizes depending on it.
- Supported more key names in Vrui::InputDeviceAdapterMouse. Now
  covering most keys on standard keyboards.
- Added a reference page listing all settings in the Vrui
  configuration file to the HTML documentation.
- Enabled spinning animation for Vrui::MouseNavigationTool.
- Added Comm::ClusterPipe abstraction for transparent TCP communication
  between clusters connected via Comm::MulticastPipeMultiplexer.
- Changed Comm::TCPSocket to optionally fall back to returning dotted
  addresses if the peer's host name cannot be resolved instead of
  throwing an exception. Default behavior is still to throw.
- Finished implementing behavior of Vrui::VRWindow for desktop
  environments where panningViewport and navigate are enabled.
  Navigation coordinates scale with the window size, and Vrui's display
  center and size are updated such that applications can center their
  displays properly.
- Added input device adapter to support the (proprietary) head tracker
  on VisBox and VisWall immersive environments.
- Added Vrui::ButtonInputDeviceTool to manipulate virtual 6-DOF input
  devices using keyboard keys or other buttons.
- Added Vrui::ToolKillZoneFrustum to simplify deleting tools in a
  desktop environment.
- Added facility to draw fake mouse cursors to
  Vrui::MouseNavigationTool.
- Replaced Images::RBGImage class with a templatized base class
  Images::Image and specialized derived classes for RGB and RGBA images.
- Added function to read Xcursor cursor files in Images/ReadImageFile.h.
- Added missing template instantiation of value coder class for
  Geometry::ComponentArray to Geometry/GeometryValueCoders.
- Fixed crash in Images::readImageFile when reading a PNG image with
  alpha channel into an RGB image.

Vrui-1.0-042:
- Extended use of GLMotif::StyleSheet to assign default attributes
  during widget creation. Deprecated widget constructors that expect
  certain attributes (such as fonts) as arguments; all initialization
  now done through the widget manager's style sheet.
- Added GLMotif::SubMenu class to more elegantly handle cascading pop-
  up menus.
- API change in GLMotif::StyleSheet: public element sliderWidth is now
  called sliderHandleWidth. Client code should stop using the now
  deprecated method passing sliderWidth into the GLMotif::Slider
  constructor and use the new constructor instead.
- Added convenience method to add new toggle buttons to
  GLMotif::RadioBox and finished interface to completely handle radio
  buttons using indices.
- Added Vrui::TransparentObject as a base class for objects that need
  a second rendering pass to render transparency. Transparency pass is
  called in physical coordinates, with alpha blending enabled and the
  depth buffer locked, after the application's display function.
- Added per-chunk functor applicator to class Misc::ChunkedArray.
- Fixed shutdown behavior in Vrui; closes VR windows and destroys
  context data items before returning from the main loop.
- Fixed layout bug in GLMotif::Slider: calcZRange method used sliderbox
  and shaftbox before they were properly initialized.
- Fixed wrong setting names for Frustum tool kill zones in Vrui
  configuration file.

Vrui-1.0-043:
- Added Images/GetImageFileSize containing a function to read the size
  of an image file without having to read the entire image.
- Added getNode() method to Geometry::ArrayKdTree.
- Fixed method scope in GL/GLTransformationWrappers.cpp.
- Added GLFrustum class for software-based frustum culling and LOD
  calculation to GLGeometryWrappers library.

Vrui-1.0-044:
- Changed BuildRoot/Packages to make it clearer how to find libraries
  in non-standard locations.
- Added Geometry/Random.h with functions to create random points and
  vectors such as random unit vectors or normally-distributed error
  vectors.
- Removed superfluous semicola from all C++ files to get rid of warnings
  when compiling with -pedantic.
- Changed return type of (obsolete) glGetFunctionPtr in
  GL/GLExtensions.h from object pointer to function pointer.
- Added indirection workaround when using dlsym() to get rid of warnings
  when compiling with -pedantic to Plugins/FactoryManager and
  VRDeviceDaemon/VRFactory.cpp.
- Moved all Vrui tool plug-ins to Vrui/Tools directory.
- Fixed problem when trying to exit a window-less Vrui application
  instance; now prints note and exits on ESC (or any other) key.
- Redesigned Vrui cluster startup process to send the application's
  command line via a multicast pipe instead of the remote login
  command's command line to get around command line length limitations
  and double-globbing.
- Added simple timeout mechanism to Comm::MulticastPipeMultiplexer to
  detect communication failures or master node crashes from the slaves
  (to shut them down reliably in case of cluster failure).
- Added spinThreshold setting to Vrui::MouseNavigationTool. Spinning
  animation is only enabled if the mouse moved by more than the given
  threshold on the screen, measured in physical coordinate units.
- Added invertDolly flag to Vrui::MouseNavigationTool to invert the
  switch between dolly and zoom mode for those who are so inclined.
- Added extension class for the GL_EXT_framebuffer_object OpenGL
  extension.
- Fixed bug in Images::writeImageFile: PNG images were shifted downwards
  by one pixel row.
- Added descriptions to many Vrui configuration file options in Vrui
  configuration file reference HTML page.
- Added HTML page describing the Vrui input model to documentation.
- Added OpenGL extension class for GL_NV_point_sprite.
- Added OpenGL extension class for GL_ARB_point_sprite.
- Added virtual Jell-O example program to Vrui release. Contains several
  versions of the same program to show how to develop cluster-aware
	multithreaded applications.
- Changed makefile in ExamplePrograms to use pattern rules.

Vrui-1.0-045:
- Fixed bug in clipping algorithm in Geometry::Polygon.
- Added extension class for GL_ARB_shader_objects.
- Added extension class for GL_ARB_vertex_shader.
- Added extension class for GL_ARB_fragment_shader.
- Fixed typo in Misc::File::WriteError.
- Added Misc::MemMappedFile class to provide a Misc::File wrapper around
  blocks of memory or memory-mapped files.
- Added Comm::TCPPipe to provide an endianness-safe pipe abstraction
  over TCP sockets.
- Fixed missing endianness conversion in std::string read/write methods
  in Comm::ClusterPipe.
- Added glCompileShaderFromFile() convenience function to
  GLARBShaderObjects extension class.
- Changed API of Comm::TCPPipe to allow explicit specification of
  network endianness during construction.
- Fixed bug in wrong endianness conversion in Comm::TCPPipe's write()
  methods.
- Added VR device driver for Vicon Tarsus optical tracking system.
- Added resize() method to Images::Image; currently uses bilinear
  interpolation and clamps against image borders.
- Added getAddress() and getHostname() methods to Comm::TCPSocket to
  retrieve the dotted IP address and resolved host name of the local
  socket.
- Added mutex to Vrui state to protect asynchronous calls to
  Vrui::requestUpdate from multiple background threads.
- Added GL/GLShader, a convenience class for simple GLSL shaders
  compiling any number of vertex and fragment shaders into a single
  program object.
- Changed implementation of Vrui::VRWindow to pass eye position into
  private render function instead of eye index; API unchanged.
- Added Autostereoscopic rendering capability to Vrui::VRWindow.

Vrui-1.0-046:
- Fixed include file names in Geometry/Cone.h; was obviously never used
  or compiled.
- Added missing include file to GL/Extensions/GLARBVertexShader.h

Vrui-1.0-047:
- Added automatic detection of compiler version (works for gcc/g++) to
  BuildRoot/SystemDefinitions. Sets proper values for COMPILERTYPE and
  DEPFILETEMPLATE, and adds -ffriend-injection compiler flag for gcc
  versions 4.1.0 and up.
- Fixed Vrui::InputDeviceDataSaver, did not store number of input
  devices.
- Added value coder method for Geometry::OrthogonalTransformation to
  Geometry/GeometryValueCoders.h.
- Changed transform calibrator in VR device daemon to use orthogonal
  transformations to allow coordinate scale transformations.

Vrui-1.0-048:
- Removed definitions of __LITTLE_ENDIAN and __BIG_ENDIAN from the
  compiler command lines and from BuildRoot/SystemDefinitions and
  BuildRoot/BasicMakefile. Now uses endian.h header files found on Linux
  and Mac OS X. This affects all applications that directly query the
  value of the endianness #define macros.
- Added short-valued GLColor class and conversion operators from/to
  short-valued colors to standard instantiations.
- Created new tool base class for transforming tools (offset tool, waldo
  tool) to Vrui tool hierarchy.
- Added clutch tool that does not affect the controlled device's
  transformation while a clutch button is pressed.
- Added Misc::FileLocator, a helper class to find files based on a list
  of search paths. Contains methods to construct search paths for
  Mac OS X application bundles (and implies bundle structure for Linux
  applications).
- Added missing include file GL/GLVertexArrayTemplates.h to
  GL/GLGeometryWrappers.h.
- Fixed wrong comment in Vrui/Tools/MouseNavigationTool.h.
- Removed extra forward declaration from Vrui/Tools/MeasurementTool.h.
- Added option of multiple DSO search paths to Misc::FactoryManager by
  using a Misc::FileLocator. Constructor splits DSO name template into
  base directory and name template, and initializes the FileLocator with
  the base directory.
- Added multiple search paths to Vrui tool manager and vislet manager.
  The tool manager reads an optional "toolSearchPaths" setting from the
  configuration file and adds all directories to the search list after
  the default directory parsed from the tool DSO name template; the
  vislet manager does the same by reading a "visletSearchPaths" setting.
- API change in Vrui kernel: Vrui::setMainMenu now takes a pointer to
  GLMotif::PopupMenu instead of GLMotif::Widget. Should not cause
  problems with existing applications, since all are supposed to use
  PopupMenus as their main menu shells anyways.
- Added "Vrui System Menu" that is either installed as the main menu, or
  automatically added as a submenu to any application-provided main
  menus. Vrui system menu content currently functionless; will be filled
  in later.
- Fixed missing virtual destructor declaration in
  Misc::HashTable::EntryNotFoundError; caused problem when declaring
  hash tables from std::string due to wrong throw() specification.
- Changed API of Geometry::SplineCurve: Now has constructor that
  automatically creates appropriate knot vectors.
- Fixed bug in Images::Image::resize method; would not actually write
  resized image data.
- Removed superfluous include file Images/RGBImage.h from
  Vrui/Tools/MouseNavigationTool.cpp.
- Added new "newbie-friendly" mouse navigation tool to Vrui tools. It
  uses a single button on a mouse and a dialog box to switch navigation
  modes between rotating, panning, dollying, and scaling. The tool's
  configuration file settings are mostly identical to those of the old
  MouseNavigationTool.
- Some updates to Vrui HTML documentation.
- Added OpenGL extension class for GL_EXT_texture_cube_map.
- Added OpenGL extension class for GL_ARB_texture_compression.
- Added OpenGL extension class for GL_EXT_texture_compression_s3tc.
- Fixed offset option of OffsetTool classes in Vrui.cfg configuration
  file.

Vrui-1.0-049:
- Added VR device driver for raw Vicon Tarsus real-time data stream.
- Added navigation tool for multiple 3-DOF devices.
- Fixed misleading variable name in Vrui::MeasurementTool.
- Added file logging mechanism to Vrui::MeasurementTool. Controlled by
  class settings of MeasurementTool.
- Added variable marker sizes to Vrui::MeasurementTool. Size defaults
  to the previous setting.
- Added ViewpointSaverTool to save viewpoints in an environment-
  independent format.
- Added ViewpointFileNavigationTool to play back viewpoints previously
  saved with a ViewpointSaverTool.
- Added CurveEditorTool to define 3D polynomial curves in Hermite
  format.
- Modified ViewpointSaverTool to store interval times for each
  viewpoint.
- Added DenseMatrix helper class to Vrui/Tools directory; used by
  ViewpointFileNavigationTool class.
- Modified ViewpointFileNavigationTool to read viewpoints with interval
  times, and animate the viewpoint sequence using a C^2-continuous cubic
  spline.
- Added dependency lines for Vrui tools derived from TransformTool to
  makefile.
- Modified CurveEditorTool to create/edit viewpoint animations using
  C^2-continuous cubic splines.
- Modified ViewpointFileNavigationTool to read viewpoint animations as
  written by CurveEditorTool.
- Fixed bug in GLMotif::Slider when slider's value increment is 0.
- Added Vrui::getMainPipe() method to Vrui kernel API; returned pipe is
  for simple synchronous cluster communication inside an application's
  (or a tool's) frame method; user must call finishMessage() when done.
- Added safeguard to Vrui main frame method to call finishMessage() on
  Vrui's main pipe in case an application forgets to do so.
- Changed Vrui.cfg to reflect most recent settings.

Vrui-1.0-050:
- Added Vrui::CoordinateManager to support scale bars and other
  application-independent navigation support.
- Added function to retrieve pointer to coordinate manager to Vrui
  kernel API.
- Added Vrui::HelicopterNavigationTool to navigate using a simplified
  helicopter flight model.
- Changed Vrui initialization sequence to call initContext() method on
  all GLObject-derived objects created in application constructor
  before the frame() method is called for the first time.
- Added page describing GLContextData and GLObject from Vrui web page
  to documentation directory.
- Added atan2 function to Math/Math.h.
- Added handling of relative axes to HIDDevice VR device daemon module;
  removed "Abs" from AbsAxisSettings and AbsAxisConverter classes to
  reuse them for relative axes as well.
- Added flag to Vrui::DesktopDeviceNavigationTool to invert navigation
  behavior from configuration file.
- Added methods to access entire image data to Images::Image class.
- Optimized several oft-used methods in Geometry::Box class.
- Changed line and marker colors in Vrui::MeasurementTool to always
  contrast the background color.
- Added Vrui::ComeHitherNavigationTool, to smoothly move the position
  and orientation of an input device to the display's center.
- Made Vrui::MouseTool a subclass of Vrui::TransformTool to clean up
  tool selection menu.
- Added new variables VRUI_TOOLSDIR and VRUI_VISLETSDIR to Vrui
  makefile fragment to allow client application to find plug-in DSOs
  for pre-linking.
- Added Misc::SelfDestructPointer, a simple class for self-deleting
  pointers in cases where Misc::Autopointer's functionality is not
  required.
- Added autoScreenSize flag to Vrui::VRWindow initialization; if set to
  true, determines physical monitor size via X11 and adjusts the
  configured size of the window's associated VR screen(s).
- Changed Vrui.cfg file to automatically detect screen size.
- Reordered user interface in Vrui::CurveEditorTool.
- Fixed Vrui::ScreenLocatorTool to use same projection formula as
  Vrui::MouseTool; can now be used as replacement in most programs.
- Moved all Vrui tool classes to Vrui/Tools directory.
- Fixed some inconsistencies in makefile.
- Added different floating-point formatting modes to GLMotif::TextField
  to improve displays of very large or small numbers.
- Improved display and file output in Vrui::MeasurementTool.
- Added Misc::createNumberedFileName, a helper function to create
  unique file names based on a base file name.
- Added configurable curve file name and handle sizes to
  Vrui::CurveEditorTool.
- Changed Vrui::MeasurementTool, Vrui::ViewpointFileSaverTool, and
  Vrui::CurveEditorTool to save to uniquely named files.
- Changed Vrui::VRWindow to save screen shots to uniquely named files.
- Added buttons to load, store (save and push) and restore (pop)
  navigation transformations to Vrui system menu. Navigation
  transformations are saved in an environment-independent format.
- Quit button in Vrui system menu now actually quits from the
  application.
- Fixed bug in GLMotif::Menu when adding new menu entries to an already
  managed menu (used to cause vertical offsets in new entries).
- Added new tool base class UserInterfaceTool, derived MenuTool,
  WidgetTool, and InputDeviceTool from it.
- Added new tool base class UtilityTool, derived all leftover tool
  classes directly derived from Tool from it instead.
- Moved Vrui::TransformTool from a plug-in to the Vrui core DSO.
- Changed makefile and Vrui.cfg to reflect changes to tool hierarchy.
- Updated Vrui configuration files (Vrui.cfg and VRDevices.cfg) to
  reflect newest environment settings.
- Changed name of default Vrui root section from "Simulator" to
  "Desktop".
- Added missing Threads/Local.h, GL/GLFrustum.h, and GL/GLFrustum.cpp to
  build / install portions of makefile.
- Moved directory containing MeshEditor sample application into
  ExamplePrograms directory.
- Added simple VRML viewer to ExamplePrograms directory; shows how to
  layer a scene graph on top of Vrui.
- Updated README file.
- Added workaround for OpenGL linking problem under Mac OS X 10.5 to
  makefile and Vrui makefile fragment.
- Added missing Vrui tool header installation script.
- Added (experimental) code to makefile to automatically detect the
  presences of libpng, libjpeg, and OpenAL.
- Fixed bug in VRWindow's automatic screen size adjustment code and
  added method to update the navigation transformation if the display
  size changed.
- Added method to GLMotif::Menu to query the index of a menu entry by
  its widget pointer.
- Replicated GLMotif::Menu's API to GLMotif::SubMenu.
- Added option to draw GLMotif widgets in an overlay layer on top of
  other 3D graphics. Option is enabled by setting drawOverlayWidgets
  option to true in the widget section in Vrui's configuration file.
- Improved build system: Can now find libraries in a list of base
  directories by searching for header and dynamic library files.
  Currently only works if library headers and DSOs are installed under
  a common base directory. Added autosearch facility for packages PNG,
  JPEG, and OPENAL.
- Make variables to include support for PNG, JPEG, and OpenAL in Vrui
  applications now depend on automatic search results; should work in
  all realistic cases.
- Fixed bug in VRMeshEditor example application; now looks for Vrui tool
  headers in proper directory.
- Added entries to create and destroy virtual input devices to Vrui
  system menu.
- Added widget interaction capability to MouseNavigationTool as an evil
  hack until a better tool chaining model comes along.
- Disabled widget interaction capability in menu tools in Vrui.cfg.
- Changed default binding for MouseNavigationTool to use the "z" key for
  panning and zooming/dollying instead of the middle mouse button, to
  make it work out-of-the-box for those MacOS X users who do not have a
  working middle mouse button. Added remark in configuration file on how
  to enable the middle mouse button.
- Added "popWidgetsOnScreen" flag to Vrui configuration file to always
  align primary widgets with the screen plane, improving display in
  desktop environments.
- Added documentation page on how to configure desktop input devices
  like joysticks or spaceballs for use with Vrui applications.
- Improved documentation page on using Vrui applications.
- Fixed bugs in Vrui::InputDeviceDataSaver and
  Vrui::InputDeviceAdapterPlayback. InputDeviceDataSaver now writes to
  unique numbered file on each execution.
- Changed key handling in Vrui::InputDeviceAdapterMouse and
  Vrui::VRWindow to ignore modifier keys for key mapping, i.e., using
  modifier keys as Vrui modifier keys now has the intended effect.
- Ported automated library finder from csh to bash; csh not installed by
  default on newer systems.
- Fixed library finder invocation in BuildRoot/Packages; used to rely on
  "." being in the user's path. Now uses full path name based on
  $PACKAGEROOT.
- Added Vrui-wide command line parameter -loadView <viewpointFile> to
  load viewpoint files in the format as saved by the Vrui system menu.
  Viewpoint files are loaded at the beginning of the startDisplay
  function, overriding any navigation transformations set in a Vrui
  application's constructor.
- Fixed behavior of Vrui::InputDeviceAdapterMouse for mice with more
  than three buttons via changes in Vrui::VRWindow.
- Changed Vrui::ViewpointFileNavigationTool to deactivate when paused.
- Ran valgrind on ShowEarthModel; added missing initializations to
  GLMotif::Widget.
- Fixed bug in Vrui::ViewpointFileNavigationTool that led to a crash
  when no viewpoint file was loaded.
- Added version of widget traversal algorithm for non-const traversal
  functors to GLMotif/WidgetAlgorithms.

Vrui-1.0-051:
- Fixed null pointer bug when the master of a cluster rendering system
  does not have a defined HOSTNAME.
- Added methods to query widget colors to GLMotif::Widget.
- Added method to query window title to GLMotif::PopupWindow.
- Fixed catastrophic typo in makefile: used result from PNG check for
  both PNG and JPEG support, leading to build failure when only libpng
  is present on a host system.
- Fixed ray intersection instability in GLMotif::Widget: ray
  intersection result might have been invalid due to numerical round-off
  for zero-thickness widgets.
- Added EyeRayTool to set ray direction of input device to sight line
  from main viewer.
- Removed superfluous #include <vector> from GL/GLContextData.h and
  #include <GL/GLObject.h> from GL/GLContextData.cpp.
- Copied context management mechanism from GL support library to AL
  support library as basis for proper sound support in Vrui. Created
  ALObject and ALThingManager and updated ALContextData.
- Added Vrui::Listener class as analog to Vrui::Viewer for sound.
- Added Vrui::SoundContext class as analog to Vrui::VRWindow for sound.
- Added proper calls to sound rendering functions to inner loops in
  Vrui.Workbench.cpp.
- Added sound processing to VruiState::sound method.
- Fixed JPEG autodetection bug in makefile.
- Fixed ray direction calculation in EyeRayTool.
- Added option to use eye line from main viewer instead of device's ray
  direction to RayMenuTool and RayScreenMenuTool.
- Changed all references to "Simulator" in Vrui configuration file to
  "Desktop" for better consistency.
- Added support for stereo rendering compatible with Texas Instruments
  "3D DLP" projectors, as used in Samsung or Mitsubishi 3D TVs. Selected
  in Vrui configuration file by setting the window's windowType to
  InterleavedViewportStereo.
- Slightly improved rendering on autostereoscopic display by reading the
  number of viewing zones, and the viewport tiling layout, from the Vrui
  configuration file.
- Fixed missing initialization in Vrui::RayMenuTool.
- Added isManaged() and isVisible() methods to GLMotif::WidgetManager.

Vrui-1.0-052:
- Changed array kd-tree construction method to use std::nth_element.
  instead of the home-grown equivalent; some speed-up.
- Removed some superfluous #include directives from GLMotif/Slider.cpp.
- Added ScrollBar class to GLMotif, to act as a component for scrolled
  widgets such as list boxes.
- Added convenience functions to GLARBShaderObjects, GLARBVertexShader,
  and GLARBFragmentShader GL extension objects to simplify compiling and
  linking GLSL shaders.
- Added extension class for GL_ARB_depth_texture OpenGL extension.
- Added extension class for GL_ARB_shadow OpenGL extension.
- Added initial implementation of ListBox class to GLMotif.
- Fixed numerical value display in Vrui::CurveEditorTool.
- Added Arrow, a helper class to render different styles of arrows, to
  GLMotif.
- Changed GLMotif::CascadeButton to use the GLMotif::Arrow helper class.
- Changed GLMotif::CascadeButton's arrow to be an "innie" instead of an
  "outie."
- Added getChild() method to GLMotif::RowColumn to retrieve a pointer to
  a child widget based on its index.
- Added dropdown box widget to GLMotif.
- Improved appearance of title-less popups by removing superfluous title
  separator.
- Added getMarginWidth() method to GLMotif::Label.
- Fixed popup size and depth offset and list item margins in
  GLMotif::DropdownBox.

Vrui-1.0-053:
- Added "home" button to Vrui::DesktopDeviceNavigationTool to reset a
  lost virtual input device back to its initial position.
- Added OrderedTuple class to Misc library to act as hash keys.
- Added UnorderedTuple class to Misc library to act as hash keys.
- GLFont class now uses alpha component in text foreground/background
  colors and uploads string textures as RGBA; enables transparent text.
- Had to remove std::nth_element from kd-tree again to get around an
  ambiguity between std::swap and Misc::swap that shouldn't even exist.
- Re-enabled std::nth_element in ArrayKdTree by not including
  Misc/Utility.h. Still no clue why Misc::swap is ambiguous with
  std::swap.
- Added explicit connect() method to Comm::UDPSocket to set/change the
  association of a UDP socket after creation.
- Added default constructors creating invalid sockets to Comm::UDPSocket
  and Comm::TCPSocket.
- Added class Comm::FdSet to simplify using the select() and pselect()
  system calls.
- Added getHeadlight() method to Vrui::Viewer; returns const reference
  to viewer's lightsource object.
- Added compiler macro to switch between std::nth_element and own
  routine more easily; std::nth_element is current default.
- Added redundant element initialization in constructors for
  GLMotif::Widget and GLMotif::Arrow to get around valgrind complaints.
- Flipped matrix traversal order in Geometry::Matrix copy constructor;
  does not change anything, but might be marginally faster.
- Improved transition time calculation in
  Vrui::ComeHitherNavigationTool, is now based on fixed max velocity and
  transition distance, both in linear and angular space.
- Added ability to set and query Vrui's physical coordinate unit both in
  imperial units (inches) and metric units (meters). Added meterScale
  setting to Vrui's root configuration file section, and
  getMeterFactor() function to Vrui's kernel API.
- Added Vrui::CoordinateTransform, base class for (non-linear)
  coordinate transformations from Vrui's navigation space to "user
  interest space." Coordinate transformation objects can be registered
  with the Vrui coordinate manager, and are used by measurement tools to
  report positions in coordinates of interest to the user of an
  application, e.g., in geoid coordinates.
- Added Vrui::OrthogonalCoordinateTransform, a coordinate transformation
  class for orthogonal transformations (translations, rotations, uniform
  scalings).
- Added support for user-space coordinate transformations to
  Vrui::MeasurementTool.
- Added Vrui::GeodeticCoordinateTransform, a coordinate transformation
  class to convert from geocentric Cartesian coordinates to latitude,
  longitude, elevation geodetic coordinates on a variety of geoids.
- Finally added operators + and += to GLMotif::ZRange to calculate the
  union of two Z ranges; changed GLMotif classes to use the operators.
- Added GLMotif::Margin class, to pad a widget against resizes of its
  parent widget.
- Improved build system on Mac OS X by sorting library dependencies
  before expanding a dependency's library names.
- Added missing return statement to non-Linux versions of
  Comm::TCPSocket::getCork().
- Fixed typo in Misc/ConfigurationFile.cpp.
- Removed extraneous data copy when creating kd-tree of cell centers in
  VRDeviceDaemon's curvilinear grid class.
- Added GLMotif::SingleChildContainer, a base class for container
  widgets with a single child widget.
- Changed GLMotif::Margin to be a descendant of
  GLMotif::SingleChildContainer.
- Added dirty flag and isDirty() method to Vrui::VRWindow to support new
  algorithm to handle X events and multiple windows.
- Implemented new pipe-based event handling mechanism in Vrui main loop.
  Improved reliability; multiple windows per node now work in blocking
  mode, exit from windowless master nodes finally works. Code is
  simpler, to boot. Paves the way for implementing event timers, as
  well.
- Added check for valid input devices to Vrui initialization; shuts down
  now when no valid input devices are found (used to cause segmentation
  fault).
- Made internal changes to Misc::PriorityHeap's Iterator class and
  added new method to remove arbitrary elements from a heap.
- Added first version of Misc::TimerEventScheduler, a class to
  implement application-level timer events in GLMotif and Vrui.
- Added pointer to a Misc::TimerEventScheduler to GLMotif::WidgetManager
  so that GLMotif widgets have a way to schedule and react to timer
  events.
- Added a Misc::TimerEventScheduler to Vrui's kernel state, and a method
  to retrieve a pointer to the scheduler to Vrui's kernel API.
- Added application timer event handling to Vrui's main loop.
- Added click-repeat using timer events to GLMotif::Slider.
- Primed Vrui's frame timer calculation to start with 1s per frame
  instead of 0; should fix timing problems when applications use
  Vrui::getCurrentFrameTime() during the first few frames.
- Added synchronization function to Vrui's private API to allow a
  playback input device adapter to synchronize the sequence of Vrui
  frames exactly to its saved input device data.
- Added quitWhenDone flag to Vrui::InputDeviceAdapterPlayback to shut
  down the Vrui application when the end of input data is reached.
- Added synchronizePlayback flag to Vrui::InputDeviceAdapterPlayback
  to replicate the timing of the saved input data as closely as
  possible.
- Added Vrui/PrintInputDeviceDataFile.cpp, a utility program to dump
  input device data files in the format used by Vrui's playback input
  device adapter as human-readable text.
- Added a setting to throttle the frame rate of Vrui's main loop, mainly
  to reduce the amount of input device data written to file while
  recording a session, and to give the playback adapter breathing room
  to synchronize playback to recording even if the playback system is
  slower.
- Added requestScreenshot() method to Vrui::VRWindow to support movie
  export from within a playback input device adapter.
- Added movie export facility to playback input device adapter; users
  can specify a filename template for the resulting frames, and an
  export frame rate. The exporter will take great care to take
  screenshots at exactly the right times, even if Vrui's frame rate
  varies.
- Added new constructor to Geometry::Polygon class that creates a vertex
  array but does not initialize or copy the vertices.
- Added special handling for C escape sequences to
  Misc::ValueCoder<std::string>. Recognizes all C escape characters
  except octal and hexadecimal character codes.
- Fixed typo (signal instead of broadcast) in Threads::MutexCond.
- Improved handling of locks in Threads::MutexCond.
- Created new low-level sound library, primarily to support built-in
  recording and playback of audio commentary with Vrui's input device
  data saver and playback input device adapters.
- Made small improvements to Vrui build system.
- Brought Vrui HTML documentation up to date.
- Changed initialization of input device data saver in Vrui
  configuration file; settings for Vrui::InputDeviceDataSaver now read
  from its own separate configuration file section.
- Added automatic sound recording to Vrui::InputDeviceDataSaver.
- Added automatic sound playback to Vrui::InputDeviceAdapterPlayback.
- Added methods to create screens programmatically to Vrui::VRScreen.
- Added methods to create viewers programmatically to Vrui::Viewer.
- Added methods to override VR window's screen and viewer to
  Vrui::VRWindow.
- Created ScreenshotTool to take screenshots from inside immersive
  environments by using a virtual camera that overrides the screen and
  viewer of a selected window on the master node.
- Changed ALSA sound code in Sound::SoundRecorder and Sound::SoundPlayer
  to use older API version for backwards compatibility.
- Added forwarding VR device driver module to connect to VRPN servers.
  Initial version works with the VRPN streaming server in OptiTrack's
  rigid body toolkit, but has not been tested with any other VRPN
  servers due to lack of access.
- Disabled mouse events in VR windows when no mouse input device adapter
  is requested.
- Changed Vrui initialization order: Vrui's system menu is created after
  vislets and their parameters have been read from command line.
- Added active flag and activation methods to Vrui::Vislet base class.
- Added vislet submenu to Vrui's system menu to enable / disable vislets
  individually at run-time.
- Added enabling/disabling animation to Vrui CAVERenderer vislet.
- Fixed serious flaw in Comm::FdSet: file descriptor sets are now
  cleared if select or pselect are interrupted before any events occur.
- Behavior change in Realtime::AlarmTimer: Used to be that a non-expired
  timer could not be reset by arming it again; that was stupid. Now
  arming an already armed timer will reset its expiration time.
  armTimer() still returns false if the timer could not be armed for
  whatever reason.
- Added VR device driver for Nintendo Wii controller to distribution;
  gets built when the FindLibrary.sh scripts detects a user-level
  Bluetooth library in either /usr or /usr/local.
- DeviceTest no longer prints any tracking information if no trackers
  are present.
- Vrui screenshot tool now keeps virtual screen and main viewer
  orthogonal to always create on-axis screenshots; what you see through
  the frame is exactly what you get.
- Removed pad flag from GLMotif::Margin class and added independent
  horizontal and vertical stretching modes.
- Added click-repeat behavior to GLMotif::ScrollBar.
- Increased click-repeat speed for GLMotif::Slider and
  GLMotif::ScrollBar to 0.5s for first repeat, then 0.1s.
- Fixed two serious bugs in Vrui kernel: 1: slave nodes must not test
  Vrui event pipe (it only exists on master); 2: slave nodes must
  always run in continuous update mode (they always block on master
  node update).
- Added -rootSection option to VRDeviceDaemon to specify which
  configuration file section to use.
- Added option to flip Z components of positions to VRPNClient VR device
  driver module to fix left-handed coordinate systems on the server
  side.
- Added flag to enable interactive resizing to GLMotif::PopupWindow. If
  enabled (currently the default for testing), users can resize windows
  by dragging their borders.
- Split GLMotif::ListBox widget into two parts: basic list box without
  scroll bars, and ScrolledListBox compound widget to implement basic
  scrolling behavior.
- Created helper GLMotif::Alignment structure to store horizontal and
  vertical alignments for objects inside larger frames.
- Changed API of GLMotif::Margin to use new GLMotif::Alignment
  structure.
- Added per-row and per-column expansion weights and grid alignment to
  GLMotif::RowColumn class. Default behavior identical to previous
  version.
- Created compound GLMotif::ScrolledListBox class.
- Added getChildRow() and getChildColumn() methods to
  GLMotif::RowColumn.
- Updated Vrui configuration file to simplify the steps required to get
  a desktop input device such as a space ball to work.
- Did some updates and fixes in the Vrui HTML documentation.
- Added method to remove an entire row or column (for vertical or
  horizontal orientations, respectively) of widgets from to
  GLMotif::RowColumn.
- Added setTime() and getTime() methods to GLMotif::WidgetManager to
  allow widgets to implement time-dependent behavior in a portable and
  cluster-compatible manner.
- Added double-click behavior to GLMotif::ListBox; double click timeout
  currently hardcoded to 0.25 seconds.
- Added getBorderType() method to GLMotif::Widget.
- Added methods to get/set the armed background color to GLMotif::Button
  and made it safe to change a button's background color while armed.
- Made most set... methods of GLMotif::Widget virtual.
- Added methods to query the number of list items and to add another
  list item to GLMotif::DropdownBox.
- Added methods to query margin width and spacing to GLMotif::RowColumn.
- Added a standard file selection dialog to GLMotif.
- Added deleteWidget() method to GLMotif::WidgetManager to safely delete
  widgets even when called from inside a callback reacting to the same
  widget.
- "Load View" button in Vrui system menu now brings up a file selection
  dialog to select a previously saved viewpoint file.
- Added class GLMotif::Separator to visually separate adjacent
  components in widget layouts.
- Split resizing flag in GLMotif::PopupWindow to separately toggle
  horizontal and vertical resizing.
- Improved layout of Vrui measurement tool dialog.
- Changed default alignment of GLMotif::Label to left.
- Changed default alignment of GLMotif radio button toggles to left.
- Changed default menu entry border width to zero in
  GLMotif::StyleSheet.
- Made GLMotif::FileSelectionDialog cluster-aware to work in the
  presence of differing file systems on master and slave nodes.
- Added new dependency for Comm library to GLMotif (incurred by cluster-
  awareness in GLMotif::FileSelectionDialog).
- Added code to synchronize changes to Vrui's navigation transformation
  and/or display center or size across clusters, mainly to allow panning
  and navigating windows on the master node of a cluster.
- Changed Vrui to load viewpoint file only on master node; automatic
  synchronization takes care of rest of cluster.
- Created Misc::StringMarshaller class to simplify sending strings
  across pipes represented by classes that support typed templatized
  reads and writes.
- Added methods to send and retrieve entire configuration files across
  arbitrary pipes supporting typed templatized read and write methods.
- Changed Vrui initialization code to send the Vrui configuration file
  from the master node to all slave nodes to get around problem of
  mismatching configuration files.
- Changed Vrui build system to better deal with missing OpenAL library
  on host system.
- Fixed code opening configuration file in VRDeviceDaemon to work with
  the updated Misc::ConfigurationFile class.
- Moved tool kill zone in default desktop configuration to lower-left
  corner of window to make life easier for Mac users.
- Slightly improved "interleaved viewport" stereo rendering mode (for 3D
  TVs) by using only a single framebuffer object and off-screen
  rendering pass.
- Added pseudo target to print configuration options to makefile.
- Added template configuration file section for Nintendo Wii controller
  to VRDevices.cfg.
- Added ability to define device glyphs to
  Vrui::InputDeviceAdapterPlayback.
- Inserted missing semicolon after class declaration of
  Misc::RefCounted.
- Fixed broken type conversions in Misc::Autopointer.
- Added missing #include <stdlib.h> to Misc/FileLocator.cpp. For some
  reason, this never caused an error.
- Fixed z axis flipping in VRDeviceDaemon/VRPNConnection.cpp; now
  properly flips orientation.
- Added missing include file string.h to VRDeviceDaemon/VRFactory.cpp.
- Adapted all templatized classes to conform to g++ 4.3.x's
  interpretation of the C++ standard.

Vrui-1.0-054:
- Added missing #include <string.h> to Misc/MemMappedFile.h.
- Fixed missing button initialization in
  VRDeviceDaemon/VRDeviceManager.cpp.
- Temporarily disabled position/orientation sanity checking in
  VRDeviceDaemon/VRPNClient.cpp.
- Added function canReadImageFileType to Images/ReadImageFile.h to check
  whether the readImageFile function supports the image's file type.
- Added hack to VRDeviceDaemon/VRFactory.cpp to get around compiler
  warnings for function pointers from DSOs.
- Added transposed matrix multiplication methods (from right and left)
  to class Geometry::Matrix.
- Fixed bug in DeviceTest: Didn't print valuator data when no trackers
  are present.
- Added templatized image file reader class for IFF image files.
- Added existing templatized image file reader classes to makefile.
- Added method to compile shaders from strings to class GLShader.
- Added methods to rotate and/or scale around a given pivot point to
  transformation classes in namespace Geometry.
- Added method to query the exact length of the last frame to Vrui
  kernel interface.
- Improved axis converters in HIDDevice VRDeviceDaemon module; can now
  easily invert axis direction and map axes to half-valuators.
- Fixed scaling pivot bug in DesktopDeviceNavigationTool.
- Fixed bug in error recovery in Vrui::InputDeviceAdapterIndexMap; now
  fails with proper error message if input devices are misconfigured.
- Added prototype of "revolver tool" to map multiple virtual buttons to
  a pair of input device buttons (action button, revolve button).
- Made ALSA requirement in Sound library optional; sound recording /
  playback will silently fail under Linux if the ALSA development
  packages are not installed on the host system.

Vrui-1.0-055:
- Improved picking algorithm and increased button size in
  Vrui::VirtualInputDevice to simplify interacting with virtual input
  devices especially in fully-immersive VR environments.
- Re-enabled position/orientation sanity checks in VRPNClient VR device
  driver module.
- Removed several warnings when compiling with g++ 4.3.2.
- Added revolver tool to list of Vrui tools in makefile; leftover bug
  from previous version. Caused failure to run any Vrui application.

Vrui-1.0-056:
- Provided several device access convenience functions in Vrui::Tool to
  slightly simplify tool development. Changed existing tool classes to
  use new convenience functions where appropriate.
- Moved handling of eye ray vs device ray into Vrui::UserInterfaceTool
  base class to get uniform behavior between all user interface tool
  classes.
- Removed warning messages when compiling with g++ 4.3.x from
  VRDeviceDaemon modules.
- Removed all warnings but one tough one from main Vrui when compiling
  with g++ 4.3.2.
- Overhauled A.R.T. DTrack VR device driver module to deal with the
  flexibility of new wireless DTrack devices (that can now have buttons
  and/or valuators), and the ASCII data format that is required to get
  button and valuator information. Stupidly, A.R.T. doesn't provide a
  binary format to get at the new bits. And, they obsoleted the Euler
  angle format in favor of full 3x3 matrices, the idiots.
- Added image file reader classes to makefile installation.
- Fixed bugs in Images::PNMImageFileReader and added it to makefile.
- Fixed CAVERenderer vislet so that it does actually turn viewers'
  headlights on/off as needed.
- Added methods to Vrui::ToolManager to query whether a given button or
  valuator on a given device has a "real" tool assigned (as opposed to a
  tool selection tool).
- Improved Vrui TransformTool base class to disable derived classes'
  transformation when an unassigned button is pressed, so that
  transformation does not interfere with tool selection.
- Fixed OpenGL state bug in Vrui::JediTool; now works properly with
  interleaved stereo on 3D TVs.
- Added multithreaded tree generation to Geometry::ArrayKdTree class.
  Uses only naive parallelization, but realizes decent speed-ups on
  large point sets.
- Added ScaleNavigationTool to be able to implement
  WandNavigationTool's navigation method using two independent buttons.
- Changed Vrui initialization to try both HOSTNAME and HOST (in that
  order) to determine the default root section name.
- API change in Geometry::Box: declared min and max public and removed
  all getMin / getMax accessor functions. Rationale: min and max have
  no invariants, and are not an implementation detail.
- Added missing error checking to array-based write() methods in
  Misc::File and Misc::LargeFile. Now throws a write error if the total
  number of bytes actually written does not match the expected number.
- Minor cleanup in Vrui initialization to improve robustness.
- Fixed error check in Misc::File and Misc::LargeFile.
- Added Misc/FileNameExtensions containing several helper functions to
  extract and match extensions from path / file names; might get
  extended to do additional file name processing in the future.
- Changed Sound::SoundPlayer and Sound::SoundRecorder to use new file
  name extension helper functions.
- Added new flags to Vrui::ValuatorFlyTurnNavigationTool to switch
  between flying/rotating in physical space vs device space. Settings
  default to all points / vectors given in device space.
- Overhauled Threads::TripleBuffer class; now it's actually useful!
- Added read/write buffering to Comm::TCPPipe, which greatly increases
  performance. Important: do no longer enable TCP corking on
  Comm::TCPPipe since it interferes with the new, better stream handling
  algorithm. To be safe, Comm::TCPPipe overrides setCork(bool) with a
  dummy method.
- Changed Comm::ClusterPipe class in the same way as Comm::TCPPipe. Now
  uses read/write buffers on the cluster's master node, and preemptively
  forwards data from master node to slave nodes on reads. Makes explicit
  flushRead() method obsolete, which is a Very Good Thing.
- Changed API of Comm::ClusterPipe: flushRead was made obsolete by
  latest change and is now gone; flushWrite was renamed to flush to make
  the ClusterPipe API template-compatible with the Comm::TCPPipe API.
- Added proper handling of getPeerPortId, getPeerAddress, and
  getPeerHostname to Comm::ClusterPipe. Change implies that these
  functions have to be called by all cluster nodes synchronously.
- Added initial support for gathering operations to Comm::MulticastPipe.
  A gathering operation collects values from all nodes (master and
  slaves) in a multicast pipe, and applies a selected accumulation
  operation on all values. The result of that accumulation is shared
  with all nodes. Implies a barrier.
- Added Comm/GatheringOperation.h, containing a class defining the valid
  gathering operations as opcodes.
- Fixed one-off bug in Math::randUniformCC(int min,int max); now all
  values in the integer range [min, max] (both inclusive) have the same
  probability. Math::randUniformCC(min,max) is thus synonymous with
  Math::randUniformCO(min,max+1).
- Added Misc/StringHashFunctions.h, defining a specialization of
  Misc::StandardHashFunction for std::string, and a new
  Misc::StringHashFunction class for C strings.
- Added ConstIterator class to Misc::HashTable.
- Added conservative intersection tests for axis-aligned boxes and
  spheres to GLFrustum class.
- Added OpenGL extension classes for GL_ARB_geometry_shader4 and
  GL_EXT_geometry_shader4 (original code supplied by Tony Bernardin).
- Added GLGeometryShader class to allow linking GLSL geometry shaders
  into shader programs. Implemented as a child class of GLShader to get
  around weighing down the latter with as-yet not widely supported
  geometry shader baggage (original code supplied by Tony Bernardin).
- Added readRaw method to Comm::TCPPipe. Shadows Comm::TCPSocket's
  read method; blocks until at least a single byte is available, and
  then returns as much data as is currently available up to the request
  size.
- Added getBufferSize method to Comm::TCPPipe to query the size of the
  internal read/write buffers. Good for efficient data forwarding while
  still enjoying the benefits of buffered typed read/writes.
- Added readRaw and getBufferSize methods to Comm::ClusterPipe to mirror
  Comm::TCPPipe.
- Improved handling of plug-in install paths (Tools, Vislets, VRDevices,
  VRCalibrators) in makefile and fixed wrong path in generated Vrui
  makefile fragment.
- Upped precision in default conversion for Misc::ValueCoder
  specializations for float and double values. Floats are now printed
  with 7, and doubles with 14 significant digits.
- Added global sleep() function to Misc/Time.h.
- Added error handling to destructors of Comm::TCPPipe and
  Comm::ClusterPipe. Problem was that the implicit flush operation
  would throw another exception if a pipe was destroyed in response to
  a previous pipe error. Now the destructors make a best-effort attempt
  to flush and fail silently in case of errors.
- Added VRUI_LIBDIR variable to Vrui makefile fragment to simplify
  developing higher-level libraries to install with Vrui itself.
- Renamed PACKAGEROOT in all build system files to VRUIPACKAGEROOT to
  simplify developing higher-level libraries based on Vrui.

Vrui-1.0-057:
- Fixed stupidest copypasta error ever: created GLARBGeometryShader4
  OpenGL extension class from GLEXTGeometryShader4, and replaced EXT by
  ARB. Result: TEXTURE became TARBURE.
- Added abstraction class for ALSA PCM devices to Sound library.
- Changed Sound::SoundRecorder and Sound::SoundPlayer to use the ALSA
  PCM device abstraction class.
- Added convenience function to set "standard" sample formats to
  Sound::SoundDataFormat.

Vrui-1.0-058:
- Fixed slight typo in Realtime::AlarmTimer, didn't have an actual bad
  effect since it was an alias from struct siginfo to its typedef
  siginfo_t.
- Removed obsolete tool classes JoystickNavigationTool and
  SpaceBallNavigationTool -- functionality of both has been generalized
  by DesktopDeviceNavigationTool for a long time.
- Added new base tool class PointingTool for tools used to point out
  features or locations in a 3D environment.
- Moved InputDeviceTool base class into Vrui library itself.
- Replaced obsolete SpaceBallTool with new DesktopDeviceTool; has same
  functionality as DesktopDeviceNavigationTool, minus the navigation
  part.
- Moved LaserpointerTool, JediTool and FlashlightTool Vrui tool classes
  to be derived from PointingTool.
- Added getName() method to all tool classes to allow returning a
  descriptive tool name for menus and other user-facing lists as
  replacement for the somewhat unreadable tool class name.
- Changed default settings of many Vrui tool classes to the settings
  most often used in actual environments; cleaned up Vrui configuration
  file by removing default settings.
- Removed sections for dead IDAV VR environments from Vrui configuration
  file: Immersive Workbench, non-stereoscopic Powerwall.
- Changed constructor of GLMotif::FileSelectionDialog: can now take
  comma-separated list of individual file name filters which will make
  up individual entries in the drop-down box.
- Changed addFileNameFilters method in GLMotif::FileSelectionDialog: can
  now take comma-separated list of filters just like constructor.
- Changed Vrui's ViewpointFileNavigationTool: if no curve file name is
  specified in the Vrui configuration file, the tool will pop up a file
  selection dialog to load a curve file on creation.
- Added VRUI_VERSION variable to Vrui makefile fragment so that
  dependent software can warn users about requirement violations -- or
  to allow dependent software to adapt.
- Added new argument to Vrui::GenericToolFactory constructor to set a
  display name for the described tool class.
- Added dependency on PTHREADS to MYGEOMETRY in BuildRoot/Packages;
  became necessary due to new multithreaded kd-tree generation method.
- Consolidated extensions of files generated by Vrui:
  .view: Binary environment-independent viewpoint file
  .views: ASCII environment-independent multi-viewpoint file (generated
          by ViewpointFileSaverTool to use as animation keyframes)
  .curve: Cubic spline curve generated by CurveEditorTool, to use as
          viewpoint animation curve
- Changed ViewpointFileNavigationTool to read either a .views file and
  auto-generated a C^2-continuous spline curve, or read a .curve file
  and use the contained spline unchanged.
- Fixed another copypasta bug in GL/Extensions/GLARBGeometryShader4.h.
- Added a non-const getEntry() method to Misc::HashTable which allows
  modifying the value of the returned hash table key/value pair.
- Added parametrization by element type to Misc::OrderedType and
  Misc::UnorderedTuple.
- Fixed long-standing makefile bug in the part that creates a runwithx
  script for pre-Leopard Mac OS X, somehow nobody complained until just
  now. The script is obsolete anyways since Leopard auto-starts X when
  running an X application. Yay!
- Removed set() method from Misc::UnorderedTuple, because it was an API
  failure -- the tuple would be re-sorted after every set(), causing a
  sequence of set() operations to create a tuple incrementally to fail
  in the weirdest ways. Unordered tuples can only be set atomically.
- Added class Misc::ASCIIFileReader to efficiently read from ASCII input
  files. Supports on-the-fly gunzipping, and memory-mapped file I/O.
- Added dependency on ZLIB to Misc library to support on-the-fly
  gunzipping in Misc::ASCIIFileReader.
- Added Threads::ASCIIFileReader class to mirror the behavior of
  Misc::ASCIIFileReader. Uses a background thread to read ahead in the
  input file, hopefully maximizing throughput.
- This now creates an actual libThreads library file; updated
  BuildRoot/Packages to reflect that.
- Added Threads::RingBuffer class to support in-memory pipes between a
  producer thread and a consumer thread.
- Added Threads::DropoutBuffer class as a generalization of the triple
  buffer communication pattern. The buffer retains up to a preset
  number of most recent elements for a consumer to read.
- Changed Misc::ConfigurationFile API: Added methods to create empty
  configuration file to simplify client code; changed load() method to
  take a file name as argument; added reload() method replacing the old
  load() method.
- Added Misc/FunctionCalls.h containing a first attempt at representing
  function calls or method invocations as first-class variables.
- Changed destruction behavior of GLMotif::Popup and
  GLMotif::PopupWindow. Top-level widgets now automatically unmanage
  themselves (pop down) when they are destroyed.
- Changed behavior of GLMotif::ListBox: if the selected item is removed,
  the next item will be selected, or the previous one at the end of the
  list.
- Created Vrui::DisplayState, a helper class to query per-display Vrui
  rendering state (window/screen/viewer, eye position, etc.) from within
  a display method during rendering. Stand-in until a real solution
  turns up at some point in the future.
- Added new getDisplayState() function to Vrui kernel API, which can be
  called from inside a display method and returns Vrui display state
  valid for that particular method invocation.
- Fixed a couple of bugs pointed out by Ed Puckett:
  - = instead of == in Geometry::HVector::isVector().
	- Missing cast to char* in Misc::PriorityHeap::~PriorityHeap().
	- Missing include Geometry/Vector.h in Vrui/VirtualInputDevice.h.
	- Missing include Geometry/Point.h, Geometry/Ray.h, and
    Vrui/Geometry.h in Vrui/VRWindow.h.
- Added floating-point classification functions to Math/Math.h in order
  to deprecate the use of the is...() macros in math.h.
- Reorganized code in Math/Math.h a little.
- Changed code in Geometry/Rotation.h to use the Math::isNan function
  instead of the isnan() macro.
- Changed code in Vrui/Tools/DenseMatrix.cpp to use the Math::isNan
  function.
- Removed dangerous assert() calls from Vrui/Tools/DenseMatrix.cpp.
- Fixed #include inside namespace in GLMotif/Separator.h (pointed out
  by Ed Puckett).
- Added getcLookAhead method to Misc::ASCIIFileReader.
- Changed Misc::ASCIIFileReader::readNextToken to skip whitespace before
  reading the next token.
- Added getVislet method to Vrui::VisletManager.
- Added new high-performance ASCII file reader classes to Misc library:
  CharacterSource, FileCharacterSource, GzippedFileCharacterSource,
  TokenSource.
- Added new high-performance ASCII file reader class to Comm library:
  ClusterFileCharacterSource.
- Added experimental header file Comm/Clusterize.h with helper functions
  to distribute an application over a cluster, and initialize
  communication using a Comm::MulticastPipeMultiplexer.
- Fixed bug in vislet parameter list processing (pointed out by Ed
  Puckett).
- Added Misc/StringPrintf.h defining a function to print into a C++
  string using a printf-style interface.
- Changed handling of modelview matrices in Vrui OpenGL display code to
  reduce effects of OpenGL's single-precision floating-point format on
  rendering accuracy when displaying small objects far away from the
  global coordinate system's origin. Detail changes:
  - Added state to store full modelview matrices for physical and
    navigational coordinates to Vrui::DisplayState.
  - Changed Vrui::VRWindow to compute full modelview matrices for both
    spaces and store them in the window's DisplayState object.
  - Changed Vrui's main display method to use the modelview matrices
    stored by VRWindow.
  - Changed Vrui::LightsourceManager to use modelview matrices from
    DisplayState object when setting navigational light sources.
  - Changed Vrui's MeasurementTool to use modelview matrices from
    DisplayState object when displaying markers for measurements in
    navigational coordinates.
  - Changed Vrui's CurveEditorTool to use modelview matrices in
    DisplayState object.

Vrui-1.0-059:
- Added GLGeometry::Vertex, an analogon to GLVertex using geometry
  types from the geometry library.
- Added dependency on Vrui dynamic library to all Vrui tools and vislets
  to enable using them from a program not linked with -rdynamic, such as
  for example a Python run-time environment.

Vrui-1.0-060:
- Fixed type problem in GLGeometry::Vertex; Position in one specialized
  type was defined as a vector.
- Created Vrui::MouseSurfaceNavigationTool, a tool class for easy
  navigation on DEMs and virtual globes. Interacts with applications via
  an align() callback function that limits the tool's local navigation
  frame to an application-defined surface.
- Started changing include file order in some sources; new style is to
  include Foo.h from Foo.cpp before any other headers, to simplify
  finding missing include files in headers.
- Added Geometry::Geoid class, to bundle all that nasty math to convert
  between different geodesic coordinate systems in one handy place.
- Added convenience creation functions to Misc/FunctionCalls.h, but
  admittedly, they're not all that convenient.
- Created Vrui::WalkSurfaceNavigationTool, a navigation tool that uses a
  walking metaphor to navigate along an application-defined surface.
- Added new method loadToolBinding to Vrui::ToolManager, to allow Vrui
  or applications to load tool bindings on demand, using the same
  configuration method as for the default bindings listed in toolNames.
- Added three new command line options to Vrui:
  - -mergeConfig <configuration file name>
    Merges another configuration file into Vrui's configuration. Options
    are processed in order, after the global and user configuration
    files have already been merged.
  - -addToolClass <tool class name>
    Adds a tool class to the list of available tools, just like adding
    <tool class name> to the toolClassNames configuration file setting.
  - -addTool <tool binding section name>
    Adds a tool binding to the list of default tools, just like adding
    <tool binding section name> to the toolNames configuration file
    setting.
- Overhauled error messages during Vrui's initialization; particularly,
  added more detail to tool binding errors to aid in configuration file
  debugging.

Vrui-1.0-061:
- Added "navigation mode" to virtual input devices, which can be toggled
  with a new button rendered underneath the input device's glyph. In
  navigation mode, the input device will move with the navigation
  transformation, and in effect act as an application-level dragger.
- Changed handling of Vrui's navigation transformation: during
  initialization, particularly from inside an application's constructor,
  changes to the navigation transformation take effect right away.
  Starting with the initDisplay() call, changes are delayed to the next
  frame as before.
- Added default tool factory destructor method to Vrui::ToolManager; can
  be used by applications to delete their custom tool factories.
- Added base class for application-specific tools to Vrui::Application,
  greatly reduces the amount of code necessary to create and manage tool
  classes that need to refer back to the application object owning them.
- Changes VruiCustomToolDemo example program to use the new tool base
  class from Vrui::Application.
- Added basic standard output operators for geometry classes in
  Geometry/OutputOperators.h.
- Added missing #include <stdio.h> in some files; were not noticed
  before g++ 4.4.0.
- Added encoder and decoder classes for geometry matrices and affine and
  projective transformations to Geometry/GeometryValueCoders.
- Added support for off-axis projectors to Vrui screen and window
  management, controlled by specifying an optional homography matrix in
  a screen's configuration file section. 3x3 homographies are extended
  to 3D and applied to the OpenGL projection matrix before the frustum
  projection.
  - Added offAxis flag and homography matrix to Vrui::VRScreen.
  - Added boolean offAxis setting and 3x3 matrix homography setting to
    screens' recognized configuration file settings.
  - Changed Vrui::VRWindow to apply homography matrix for off-axis
    screens when creating a window's projection matrix.
  - Changed Vrui::VRWindow to apply homography matrix for off-axis
    screens when reprojecting a window position into model space.
- Changed Vrui::InputDeviceAdapterMouse such that modifier keys also
  apply to the mouse wheel valuator.
- Changed Misc::ConfigurationFile to ignore comments and whitespace at
  the end of lines read from a configuration file; paves the way for
  some simplifications in the future. No more quotes around section
  names starting in the next release.
- Fixed a problem with Sound library: SOUND_USE_ALSA was only defined
  while building the library itself, not client code depending on it.
  Added -DSOUND_USE_ALSA to MYSOUND_CFLAGS in BuildRoot/Packages.
- Fixed stupid bug in MouseSurfaceNavigationTool's widget dragging
  behavior; now works as it should.
- Added helper class Vrui::MouseCursorFaker to render a fake mouse
  cursor in cases where there is no hardware cursor, or it is
  inappropriate.
- Changed Vrui::InputDeviceAdapterMouse to render a fake mouse cursor if
  requested.
- Changed Vrui::InputDeviceAdapterPlayback to render a fake mouse cursor
  if requested.
- Removed option to render fake mouse cursors from diverse mouse
  navigation tools.
- Added virtual compass to Vrui::MouseSurfaceNavigationTool.

Vrui-1.0-062:
- Fixed up cosmetics in Vrui::MouseSurfaceNavigationTool's virtual
  compass.
- Changed API of GLMotif::ListBox to allow multiple selections.
  Dependent changes:
  - Changed constructor to take selection mode; removed method to change
    selection mode after construction.
  - Added new callbacks and callback data classes.
  - Added new methods to query and change set of selected list items.
- Changed constructor of GLMotif::ScrolledListBox to take selection mode
  argument.
- Changed GLMotif::FileSelectionBox to use new ListBox API.
- Added temporary guard against using direct calls to floating-point
  number classification functions (isnan etc.) on Mac OS X, until I
  figure out what the hell Apple broke now.

Vrui-1.0-063:
- Added definitions for static constant data members to template classes
  in Math and Geometry libraries to simplify the life of people who want
  to use them with non-C++ user code.
- Fixed some problems in template friend function instantiations for
  same reason.
- Added Misc::ValueSource, a class to read strings or numbers from ASCII
  files represented by CharacterSource objects. Obsoletes the various
  versions of ASCIIFileReader.
- Removed Misc::ASCIIFileReader; obsoleted by Misc::ValueSource.
- Removed Threads::ASCIIFileReader; obsoleted by Misc::ValueSource.
- Added class Misc::XBaseTable to read from database tables in XBase
  (dBASE III, FoxPro, Clipper,...) format.
- Changed makefile to use relative paths when creating symbolic links
  for generated libraries (suggested by Jordan Van Aalsburg).
- Changed makefile to remove generated Vrui makefile fragment's
  dependency on makefile itself; probably not dangerous, but simplifies
  building Vrui for one installation directory, and then temporarily
  installing it elsewhere (to create an RPM or Debian package, for
  example).
- Changed implementation of Misc::TokenSource to be more in line with
  Misc::ValueSource.
- Added skipString() method to Misc::ValueSource.
- Changed VruiCustomToolDemo example program; added clarification that
  the custom tool class requires two buttons to bind.
- Added PCACalculator class from LiDAR Viewer to Geometry library.
- Removed use of EOF from Misc/MemMappedFile.h, directly using -1 now.
- Added option to save triggered and averaged point measurements to
  DeviceTest program.
- Added AlignTrackingMarkers, a utility program to calibrate rigid
  bodies from definition files in the format written by the NaturalPoint
  Optitrack rigid body toolkit.
- Removed Vrui/Lightsource.cpp by inlining all methods; were trivial
  anyways.
- Added classes Vrui::ClipPlane and Vrui::ClipPlaneManager to manage
  OpenGL clipping planes as part of Vrui state.
- Added function to retrieve clipping plane manager to Vrui kernel API.
- Added code to Vrui's display function to set up clipping planes before
  calling the application's display function.
- Fixed bug in Vrui::LightsourceManager that overrode physical light
  sources with navigational light sources if both were defined.
- Fixed base class initialization bug in Vrui:FlashlightTool.
- Added Vrui::ClipPlaneTool to interactively add clipping planes to an
  environment.
- Fixed bug in Vrui::Application; application object's tool manager
  callbacks are now installed from inside the constructor as opposed to
  from inside the run() method, to catch creation of application-
  specific tools from within an application's constructor.
- Added getBuffer method to Threads::TripleBuffer to provide a low-level
  access point to the buffer values bypassing the locking scheme.
- Added new class GLMotif::NewButton to move towards a new and improved
  inheritance tree for button widgets. New button widget is a container
  that can pop in/out arbitrary child widgets. Contains convenience
  constructors to create "blind" buttons and label buttons.
- Added Threads::GzippedFileCharacterSource, a class to read gzip-
  compressed files with readahead and background decompression.
- Added option to list link flags with packages to
  BuildRoot/BasicMakefile.

Vrui-1.0-064:
- Added methods to print TranslationTransformation and
  RotationTransformation objects to Geometry/OutputOperators.
- Fixed minor formatting bug in Geometry/OutputOperators.
- Added Plugins::ObjectLoader, a light-weight class to load objects
  from DSOs without the code overhead induced by
  Plugins::FactoryManager.
- Isolated the evil dlsym function pointer hack into
  Plugins/FunctionPointerHack.h for sanity.
- Added getEntries() methods to Geometry::Matrix to get access to
  entries as row-major array.
- Added OpenGL extension class for GL_ARB_texture_float.
- Added calcOffset() method to Misc::ArrayIndex.
- Added calcIndex() method to Misc::ArrayIndex.
- Added functions to read TIFF images in a variety of formats to Images
  library.
- Changed build system to optionally support the libtiff TIFF image
  library. Support is advertised to applications via defining the
  IMAGES_HAVE_TIFF macro.
- Added a new input device tool to snap virtual input devices to planes
  defined by three points in navigational coordinates.

Vrui-1.0-065:
- Templatized Geometry::PCACalculator by dimension and provided
  implementation for 2D and 3D PCA.
- Fixed Vrui::LightsourceManager to properly handle a mix of physical
  and navigational light sources.
- Changed Vrui::ClutchTool to provide a saner user interface.
- Added missing dependency on MYTHREADS to MYSCENEGRAPH package.

Vrui-1.0-066:
- Added sketching tool to interactively create and edit polylines.
- Added Plugins::FactoryManager::releaseClass method to selectively
  unregister plugin classes by name; sometimes required to control
  destruction order.
- Added std::string interface to Misc::createNumberedFileName.
- Added default callback to GLMotif::FileSelectionDialog that simply
  closes the dialog when added to OK or cancel callback list.
- Added several programs to aid in VR environment calibration to the
  Calibration subdirectory.
- Fixed bug in TIFF image reader in Images::readImageFile.
- Removed final warning when building Vrui under Ubuntu.
- Added methods to lock / unlock the queue for delayed reading to
  Threads::DropoutBuffer; was required for idempotent read access to
  buffer.

Vrui-1.0-067:
- Fixed bug in baud rate setting in Comm::SerialPort::setSerialSettings
  and improved error checking in many methods.
- Removed optional desktop input devices from Vrui.cfg and split them
  into separate patch configuration files for 3Dconnexion SpaceBall
  4000FLX, Logitech/3Dconnexion SpaceTraveler, and Logitech Wingman
  Extreme 3D Pro.
- Added configurations for same desktop device types to VRDevices.cfg.
- Provided default values for essential settings in
  Vrui::DesktopDeviceTool and Vrui::DesktopDeviceNavigationTool to
  allow advertising the tool classes without specific configuration
  sections.
- Added new input device adapter type Vrui::InputDeviceAdapterJoystick
  to directly connect to desktop input devices such as joysticks,
  gamepads, or spaceballs without a VR device daemon. Currently only
  works on Linux using the joystick API.
- Added Mac OS X support for Vrui::InputDeviceAdapterJoystick using the
  IOKit HID API.
- Fixed printf type mismatches in VRDeviceDaemon/HIDDevice.MacOSX.cpp.
- Removed macro definition of GL_GLEXT_PROTOTYPES from
  BuildRoot/Packages for Mac OS X 10.6.
- Fixed version detection code for Mac OS X.
- Added new class Math::BrokenLine to simplify range mappings as used in
  joysticks and other HID input devices.

Vrui-1.0-068:
- Fixed regression bug in VRDeviceDaemon's ViconTarsus and
  ViconTarsusRaw modules: did not flush TCP pipe after writing request
  packets.
- Fixed syntax error in optional code in VRDeviceDaemon's
  PolhemusFastrak module.
- Added methods to query unit names to Vrui::CoordinateTransformation.
- Added unit display to measurement tool.
- Added Vrui::GenericAbstractToolFactory, a templatized factory class
  for tool classes that only serve as base classes and are never
  instantiated.
- Simplified naming scheme in default Vrui.cfg configuration file. For
  example, Desktop/DesktopWindow is now just Desktop/Window.
- Added section for IDAV VR lab's low-cost 3D TV environment to default
  Vrui.cfg configuration file.
- Added Comm::TCPSocketCharacterSource, a character source wrapper for
  TCP sockets. Does not currently include code to detect end-of-file
  conditions arising when the remote socket disconnects, 'cuz that's
  kinda hard.
- Defined a file name insert for OS-specific implementations of cross-
  platform classes as OSSPECFILEINSERT in BuildRoot/SystemDefinitions.
  Defaults to Linux on Linux and MacOSX on Mac OSX.
- Changed makefile to always enable support for OpenAL when building
  under Mac OSX, since OpenAL seems to be a standard package now.
- Added new support library for MacOSX, currently only containing
  MacOSX::AutoRef, a wrapper class to simplify managing Core Foundation
  object references.
- Removed Vrui::InputDeviceAdapterJoystick and replaced it with
  Vrui::InputDeviceAdapterHID, using the same HID interface on Mac OSX
  and the event HID interface instead of the joystick interface on
  Linux.
- Fixed typo in VRDeviceDaemon/HIDDevice.Linux.cpp that led to a
  segfault when encountering devices with relative axes.
- Changed socket initialization code in VRDeviceDaemon/Wiimote.cpp to
  work with newer versions of the bluez bluetooth library.
- Removed some unused #includes from Vrui/Vrui.Workbench.cpp.
- Improved Vrui event loop such that Vrui instances which open a display
  window can once again run as background processes.
- Added type-inferring wrapper functions for selected OpenAL API calls
  as AL/ALTemplates.h.
- Added wrappers to call selected OpenAL API calls with templatized
  geometry types to AL/ALGeometryWrappers.h.
- Added "modelview" stack management to ALContextData class to get
  OpenAL model rendering in line with OpenGL rendering.
- Added normalization of listenDirection and upDirection vectors to
  Vrui::Listener's initialization function.
- Changed handling of sound when OpenAL is not supported; should not
  change application processing.
- Added important OpenAL parameters to Vrui::SoundContext and
  Vrui::Listener classes and their configuration file sections.
- Added functions to query number of sound contexts and return sound
  context pointers to Vrui kernel API.
- Added proper handling of navigation transformation to VruiState::sound
  method.
- Added overall gain factor to Vrui::Listener.
- Added listener and sound context sections to Desktop section in
  default Vrui configuration file.
- Improved error handling in Vrui's display and sound initialization
  routines.
- Fixed typo in Mac OS X version checking in BuildRoot/
  SystemDefinitions.
- Added a new "Dual-Ray Transform Tool" to locate 3D positions by
  specifying two non-collinear rays using a ray-based input device in
  a modal interaction sequence.
- Fixed copypasta bug in command line argument removal in
  Vrui/Vrui.Workbench.cpp that prohibited use of -mergeConfig and
  -rootSection options if not at the end of the command line. Found by
  Tony Bernardin.
- Reordered code in Vrui's main loop in Vrui/Vrui.Workbench.cpp; does
  not change functionality.

Vrui-2.0-001:
- Added flag to Vrui::popupPrimaryWidget to specify whether the given
  hot spot position is in physical or navigational coordinates.
  Parameter defaults to navigational, the previous setting.
- Added new position-less Vrui::popupPrimaryWidget method which uses a
  default position (environment center).
- Fixed nasty old bug in Vrui::ToolManager that caused crashes and
  strange behavior when deleting deeply-stacked transform tools and
  multi-button tools.
- Fixed rendering and layout bug in GLMotif::RowColumn when there are
  no children.
- Moved Earth images to proper resource directory in Vrui example
  programs.
- Added callbacks for widget pop-up and pop-down events to
  GLMotif::WidgetManager.
- Added iterator class to enumerate primary and secondary popped-up
  widgets to GLMotif::WidgetManager.
- Added configuration flag movePrimaryWidgets to Vrui::VRWindow, to move
  primary popped-up widgets along with the window when it is moved/
  resized.
- Added "Dialogs" submenu to Vrui's system menu which lists all
  currently popped-up dialog windows and can be used to show hidden
  dialogs and bring visible dialogs to the current input device
  position.
- Added new GLMotif::GlyphGadget class to bundle code related to drawing
  2.5D glyphs used by other widgets.
- Removed class GLMotif::Arrow; is replaced by GLMotif::GlyphGadget.
- Added GLMotif::Glyph, a widget class that contains only a 2.5D glyph.
- Added optional hide and close buttons to GLMotif::PopupWindow. Hide
  button is enabled by default.
- Added callbacks for window closure events to GLMotif::PopupWindow.
- Fixed bug that had GLMotif::WidgetManager considering hidden widgets
  when looking for an event recipient.
- Removed code to pop down deleted widgets in GLMotif::WidgetManager's
  deferred widget deletion method; top-level widgets pop themselves down
  via their destructors.
- Replaced GLMotif::Arrow class with GLMotif::GlyphGadget class in
  GLMotif::CascadeButton, GLMotif::DropdownBox, and GLMotif::ScrollBar.
- Added close button to GLMotif::FileSelectionDialog as an alternative
  to the Cancel button.
- Improved resizing behavior in GLMotif::SingleChildContainer to retain
  adjusted widget sizes if possible.
- Changed Vrui initialization / deinitialization sequence such that
  tools and Vrui's system menu are created right before mainLoop.
- Started adding text input capabilities to GLMotif library:
  - Added new classes GLMotif::TextEvent and GLMotif::TextControlEvent
    to represent text entry events.
  - Added virtual giveFocus and takeFocus methods to GLMotif::Widget, to
    give and take away text focus from a widget, respectively.
  - Added virtual textEvent and textControlEvent methods to
    GLMotif::Widget.
  - Added editable flag to GLMotif::TextField.
  - Added text and text control event behavior to GLMotif::TextField.
  - Added pointer event handling to GLMotif::TextField: single click
    moves cursor, double click selects entire text field content.
  - Added preliminary cursor drawing to GLMotif::TextField.
  - Added text focus management to GLMotif::WidgetManager.
  - Added text and text control event handling to
    GLMotif::WidgetManager.
  - Added cut & paste buffer handling to GLMotif::WidgetManager.
- Fixed bug in GLMotif::Widget::getManager() for parent-less widgets.
- Added functions to traverse widget hierarchies depth-first to
  GLMotif/WidgetAlgorithms.h.
- Added hash table to simplify and speed up matching of top-level
  widgets and their popup bindings.
- Added redundancy checks to popup and popdown methods in
  GLMotif::WidgetManager.
- Added text input capability to Vrui::InputDeviceAdapterMouse. Now has
  a toggle to switch the keyboard from virtual input device mode into
  regular keyboard mode.
- Added GLMotif::TextFieldSlider, a compound widget class consisting of
  a slider and a text field displaying the slider's current value.
- Improved layout algorithm in GLMotif::Label to clip the label to the
  current interior of the widget.
- Added multiClickTime field to GLMotif::StyleSheet, and changed
  GLMotif::ListBox and GLMotif::TextField to use it when checking for
  multi-clicks.
- Added calcCharacterPos method to GLFont to convert a string texture
  coordinate into a character index into the string, to convert pointer
  clicks or drags to cursor movements.
- Added calcCharacterTexCoord method to GLFont to convert a string
  character index into a texture position.
- Added accept() method to Comm::UDPSocket to simulate the connection
  behavior of a TCP socket. accept() assumes that the connecting caller
  sent a short (<256 bytes) connection establishment message, which will
  be discarded.
- Added class GLString to associate data with C-style strings that is
  required to draw such strings using texture-based fonts.
- Added class GLLabel to simplify drawing labels using texture-based
  fonts.
- Extensive changes to GLFont class to simplify use of strings and
  improve efficiency:
  - Replicated existing string-related methods to accept GLString
    objects to improve efficiency.
  - Added methods to only query the scaled size of strings.
  - Removed embedded GLFont::String class; same functionality is now
    available through new GLLabel class.
  - Moved formerly private methods taking texel and texture widths to
    public interface to enable efficient calculations in GLString and
    GLLabel.
- Changed GLMotif::Label to use a GLLabel object instead of managing
  string rendering itself.
  - Renamed former getLabel method to getString.
  - Created new getLabel method to return the GLLabel object.
  - Renamed former setLabel method to setString.
  - Changed implementation of the following classes to match new API:
    - GLMotif::TextFieldSlider
    - GLMotif::DropdownBox
    - GLMotif::PopupWindow
    - GLMotif::FileSelectionDialog
- Changed API of GLMotif::TextField to match new GLMotif::Label API by
  renaming setLabel method to setString.
- Fixed implementation of Vrui::MeasurementTool for new GLMotif::Label
  API.
- Fixed code of several Vrui example programs for new GLMotif::Label
  API.
- Created new daisy wheel tool for text entry in keyboard-less
  environments.
- Added code to Vrui::InputDeviceDataSaver and
  Vrui::InputDeviceAdapterPlayback to save Vrui's random number seed in
  input device files such that applications using random numbers can
  exactly be replicated from saved input device files.
- Added resetMatrixStack method to ALContextData class.
- Added sound() method to Vrui::Vislet to render OpenAL spatial sound.
- Added sound() method to Vrui::VisletManager to call the sound()
  methods of all active vislets.
- Added -DVRUI_HAVE_OPENAL to application compiler flags in
	Vrui.makeinclude if Vrui was compiled with OpenAL spatial sound
  support.
- Fixed Vrui::TransformTool to reset virtual device pointer to zero
  after destroying device (not really necessary, but better).
- Added virtual input device shadowing the zoom button to
  Vrui::WandNavigationTool, so that the zoom button can have a second
  function while the navigation tool is inactive.
- Removed deprecated features from Vrui initialization sequence to bring
  application behavior in line with vislet behavior and increase
  flexibility.
  - startDisplay() and startSound() functions no longer exposed to
    applications; are now called internally from mainLoop().
  - Global perDisplayInitFunction and perSoundInitFunction have been
    removed in favor of the GLObject / ALObject mechanism.
  - useSound() method in Vrui::Application has been removed.
  - Sound processing can now be requested by any entity by calling
    Vrui::requestSound at any point during initialization before
    mainLoop() is called.
- Changed GLMotif::RadioBox to optimize the sequence of operations when
  a new button is added to a radio box.
- Added update() method to GLMotif::Widget which is used by a widget
  to notify its parent that its visual representation has changed, to
  invalidate any render caching performed by the parent.
- Changed code of most GLMotif widget classes to guarantee that update()
  is called on any changes to the visual representations of widgets.
- Implemented render caching for GLMotif::PopupWindow, but alas, it
  decreases performance. Disabled for now; need to test on other
  architectures and environments.
- Added subclass DeferredRenderer to GLLabel class to collect label
  objects during a rendering pass and render them later en-bloc to
  minimize OpenGL state change penalties.
- Added support for deferred rendering of GLLabel objects to
  GLMotif::WidgetManager, with astonishing performance gains.
- Added file selection dialog to "Load Curve" button in viewpoint curve
  editing tool.
- Fixed some inconsistencies in event and selection handling in
  GLMotif::ListBox.
- Added optional text field to GLMotif::FileSelectionDialog to enable
  typing in the name of a file to load or save.
- Added specification of traversal functor interface to
  Geometry/ArrayKdTree.h and changed the names of functor template
  parameters to better match semantics.
- Fixed bug in makefile in ExamplePrograms directory; linking failed in
  debug mode. Pointed out by Tyler Martin.
- Added new callback to GLMotif::TextField that notifies a callee that a
  text field's display width has changed in response to a resize.
- Fixed bug in GLMotif::FileSelectionDialog: forgot to close directory
  after reading.
- Fixed small bug in Comm::MulticastPipeMultiplexer that wouldn't close
  the socket on some initialization failures.
- Improved Vrui calibration utilities to work better with NaturalPoint
  OptiTrack systems:
  - MeasureEnvironment can collect ball positions directly from a
    running OptiTrack Rigid Body Toolkit or Tracking Tools application.
  - AlignTrackingMarkers can query rigid body definitions directly from
    a running OptiTrack Rigid Body Toolkit or Tracking Tools
    application.
  - All calibration applications recognize a flipZ flag to enable
    changing a left-handed into a right-handed coordinate system (was
    default behavior before).
- Removed AlignTrackingMarkers from main Vrui makefile as it is now
  part of the separate Calibration package.
- Improved VRPNClient VRDeviceDaemon module to send state updates after
  each received VRPN packet, even if not all trackers were updated, and
  to process multiple protocol messages that arrive over the TCP socket
  en bloc.
- Fixed makefile for installations that do not have OpenAL support.
- Fixed makefile in ExamplePrograms.
- Added VruiDemoSmall and VruiSoundTest to ExamplePrograms.
- Major code overhaul to better organize library sources, and to
  properly separate header files and included icpp files from linked cpp
  files.
- Redefinition of NONSTANDARD_TEMPLATES #define in Math library to
  MATH_NONSTANDARD_TEMPLATES.
- Redefinition of NONSTANDARD_TEMPLATES #define in Geometry library to
  GEOMETRY_NONSTANDARD_TEMPLATES.
- Redefinition of NONSTANDARD_GLVERTEX_TEMPLATES #define in GLWrappers
  library to GLVERTEX_NONSTANDARD_TEMPLATES.
- Redefinition of NONSTANDARD_TEMPLATES #define in GLGeometry library to
  GLGEOMETRY_NONSTANDARD_TEMPLATES.
- Fixed implementation of templatized glVertexPointer function for
  classes GLVertex and GLGeometry::Vertex to properly use a partially
  specialized implementation class.
- Added Math::Matrix, a class to represent double-valued matrices of
  dynamic sizes with general linear algebra operations.
- Changed makefile to automatically build and install calibration
  utilities.
- Shortened makefile by using glob patterns instead of explicite file
  lists where appropriate.
- Added shutdownThingManager() method to GLContextData to completely
  hide GLThingManager.
- Added shutdownThingManager() method to ALContextData to completely
  hide ALThingManager.
- Changed Vrui/Internal/Vrui.Workbench.cpp to use the new methods in
  GLContextData and ALContextData.
- Fixed bug in GLMotif::FileSelectionDialog constructor that misapplied
  given file name filters on first directory read.
- Removed DenseMatrix class from Vrui/Tools directory; redirected
  CurveEditorTool and ViewpointFileNavigationTool to use Math::Matrix.
- Improved Gauss elimination code in Geometry/MatrixHelperFunctions.h.
- Added extension class for GL_EXT_framebuffer_blit extension.
- Improved performance of GLExtensionManager by building a hash table
  mapping supported extensions to extension pointer objects at creation
  time.
- Changed constructor of Vrui::VRWindow to delay construction of GL
  extension manager object until OpenGL context is made current.
- Added readLine() method to Misc::ValueSource.
- Added matchString() method to Misc::ValueSource.
- Changed Vrui::SketchingTool to read curve files via
  Misc::FileCharacterSource and Misc::ValueSource.
- Fixed bug in initialization of Vrui navigation transformation; forgot
  to initialize inverse transformation before delay is started.
- Improved user interface tools for environments with ray-based input
  devices:
  - Changed Vrui::UserInterfaceTool such that selection rays in eye ray
    mode always start from the viewer position, to fix problems when 3D
    devices are behind the screen.
  - Added isUseEyeRay() method to Vrui::UserInterfaceTool.
  - Added calcScreenTransform() method to Vrui::UserInterfaceTool.
  - Changed Vrui::RayScreenMenuTool to properly pop up menus and drag
    widgets across multiple screens.
  - Changed Vrui::WidgetTool to properly drag widgets for ray-based
    input devices.
  - Changed Vrui::RayMenuTool to automatically project to screens for
    ray-based devices or if eye rays are used. Obsoletes
    Vrui::RayScreenMenuTool.
- Added virtual device management to Vrui::WidgetTool to allow daisy-
  chaining of other tools.
- Added a udev rule file and a HAL policy file to enable use of 3D USB
  input devices for non-root users to Share directory; need to add them
  to install script.
- Fixed nasty typo bug in GLMotif::DropdownBox::calcNaturalSize().
- Added new method callback types that take additional parameters of
  arbitrary types to Misc::CallbackList.
- Added method getItemWidget() to GLMotif::DropdownBox.
- Added new generic attribute class GLMotif::WidgetAttribute to store
  widget attributes.
- Added ability to associate a single additional attribute of arbitrary
  type with any GLMotif widget via the GLMotif::WidgetManager.
- Added ability to generate package meta data file for pkg-config to
  makefile.
- Added Misc::SelfDestructArray, a low-overhead class to automatically
  release new[]-allocated memory when the pointer goes out of scope.
- Added setTarget() method to Misc::SelfDestructPointer.
- Added non-const getLockedValue() method to Threads::TripleBuffer.
- Changed default constructor of Misc::Array to assign an array size of
  zero in all dimensions.
- Added GL/GLPrintError, a helper function to print clear-text OpenGL
  error messages to a std::ostream.
- Fixed signed/unsigned comparison warnings in Misc::MemMappedFile.
- Added Misc::BufferCharacterSource to read from in-memory buffers.
- Added readChar() method to Misc::ValueSource.
- Added isString() method to Misc::ValueSource.
- Had to rename getc() method of Misc::CharacterSource to getChar() to
  avoid macro conflicts with C standard library.
- Added ungetChar() method to Misc::CharacterSource.
- Had to change Misc::ValueSource and Misc::TokenSource to follow
  Misc::CharacterSource.
- Added getChar() and ungetChar() methods to Misc::ValueSource.
- Modified Misc::ValueSource such that ASCII character NUL is considered
  whitespace.
- Fixed bug in endianness swap branch in Misc::LargeFile::write (pointed
  out by Scott Bishop).
- Added Vrui/alc.h and Vrui/al.h as wrappers around the respective
  OpenAL include files, to shield client code from missing OpenAL
  libraries or different include file locations.
- Changed API of Threads::DropoutBuffer: renamed old popSegment() method
  to testPopSegment(), and added new popSegment() method that blocks on
  empty queue.
- Added explicit calls to resize() to setCloseButton() and
  setHideButton() methods in GLMotif::PopupWindow since it didn't seem
  to get done.
- Fixed null pointer bug in GLExtensionManager when the manager is
  created without a current OpenGL context.
- Fixed row and column counting bug in GLMotif::RowColumn (pointed out
  by Tyler Martin).
- Fixed initialization bug in Vrui::VRWindow caused by change in
  GLExtensionManager API.
- Fixed subtle rendering bug in Vrui's display function when using a
  transparent rendering pass on an interleaved stereo window.
- Added widget move callback to GLMotif::WidgetManager, which is called
  whenever a primary or secondary top-level widget's transformation is
  changed.
- Added setTrackType method to Vrui::InputDevice.
- Added getUnit method to Vrui::CoordinateManager.
- Added prototype of a scale bar to Vrui.
- Added new class Vrui::GUIInteractor to extract common code from tools
  that allow interacting with graphical user interface elements.
- Added new getRayOffset() method to Vrui::UserInterfaceTool.
- Changed widget- and menu-related tool classes to use new GUIInteractor
  class.
- Changed code in Vrui::popupPrimaryWidget to align widgets by their hot
  spots instead of their center points.
- Changed GLMotif::Popup and GLMotif::PopupWindow to have their hot
  spots in the center.
- Changed GLMotif::PopupMenu to have its hot spot vertically centered
  and off to the right to ease menu selection.
- Removed Vrui::ToolManagementTool class.
- Added new setUnit() method taking a unit name as a string to
  Vrui::CoordinateManager.
- Changed Vrui initialization order such that managers see valid state
  in their constructors.
- Changed rendering code in GLLabel to adapt to the current setting of
  GL_LIGHTING.
- Added some more units to Vrui::CoordinateManager.
- Changed Vrui::CoordinateTransform base class to use the same unit
  names as registered with the coordinate manager.
- Added class Geometry::LinearUnit to move handling of units of length
  to geometry library.
- Changed Vrui::CoordinateManager, Vrui::CoordinateTransform, and
  Vrui::MeasurementTool to use Geometry::LinearUnit.
- Added callback to notify clients of changes to the navigation
  transformation to Vrui kernel.
- Factored out navigation transformation update process in Vrui kernel.
- Added new mix-in class GLMotif::Draggable to denote widgets that can
  be dragged in 3D space by GUI interaction widgets.
  - Changed GLMotif::TitleBar to inherit from GLMotif::Draggable.
  - Changed Vrui::GUIInteractor to check for widgets derived from
    GLMotif::Draggable.
- Changed Vrui::MouseNavigationTool to inherit from Vrui::GUIInteractor
  class.
- Fixed pass-through button behavior in Vrui::WandNavigationTool.
- Added scaling display and functionality to Vrui's scale bar widget.
- Changed Vrui::FPSNavigationTool to move in physical-space units.
- Fixed directory filter signature for Mac OS X in
  SceneGraph::Doom3FileManager.
- Fixed include file path in
  Vrui/Internal/MacOSX/InputDeviceAdapterHID.cpp.
- Clarified use of pixel vs screen coordinates in Vrui/VRWindow.h.
- Added method to copy window's screen viewport to Vrui::VRWindow.
- Added method to copy screen's viewport to Vrui::VRScreen.
- Added helper function getMouseScreenTransform to
  Vrui::InputDeviceAdapterMouse.
- Simplified handling of screens and windows in Vrui::FPSNavigationTool,
  Vrui::MouseNavigationTool, Vrui::MouseDialogNavigationTool, and
  Vrui::MouseSurfaceNavigationTool.
- Added GLNumberRenderer, a class to render numbers using a HUD-like
  font.
- Extended API of Vrui::SurfaceNavigationTool:
  - Added physical navigation frame as protected element.
  - Added method to calculate default physical navigation frame.
  - Added method to align surface frames while calculating Euler angles.
- Fixed navigation behavior of Vrui::FPSNavigationTool.
- Fixed serial port parameter setting code in Comm::SerialPort; forgot
  to clear settings before overriding them.
- Fixed Total Station initialization code in MeasureEnvironment utility.
- Fixed some minor issues in MeasureEnvironment and ScreenCalibrator
  utilities.
- Improved focus behavior of GLMotif::TextField.
- Added hasFocus method to GLMotif::TextField.
- Added value type field to GLMotif::TextFieldSlider.
- Fixed scaling behavior of Vrui's scale bar widget.
- Added maximum point picking distance in navigational space and (cosine
  of) maximum ray picking angle to Vrui kernel state as
  Vrui::getPointPickDistance() and Vrui::getRayPickCosine().
- Added pointPickDistance and rayPickAngle (in degrees) to Vrui main
  configuration file section.
- Added projectToFloor method to Vrui::SurfaceNavigationTool.
- Added getFactor method to Geometry::LinearUnit.
- Fixed display in Vrui::MeasurementTool when using scaled units.
- Started improving navigation behavior of
  Vrui::WalkSurfaceNavigationTool.
- Changed parameter of surface frame alignment callback in
  Vrui::SurfaceNavigationTool from orthogonal transformation to an
  alignment structure to facilitate full collision detection.
  - Adapted Vrui::MouseSurfaceNavigationTool, Vrui::FPSNavigationTool,
    and Vrui::WalkSurfaceNavigationTool accordingly.
- Fixed behaviors of Vrui::FPSNavigationTool and
  Vrui::WalkSurfaceNavigationTool.
- Created Vrui::QuikWriteTool implementing Ken Perlin's QuikWrite user
  interface for text entry.
- Added new protected dependsOn() method to GLObject to allow enforcing
  initialization order of GL state, in case an object depends on the
  state of an embedded object that would otherwise be initialized after
  it.
  - Adapted APIs of GLThingManager and GLContextData to support GLObject
    dependency tracking.
- Fixed background color initialization and label rendering in
  Vrui::ScaleBar.
- Fixed resizing algorithm in Vrui::ScaleBar to keep scale bar centered
  on the same spot during resizes.
- Added calcHUDTransform function to Vrui kernel API.
- Changed all mentions of "model coordinates" in Vrui.h to "navigational
  coordinates."
- Changed name of USE_RENDERCACHE macro in GLMotif/PopupWindow.h to
  GLMOTIF_POPUPWINDOW_USE_RENDERCACHE to prohibit potential clashes.
- Added facility to pop up top-level widgets at the current position of
  the most-recently-used menu tool, to simplify user interaction.
  - Added pointer to most-recently-used menu tool to Vrui state object.
  - Added tool destruction callback to Vrui state object.
  - Added abstract calcHotSpot method to Vrui::MenuTool.
  - Added implementations of calcHotSpot method to Vrui menu tool
    classes.
  - Added mostRecentHotSpot to keep track of hot spots should the most-
    recently-used menu tool get destroyed.
  - Changed popupPrimaryWidget method to pop up dialogs at most-
    recently-used menu tool's hot spot position.
- Updated Vrui::MouseSurfaceNavigationTool to use GUIInteractor helper
  class.
- Removed superfluous forward declaration of GLMotif::Widget from
  Vrui::MouseNavigationTool and Vrui::MouseSurfaceNavigationTool.
- Changed menu tools to grab the pointer when popping up a menu to
  prevent lost button-up events.
- Changed visual selection code in GLWindow to initially ask for at
  least 8 bits of resolution per color channel, and fall back to fewer
  bits if that fails, to work around Apple's stupid decision to default
  to hi-color visuals in Mac OS X 10.6.
- Fixed cursor dragging and double-click behavior in GLMotif::TextField.
- Improved accuracy of calculation in Geometry::Rotation::fromMatrix.
- Added selection rendering to GL labels and GLMotif text fields:
  - Added selection-aware string texture upload methods to GLFont.
  - Added selection-aware draw method to GLLabel.
  - Added invalidate method to GLLabel.
  - Added selection colors to GLMotif::StyleSheet.
  - Added selection rendering to GLMotif::TextField.
  - Added selection color tags to Vrui's main configuration file
   section.
- Changed GLMotif::ListBox to use selection color from style sheet.
- Changed Vrui build system to simplify binary installations via RPM
  or DEB packages.
- Added WhyTools build system to Vrui installation.
- Added HTML documentation to Vrui installation.
- Added flag indicating whether the window has been resized since the
  last redraw to Vrui::DisplayState.
- Armor-plated timer initialization in Realtime::AlarmTimer due to
  warning from valgrind.
- Added Misc/FileTests.h containing helper functions to query file
  system objects in an operating system-independent manner.
- Added Misc/GetCurrentDirectory.h containing a helper function to
  retrieve the name of the calling process' current working directory as
  a string.
- Added Misc/Directory.h for exception-safe access to directories.
- Changed Misc::FileLocator, Comm::Clusterize,
  GLMotif::FileSelectionDialog, and Vrui/Internal/Vrui.Workbench.cpp to
  use new functions from Misc/GetCurrentDirectory.h and
  Misc/FileTests.h.
- Added isValid method to Misc::SelfDestructPointer.
- Fixed subtle memory access bug shown by valgrind in GLMotif::RowColumn.
- Added Misc::ReadBuffer to support an endianness-safe pipe interface
  for reading from a memory buffer.
- Added Misc::WriteBuffer to support an endianness-safe pipe interface
  for writing into a dynamic memory buffer.
- Added Basic Video Library (Video) to the Vrui library bundle, to
  support video capture via multiple video APIs, and video encoding/
  decoding using the Theora codec library.
- Unified endianness-safe binary I/O interface in Misc::File,
  Misc::LargeFile, Misc::MemMappedFile, Comm::TCPPipe,
  Comm::MulticastPipe, and Comm::ClusterPipe by adding mustSwapOnRead,
	readRaw, mustSwapOnWrite, and writeRaw methods.
- API change: Needed to rename readRaw method in Comm::TCPPipe and
  Comm::ClusterPipe to readUpto to enable uniform binary I/O interface
  across all supported data sources and sinks. Changed dependent classes
  and code accordingly.
- Improved performance in Comm::TCPPipe and Comm::ClusterPipe by
  correcting size comparisons; behavior was not affected.
- Added override releaseClass method to Vrui::ToolManager to safely
  destroy all tool of the given class before destroying the class
  itself.
- Added beginTools and endTools method to Vrui::ToolManager to iterate
  through currently instantiated tools.
- Added killTool method to Vrui::ToolManager.
- Added input device update callback to Vrui::InputDeviceManager to give
  code a well-defined point at which to change the state of Vrui input
  devices.
- Added class Misc::CSVSource to read comma-separated value files
  through a Misc::CharacterSource.
- Added value coder class for std::pair to Misc/CompoundValueCoders.h.
- Added singularity check to invertFullPivot and divideFullPivot methods
  in Math::Matrix.
- Added string length element to GLString class, and added (begin, end)-
  based constructors and copy operators.
  - Changed GLLabel, GLMotif::Label, and GLMotif::TextField accordingly.
- Added showErrorMessage method to Vrui kernel API.
- Removed now superfluous plug-in initialization functions from those
  Vrui tool classes that moved into the base library.
- Removed extra valuators for 2D mouse position and mouse velocity from
  Vrui::InputDeviceAdapterMouse.
- API change: major rewrite of Vrui's tool management architecture.
  - Simplified Vrui::ToolInputLayout class to use a flat list of button
    and valuator slots and additional optional buttons or valuators.
  - Simplified Vrui::ToolInputAssignment to use flat lists of (device,
    slot index) pairs for button and valuator assignments.
  - Rewrote Vrui::Tool to use new layout and input assignment classes,
    and to present a flat button / valuator slot list.
  - Added getButtonFunction and getValuatorFunction introspection
    methods to Vrui::ToolFactory to provide a better user interface for
    tool management.
  - Adapted Vrui::InputGraphManager to new tool input assignment
    structure.
  - Adapted Vrui tool base classes to new tool input assignment
    structure and provided default implementations of introspection
    methods.
  - Rewrote Vrui::TransformTool to properly deal with dynamic numbers
    of button and valuator slots.
  - Removed button hijacking facility from Vrui::InputDeviceTool, since
    that functionality is better implemented using layered tools.
  - Major rewrite of Vrui::ToolManager to support a modal multi-slot
    tool assignment process with visual feedback, adapt to the tool
    management architecture changes, and implement a new syntax for
    configuration file tool bindings.
  - Made Vrui::ToolManager::assignTool method private, renamed private
    destroyTool method to deleteTool, and added public createTool and
    destroyTool methods, both bypassing the tool management queue for
    immediate effect.
  - Improved performance in Vrui::ToolManager by replacing the
    inefficient std::list of tool assignment slots with a per-device C-
    style array.
  - Replaced old strategy of assigning tool selection tools to all empty
    device slots by single virtual input device and tool selection tool
    assigned to slots on demand. Now support assigning tools to
    valuators.
  - Adapted and partially rewrote concrete tool classes for new tool
    management architecture and introspection methods.
  - Fixed bugs in tool creation process in Vrui::ToolManager and added
    dead zone with hysteresis when moving valuators during tool
    creation.
  - Added getRootDevice method to Vrui::InputGraphManager to find the
    source device of a chain of transform tools, to disable
    transformations during tool selection.
  - Removed now-superfluous state to disable transform tools during tool
    creation from Vrui::TransformTool and derived classes.
  - Added new mixin class Vrui::DeviceForwarder to group tool types that
    create and manage permanently-bound virtual input devices.
  - Derived Vrui::TransformTool from Vrui::DeviceForwarder and provided
    default implementations of the latter's methods.
  - Added FeatureType enum to Vrui::InputDevice so it won't have to be
    redefined all over the place.
  - Added feature-based unified accessor methods to Vrui::InputDevice.
  - Added isAssigned method to Vrui::ToolInputAssignment.
  - Added slot-based accessor methods to Vrui::ToolInputAssignment.
  - Removed doesButonHaveTool and doesValuatorHaveTool methods from
    Vrui::ToolManager.
  - Changed syntax of tool bindings in Vrui configuration file to use
    lists of (device name, button / valuator index list).
  - Started adding code to display tool stacking for an input device
    feature when activating a feature in the tool kill zone and then
    releasing it outside.
  - Reimplemented Vrui::InputGraphManager to take over tool assignment
    slot management from Vrui::ToolManager to avoid duplication of data
    structures.
  - Removed tool assignment slot management from Vrui::ToolManager.
  - Added new helper class Vrui::InputDeviceFeature to simplify passing
    individual input device buttons or valuators.
  - Added capability to stack tools from default tool bindings in Vrui
    configuration file by repeating base input device buttons and
    valuators.
  - Added facility to query names of input device features and find
    input device features by name to Vrui::InputDeviceManager. Behavior
    is implemented by concrete input device adapter classes.
  - Added addAdapter method to Vrui::InputDeviceManager.
  - Rewrote Vrui::MultipipeDispatcher to act as an InputDeviceAdapter,
    such that feature name queries work on slave nodes in a cluster.
    As a result, input device data is now sent to slave nodes before
    other frame data, and feature names are exchanged during startup.
  - Added cleanup code to Vrui::InputDeviceManager such that input
    devices not owned by any input device adapters are removed on
    destruction; should fix shutdown segfault in cluster environments.
  - Added configure method to Vrui::Tool, to allow a just-created tool
    to read configuration data from a configuration file section.
  - Added optional configuration file section parameter to
    Vrui::ToolManager::createTool.
  - Added optional pointer to configuration file section to
    Vrui::ToolManager::ToolCreationCallback.
  - Added method to query all forwarded devices to
    Vrui::DeviceForwarder.
  - Added function to remove all tools and virtual input devices from
    the input graph to Vrui::InputGraphManager.
  - Added functions to load and save input graph states to
    Vrui::InputGraphManager.
  - Added getName method to Vrui::Tool, to return a descriptive name for
    a particular tool object.
  - Added storeState and getName function pointers to Vrui::LocatorTool
    and Vrui::DraggingTool to allow applications to insert behavior.
  - Added virtual storeState and getName methods to
    Vrui::LocatorToolAdapter and Vrui::DraggingToolAdapter.
  - Added simplistic tool stack visualization if button or valuator are
    pushed within the tool kill zone; as a result, Vrui now depends on
    scene graph library.
  - Fixed button and valuator function query methods in
    Vrui::ToolFactory.
  - Fixed input graph saving and loading algorithms.
  - Changed tool destruction process to incremental unwind of tool
    stacks.
- Added several convenience methods and default behaviors to Vrui base
  tool classes.
  - Vrui::TransformTool has sourceDevice, numPrivateButtons, and
    numPrivateValuators which need to be set by derived tool objects in
    their constructors.
  - Vrui::TransformTool has getSourceDevice virtual method to support
    root device finding in Vrui::InputGraphManager.
  - Vrui::UserInterfaceTool has interactionDevice, which needs to be set
    by derived tool objects in their constructors.
  - Added method getInteractionPosition to Vrui::UserInterfaceTool.
  - Vrui::InputDeviceTool has numPrivateButtons and numPrivateValuators
    which need to be set by derived tool objects in their constructors.
- Added support for introspection methods to Vrui::GenericToolFactory.
- Added callback data base class to Vrui::MenuTool.
- Added extension class for GL_ARB_draw_instanced; code provided by Rolf
  Westerteiger.
- Added Geometry::PointPicker and Geometry::RayPicker, two functor
  classes to pick points based on distance from a point and along a ray,
  respectively.
- Added configuration option to disable toggle behavior on device select
  button to SixDofInputDeviceTool; changed default behavior to switch.
- Added broken-line axis mappings to SpaceBallRaw VRDeviceDaemon driver
  module.
- Added tool class SixAxisInputDeviceTool to control virtual input
  devices using six valuators for translations and rotations.
- Added Sound::SpeexEncoder and Sound::SpeexDecoder to Linux portion of
  basic sound library, currently using the same API as used by
  collaboration infrastructure.
- Removed obsolete widgetInteraction and motionWidget elements from
  internal Vrui kernel state.
- Added locking mechanism to Vrui::GUIInteractor such that only one GUI
  interactor can be active at a time.
- Changed how Vrui kernel keeps track of most-recently used GUI tools to
  determine reasonable popup positions; now based on GUIInteractor.
- Added Vrui tool class SixAxisTransformTool to create virtual 6-DOF
  devices from six valuators.
- Changed Vrui::Application::Tool to public to enable out-of-class
  application tools.
- Finally fixed problem with "stuck" modifier keys when a Vrui window
  loses and regains focus.
- Fixed conversion bug in Intersense VRDeviceDaemon module that did not
  allow valuator values to go to 0.0.
- Added proper input device destruction to Vrui::InputDeviceAdapter.
- Fixed minor bug in Misc::ValueCoder<std::pair<...> >.
- Major upgrade of basic video library:
  - Added Video::ImageExtractorRGB8 to extract images from raw frames in
    8-bit RGB format.
  - Improved and fixed Video::ImageExtractorBA81 for Bayer images.
  - Added Video/Colorspaces.h containing convenience functions to
    convert color values between several common color spaces.
  - Unified color space conversion functions in ImageExtractor classes.
  - Improved API of Theora wrapper classes in Video library.
  - Added video device enumeration and selection to Video::VideoDevice.
  - Added video format enumeration to Video::VideoDevice and derived
    classes.
  - Made other improvements to Video::V4L2VideoDevice and
    Video::DC1394VideoDevice.
  - Added Video::YpCbCr420Texture, a class to encapsulate video
    textures.
  - Added Video::VideoPane, a GLMotif widget class to display streaming
    video frames in Y'CbCr 4:2:0 pixel format.
  - Added Video::OggPage, Video::OggSync, and Video::OggStream to
    simplify writing Theora video packets to Ogg stream containers.
- Added Vrui::MovieSaver to internal Vrui library to enable saving video
  from VRWindows, either as stacks of images or Theora video streams in
  Ogg containers. Vrui now depends on Video.
- Added saveAs method to Misc::ConfigurationFile to allow creating an
  unnamed configuration file in memory and then saving it.
- Added clear, removeSubsection, and removeTag methods to
  Misc::ConfigurationFileBase::Section and
  Misc::ConfigurationFileSection.
- Added section iteration methods to
  Misc::ConfigurationFileBase::SectionValueCoder.
- Changed skipSeparator function semantics and name in
  Misc/ValueCoder.h.
- Reimplemented or cleaned up value coder classes.
- Changed class names and APIs in Misc/ArrayValueCoders.h.
- Fixed bug in Misc::ValueCoder<Geometry::Rotation<ScalarParam,2> >: did
  not convert angle to degrees before encoding.
- Added value coder classes for short int and unsigned short int to
  Misc/StandardValueCoders.h.
- Added value coder classes for GLVector and GLBox to
  GL/GLValueCoders.h.
- Added GLMotif/WidgetStateHelper.h to read/write widget state from/to
  configuration files.
- Added Misc/Marshaller.h, Misc/StandardMarshallers.h,
  Misc::ArrayMarshallers, and Misc/CompoundMarshallers.h.
- Added Math/MathMarshallers.h, Geometry/GeometryMarshallers.h, and
  GL/GLMarshallers.h.
- Improved support for dynamic removal of widgets in GLMotif library:
  - Added unmanageChild method to GLMotif::Widget; can only be called by
    widget's parent.
  - Added pure removeChild method to GLMotif::Container.
  - Added deleteChild convenience method to safely unmanage and delete a
    child widget to GLMotif::Container.
  - Added implementations of GLMotif::Container::removeWidget to all
    GLMotif container classes.
- Reimplemented Vrui device daemon protocol:
  - Rebased VRDevicePipe to use Comm::TCPPipe for performance and
    endianness safety.
  - Reimplemented VRDeviceServer to support proper client disconnect
    when all devices are idle.
- Added isValid method to GLShader and improved error handling.
- Added method to limit ray to current clipping volume to
  Vrui::ClipPlaneManager.
- Added ShiftButtonTool class to generalize InputDeviceAdapterMouse's
  modifier key behavior to any input device button.
- Removed replicated value coder implementation for Math::BrokenLine
  from VRDeviceDaemon HIDDevice module.
- Added pre-calibration debugging output to Linux version of
  VRDeviceDaemon HIDDevice module.
- Added methods to draw positioned and aligned numbers to
  GLNumberRenderer.
- Added constructor with emtpy drop-down box to GLMotif::DropdownBox.
- Added clearItems method to GLMotif::DropdownBox.
- Improved Vrui::MovieSaver by splitting into abstract base class and
  separate derived classes for movie formats (image stack, Theora).
- Fixed error in Comm::TCPSocket::blockingRead which didn't handle EINTR
  correctly in newer socket implementations.
- Fixed some minor issues compiling Vrui and applications on Mac OS X.
- Changed build system and code to use per-library configuration header
  files instead of compiler command line arguments to set configuration
  options.
- Added hasTag method to Misc::ConfigurationFile::SectionValueCoder.
- Added SixAxisNavigationTool.
- Fixed and improved ShiftButtonTool.
- Changed loadDefaultTools method in Vrui::ToolManager to use the new
  Vrui::InputGraphManager::loadInputGraph method instead.
  - Uses new tag defaultTools in tool manager's configuration file
    section to specify name of section containing tool bindings.
  - Tool bindings in named section are processed in order of appearance
    in the configuration file.
- Removed obsolete DesktopDeviceTool and DesktopDeviceNavigationTool
  Vrui tool classes.
- Changed VR device daemon protocol to exchange a version number between
  client and server, to proof against the upcoming protocol change.

Vrui-2.0-002:
- Added merge method to Geometry::PCACalculator.
- Fixed installation bug in makefile.
- Fixed bug in creation of pkg-config metafile Vrui.pc.

Vrui-2.0-003:
- Fixed compiler flag bug for GLExtensionManager in makefile.
- Changed default Vrui installation directory back to ~/Vrui-2.0.

Vrui-2.1-001:
- Fixed bug in Misc::ConfigurationFile; current section was not reset on
  load or reload call. Pointed out by Tony Bernardin.
- Fixed package autodetection bug in Vrui build system; had SPEEX and
  OGG flipped.
- Added readTransparentImageFile method to Images/ReadImageFile.h to
  create images with alpha channel.
- Changed SceneGraph::ImageTextureNode to use textures with alpha
  channel.
- Added Misc::RefCountedArray.
- Added Threads::RefCountedArray, a thread-safe version of
  Misc::RefCountedArray.
- Added new abstract class Misc::BufferedFile for high-performance
  access to binary files,
- Added Misc::BufferedStandardFile as concrete implementation of
  Misc::BufferedFile.
- Added getMaxSpeedLeve and setSpeedLevel methods to
  Video::TheoraEncoder.
- Fixed bug in handling of old recordings in
  Vrui::InputDeviceAdapterPlayback.
- Added class Misc::BufferedMemoryFile to write data to lists of in-
  memory buffers.
- Added readRaw and writeRaw methods to Comm::TCPSocket to get APIs
  unified.
- Added Comm::BufferedTCPSocket as concrete implementation of
  Misc::BufferedFile.
- Fixed some flaws and bugs in Misc::BufferedFile and derived classes.
- Fixed typo in sound context names in Vrui.cfg, and added sound support
  in the KeckCAVES CAVE by default.
- Fixed bad write of compound glyph to pipe in
  Vrui::MultipipeDispatcher.
- Fixed race condition due to lax pipe locks in
  Comm::MulticastPipeMultiplexer.
- Added missing public: access modifier to Misc::Marshaller<GLMaterial>.
- Added default initializations to Vrui::InputDevice and removed
  redundant initializations from Vrui::addVirtualInputDevice.
- Fixed missing socket check in Comm::ClusterPipe::writeRaw.
- Removed implicit shutdown from Comm::BufferedTCPSocket destructor and
  added explicit shutdown method.
- Added ability to specify audio data sources by name to
  Sound::SoundRecorder.
- Added levelOnExit flag to Vrui::FPSNavigationTool.
- Added Vrui::ForceJumpNavigationTool.
- Added Comm::BufferedClusterSocket, a Misc::BufferedFile wrapper for
  Comm::ClusterPipe. Currently unoptimized and using double buffering.
- Added waitForData methods to Comm::BufferedTCPSocket.
- Changed internal API of Comm::MulticastPipeMultiplexer to support new
  Comm::BufferedMulticastPipe class.
- Changed constructor of Comm::MulticastPipe to public, to allow clients
  to directly create pipes from multiplexers.
- Added Comm::BufferedMulticastPipe.
- Added Vrui::getMulticastPipeMultiplexer function to Vrui kernel API.
- Added Comm::ClusterBufferedTCPSocket to forward incoming data from a
  TCP socket across a cluster using a multicast pipe.
- Added method to traverse points inside a box to Geometry::ArrayKdTree.
- Fixed typo in Marshaller for OrthogonalTransformation in
  Geometry/GeometryMarshallers.icpp.
- Added getChar and ungetChar methods to Misc::BufferedFile to replace
  Misc::CharacterSource as backbone for ASCII-based file readers.
- Rebased Misc::TokenSource and Misc::ValueSource to Misc::BufferedFile
  abstraction.
- Added Misc::BufferedGzippedFile.
- Started adding Threads::BufferedGzippedFile.
- Added Comm::ClusterBufferedStandardFile.
- Started moving Vrui to use Misc::BufferedFile abstraction internally
  instead of Misc::CharacterSource.
- Added Misc/OpenFile.h and Comm/OpenFile.h to simplify opening files
  of varying types using the Misc::BufferedFile abstraction.
- Added getMultiplexer method to Comm::MulticastPipe.
- Added multicast pipe multiplexer pointer to SceneGraph::VRMLFile.
- Rebased Misc::CSVSource to use Misc::BufferedFile.
- Added error message display to Vrui::ViewpointFileNavigationTool.
- Added color configuration options and interaction ray rendering to
  Vrui::QuikWriteTool.
- Added optional parameter to receive hotpot position to
  Images::readCursorFile.
- Added glyph type for screen-aligned texture-based cursors to
  Vrui::GlyphRenderer.
- Changed Vrui::InputDeviceAdapterMouse to use cursor glyph instead of
  Vrui::MouseCursorFaker.
- Added base class Misc::SeekableFile to indicate files whose file
  position can be changed.
- Rebased Misc::BufferedStandardFile to Misc::SeekableFile.
- Added skip() method to Misc::BufferedFile to quickly skip typed values
  during reading.
- Added getTarget method to Misc::SelfDestructPointer.
- Replaced Misc::File API with Misc::BufferedFile API in many classes.
- Fixed memory leak in glLinkShader functions in
  GL/Extensions/GLARBShaderObjects.cpp.
- Moved FdSet from Comm library to Misc library.
- Added base class Comm::BufferedPipe to indicate files implementing
  pipes and sockets, with automatic endianness negotiation and wait()
  methods.
- Added Comm::BufferedSerialPort to create Misc::BufferedFile
  abstraction for serial ports.
- Rebased SpaceballRaw VRDevice module to use Comm::BufferedSerialPort.
- Rebased InterSense VRDevice module to use either
  Comm::BufferedSerialPort or Comm::BufferedTCPSocket to support
  connecting via both serial ports or Ethernet cables.
- Upped window size in Comm::MulticastPipeMultiplexer to improve bulk
  throughput on GigE networks.
- Added glRenderAction method to Vrui::InputDeviceAdapter and
  Vrui::InputDeviceManager to allow input device adapters to render
  graphical state.
- Started adding Vrui::AnnotationTool.
- Fixed bug in GLMotif::RadioBox::setSelectedToggle(int).
- Added #include <stddef.h> to Misc/PriorityHeap.h and
  Plugins/FunctionPointerHack.h to adapt to changes in gcc 4.6.0.
  Pointed out by James Mouradian.
- Added Misc::ZipArchive to read and process ZIP archives using
  Misc::BufferedFile abstractions.
- Added Misc::BufferedMemoryBlock to represent in-memory files using a
  Misc::SeekableFile interface.
- Fixed normal vector transformation bug in
  SceneGraph::GeodeticToCartesianPointTransformNode.
- Added simple node for quad sets to scene graph library.
- Fixed some bugs in SceneGraph/LoadElevationGrid.cpp.
- Added build line for single-source executables to Vrui's make system.
- Split new file abstraction classes from Misc library off into new IO
  library and shortened/improved class names while at it.
  - Renamed Misc::BufferedFile to IO::File.
  - Renamed Misc::BufferedStandardFile to IO::StandardFile.
  - Renamed Misc::BufferedGzippedFile to IO::GzippedFile.
  - Renamed Misc::BufferedMemMappedFile to IO::MemMappedFile.
  - Renamed Misc::BufferedMemoryBlock to IO::FixedMemoryFile.
  - Renamed Misc::BufferedMemoryFile to IO::VariableMemoryFile.
  - Moved Misc/OpenFile.h to IO.
  - Moved Misc::ZipArchive, Misc::XBaseTable, Misc::TokenSource,
    Misc::ValueSource, Misc::CSVSource to IO.
  - Added openSeekableFile function to IO/OpenFile.h.
  - Renamed Threads::BufferedGzippedFile to Threads::GzippedFile.
  - Renamed Comm::BufferedPipe to Comm::Pipe.
  - Adapted Comm::BufferedSerialPort.
  - Adapted Comm::BufferedTCPSocket.
  - Renamed Comm::SlaveBufferedFile to Comm::SlaveFile.
  - Adapted Comm::SlaveSeekableFile.
  - Renamed Comm::MasterBufferedStandardFile to Comm::MasterStandardFile.
  - Adapted Comm::BufferedMulticastPipe.
  - Renamed Comm::ClusterBufferedStandardFile to Comm::ClusterStandardFile.
  - Adapted Comm/OpenFile.h.
    - Added openSeekableFile functions to Comm/OpenFile.h.
  - Adapted Comm/ClusterBufferedTCPSocket.h.
  - Adapted Comm/BufferedClusterSocket.h.
  - Adapted GLARBShaderObjects.
    - Added function to compile shader by reading from supplied IO::File object.
  - Adapted GLColorMap.
  - Adapted GLFont.
  - Adapted Sound::SoundRecorder.
  - Adapted Sound::SoundPlayer.
  - Adapted Video::OggSync.
  - Adapted SceneGraph::VRMLFile.
  - Adapted SceneGraph::InlineNode.
  - Adapted SceneGraph::CurveSetNode.
  - Adapted SceneGraph::LoadElevationGrid.
  - Adapted SceneGraph::TSurfFileNode.
  - Adapted SceneGraph::ArcInfoExportFileNode.
  - Adapted SceneGraph::EsriShapeFileNode.
  - Adapted SceneGraph::Doom3FileManager.
  - Adapted SceneGraph::Doom3TextureManager.
  - Adapted SceneGraph::Doom3ValueSource.
  - Adapted SceneGraph::Doom3MaterialManager.
  - Adapted SceneGraph/Internal/LoadModelFromASEFile.cpp.
  - Adapted SceneGraph/Internal/LoadModelFromLWOFile.cpp.
  - Adapted SceneGraph::Doom3MD5Mesh.
  - Adapted SceneGraph::Doom3MD5Anim.
  - Adapted Vrui::InputDeviceAdapterPlayback.
    - Made Kinect 3D video playback optional via #define
  - Adapted Vrui::KinectPlayback.
  - Adapted Vrui::TheoraMovieSaver.
  - Adapted Vrui::InputDeviceDataSaver.
    - Made Kinect 3D video recording optional via #define
  - Adapted Vrui/Internal/Vrui.General.cpp.
  - Adapted Vrui::SketchingTool.
  - Adapted Vrui utilities.
  - Adapted Vrui demo programs.
  - Adapted VRDeviceDaemon::Intersense.
  - Adapted VRDeviceDaemon utilities.
- Started improving cluster transparency provided by file abstractions
  in Comm library.
  - Implemented Comm::StandardFile and Comm/OpenFile.h.
  - Added Vrui/OpenFile.h.
- Removed some now-obsolete classes and files from libraries.

Vrui-2.2-001:
- Added configurable interleaved stereo patterns to Vrui::VRWindow,
  generalizing patch submitted by Matthias Deller.
- Improved VRDeviceDaemon module for A.R.T. DTrack
  - Now handles all device types, including gloves (no finger tracking
    yet)
  - Per-device report format (6d, 6df, ...) must now be defined in
    device's configuration file section using the reportFormat tag.
  - Now allows shared device IDs between report types.
- Updated a lot of documentation; improved "Using Vrui Applications"
  page. A lot.
- Added useRemoteControl flag to A.R.T. DTrack tracker driver to disable
  the use of server remote control, for those weirdos who don't want to
	use it. :)
- Added Mac OS X-specific #include to Misc/FdSet.h to work around old-
  style declaration of pselect in BSD.
- Made Vrui::AnnotationTool::markerSize public.
- Added Misc::SizedTypes.h defining exact-size integer and floating-
  point types to guarantee matching data sizes across binary files and
  network connections.
- Fixed g++ 4.6.0-issue in Misc/UnorderedTuple.h.
- Fixed new version of A.R.T. DTrack VR device driver module with help
  from Matthias Deller.
- Added new[]-like constructor to Misc::SelfDestructArray.
- Added configuration header to Threads library.
- Added Threads::Spinlock as a busy-waiting low-overhead alternative to
  Threads::Mutex. Should only be used if the time any caller holds a
  lock is very short.
- Fixed extremely nasty race condition in Threads::TripleBuffer; alas,
  needed to insert spinlock.
- Changed behavior of Threads::Barrier; throws exception when changing
  barrier size in mid-wait; synchronize() returns true for exactly one
  caller.
- Augmented API of Misc::HashTable. Map-style tables now support get/set
  operations using brackets; set-style tables can directly take source
  value in setEntry().
- Changed Threads::RefCounted and Threads::RefCountedArray to use atomic
  counters instead of spinlocks where available.
- Disabled asynchronous dependent thread cancellation in all library
  sources.
- Changed Vrui::SixAxisTransformTool to use the dynamic display center
  as home position by default.
- Added Vrui::NopTool, which does nothing at all, to allow "capping"
  buttons or valuators to disable them.
- Fixed cluster bug in code to save input graphs.
- Replaced some time-critical mutexes in Comm::MulticastPipeMultiplexer
  with spinlocks.
- Added method to set send buffer size to
  Comm::MulticastPipeMultiplexer.
- Added configuration file setting multipipeSendBufferSize to Vrui
  environment main section.
- Added constructor to wrap an already-opened file descriptor to
  IO::StandardFile; does not duplicate file descriptor or change file's
  mode or flags.
- Fixed mutex lock leak in Threads::MutexCond; changed MutexCond
  behavior to not implicitly lock on signal and broadcast, and removed
  signal and broadcast methods with lock argument.
- Fixed synchronization bug in Intersense VR device module.
- Fixed missing tracker report mask update bug in VRDeviceManager.
- Added specific exception class FileNotFound to Misc::FileLocator.
- Changed event handling in VR windows to improve responsiveness for
  slow-running programs:
  - Added close callback to GLWindow; removed "closed" return value for
    processEvent().
  - Added return values indicating whether state has changed to setter
    methods of Vrui::InputDeviceAdapterMouse.
    - Removed (redundant?) calls to Vrui::requestUpdate from setter
      methods.
  - Changed meaning of return value of Vrui::VRWindow::processEvent from
    "closed" to "finish processing events for this frame."
  - Adapted Vrui mainloop to these changes.
    - Added code to completely ignore key repeat events to
      vruiHandleAllEvents.
    - Added return value indicating if any events were processed to
      vruiHandleAllEvents.
- Some code cleanup in Vrui::InputDeviceDataSaver and
  Vrui::InputDeviceAdapterPlayback.
- Fixed buffer allocation bug and subsequent memory leak in IO::File.
- Fixed subtle but serious bug in code that sends rotations across files
  or pipes: removed extra renormalization on the receiver side by making
  elementwise constructors public and using them instead of
  fromQuaternion().
- Fixed spinning speed calculation in Vrui::MouseNavigationTool and
  Vrui::MouseDialogNavigationTool.
- Added throwing animation to Vrui::MouseSurfaceNavigationTool.
- Removed superfluous forward declaration for Misc::File from
  IO/ZipArchive.h.
- Fixed missing slash bug in Misc::createNumberedFileName.
- Added pre-transformation option to VRScreen's configuration file
  settings.
- Added key-based scrolling to GLMotif::ListBox.
- Fixed key repeat issue again, this time for good?
- Fixed bug with empty file pattern list in GLMotif::FileSelectionDialog
  constructor.
- Added #include <stddef.h> to Misc/SelfDestructArray.h.
- Fixed missing initialization for VruiState::dialogsMenu.
- Fixed slash insertion bug in Misc::CreateNumberedFileName.
- Added configuration file settings to set interaction ray draw enable
  flag, color, and line width to Vrui::UserInterfaceTool.
- Added missing parameter to method declaration in downcasted method
  callback with additional parameter in Misc::CallbackList.
- Added GLMotif::Image, a widget to display images.
- GLMotif library now depends on Images library; changed order in
  makefile and Packages file.
- Significantly improved performance of transform() and
  inverseTransform() methods of Geometry::Rotation.
- Added specialization for one-dimensional arrays to Misc::Array.
- Added conversion operator to int to Misc::ArrayIndex<1>.
- Created generic Geometry::LinearInterpolator class to interpolate
  arbitrary geometry types.
- Created unified generic class for tensor-product B-spline curves/
  surfaces/etc. of arbitrary dimensions and control point types.
- Finally fixed light source behavior in Vrui::CAVERenderer vislet.
- Added redundant initializations to Comm::MulticastPipeMultiplexer to
  shut up valgrind.
- Added workaround for spurious packet receive error to
  Comm::MulticastPipeMultiplexer.
- Added a new Vrui application template source to example programs.
- Fixes to widget handling in GLMotif::WidgetManager:
  - Changed event processing lock to use RAII for exception safety.
  - Inserted missing code to pop down secondary widgets before popping
    down a primary widget.
- Fixed Vrui shutdown sequence to allow clean shutdown when exceptions
  are thrown from inside UI and tool callbacks.
- Added directed textControl() method to GLMotif::WidgetManager.
- Added textControl() method to Vrui::GUIInteractor.
- Added valuator-based GUI scroll tool to enable the use of the mouse
  wheel to scroll in GLMotif widgets in desktop mode.
- Fixed reaction of Vrui's blocking main loop to due timer events.
- Added "transform" tag to screen configuration file sections to
  directly specify a screen's transformation with respect to physical or
  device space.
- Added range adjustment to GLMotif::ScrollBar's setPosition() method.
- Slight changes to Vrui::WalkSurfaceNavigationTool to be compatible
  with Vrui::FPSNavigationTool.
- Added -setLinearUnit <unit name> <unit factor> optional argument to
  Vrui command line.
- Added valuator-based "jetpack" to Vrui::WalkSurfaceNavigationTool.
- New protected convenience methods in Vrui::SurfaceNavigationTool:
  - wrapAngle.
  - limitAngle.
  - calcAzimuth.
  - calcEulerAngles.
- Updated surface navigation tool classes to use new convenience methods
  from Vrui::SurfaceNavigationTool where applicable.
- Improved Vrui::HelicopterNavigationTool:
  - Improved collision detection.
  - New planar HUD rendering with compass ribbon.
- Added Vrui::SixAxisSurfaceNavigationTool; HUD copied from
  Vrui::HelicopterNavigationTool.
- Added new class Comm::ListeningTCPSocket to cleanly separate server-
  and client-side TCP connection establishment.
- Split off new cluster abstraction library (Cluster) from Comm library
  to simplify class names and APIs.
  - Adapted dependent library classes and applications to new API.
- Renamed Vrui::getMulticastPipeMultiplexer function to
  Vrui::getClusterMultiplexer.
- Added Cluster::ClusterPipe as base class for cluster abstraction
  classes using multicast pipes internally.
- Rebased Cluster::MulticastPipe to implement IO::File abstraction; old
  finishMessage() method is now IO::File's flush() method.
- Needed to rename dummy access mode "None" in IO::File to "NoAccess" to
  dodge #define conflict with system header files.
- Rebased Vrui::VRDeviceState, Vrui::VRDevicePipe,
  Vrui::VRDeviceDescriptor, Vrui::VRDeviceClient, and VRDeviceServer
  from Comm::TCPPipe to Comm::BufferedTCPPipe.
- Updated ViconTarsusRaw and ViconTarsus VR device driver modules to use
  Comm::BufferedTCPPipe.
- Updated RemoteDevice VR device driver module to new
  Vrui::VRDeviceClient API.
- Removed obsolete class Comm::TCPPipe; functionality is assumed by
  Comm::BufferedTCPSocket.
- Renamed Comm::BufferedTCPSocket to Comm::TCPPipe; in effect,
  Comm::TCPPipe class has been reimplemented using the Comm::Pipe
  abstraction.
- Added Cluster::TCPPipe for cluster-transparent TCP pipes based on the
  Comm::Pipe abstraction.
- Added Cluster/OpenPipe.h containing convenience functions to open
  pipes based on the Comm::Pipe abstraction in a cluster-transparent
  manner.
- Fixed missing flush() bug in SpaceBallRaw VR device driver module.
- Updated Vrui/ClusterSupport.h to use Cluster library.
- Added new image readers using the IO:File abstractions to Images
  library:
  - ReadPNMImage.h for images in Portable AnyMap format.
  - ReadPNGImage.h for images in PNG format (uses libpng).
  - ReadJPEGImage.h for images in JPEG format (uses libjpeg).
  - ReadTIFFImage.h for images in TIFF format (uses libtiff).
- Made getReadBufferSize and getWriteBufferSize methods in IO::File
  public.
- Fixed semantics of IO::ValueSource::isLiteral and isCaseLiteral
  methods: stop reading at the first mismatch.
- Renamed IO::ValueSource::initCharacterClasses to resetCharacterClasses
  and made it public.
- Added explicit conversion operator getArray() to
  Misc::SelfDestructArray.
- Added readImageFile functions for IO::File abstractions to
  Images/ReadImageFile.h and reimplemented functions in terms of new
  image file reader classes.
- Changed semantics of Misc::getExtension function in
  Misc/FileNameExtensions.h to include period in result, and return
  empty string in case of no extension instead of null pointer.
  - Improved use of Misc::getExtension in other library sources.
- Added getExtension method taking begin and end pointers to
  Misc/FileNameExtensions.h to facilitate repeated extension removal.
- Added scalar type and channel number conversion methods to
  Images::Image and derived classes.
- Added optimized implementations for common GLColor scalar type
  conversions.
- Added readInBuffer method to IO::File to enable zero-copy read access.
- Created IO::GzipFilter, a IO::File-derived class to read/write gzip-
  compressed files via an IO::File abstraction for the compressed file.
- Added rotateAround token to Misc::ValueCoder class for orthonormal
  transformations.
- Added rotateAround and scaleAround tokens to Misc::ValueCoder class
  for orthogonal transformations.
- Derived IO::File from Misc::RefCounted to simplify memory management
  of file objects, especially when stacking.
- Changed IO::OpenFile.h, Cluster::openFile, Cluster::openPipe, and
  Vrui::openFile to return automatic pointers.
  - Moved all higher libraries and applications to new API.
- Changed IO::ValueSource, IO::TokenSource, IO::CSVSource to retain
  autopointers to underlying files.
- Changed template definition in GL/GLColor.h to get around annoying
  compiler warning, but to no avail.
- Added protected appendReadBufferData method to IO::File to further
  support zero-copy reads.
- Added IO::IFFChunk, a class to simplify reading from files using the
  IFF/RIFF container format.
- Moved all classes using Comm::SerialPort to Comm::BufferedSerialPort.
  - Improved SpaceBall and PolhemusFastrak VR device drivers.
- Replaced implementation of Comm::SerialPort with
  Comm::BufferedSerialPort and removed latter from library.
- Added GL/GLLightTracker to provide a shared collection point for
  changing OpenGL lighting states to support just-in-time compilation
  for GLSL shaders.
- Added a GLLightTracker object to Vrui::LightsourceManager to track the
  state of lighting as set up by Vrui.
- Added getLightTracker method to Vrui::LightsourceManager.
- Added writeInBufferPrepare and writeInBufferFinish methods to IO::File
  to support zero-copy writes.
- Changed main functions in Images/ReadImageFile.h to take an already-
  opened IO::File object, and provided convenience functions with old
  signatures.
- Added Comm::HttpFile to read remote files using the HTTP/1.1 protocol
  and an IO::File abstraction.
- Added Comm::OpenFile.h handling remote HTTP files.
- Added support for remote HTTP files to Cluster::OpenFile.h.
- Added full set of dynamic casting operators to Misc::Autopointer.
- Created IO::SeekableFilter, a caching adapter to convert streaming
  files into seekable files.
- Added default implementations of readData and writeData methods to
  IO::File; readData returns EOF and writeData throws a WriteError
  exception.
- Made IO::File::getReadBufferSize and IO::File::getWriteBufferSize
  virtual so that derived classes playing with the buffers for zero-copy
  access can report "nominal" buffer sizes.
- Added type size safeguard to Misc::Marshaller<std::string>.
- Added clear() method to IO::VariableMemoryFile.
- Oops. Fixed infinite-recursion typos in three classes: Comm::TCPPipe,
  Cluster::TCPPipe, and one I can't remember. Sorry.
- Added comparison operators to all transformation classes from the
  Geometry library.
- Improved Vrui navigation management by only requesting a post-
  navigation frame if the navigation transformation actually changed,
  saving tons of CPU cycles in most applications.
- Reduced default spin threshold in mouse navigation tool for smoother
  spinning.
- Added comparison operators to Geometry::Plane.
- Added copy constructor with scalar type conversion to Geometry::Plane.
- Added getMostRecentValue() method to Threads::TripleBuffer and
  clarified producer/consumer API.
- Added class name-based getFactory() method to Plugins::FactoryManager.
- Added missing initialization to Vrui::ToolManager constructor.
- Fixed bug when trying to release non-registered tool classes in
  Vrui::ToolManager::releaseClass().
- Added Misc::Marshaller for Geometry::Ray to
  Geometry/GeometryMarshallers.h.
- Added scheduleUpdate() function to Vrui kernel API to request the next
  Vrui frame at the given application time.
- Changed Vrui::MouseNavigationTool and Vrui::MouseSurfaceNavigationTool
  to use Vrui::scheduleUpdate during animations.
- Changed Vrui::InputDeviceAdapterMouse to schedule a frame shortly
  after any mouse wheel tick to detect the end of mouse wheel motion.
- Changed animation and navigation tools to use scheduleUpdate.
- Changed order of Vrui library layers: Threads now below Plugins and
  Realtime, IO now above Threads.
  - Moved IO-related classes from Threads into IO library.
- Retired Threads::GzippedFile and Threads::GzippedFileCharacterSource.
- Retired Misc::ReadBuffer and Misc::WriteBuffer.
- Retired Misc::CharacterSource, Misc::BufferCharacterSource,
  Misc::FileCharacterSource, and Misc::GzippedFileCharacterSource.
- Retired Comm::TCPSocketCharacterSource.
- Removed superfluous reference to Misc::BufferCharacterSource from
  SceneGraph/Internal/Doom3MaterialManager.h.
- Created new IO::Directory abstraction.
  - Created concrete implementations IO::StandardDirectory and
    Cluster::StandardDirectory.
  - Added openDirectory functions to IO::OpenFile.h and
    Cluster::OpenFile.h.
- Improved openSeekableFile functions in OpenFile.h in IO, Comm, and
  Cluster libraries by automatically using an IO::SeekableFilter wrapper
  if the base file is not seekable.
- Improved IO::Directory:
  - Changed API compared to obsoleted Misc::Directory to increase
    performance when using Directory objects as file factories.
    Use
    while(dir.readNextEntry())
      ...dir.getEntryName()...
    instead of
    while(!dir.eod()) {
      ...dir.getEntryName()...
      dir.readNextEntry(); }
  - Added rewind() method.
  - Added hasParent / getParent directory traversal methods.
  - Added convenience method normalizePath.
- Added openDirectory method to IO::ZipArchive to traverse archives
  using an IO::Directory abstraction.
- Improvements to GLMotif::FileSelectionDialog:
  - Now uses IO::Directory objects to traverse directory structure.
	- Added getCurrentDirectory method to return currently displayed
    directory as IO::DirectoryPtr.
  - Added setCanSelectDirectory method to enable pressing OK when no
    file in the current directory is selected, in which case the OK
    callbacks are called with the full path of the current directory.
  - Added isFile flag to OKCallbackData to distinguish between file and
    directory names.
  - Changed OK callback data structure to provide an IO::Directory
    object for the current directory, and a directory-relative file
    name.
  - Added close method to simplify deleting a file selection dialog for
    callers.
- Added openDirectory function to Vrui::OpenFile.h.
- Adapted rest of Vrui to new file selection dialog API.
- Changed SceneGraph::Doom3FileManager to use IO::Directory objects for
  transparent file access.
- Added getPath(const char* relativePath) method to IO::Directory.
- Moved USB support classes from Kinect project into new USB Support
  Library (USB) and made a few additions.
- Added Endianness enumerated type to Misc/Endianness.h to unify
  separate definitions.
  - Changed "DontCare" enum to "HostEndianness".
  - Removed definition of Endianness from IO::File.
- Revived Misc::ReadBuffer with streamlined IO::File-like API.
- Significantly improved Misc/FunctionCalls.h:
  - Added functor type for const methods taking an additional argument.
  - Convenience functions are finally working.
- Added "confirm" flag to GLMotif::TextField::ValueChangedCallbackData
  so that a client can react if the user causes a confirmation event.
- Added new constructor for "save-like" file selection dialogs to
  GLMotif::FileSelectionDialog, which will then add a text field to
  enter a file name.
- Added a "Save View..." file selection dialog to Vrui.
- Added a "Save Input Graph..." file selection dialog to Vrui.
- Added createNumberedFileName to IO::Directory replacing
  Misc::createNumberedFileName.
- Created new VR device driver module for Razer Hydra desktop 6-DOF
  tracking devices.
- Improved Vrui build system to simplify creating extension libraries.
  - Moved DEPENDENCIES function and CREATE_SYMLINK and DESTROY_SYMLINK
    sequences into BuildRoot/BasicMakefile.
  - Replaced references to $(VRUIPACKAGEROOT)/BuildRoot with
    $(VRUI_MAKEDIR).
- Added optional cancel parameter to VRDevice::stopDeviceThread to
  handle cases where cancellation might cause trouble.
- Removed superfluous deinitialize method from Vrui::RevolverTool.
- Created Vrui tool to convert one or two buttons into a two- or three-
  state valuator, respectively.
- Created Vrui tool to convert a set of valuators into a pair of buttons
  each.
- Added configuration flag for pthread spinlocks support and fallback to
  mutexes if spinlocks are not supported.
- Fixed bad calls to Threads::MutexCond::broadcast in
  Sound::SoundRecorder.
- Changed build system to improve handling of optional system packages:
  - Split BuildRoot/Packages into Packages.System and Packages.Vrui.
  - Packages.System contains code to auto-detect optional system
    libraries.
  - Main Vrui makefile contains commented-out lines to disable each
    optional library individually if auto-detection fails.
  - Main Vrui makefile generates $(VRUI_MAKEDIR)/Configuration.Vrui
    makefile fragment with all settings configured during build.
  - Extension packages can add their own Packages.<extension> and
    Configuration.<extension> files in $(VRUI_MAKEDIR).
  - Moved common functionality from makefiles into build system files.
- Changed example programs makefile to use new modular build system.
- Added scaleFactor element to Vrui::PointingTool base class to enable
  proper scaling for remote pointing tools.
  - Adapted Vrui::LaserpointerTool and Vrui::JediTool to use
    scaleFactor.
- Needed to disable end-of-play detection in Sound::SoundPlayer:
  pcm_drain doesn't actually wait until all written samples have been
  played, so there is no way to tell when a PCM is done playing.
  Probably a bug in pulseaudio, that pile of manure. For now,
  SoundPlayer signals end-of-play when it's done writing, which can be
  many seconds before the PCM is done playing.

Vrui-2.2-002:
- Fixed minor bug in conditional compilation code in
  Images/ReadPNGImage.cpp when PNG library is not installed.
- Improved conditional compilation brackets in other
  Images/Read...Image.cpp sources.

Vrui-2.2-003:
- Added Vrui::getTimeOfDay to return the system's current wall clock
  time in a cluster-transparent fashion.
- Removed libv4l2.so library file from V4L2 package dependency, because
  it is not actually needed to use V4L2, and sometimes missing on older
  systems.
- Changed include order of makefile fragments in Vrui build system to
  work correctly when optional packages are manually disabled.

Vrui-2.3-001:
- Improved Vrui::WalkSurfaceNavigationTool:
  - Fixed crash when no jetpack valuator is assigned.
  - Improved jetpack handling
  - Added configuration options for jetpack acceleration and HUD font
    size.
- Changed void* to gzFile in IO/GzippedFile.h to account for changed
  zlib headers.
- Allowed per-instance override of Vrui::ViewpointFileNavigationTool's
  configuration settings.
- Fixed pixel pipeline handling in Vrui::VRWindow's InterleavedViewport
  mode.
- Fixed pixel pipeline handling in Video::YpCbCr420Texture.
- Added reset() method to GLShader.
- Added cross-machine thread identification mechanism to
  Threads::Thread.
  - Threads library again has a dynamic library file.
  - Threads library now requires initialization and deinitialization,
    transparently handled using gcc function attributes.
- Concomitant changes to Threads library:
  - Added optional debugging features selected by THREADS_CONFIG_DEBUG
    in Threads/Config.h.
  - Added configuration flag whether pthread implementation supports
    thread cancellation (Mac OS X doesn't).
- Overhaul of Cluster::Multiplexer:
  - Fixed bad bug: A slave missing a pipe-closing barrier completion
    message used to be left hanging; now master simply sends another
    completion message.
  - Removed internal structure definitions from Cluster/Multiplexer.h.
  - Improved protocol message data structures.
  - Fixed concurrent openPipe() calls by associating calls with global
    thread IDs provided by Threads::Thread.
  - Fixed another bad bug: In a broadcast cluster, master would receive
    its own multicast packets and sometimes interpret them wrongly.
  - Fixed packet handling bugs in Cluster::MulticastPipe that could lead
    to crashes or memory leaks.
- Added configuration option for intra-cluster MTU size to
  Cluster/Config.h. This allows to exploit jumbo packets by increasing
  from the default of 1500 bytes, albeit only at build-time.
- Fixed const bug in GLMotif::WidgetManager::getWidgetAttribute.
  Reported by Braden Pellett.
- Fixed missing system-package include directories in Vrui pkg-config
  file. Reported by Braden Pellett.
- Clarified normal vector transformation return value semantics in
  SceneGraph::PointTransformNode.
- Added handling of invalid elevation values to
  SceneGraph::ElevationGridNode and improved performance somewhat.
- Fixed copyright notices in GL/GLLightTracker.h and
  GL/GLLightTracker.cpp.
- Added OpenGL extension class for GL_EXT_rescale_normal.
- Added tracking of normal vector rescaling and/or normalization state
  to GLLightTracker.
- Added set... functions to GLLightTracker to avoid having to query
  state from OpenGL in many cases.
- Added GLLightTracker object directly to GLContextData.
  - Started using GLLightTracker in GLLabel's rendering methods.
  - Changed context data and display state initialization sequence in
    Vrui::VRWindow.
  - Removed GLLightTracker object from Vrui::LightsourceManager.
    - Vrui::LightsourceManager no longer has OpenGL state.
  - Added light tracker initialization to Vrui's display function.
- Added GLClipPlaneTracker, a class to track the state of OpenGL's
  clipping planes to support dynamic shader compilation.
- Added GLClipPlaneTracker object directly to GLContextData.
- Changed Vrui::ClipPlaneManager to use GLClipPlaneTracker.
  - Vrui::ClipPlaneManager no longer has OpenGL state.
  - Removed now-redundant disableClipPlanes method.
- Changed GLMotif::DragWidget from an intermediate base class into a
  mix-in class to increase flexibility.
  - Changed GLMotif::Slider and GLMotif::ScrollBar accordingly.
- Fixed minor layout bug in GLMotif::TextFieldSlider.
- Added GLMotif::HSVColorSelector, a class to select an RGB color using
  an interface around the HSV color model.
- Added GLAutomaticShader, a base class for GLSL shaders that
  automatically track the fixed-functionality state of the current
  OpenGL context.
- Added GLLineLightingShader, a shader for Phong illumination of curves.
- Changed default Vrui.cfg such that selection rays are not drawn in
  desktop mode.
- Fixed ray drawing behavior in Vrui::RayInputDeviceTool.
- Implemented Vrui::VRWindow::setCursorPos and
  Vrui::VRWindow::setCursorPosWithAdjust for split-viewport windows.
- Added Threads::Atomic, a class for atomic operations on integral value
  types.
- Finally fixed bug in program shutdown detection for headless Vrui
  environments.

Vrui-2.4-001:
- Fixed some subtle potential problems in Cluster::Multiplexer's packet
  loss handling protocol.
- Changed key handling in Vrui::VRWindow:
  - Screenshot key is now Win+PrintScreen.
    - Window now prints confirmation when saving a screenshot.
  - Exit application key is still Escape, but now without any modifier
    keys (except NumLock or CapsLock).
- Changed fps display in Vrui::VRWindow:
  - To show fps rate in window, window must have showFps=true, and must
    be in new "burn mode," where it requests Vrui frames as rapidly as
    possible.
  - Burn mode is entered/exited by pressing Win+ScrollLock.
  - Upon exiting burn mode, window prints total number of frames, time,
    and average fps.
- Added VR device driver module for various models of 5DT finger-bend
  data gloves, including simple gesture detection.
- Added several Vrui-wide command line options to Vrui::init:
  - -vruiHelp explains all Vrui-wide command line options.
  - -vruiVerbose prints details about Vrui's initialization and shutdown
    procedures.
  - dumpConfig writes the current configuration space, as the command
    line is being processed, to a configuration file.
- Fixed several bugs in Vrui's startup and shutdown procedure.
- Fixed potential spurious object deletion bug in Misc::Autopointer's
  assignment operators. Reported by Jens Bauer.
- Added missing #include <stddef.h> to Misc/ChunkedArray.h.
- Added detachPoints method to Geometry::ArrayKdTree to enable in-place
  kd-tree creation.
- Added Threads::Queue and Threads::LimitedQueue, two classes for simple
  unlimited and limited producer/consumer queues to Threads library.
- Added ability to request additional visual properties for Vrui's
  rendering windows before the main loop starts, such as stencil or
  accumulation buffers.
  - Added struct Vrui::WindowProperties.
  - Added Vrui::requestWindowProperties() to Vrui kernel API; can be
    called by any entity before Vrui's main loop starts.
  - Added property handling to Vrui::VRWindow's initialization code.
- Moved OpenGL initialization and buffer clearing code from
  Vrui::VruiState::display() to Vrui::VRWindow::render().
- Fixed cursor positioning code in Vrui::VRWindow once again.
- Added Geometry/IntersectionTests.h, providing namespace-global
  functions to test for intersections between various geometric objects.
- Added clamp() function to Math/Math.h.
- Added application state retention to Vrui::SurfaceNavigationTool.
  - Added AlignmentState base class.
  - Added alignmentState pointer to AlignmentData structure.
  - Added alignmentState pointer to tool state.
  - alignmentState pointers stay valid while the tool stays active.
- API change: removed limitAngle protected function from
  Vrui::SurfaceNavigationTool, replaced by Math::clamp in Math/Math.h.
- Added orthogonalize and reflect methods and friend functions to
  Geometry::Vector.
- Reduced default maxClimb value in Vrui::FPSNavigationTool and
  Vrui::WalkSurfaceNavigationTool.
- Changed Vrui::FPSNavigationTool to forward movement buttons when not
  active.
- Improved user guidance in tool creation status dialog by displaying
  the full name of the button/valuator to confirm or cancel creation.
- Changed GLMotif::CascadeButton to vertically center popups relative to
  the cascade button.
  - Added #define to GLMotif/CascadeButton.cpp to switch between old and
    new behaviors.
- Added getFileName function to Misc/FileNameExtensions.h.
- API change: Changed constructors of IO::StandardDirectory and
  Cluster::StandardDirectory to take const char* instead of std::string.
- Changed Vrui mainloop starter to properly handle command-line provided
  view files from other directories than the current. Pointed out by
  Braden Pellett.
- Added getDefaultRadius and getDefaultFlatteningFactor static methods
  to Geometry::Geoid.
- Added inverseTransform method to Vrui::CoordinateTransform and all
  derived transformation classes.
- Changed Vrui::GeodeticCoordinateTransform to use Geometry::Geoid class
  and its improved formula.
- Changed Vrui::MeasurementTool to store points in whatever selected
  coordinate system and render in physical coordinates.
- Added Vrui::AffineCoordinateTransform, a user transformation class for
  arbitrary affine transformations.
- Improved error handling in Vrui callbacks dealing with file selection.
- Improved behavior of Vrui scale bar when clicking on left or right
  ends.
- Added methods to couple and decouple cluster-forwarded pipes on demand
  to Cluster::ClusterPipe. While decoupled, slaves must not read from or
  write to pipe until re-coupled.
- Changed default for drawRay in Vrui::UserInterfaceTool; now defaults
  to !useEyeRay.
- Disabled interaction ray drawing in Vrui::MouseNavigationTool and
  Vrui::MouseSurfaceNavigationTool. After all, they're supposed to be
  used with mouse devices.
- Added GLMotif::PopupWindow::close, a convenience method to safely
  close and destroy a popup window from within a callback.
- Added static GLMotif::PopupWindow::defaultCloseCallback that simply
  destroys the window.
- API change: Rebased GLMotif::FileSelectionDialog::CallbackData to
  GLMotif::PopupWindow::CallbackData so that file selection dialogs can
  use PopupWindow's default close callback.
- Removed defaultCloseCallback and close methods from
  GLMotif::FileSelectionDialog; same functionality now handled by
  GLMotif::PopupWindow base class.
  - Adapted client classes and code accordingly.
- Added calback type for C functions taking no extra arguments to
  Misc::CallbackList.
- Replaced typeid comparisons in Misc::CallbackList with dynamic casts.
- Added constructor with piecewise linear color function to GLColorMap.
- Fixed typo in compile guard in GLARBTextureFloat OpenGL extension
  class.
- Added readMore method to Misc::DynamicArrayMarshaller.
- Added OpenGL extension class for GL_ARB_texture_rectangle.
- Added OpenGL extension class for GL_ARB_texture_rg.
- Added Misc::print, low-level helper functions to print all types of
  integers, to Misc/PrintInteger.h.
  - Changed the following classes and functions to use Misc::print:
    - Integer value coders in Misc/StandardValueCoders.h
    - GLNumberRenderer
    - GLLightTracker
    - GLClipPlaneTracker
    - GLLineLightingShader
    - GLMotif::TextField
- Added findParallelAxis and findOrthogonalAxis namespace-global
  functions to Geometry/Vector.h.
- Fixed bug in Geometry::Vector::operator- for 4 or more dimensional
  vectors. Pointed out by Chris Ellison.
- Added Math::Noise, implementing Ken Perlin's improved 3D band-limited
  noise function following his 2002 SIGGRAPH paper.
- Added IO::FileMonitor class to monitor changes to files or directories
  using Linux's inotify service; currently no Mac OS X implementation.
- Adapted GLColor, Video::V4L2VideoDevice, Vrui::InputDeviceAdapterHID
  to g++ 4.7.0.
- Added convenience functions to compile shaders from variable argument
  lists to GLARBShaderObject, GLARBVertexShader, GLARBGeometryShader4,
  and GLARBFragmentShader.
- Added convenience functions to link shaders from variable argument
  lists to GLARBShaderObject.
- Added convenience functions to compile shaders from already-opened
  files to GLARBVertexShader, GLARBGeometryShader4, and
  GLARBFragmentShader.
- Improved exception handling in GLSL shader convenience functions.
- Fixed key handling in Vrui::VRWindow when the shift key is held.
- Improved window handling by fixing window positioning code in GLWindow
  and adding toggle to disable window decorations to GLWindow and
  Vrui::VRWindow. Suggested by, and following code by, William Sherman.
- Finally caved and created alternative constructor for
  Vrui::Application that does not require the appDefaults argument.
- Added min and max functions to Math/Math.h.
- Added int versions of floor and ceil, which are both no-ops, to
  Math/Math.h for completeness sake.
- Added extension class for GL_ARB_draw_buffers.
- Removed GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT enum from
  GLEXTFramebufferObject extension because it was removed from the
  specification.
- Added convenience function to print frame buffer status to
  GLEXTFramebufferObject extension.
- Fixed bad initialization code in Vrui::ViewpointFileNavigationTool.
  Reported by Dawn Sumner.
- Fixed API mismatch bug in Vrui::CurveEditorTool. Reported by Dawn
  Sumner.
- Made some improvements to UI of Vrui::CurveEditorTool.
- Changed makefile to retain previously-installed versions of Vrui.cfg
  and VRDevices.cfg during make install.
- Added support for notches to GLMotif::Slider.
- Added variable speeds and playback control dialog to
  Vrui::ViewpointFileNavigationTool.
- Improved Vrui::InputGraphManager's loadInputGraph and saveInputGraph
  methods.
  - Changed naming scheme of created virtual input devices to make
    bindings mix-and-matchable; device names are based on section names.
  - Improved fault tolerance of loadInputGraph by catching binding
    exceptions per-section.
- Added bankFactor configuration setting to
  Vrui::SixAxisSurfaceNavigationTool.
- Added activation button and activationToggle setting to
  Vrui::SixAxisSurfaceNavigationTool.
- Added -loadInputGraph option to Vrui command line.
- Improved HUD rendering in Vrui::SixAxisNavigationTool and
  Vrui::HelicopterNavigationTool via new configuration settings hudDist,
  hudRadius, and hudFontSize.
- Added forwardShiftButton setting to Vrui::ShiftButtonTool.
- Added methods to temporarily pause all clipping to GLClipPlaneTracker.

Vrui-2.4-002:
- Adapted Realtime/AlarmTimer.cpp to API shift in signal.h. Pointed out
  by Braden Pellett.
- Fixed wrong base directory setting in template makefile installed in
  <install dir>/share/make.
- Added jumping to FPSNavigationTool; requires sixth button binding.
  Changed packaged Vrui.cfg accordingly.
- Fixed battery level indicator in Wiimote VR device driver module.
- Fixed handling of forced shutdowns in VRDeviceDaemon when clients are
  still listening.
- Fixed layout bug in GLMotif::FileSelectionDialog.
- Fixed file selection dialog handling bug in
  Vrui::ViewpointFileNavigationTool.
- Fixed bad bug in Cluster::ClusterPipe's handling of uncoupled pipes.
- Added Vrui::MultiShiftButtonTool, a tool class to manage multiple
  virtual button/valuator planes via a set of "radio buttons."
- Started moving Vrui tool classes towards per-tool configuration
  options.
- Added new string-based setGlyphType method to
  Vrui::GlyphRenderer::Glyph.
- Added Misc::FixedArray.
- Added value coder class for Misc::FixedArray to
  Misc/ArrayValueCoders.h.
- Added drag torque to Vrui::HelicopterNavigationTool.

Vrui-2.4-003:
- Removed superfluous copy constructors from tool configuration classes.
- Added five-axis surface-aligned navigation tool for spaceball or
  similar devices; acts like surface-aligned mouse navigation tool.
- Fixed lock type mismatch in fallback path of Threads::Atomic.
- Improved virtual compass handling in Vrui::MouseSurfaceNavigationTool
  and Vrui::FiveAxisSurfaceNavigationTool. Compass stays visible until
  the navigation transformation is changed from outside the tool. Also,
  moved compass rendering to display list.
- Fixed bug in tool deconstruction during Vrui shutdown.

Vrui-2.4-004:
- Removed default request for accumulation buffer from
  Vrui::WindowProperties to work with new Mac OS X, and certain virtual
  machines.
- Removed "find" warning on first-time builds from build system.

Vrui-2.5-001:
- Added marshaller for Misc::FixedArray wrapper class to
  Misc/ArrayMarshallers.h.
- Added support for two different viewers to Vrui::VRWindow, as a hack
  to allow another way of setting up split views specifically for
  filming.
- Added readFromPipe method to Misc::ConfigurationFile.
- Improved debugging mode in Cluster::Multiplexer.
- Added Cluster::ThreadSynchronizer, a helper class to ensure that
  thread IDs stay consistent across a cluster even when different code
  paths are used on master and slaves.
- Added cluster thread synchronization to
  Vrui/Internal/Vrui.Workbench.cpp.
- Fixed bug when automatically incrementing a GLMotif::Slider.
- Slightly improved debugging output in Cluster::Multiplexer's verbose
  mode.
- Fixed some minor issues in calibration utilities.
- API change: removed defaultCloseCallback in GLMotif::PopupWindow.
  - Added popDownFunction and deleteFunction instead.
  - Added convenience methods popDownOnClose and deleteOnClose.
- Added deleteOnCancel to GLMotif::FileSelectionDialog.
- Build system change: debug version of Vrui build system now installed
  in /debug/ subdirectory of $(VRUI_MAKEDIR). Application makefiles need
  to be adapted accordingly, following the template makefile in
  $(VRUI_MAKEDIR).
- Added MAKEINSTALLDIR variable to $(VRUI_MAKEDIR)/Configuration.Vrui.
- Fixed bug in Vrui verbose mode.
- Improved window initialization logging in Vrui verbose mode.
- Improved error handling in Comm::UDPSocket.
- Improved error handling in Calibration/NaturalPointClient.cpp.
- Improved error handling in MeasureEnvironment calibration utility.
- MeasureEnvironment calibration utility now saves points received from
  an OptiTrack engine when user requests saving measurement file.
- Improvements to SceneGraph::ElevationGridNode:
  - Added ability to load elevation grids from greyscale image files.
  - Added heightScale field.
  - Fixed minor bug in file type checking.
- Added explanation of vertex coordinates to icosahedron generator in
  GL/GLModels.cpp.
- Removed manage checks in resize() methods of several GLMotif widgets,
  which caused initialization problems.
- Added -physical option to SceneGraphViewer vislet to place scene
  graphs into physical space.
- Enabled texture transformations in SceneGraph::AppearanceNode.
- Added simplified method to bind callback methods to input device
  button presses to Vrui::Application; removes almost all overhead from
  creating simple button-based user interfaces.
  - Added VruiEventToolDemo to ExamplePrograms to illustrate the new
    event tool mechanism.
- Adapted Wiimote VR device driver module to new bluetooth protocol used
  in Wii Remote Plus devices.
- Improvements to build system to reduce redundancies during linking and
  fix plug-in library issues on newest Ubuntu release (pointed out by
  Hannes Hofmann and Chris Want).

Vrui-2.6-001:
- Disabled clipping planes for CAVERenderer vislet.
- Added methods to set and query individual viewers and screens to
  Vrui::VRWindow.
- Added getItemWidget() and getItem() convenience methods to
  GLMotif::DropdownBox::ValueChangedCallbackData.
- API change: Changed vislet initialization procedure:
  - All vislets start in disabled state.
	- Added enable() and disable() methods to Vrui::VisletManager.
  - Each vislet's enable() methods is called once immediately before
    Vrui's main loop starts.
  - Each active vislet's disable() method is called immediately after
    Vrui's main loop ends.
- Added isReal() and isGrabbed() methods to Vrui::InputGraphManager.
- API change: changed semantics of Vrui::getNumWindows() and
  Vrui::getWindow() functions:
  - Vrui::getNumWindows() returns total number of windows in the entire
    environment, including non-local windows on other cluster nodes.
  - Vrui::getWindow() returns NULL for non-local windows.
  - Vrui::calcViewSpec returns garbage for non-local windows.
- Added uniform scaling glScale(factor) to GL/GLMatrixTemplates.h.

Vrui-2.6-002:
- Added new filming support vislet to interactively change rendering
  modes and camera positions.
- Fixed linking problem in Razer Hydra VR device driver module.
- Added template setup for Razer Hydra to VRDevices.cfg.
- Added patch configuration files for typical 3D TV and Razer Hydra.

Vrui-2.7-001:
- Fixed missing initialization of heightScale in ElevationGrid scene
  graph node.
- Added missing #include <sys/types.h> to Images/ImageReader.h.
- Fixed typo in compilation guard in Video/TheoraDecoder.h.
- Added Video::ImageExtractorYV12, an image extractor class for Y'CbCr
  4:2:0 video frames.
- Added pixel format request option to Video::VideoDevice::configure.
- Fixed compilation problem with Razer Hydra driver on systems with
  libusb1 in a non-standard location.
- Added some error recovery to Video::V4L2VideoDevice's capture thread.
- Added new video viewer example program using the Video library.
- Added Video::ImageExtractorY10B to unpack 10-bit greyscale video from
  the Kinect's IR camera.
- Added support for Y10B and GRBG pixel formats to
  Video::V4L2VideoDevice.
- API change: changed how Vrui's scene graph module handles
  transformation nodes to support working around OpenGL's precision
  limits. The SceneGraph::GLRenderState constructor now takes an initial
  transformation from eye space to model space.
- Added scene graph support functions in Vrui/SceneGraphSupport to
  simplify creating SceneGraph::GLRenderState objects, and rendering
  simple scene graphs.
- Changed all uses of the scene graph inside Vrui to new API and
  convenience functions.
- Added moveToOrigin flag and originPoint position to
  SceneGraph::GeodeticToCartesianPointTransformNode to work around
  precision problems.
- Changed internal representation of transformations in
  SceneGraph::GLRenderState to double precision.
- Changed transformation stack manipulation code in
  SceneGraph::TransformNode to work with temporary double-precision
  transformations.
- Added manual control of RTS/CTS lines to Comm::SerialPort.
- Added (experimental) device driver for Ascension Wanda 6-DOF tracked
  wands compatible with Flock of Birds tracking system.
- API change: Changed access of elements of Geometry::Geoid to
  protected.
- Added new Geometry::AlbersEqualAreaProjection class to transform from
  Albers equal area conic coordinates to geodetic and Earth-centered
  Earth-fixed Cartesian coordinates and back.
- Added hyperbolic trigonometric functions and their inverses to
  Math/Math.h.
- Added new Geometry::UTMProjection class to transform from Universal
  Transverse Mercator coordinates to geodetic and Earth-centered Earth-
  fixed Cartesian coordinates and back.
- Adapted SceneGraph::ESRIShapeFileNode to use new projection classes.
- Added Geometry::LambertConformalProjection class to transform from
  Lambert conformal conic coordinates to geodetic and Earth-centered
  Earth-fixed Cartesian coordinates and back.
- Added Math::copysign as a generic function for all signed types to
  Math/Math.h.
- Added "inverseFlattening" virtual field to
  SceneGraph::ReferenceEllipsoidNode.
- API change: Changed data types of points and vectors used by
  SceneGraph::PointTransformNode and derived classes to double.
- Added inverseTransformPoint and transformBox virtual methods to
  SceneGraph::PointTransformNode.
- Added parsers for double-precision points and vectors to
  SceneGraph::VRMLFile.
- Added SceneGraph::UTMPointTransformNode to transform from UTM
  coordinates to geodetic coordinates.
- Added translateOnly flag to
  SceneGraph::GeodeticToCartesianTransformNode to simplify undoing a
  offset point transformation.
- Added SceneGraph::ImageProjectionNode to support on-the-fly
  reprojection of georeferenced images onto elevation grids.
- Added imageProjection field holding an ImageProjection node to
  SceneGraph::ElevationGridNode.
- Added "pure" color snapping to GLMotif::HSVColorSelector.
- Added GLMotif::MaterialEditor, a composite widget to edit OpenGL
  material properties.
- Inconsequential changes in GLMotif::RowColumn::draw and
  GLMotif::RowColumn::findRecipient methods.
- New GLMotif::Pager class to create multi-page flip-book style
  container widgets.
- Added Geometry::GeoCoordinateSystem, an abstract base class to
  represent geodetic coordinate systems, and a namespace-global function
  to parse projection files in WKT (well-known text) format.
- Geometry library now depends on IO library.
- Corrected handling of absolute file and directory names in
  IO::StandardDirectory and Cluster::StandardDirectory.
- Added new Geometry::TransverseMercatorProjection class to transform
  from generic transverse Mercator coordinates to geodetic and Earth-
  centered Earth- fixed Cartesian coordinates and back.
- Changed TIFF reader in Images::getImageFileSize to suppress warnings
  messages from the TIFF library.
- Fixed problem in IO/StandardFile and Cluster/StandardFile with
  returning stale data in a read immediately following a write and
  flush.
- Added simple "alarm" facility to Threads::Queue, where a caller can
  wait until at least a given number of consumers is blocked on an empty
  queue.
- Removed redundant conditional in Geometry::ClosePointSet::insertPoint.
- Added non-recursive versions of Geometry::ArrayKdTree's
  traverseTreeDirected and findClosestPoints methods, for fugly code and
  a significant speed-up.
- Improved configuration parser in Vrui::SixAxisTransformTool; setting
  homePosition now works as expected.
- Fixed visibility of Plugins::FactoryManager::DestroyFactoryFunction.
- Added findChild and findDescendant methods to GLMotif::Container.
- Added state saving to Vrui::AnnotationTool.
- API change: added addAbstractClass to Vrui::ToolManager. Abstract tool
  classes, i.e., those that have child tool classes, must be registered
  using the new method instead of addClass.
- Added experimental hack to Vrui::VRWindow::render to increase the
  precision of OpenGL's matrix stack by calculating the accumulated
  rounding error in the modelview matrix and applying a correction
  translation.
- Added Vrui input device adapter to receive tracking, button, and
  valuator data from an external trackd daemon, including an option to
  convert tracking coordinate systems on-the-fly.
- Added DrawEnvironment, a simple program to visualize the layout of a
  Vrui environment, to example programs.
- Fixed #include bug in Geometry/UniformScalingTransformation.cpp.
- Added Vrui::FileSelectionHelper, a helper class to simplify working
  with GLMotif file selection dialogs.
- Simplified file selection code inside Vrui by using
  Vrui::FileSelectionHelper.
- Changed Vrui view menu: Added dedicated push/pop buttons; "save view"
  no longer pushes.
- API change: changed loadInputGraph and saveInputGraph methods in
  Vrui::InputGraphManager to accept an IO::Directory& and a directory-
  relative file name.
- Included the virtual clay modeling application as another Vrui example
  program.
- Added ImageSequenceViewer as Vrui example program.

Vrui-2.8-001:
- Added singular value decomposition, following Gene Golub's 1970 paper,
  to Math::Matrix. Need to do more testing.
- Fixed shared memory handling bug in Vrui::InputDeviceAdapterTrackd,
  found by Calvin Robinson.
  - Fixed another bug: passed calibrat*ion* transformation to controlled
    device instead of calibrat*ed* transformation. D'oh.
- Changed Vrui.Workbench.cpp to look for configuration files requested
  by -mergeConfig in the main configuration directory first.
- Fixed bug in VRDeviceDaemon/VRDeviceServer: default TCP port number
  now correctly uses kernel-assigned listening port number.
- Added suspend/resume functionality to
  SceneGraph::Doom3MaterialManager::RenderContext.
- Improved error handling in USB::Device::claimInterface.
- Shuffled some code in Vrui::VRWindow::render().
- Simplified tool kill zone position reading code in
  Vrui::VRWindow::VRWindow.
- Started adding lens distortion correction facilities to Vrui::VRWindow
  to add support for Oculus Rift HMD.
- Behavior change: calling initExtension on an OpenGL extension object
  not supported by the local OpenGL will throw an exception.
  - Changed GLShader, GLGeometryShader, GLFrameBuffer, and
    Vrui::VRWindow to use new simplified extension initialization.
- Added VRUI_APPLICATION_RUN(AppClassName) macro to Vrui/Application.h.
- Added glDrawArrow function to GL/GLModels.h.
- Added VR device driver for the Oculus Rift's built-in orientational
  tracker.
- Added two patch configuration files for Oculus Rift (5.6" and 7.0"
  screens), and a template section for its tracker in VRDevices.cfg.
- Added a main menu with toggle buttons for each loaded scene graph to
  VruiSceneGraphDemo.
- Added getWriteSize() method to IO::FixedMemoryFile.
- Added new ToggleButtonTool to convert a set of regular buttons into
  toggle buttons.
- Added explicit sync() method to Cluster::ThreadSynchronizer.
- Added thread ID synchronization points to Vrui initialization sequence
  to guarantee matching thread IDs during vislet and tool creation.
- Improved Vrui initialization so that input devices, viewers, and
  listeners have valid states when Vrui::init function returns.
- Improved valuator naming scheme in Vrui::WalkSurfaceNavigationTool.
- Added Vrui::ValuatorWalkSurfaceNavigationTool to add valuator-based
  movement to Vrui::WalkSurfaceNavigationTool.
- Added support for TIFF format to Images::writeImageFile, if TIFF
  library is installed.
- Improved start-up behavior of Vrui::ViewpointFileNavigationTool.
- Added "raw" interface to Images::writeImageFile.
- Changed Vrui::ImageSequenceMovieSaver to use Images::writeImageFile,
  giving it ability to write other formats than PPM.
- Fixed Vrui::InputDeviceAdapterPlayback for new Vrui startup sequence.
- Added movieFirstFrameIndex configuration tag to
  Vrui::InputDeviceAdapterPlayback.
- Complete overhaul of window management in Vrui:
  - Windows are sorted into "window groups" using a groupId tag in a
    window's configuration file section.
  - Windows inside the same group share an X11 server connection, but
    can be directed to different X screens on the same server via the
    new screen tag in a window's configuration file section.
  - Windows inside the same window groups share OpenGL contexts and
    context data, and are always rendered in sequence.
  - Different window groups have separate OpenGL contexts and context
    data, and are rendered in parallel from multiple threads if support
    for multithreaded OpenGL is enabled via setting GLSUPPORT_USE_TLS to
    1 in the makefile.
  - Window groups should coincide with physical GPUs inside the host
    system for optimal performance.
  - Resulting API changes: new class GLContext, many changes in GLWindow
    and VRWindow. These changes do not affect the Vrui API.
  - windowsMultithreaded and node<index>WindowsMultithreaded tags in
    configuration file root section no longer exist.
  - MYGLXSUPPORT package now depends on MYGLSUPPORT.
- Added new page describing multi-window rendering options to Vrui
  documentation.
- Added questions about multi-window rendering and context data
  management to Vrui FAQ.
- Fixed memory leak in Vrui::FileSelectionHelper destructor.
- Removed compose status handling from XLookupString call in
  Vrui::VRWindow event handler to follow Xlib manual recommendation.
- Fixed build commands for single-source executables in
  BuildRoot/BasicMakefile.
- Added functions to extract blobs of foreground pixels from images to
  Images/ExtractBlobs.h.
- Removed EnterWindowMask and LeaveWindowMask from X window event mask
  in GLWindow.
- Added FocusChangeMask to X window event mask in Vrui::VRWindow.
- Changed event behavior in Vrui::VRWindow:
  - Vrui display size tracks exact window size when panningViewport is
    true.
  - Vrui display center and size are updated when switching focus
    between multiple windows with panningViewport.
  - Tool kill zone tracks properly when switching focus.
- Started removing direct references to mouse input device adapters from
  desktop-based tool classes.
- Added Vrui kernel functions: getUiPlane, calcUiPoint, calcUiTransform.
  Might disappear again as Vrui moves towards having a proper "3D window
  manager."

Vrui-3.0-001:
- Added subdivision to SceneGraph::QuadSetNode to support non-linear
  point transformation. Controlled by new fields subdivideX and
  subdivideY.
- Added check for shutdown to beginning of Vrui::mainLoop in
  Vrui/Internal/Vrui.Workbench.cpp to allow applications to exit during
  initialization by calling Vrui::shutdown().
- Changed lens distortion correction code in Vrui::VRWindow:
  - Changed lcPoly to work with "normalized" coordinates in the [-w/h,
    w/h] x [-1, 1] range for wide (half-)screens and the [-1, 1] x
    [-h/w, h/w] range for tall (half-)screens. Makes it compatible with
    factory calibration data stored in Oculus Rift HMD.
  - Changed lcCenter to viewport-relative in [0, 1] x [0, 1].
  - Enabled flexible overscan by extending each border of the view
    individually.
- Added accelerometer and magnetometer correction to Oculus Rift
  tracking driver.
- Added useMagnetometer switch to Oculus Rift tracking driver.
- Improved tracking data output format of DeviceTest utility.
- Changed section header parser in Misc::ConfigurationFile; section
  names are now read to end-of-line; quoted section headers are parsed
  as before for backwards compatibility.
- Added special "+=" operator to the Misc::ConfigurationFile parser to
  concatenate list-valued tags instead of overriding them. Requires that
  current tag value ends with a ')', and new value starts with a '('.
  Will remove starting/ending parentheses, insert a ", " list item
  separator if the current list is not (), and concatenate the current
  and new values. Will not do any other checking or processing.
- Added "intersect" element and configuration file tag to Vrui::VRScreen
  to exclude unsuitable screens, such as HMD screens, from UI
  intersection tests.
- Added operator/= and operator/ to Geometry::Rotation.
- Added operator^ to Geometry::Vector as shorthand for vector cross
  product.
- Replaced Geometry::cross with operator^ in all library sources.
- Added one frame delay to Vrui::InputDeviceDataSaver so that audio
  recording starts at the first frame boundary, as playback expects.
- Fixed PCM draining behavior in the ALSA version of
  Sound::SoundRecorder.
- Added hudRadius configuration file tag to
  Vrui::ValuatorWalkSurfaceNavigationTool.
- API changes in Vrui::VRDeviceClient:
  - Rebased callback objects to Misc::FunctionCall.
  - Changed callback semantics: callbacks only valid when in streaming
    mode.
  - Removed enable/disable methods for packet notification callback;
    callback object is now passed to startStream method.
  - Added error callback to notify clients of errors encountered in
    background streaming thread.
  - ProtocolError exception class now contains pointer to client object
    causing the exception.
  - Error callback receives ProtocolError exception object.
  - Added proper error handling to getPacket() when in streaming mode.
  - No longer crashes when server connection breaks down in streaming
    mode.
- Changed Vrui::InputDeviceAdapterDeviceDaemon to new
  Vrui::VRDeviceClient API and added proper error handling. Vrui
  applications now keep running when device server connection goes down.
- New error handling keeps device server socket open if either side
  crashes.
- Adapted and robustified DeviceTest utility.
- Added CFixedArrayCoder, a class to encode/decode arrays with compile-
  time known sizes, to Misc/ArrayValueCoders.h.
- Changed all uses of Misc::FixedArrayValueCoder in library sources to
  Misc::CFixedArrayValueCoder.
- API change: changed Misc::FixedArrayValueCoder to keep numElements and
  elements pointer (for decoding) as state instead of method parameter;
  methods no longer static.
- API change: changed Misc::DynamicArrayValueCoder to keep numElements
  and elements pointer (for decoding) as state instead of method
  parameter; methods no longer static.
  - Actual number of elements in parsed array now written to numElements
    upon exit from decode().
- API change: changed the retrieveValue and storeValue methods in
  Misc::ConfigurationFile that take non-standard value coder classes to
  expect a value coder object as last parameter, and changed their names
  to ...WC (for "with coder") to avoid template ambiguities. Work in
  progress.
- Improved retrieveValue methods in Misc::ConfigurationFile: methods
  with default values only call encode if absolutely necessary.
- Added Vrui/Internal/VRDeviceDescriptor to enable defining compound
  devices on the device server instead of the device client.
- API change: changed type of configuration file section in
  Vrui::Tool::configure to const; must be fixed by client code since
  configure methods without const modifier will be ignored without
  compiler warnings.
- API change: changed type of configuration file sections in state-
  reading functions to const throughout library.
- Added contains() methods to GLWindow::WindowPos.
- Changed mouse position traded between Vrui::VRWindow and
  Vrui::InputDeviceAdapterMouse from screen coordinates to window
  coordinates, as the former have become ambiguous due to dual-screen
  windows.
- Added grabPointer() and releasePointer() methods to GLWindow.
- Fixed Vrui::FPSNavigationTool to work with changed VRWindow and
  InputDeviceAdapterMouse interface.
- Fixed accelerometer and magnetometer correction in Oculus Rift
  tracking driver.
- Changed Vrui::Viewer to immediately reflect the state of the head
  tracking input device to reduce latency.
- Changed Vrui::InputDeviceManager to always place mouse input device
  adapters at the end of the adapter list in case the mouse depends on
  other input devices (if viewers or screens are head-tracked).
- Added code to change mouse cursor shape in all windows when switching
  a mouse input device adapter between keyboard and button mode.
  - Does not yet work for fake mouse cursors.
  - Removed now-superfluous glRenderAction method.
- Added buttonIndexBase and valuatorIndexBase configuration file tags to
  Vrui::VRDeviceDescriptor.
- Major API change in Vrui::InputDevice: added device ray starting
  parameter as device state, and made deviceRayDirection part of current
  state to support better handling of ray-based input devices.
  - Renamed setDeviceRayDirection method to setDeviceRay and added ray
    start parameter as method parameter.
  - setDeviceRay can only be called immediately before
    setTransformation.
  - Added getDeviceRayStart and getRay methods.
  - Added deviceRayDirection and deviceRayStart to input device state
    distributed by Vrui::MultipipeDispatcher.
  - Added deviceRayStart as per-device configuration option to
    Vrui::InputDeviceAdapter.
  - Added device ray start to Vrui::VRDeviceDescriptor.
  - Added rayStart configuration parameter to
    Vrui::InputDeviceAdapterTrackd.
  - Added device ray direction and start to state saved by
    Vrui::InputDeviceDataSaver and loaded by
    Vrui::InputDeviceAdapterPlayback.
    - Upped file version number to 3.0.
    - Also added linear and angular velocities.
  - Fixed device ray handling in Vrui::ToolManager.
  - Fixed device ray handling in Vrui::TransformTool.
  - More fixes in Vrui::WandNavigationTool,
    Vrui::SixDofWithScaleNavigationTool, Vrui::FPSNavigationTool,
    Vrui::MouseTool, Vrui::EyeRayTool, Vrui::TwoRayTransformTool,
    Vrui::SixAxisTransformTool, Vrui::PanelMenuTool, Vrui::WidgetTool,
    and Vrui::ScrollTool.
  - Fixed PrintInputDeviceDataFile utility.
  - Fixed device rendering in Vrui::InputGraphManager so that device
    glyphs are properly aligned with a device's ray direction.
  - Added mouse device velocity calculation to
    Vrui::InputDeviceAdapterMouse.
- Split Vrui::InputGraphManager's glRenderAction method into
  glRenderDevices and glRenderTools to properly layer renderings when
  GLMotif widgets are drawn in an overlay plane.
  - Adjusted main rendering method in Vrui/Internal/Vrui.General.cpp.
- Changed rendering order in main rendering method in
  Vrui/Internal/Vrui.General.cpp so that tools are affected by clipping
  planes.
- Changed texture glyph rendering code in Vrui::GlyphRenderer to render
  glyph at given 3D position, but aligned to the current window's screen
  plane.
- Added lockMouse and unlockMouse methods to
  Vrui::InputDeviceAdapterMouse to support "relative" mouse mode, as
  used by Vrui::FPSNavigationTool.
- Fixed a time keeping bug in Vrui's main update method in
  Vrui/Internal/Vrui.General.cpp; frame times are now consistent at
  every step during frame processing.
- Fixed FPSNavigationTool to work again, now using input device
  velocities for rotation updates.
  - Changed rotateFactor configuration tag to rotateFactors, a 2D vector
    to support different horizontal and vertical speeds.
  - Changed moveSpeed to moveSpeeds, a 2D vector, to support independent
    speeds for forward motion and strafing.
  - Replaced HUD rendering code with same used in
    Vrui::SixAxisSurfaceNavigationTool with the following new settings:
    drawHud, hudColor, hudDist, hudRadius, hudFontSize.
- Changed Vrui::synchronize function: instead of setting the frame time
  for the current frame, it sets the frame time for the next frame and
  optionally delays the next frame until synch time matches real time.
  - Added synchFrameTime and synchWait elements to Vrui::VruiState.
- Added new state to Vrui::DisplayState:
  - Added current viewport position/size and frame buffer size of
    current window.
  - Added maximum viewport and frame buffer size of all windows in the
    current window group to support better frame buffer management.
- Changed VruiWindowGroup structure to associate viewport and frame
  buffer sizes with each window in a group.
- Added full handling of "virtual" input devices, assembled from a
  tracker and optional sets of buttons and/or valuators, to VR device
  daemon.
  - Changed version number of client/server protocol to 2
- Added handling of virtual input devices to Vrui::VRDeviceClient.
- Added option to list a device daemon's virtual devices to DeviceTest
  utility.
- Changed VRDeviceDaemon configuration file format: type of device
  calibrators is now listed inside the calibrator's section, using the
  "type" tag.
- Changed OculusRift VR device driver module to create one virtual
  device for the head tracker, "OculusRift" by default.
- Changed RazerHydra VR device driver module to create one virtual
  device for each handle, "RazerHydraLeft" and "RazerHydraRight,"
  respectively, by default.
- Added protected createIndexMappings method to
  Vrui::InputDeviceAdapterIndexMap.
- Added handling of server-defined virtual input devices to
  Vrui::InputDeviceAdapterDeviceDaemon.
- Changed Vrui::InputDeviceManager to remove all duplicates from the
  list of input device adapters to improve configuration modularity.

Vrui-3.0-002:
- Fixed tool name in Vrui::ValuatorWalkSurfaceNavigationTool.
- Fixed missing initialization of per-window group maximum frame and
  viewport sizes. D'oh!

Vrui-3.1-001:
- Added option to skip initial frames when saving movies using a
  Vrui::InputDeviceAdapterPlayback. Controlled by movieSkipFrames
  configuration file option.
- Added EyeCalibrator, a calibration program to generate precise viewer
  configurations, to Vrui utilities.
- Added new event tool creation and destruction callbacks to
  Vrui::Application to allow applications to manage event tool state.
  - Had to insert common base classes for event tools and their
    factories into Vrui::Application's private interface.
- Added PrecisionTest utility to Vrui example programs.
- Disabled some yet-unused code in SceneGraph::IndexedFaceSetNode.
- Removed O_NDELAY opening flag from Comm::SerialPort; must have been
  left over from some debugging or experiments.
- Fixed include file order in GL/Extensions/GLEXTTexture3D.cpp.
- Added new extension class GLEXTTextureInteger.
- Shuffled OpenGL matrix code in Vrui::VRWindow methods to save a few
  API calls.
- Reorganized off-screen rendering buffer management code in
  Vrui::VRWindow.
- Added automatic flush() to Comm::TCPPipe's destructor.
- Fixed getButtonDeviceRay and getValuatorDeviceRay methods in
  Vrui::Tool to take input device's rayStart parameter into account.
- Improved value coders for affine and projective transformations in
  Geometry/GeometryValueCoders.h; can now parse any combination of
  elementary transformations and matrices.
- Added delayed initialization option to GLObject constructor such that
  derived class state is properly constructed before initContext is
  called. Derived classes can pass false to the GLObject constructor,
  and initialize the GLObject at a later point inside the constructor
  by calling GLObject::init().
- Added delayed initialization to the following classes:
  - GLNumberRenderer
  - GLPolylineTube
  - Video::YpCbCr420Texture
  - SceneGraph::LabelSetNode
  - SceneGraph::TextNode
  - SceneGraph::QuadSetNode
  - SceneGraph::IndexedFaceSetNode
  - SceneGraph::Doom3MD5Mesh
  - Vrui::Vislets::CAVERenderer
  - Vrui::MouseCursorFaker
  - Vrui::JediTool
  - Vrui::GlyphRenderer
- Fixed wrong initialization order of window group frame sizes in
  Vrui/Internal/Vrui.Workbench.cpp.
- Fixed bad group stack management in
  Vrui/SceneGraph/Internal/LoadModelFromASEFile.cpp.
- Fixed wrong handling of absolute paths in
  IO::StandardDirectory::getPath and
  Cluster::StandardDirectory::getPath. Pointed out by Daniel Rubin.
- Added ViewerConfiguration, a Vrui vislet class to configure the eye
  positions of viewers from inside a running Vrui application.
- Fixed Vrui::RevolverTool::initialize() method to fully initialize
  virtual device state.
- Added option to use bicubic sampling during post-rendering lens
  distortion correction to Vrui::VRWindow.
- Added branch for unknown GL error codes to GL/GLPrintError.cpp.
- Fixed include file order in GL/Extensions/GLARBTextureRectangle.cpp.
- Added extension class for GL_EXT_packed_depth_stencil OpenGL
  extension.
- Added extension class for GL_EXT_framebuffer_multisample OpenGL
  extension.
- Added option to use multisampling for post-rendering lens distortion
  correction to Vrui::VRWindow.
- Added note that Oculus Rift tracker module depends on libusb-1 to
  makefile's configuration output.
- Added error check on number of connected devices to RazerHydra
  VRDeviceDaemon module.
- Added more content to "VR Device Daemon Configuration File Settings
  Reference."
- Added class USB::VendorProductId to represent USB device IDs.
- Added getDeviceDescriptor and getVendorProductId methods to
  USB::DeviceList.
- Added getVendorProductId method to USB::Device.
- Added functor-based getNumDevices and getDevice methods to
  USB::DeviceList to allow arbitrary matching comparisons. Implemented
  in USB/DeviceList.icpp.
- Changed default value of remoteControl tag in ArtDTrack VR device
  driver module to false; apparently, that functionality is no longer
  supported by DTrack.
- Fixed bug in animation parameter calculation in
  Vrui::ViewpointFileNavigationTool.
- Changed showGui setting default value in
  Vrui::ViewpointFileNavigationTool to true.
- Added Vrui build version and installation directories to output from
  -vruiVerbose command line option.
- Fixed orientation and ray start parameter of mouse input devices in
  screen plane.
- Fixed friend function declarations in Misc/FdSet.h; as a result, Vrui
  should now compile again with the new version of llvm shipping with
  Mac OS X Mavericks.
- Added panningDomain tag to Vrui::VRWindow's configuration settings to
  support panning windows in multi-monitor setups with mismatching
  resolutions.
- Fixed missing initialization in Geometry::Box::add. Pointed out by
  Jens Bauer.
- Fixed wrong destructor name in Vrui::GenericAbstractToolFactory.
  Pointed out by Jens Bauer.
- Adapted GLFrameBuffer class to revision #117 of
  GL_EXT_framebuffer_object extension specification. Pointed out by Jens
  Bauer.
- Introduced new variable SYSTEM_PACKAGE_SEARCH_PATHS to centralize
  search locations for system packages in BuildRoot/SystemDefinitions
  and BuildRoot/Packages.System.
- Added /opt/local to search paths when on Mac OS X, to accomodate
  MacPorts' default installation location. Suggested by Jens Bauer.
- Fixed wrong parameter name in declaration of Vrui::setBackplaneDist in
  Vrui/Vrui.h.
- Changed default rotate and scale factors in
  Vrui::MouseSurfaceNavigationTool to be display-dependent.
- Increased default rotation factors in Vrui::FPSNavigationTool for
  smoother rotation.
- Added initial code for Vrui::PanelButtonTool, but is not functional at
  this point.
- Added forward declarations for all friend functions defined inside
  class declarations to get rid of reliance on -ffriend-injection
  compiler flag, which no longer exists on C++ compiler shipped with Mac
  OS X Mavericks.
- Removed reliance on GL_GLEXT_PROTOTYPES from all source files.
- Removed handling of GL_GLEXT_PROTOTYPES from build system.
- Fixed a typo in function pointer loader in GLEXTPalettedTexture
  extension.
- API change: Added new extension class GLEXTFogCoord for
  GL_EXT_fog_coord extension.
  - Removed GL/GLFogCoordTemplates.h and added its functions to
    GLEXTFogCoord.h.
    - Removed #include <GL/GLFogCoordTemplates.h> from
      GL/GLPrimitiveTemplates.h.
  - Removed fog coordinate functions from GL/GLVertexArrayTemplates.h
    and added them to GLEXTFogCoord.
  - Removed fog coordinate gets from GL/GLGetPrimitiveTemplates.h and
    added them to GLEXTFogCoord.
- Added some smarts to the build system to generate better installation
  directory hierarchies.
  - Added new make target "planinstall" that prints out the configured
    installation directories.
  - Added description of installation hierachy, fine-tuning, and binary
    package generation to README file.
- Added getParent method to USB::DeviceList using the topology query
  functions from libusbx. Returns a null pointer for every device if
  libusbx is not installed.
- Added script to search for function declarations in system header
  files to Vrui build system.
- Added setting to select USB bus topology query functions to build
  system; auto-detected in BuildRoot/Packages.system; manual override in
  makefile.
- #ifdef-ed out experimental code in Vrui::VRWindow::render method to
  reduce numerical jitter when rotating; wasn't such a hot idea after
  all.
- Added SceneGraph::SphereNode (finally!).

Vrui-3.1-002:
- Fixed orientation of SceneGraph::SphereNode, and added flags to
  disable texture coordinate generation and to select icosahedral
  tesselation mode.
- Improved build system by using order-only prerequisites for
  prerequisite dynamic libraries.
- Fixed target directory generation in implicit makefile rules.
- Fixed templated function calls in Video::OggPage and
  Video::TheoraPacket. Pointed out by Jens Bauer.
- Clarified semantics of GLMotif::Container::getFirstChild: returns null
  if container has no children.
- Fixed getFirstChild method in GLMotif::RowColumn. Suggested by Jens
  Bauer.
- Fixed getFirstChild method in GLMotif::Pager.

Vrui-3.1-003:
- Fixed event handling bug in Vrui::VRWindow: keyboard events now set
  mouse position in window-attached mouse input device adapter, fixing
  a possible crash at start-up. Reported by Burak Yikilmaz.

Vrui-3.1-004:
- Fixed convenience function for argument-taking functions/methods in
  Misc/FunctionCalls.h.
- Replaced use of GL_ARB_imaging extension to create anti-aliased text
  in GLFont with software implementation.
- Added toggleFullscreen method to GLWindow class.
- Added code to toggle window's fullscreen state when Win+F is pressed
  to Vrui::VRWindow::processEvent.
- Changes to XBackground calibration utility:
  - Starts in windowed mode by default.
  - Passing -f on command line starts in full-screen mode.
  - Pressing "f" toggles window between windowed and full-screen modes.
- Fixed event handling in Vrui/Internal/Vrui.Workbench.cpp to properly
  react to Vrui::requestUpdate calls from background threads.
- Added isDeviceInToolKillZone method to Vrui::ToolManager, to allow
  tools or applications to use the kill zone for additional purposes
  such as deleting objects.
  - Changed device parameter of ToolKillZone::isDeviceIn method to
    const.
  - Updated derived classes accordingly.
- Added Geometry/LevenbergMarquardtMinimizer.
- Added Math/SimplexMinimizer.

Vrui-4.0-001:
- Removed some redundant matrix operations from lens correction shader.
- Refactored generic Vrui::GenericToolFactory class by splitting out
  code not dependent on template parameter.
- API change: Changed modal tool binding dialog to ask tool classes for
  proper function names for optional feature slots, instead of asking
  for name of first slot following required slots. Custom tool factory
  classes need to be checked for proper behavior.
  - Fixed slot function name handling in Vrui::GenericToolFactory
    classes.
- Split key name translation code from Vrui::InputDeviceAdapterMouse
  into new Vrui::KeyMapper class.
- Added option to represent modifier keys as special button keys to
  Vrui::InputDeviceAdapterMouse via modifiersAsButtons setting.
- keyboardModeToggleKey setting in InputDeviceAdapterMouse sections is
  now a qualified key name, i.e., combination of key name and modifier
  states.
- Moved window key parsing in Vrui::VRWindow to Vrui::KeyMapper class.
- Made window control keys in Vrui::VRWindow configurable via exitKey,
  screenshotKey, burnModeKey qualified key name settings.
- Added option for a global per-user Vrui configuration file to
  Vrui.Workbench.cpp, to better support system-wide Vrui installations.
  Uses HOME environment variable during run-time initialization to find
  configuration file.
- -mergeConfig Vrui option automatically appends .cfg extension, and
  merges given configuration files found in the system-wide and per-user
  global configuration directories, and then the fully-qualified file
  name as given.
- In GL/GLExtensionManager.cpp, renamed #define variable to
  GLSUPPORT_CONFIG_HAVE_GLXGETPROCADDRESS and moved from compiler
  command line to GL/Config.h.
- In GL/GLFont.cpp, renamed #define variable to
  GLSUPPORT_CONFIG_GL_FONT_DIR and moved from compiler command line to
  GL/Config.h.
- In SceneGraph/Internal/Doom3MaterialManager.cpp, renamed #define
  variable to SCENEGRAPH_CONFIG_DOOM3MATERIALMANAGER_SHADERDIR and moved
  from compiler command line to SceneGraph/Internal/Config.h.
- Created Vrui/Internal/Config.h file to provide configuration options
  to Vrui sources instead of using the compiler command line. Removed
  compiler command line definitions from:
  - Vrui/ToolManager.cpp
  - Vrui/VisletManager.cpp
  - Vrui/Internal/InputDeviceAdapterPlayback.cpp
  - Vrui/Internal/Linux/InputDeviceAdapterHID.cpp
  - Vrui/Internal/Vrui.General.cpp
  - Vrui/Internal/Vrui.Workbench.cpp
  - Vrui/Tools/JediTool.cpp
- Created VRDeviceDaemon/Config.h file to provide configuration options
  to VRDeviceDaemon sources instead of using the compiler command line.
  Removed compiler command line definitions from:
  - VRDeviceDaemon/VRFactory.icpp
  - VRDeviceDaemon/VRDeviceManager.cpp
  - VRDeviceDaemon/VRDeviceDaemon.cpp
- Changed installation path logic in makefile to install headers and
  libraries under named subdirectories of include and lib, respectively,
  when installing to a system location.
- Changed configuration logic in Vrui makefile to auto-set Vrui paths in
  template makefile in BuildRoot and makefiles in ExamplePrograms.
- Added mode for rendering checkerboard patterns to XBackground utility;
  can be used for camera calibration.
- Combined VRDEVICES_INPUT_H_HAS_STRUCTS and
  HIDDEVICE_CPP_INPUT_H_HAS_STRUCTS makefile variables into
  LINUX_INPUT_H_HAS_STRUCTS.
- Added #include <VRDeviceDaemon/Config.h> to
  VRDeviceDaemon/VRDevices/Linux/HIDDevice.cpp and fixed #define name.
- Changed makefile to execute configuration step only on first make, or
  when explicitly requested by "make config".
- Added separate handling for modifier key masks and Alt as modifier or
  button key on Linux and Mac OS X to Vrui/Internal/KeyMapper.cpp.
- Added valuator-based rotation and per-tool configuration to
  Vrui::ValuatorWalkSurfaceNavigationTool.
- Added OpenGL extension class for GL_ARB_debug_output.
- Minor error checking and connection management improvements in Wiimote
  VR device driver module.
- Added split method to Geometry::Polygon class.
- Fixed maximum number of vertices in temporary arrays during clipping
  and splitting in Geometry::Polygon.
- Added class Geometry::Paraboloid to perform ray intersection tests on
  upright circular paraboloids in n-dimensional affine space.
- Added a catch for unreadable video device controls to
  Video::V4L2VideoDevice::createControlDialog.
- Fixed a mistake in the comment for Geometry::SplineCurve's UNIFORM
  knot vector type.
- Fixed aliasing detection bug in Images::Image assignment operator.
- Added invalidate method to Images::Image.
- Changes to GLMotif::Image widget:
  - Added non-const getImage method and updateImage method.
  - Added methods to get/set interpolation mode (GL_NEAREST or
    GL_LINEAR).
  - Added method to enable/disable illumination.
  - Added methods to convert between image and widget coordinate spaces.
- Fixed scrolling and zooming behavior in GLMotif::ScrolledImage; now
  actually works as intended.
- Added reparent method to GLMotif::Widget.
- Added new constructor for GLMotif::ScrolledImage that takes an already
  existing widget derived from GLMotif::Image, and reparents it to the
  scrolled image shell.
- Fixed visibility of elements of GLMotif::Event.
- Behavior change to GLMotif event model: widgets now receive pointer
  motion events even when the pointer button is not pressed. This was
  always possible, but never happened because Vrui GUI tools did not
  send such events.
  - Added isPressed method to GLMotif::Event.
  - Fixed pointerMotion methods in several widget classes to work
    properly with non-pressed motion events:
    - Button, CascadeButton, DropdownBox, TextField, and PopupMenu.
- Change to text entry focus handling in GLMotif::WidgetManager:
  - Deleted widgets are automatically de-focused
  - Added hasFocus method.
  - Focus element in GLMotif::TextField no longer needed, but still
    there.
- Added SampleTrackerField to Vrui calibration utilities.
- Added new VR device calibrator class based on a forward grid look-up,
  to work with the grid sampling method used in SampleTrackerField.
- Added check to ensure that vislet enable toggle button state matches
  vislet's actual enable state in Vrui::VisletManager.
- Fixed OpenGL context state initialization sequence problem in
  Vrui::ValuatorWalkSurfaceNavigationTool.
- Fixed bug when assigning Vrui windows to window groups based on
  display name in Vrui/Internal/Vrui.Workbench.cpp.
- Fixed major bug in OpenGL context sharing; when calling
  registerContext multiple times for the same context, the same
  DisplayState object has to be returned.
- Moved pcm.prepare from Sound::SoundRecorder's constructor to the start
  method; apparently pulseaudio starts recording when prepare is called,
  not when record is called.
- Added Misc/VarInt.h, defining read/write functions for variable-sized
  unsigned integers.
- Added class Vrui::TextEventDispatcher to centralize management of
  GLMotif text and text control events and make them work reliably
  across a cluster, and between a saved and restored session.
- Added getTextEventDispatcher function to Vrui kernel interface in
  Vrui/Vrui.h.
- Added textEventDispatcher element to class VruiState in
  Vrui/Internal/Vrui.h.
- Added handling of text event dispatcher to Vrui initialization and
  update functions in Vrui/Internal/Vrui.General.cpp.
- Added text event handling to Vrui::InputDeviceDataSaver, changing the
  file format to version 4.0.
- Added pointer to text event dispatcher to Vrui::InputDeviceManager to
  give access to input device adapters that generate text events.
- Added text event handling to Vrui::InputDeviceAdapterPlayback.
- Replaced text event handling in Vrui::InputDeviceAdapterMouse with
  Vrui::TextEventDispatcher.
- Added resize callbacks to GLMotif::PopupWindow; are called after
  window layout has already been updated.
- Added getPathType method to IO::Directory to quickly check whether a
  directory-relative path exists, and what file system object type it
  is.
  - Implemented getPathType method in IO::StandardDirectory.
  - Implemented getPathType method in Cluster::StandardDirectory.
    - Needed to make pipe element of Cluster::StandardDirectory mutable.
- Rewrote major portions of IO::ZipArchive to make getPathType method
  efficient by caching a ZIP archive's directory tree in memory.
  - API change: IO::ZipArchive::DirectoryIterator class and related
    methods in IO::ZipArchive changed significantly.
    - Iteration now returns directories (except the root directory)
      themselves; added isDirectory method to check for iterator type.
- Punted on getPathType method in Doom3FileManagerDirectory in
  SceneGraph/Internal/Doom3FileManager because the whole thing is going
  to get changed anyway.
- Mopped up some leftover problems from change in input device ray model
  in several support or tool classes:
  - Vrui::GUIInteractor
  - Vrui::TwoRayTransformTool
  - Vrui::UserInterfaceTool
  - Vrui::ToolKillZoneBox
  - Vrui::MouseCursorFaker
- Mopped up some leftover problems from change to widget positioning
  method in several support or tool classes:
  - Vrui::RayMenuTool
  - Vrui::RayScreenMenuTool
- Added per-tool configuration to Vrui::UserInterfaceTool.
- Put a hack into Vrui::calcHUDTransform method to align the transform
  with the UI plane if the hot spot is already on the UI plane.
- Added discrete azimuth increment to Vrui::FPSNavigationTool following
  a suggestion by the good folks at Cloudhead Games.
- Additions to Vrui::ValuatorWalkSurfaceNavigationTool:
  - Added valuatorViewFollowFactor, a weight factor between moving
    relative to the fixed forward direction or current view direction
    when using the move valuators.
  - Added valuatorSnapRotate, a flag to rotate instantaneously when
    using the rotation valuator.
  - Added valuator forwarding for all bound valuators when tool is not
    active.
- Added Vrui::DeviceForwarderCreator, a helper class to assist device-
  forwarding tools in creating their forwarding virtual input devices,
  and associate input button slots with forwarded device features.
- Added enabled flag and isEnabled and setEnabled methods to
  GLMotif::Widget; findRecipient method returns false if widget is
  disabled.
- Changed GLMotif::Label to dim foreground color in disabled state.
- Changed GLMotif::Button and GLMotif::CascadeButton to ignore events
  when disabled.
- Changed Vrui/Internal/Vrui.h and Vrui/Internal/Vrui.General.cpp to
  disable the "Dialogs" cascade button in the system menu when there are
  no dialogs.
- Added projection matrix to Vrui::DisplayState object and changed
  Vrui::VRWindow::render() method to upload explicit projection matrix.
- Added GLTextureObject, a helper class to simplify managing single
  texture objects.
- Added setEntries() method for piecewise linear color function to
  GLColorMap.
- Added overloaded versions of glUniformMatrix4fv API call for Geometry
  library transformation types to GL/GLTransformationWrappers.
- Fixed typos in GLLightTracker's attenuated light accumulation vertex
  shader source templates.
- Refactored configuration management in Vrui::MultiShiftButtonTool and
  added configuration option initialPlane to select the initially active
  button/valuator plane.
- Added Misc::Optional, class representing optional values in
  configuration files.
- Added per-tool configuration management and option to draw the current
  interaction point and use a non-bound device for interaction (to
  support gaze-directed writing) to Vrui::QuikWriteTool.
- Added Oculus Rift-specific handling of interpupillary distance
  adjustment to Vrui::ViewerConfiguration vislet.
- Added FileSelection.cpp, a demonstration of file selection and file
  I/O, to Vrui example progams.
- Added Animation.cpp, a demonstration program for multi-threaded
  animation and retained-mode rendering.
- Added minSize elements and getMinSize/setMinSize methods to
  GLMotif::Label to specify lower bounds for labels' interiors.
- Added new transform tool class ThumbstickTransformTool for an
  experiment with thumbstick-based Quikwrite.
- Added optional OpenAL context creation attributes to
  Vrui::SoundContext: mixerFrequency, refreshFrequency, synchronous,
  numMonoSources, numStereoSources.
- Removed some Vrui configuration settings from Vrui/Internal/Config.h
  again because they were dependent on debug vs release mode.
- Changed Oculus Rift VRDeviceDaemon module to load calibration data
  from binary file identified by device's serial number.
- Changed OculusCalibrator utility to improve calibration matrices and
  automatically write calibration data to binary calibration file.
- Added getSpeedClass and getDescriptorString methods to USB::Device.
- Added bulkTransfer method to USB::Device.
- Changed forward declaration of GLMotif::StyleSheet from class to
  struct in several header files.
- Added ability to load single-viewpoint .view files in
  Vrui::ViewpointFileNavigationTool and refactored configuration
  management.
- Fixed argument type in convenience creator for single-argument C-style
  function calls in Misc/FunctionCalls.h.
- Fixed type in forward declaration of GLMaterial in Vrui/Vrui.h.
- Added getRoot method to GLWindow class to retrieve the X screen's root
  window.
- Added setWindowPos method to GLWindow, but window manager still gets
  its fingers in there.
- Added bypassCompositor method to GLWindow to try and reduce latency.
- Added output names to Vrui window configuration file sections, to send
  windows to named displays (by connector or monitor name) in multi-
  display environments. Almost plug&play.
  - New configuration tag outputName.
  - New configuration tag windowSize, to let Vrui choose window
    position.
- Added bypassCompositor tag to Vrui window configuration file sections.
- Improved Vrui desktop mode in multi-display environments by using the
  main display, or the display named in outputName, as the panning
  domain by default. Having multiple displays form a continuous screen
  now requires custom configuration.
- Added libXrandr as an optional library to Vrui dependencies, to
  support named displays.
- Fixed bug for negative indices in
  GLMotif::RadioBox::setSelectedToggle(int).
- Added copyTrackingState method to Vrui::InputDevice.
- Added option to follow a tracked device to per-device settings in
  Vrui::InputDeviceAdapterHID, selected by trackingDeviceName tag.
- Added bindAttribLocation and getAttribLocation methods to GLShader.
- Added preliminary Vrui::LensCorrector class to start refactoring the
  Vrui::VRWindow class and support newer lens distortion algorithms.
- Added preliminary support for forced vsync to GLWindow, via new
  methods canVsync, setVsyncInterval, and waitForVsync.
- Minor optimizations to OpenGL call sequence in Vrui::VRWindow and
  Vrui/Internal/Vrui.General.cpp.
- Added Realtime/Time.h, defining several classes to deal with
  nanosecond-resolution POSIX clocks.
- Added Realtime::Timer, a class for high-resolution timing and sleeping
  using a nanosecond-resolution monotonic system clock.
- Moved Realtime library towards bottom of library stack, just above
  Misc library, to allow inclusion in USB and RawHID libraries in the
  future.
- Added convenience functions to print error messages or throw
  exceptions about incomplete frame buffer objects to
  GL/Extensions/GLEXTFramebufferObject.h.
- Added experimental support for tracking data time stamps to
  VRDeviceDaemon protocol, upping protocol version to 3.
- Realtime library is now a dependency of Vrui library.
- Added option to print device data latency histograms to DeviceTest
  utility.
- Added clarification to Vrui::VRDeviceState that linear and angular
  velocities are defined in physical space, not device-local space.
- Fixed linear and angular velocities in Oculus Rift tracking driver;
  transformed from device-local to physical space.
- Added motion prediction for tracked devices to
  Vrui::InputDeviceAdapterDeviceDaemon.
- Added extension class GLARBInstancedArrays for GL_ARB_instanced_arrays
  extension.
- Added isDirect method to GLContext.
- Added extension class GLARBTextureMultisample for
  GL_ARB_texture_multisample extension.
- Cleaned up redundant uses of extension name strings in OpenGL
  extension classes.
- Added support for front buffer rendering to Vrui::VRWindow and did
  some minor clean-up.
- First version of Vrui::LensCorrector class ready:
  - Fully configurable for DK1, DK2, DK2 in rotated mode.
    - See Vrui Configuration File Reference for configuration options.
  - Lens distortion and chromatic aberration correction.
  - Support for OLED response time correction ("black smear" fix).
- Added new class Math::Histogram to create histograms of values of
  arbitrary scalar types.
- Added missing #include <Math/Math.h> to Images/ExtractBlobs.icpp and
  added MYMATH as dependency to MYIMAGES.
- Redid the internal API of Video::VideoDevice and derived classes to
  support dynamic registration of custom video device classes.
- Improved device enumeration code in Video::V4L2VideoDevice by only
  stopping when no more device nodes exist, not on other errors.
- Changed videoFd element in Video::V4L2VideoDevice to protected to
  allow deriving the class for quirky devices.
- Added Video::OculusRiftDK2VideoDevice as a subclass of
  Video::V4L2VideoDevice to support the tracking camera's quirky
  interface.
- Added fudge value to detect rank-deficient systems to
  Math::Matrix::solveLinearEquations.
- Added missing include files in USB/TransferBuffer.h and
  USB/TransferBuffer.cpp.
- Added initial version of RawHID library to Vrui installation.
- Added code to properly initialize HMD orientation to OculusRift
  VRDeviceDaemon module; removed previous fast-start code.
- Changed several Vrui classes so that object names read from
  configuration files now default to the name of the configuration file
  section containing them.
- Added get() method to Threads::Atomic.
- Re-implemented Threads::TripleBuffer using working lock-free
  synchronization method based on CAS loops.
- Behavior change: Threads::TripleBuffer::postNewValue() method no
  longer idempotent.
- Added texSubImage2D method to Images::Image and Images::RGBImage.
- Removed some conditional-dependent code in
  VRDeviceDaemon/NaturalPointClient.cpp inside conditional.
- Added MYREALTIME package to VRDeviceDaemon dependencies.
- Added Vrui::FileSelectionHelper::saveFile method with explicitly
  provided initial file name.
- Added optional preTransform configuration file setting to
  Vrui::InputDeviceAdapterPlayback to transform stored input device data
  using a global orthogonal transformation.
- Fixed behavior of "Save Curve File..." in viewpoint curve editor for
  cluster-based systems.
- Added a file defining an empty cursor (EmptyCursor.Xcur) to
  share/Textures directory to simplify disabling the mouse cursor for
  Vrui applications.
- Fixed bug in Misc::ConfigurationFile::readFromPipe: did not reset base
  section pointer.
- Added methods to and fixed bugs in Sound::ALSAPCMDevice.
- Added waitForConnection method to Comm::ListeningTCPSocket.
- Added IPv4Address and IPv4SocketAddress to Comm library.
- Added sendMessage and receiveMessage methods with recipient/sender
  addresses to Comm::UDPSocket.
- Added waitForMessage method to Comm::UDPSocket.
- Added setReadDataSize method to IO::FixedMemoryFile and adapted
  getSize method and added getMemorySize method to work with variable-
  size files; added clear method to write anew into an existing buffer.
- Added optional flag to open serial ports in non-blocking mode to
  Comm::SerialPort, to work around devices that don't provide a carrier
  signal. Call setPortSettings(Comm::SerialPort::Blocking) afterwards to
  go back to blocking read/write behavior.
- Added new class Math::VarianceAccumulator.
- Reimplemented Threads::RefCounted and Threads::RefCountedArray using
  Threads::Atomic.
- API change in USB library: Changed USB::Context to reference-counted
  singleton to automate handling of USB library contexts and event
  dispatch.
  - Major change is that applications or indirect clients of the USB
    library no longer need to use USB::Context objects.
  - Adapted all USB library clients to new API.
- Removed vruiTerminate function in Vrui.Workbench.cpp; wasn't used.
- Added constructor for pre-existing memory block to
  IO::FixedMemoryFile; the object will adopt the block and delete[] it
  when destroyed.
- Added IO::OStream, a wrapper class to layer a std::ostream abstraction
  over an IO::File object.
- Added option to disable grabbing the mouse pointer to
  Vrui::InputDeviceAdapterMouse.
- Added a background refresh thread for fake streaming updates to
  Video::ImageSequenceVideoDevice.
- Added support for raw files with varying data types and endianness to
  SceneGraph::loadElevationGridNode.
- SceneGraph::ElevationGridNode no longer silently ignores problems
  reading an external height file.
- Reworked Vrui::SketchingTool for better error handling and ability to
  create multiple sketch object types; right now, curves and polylines.
- Added getMaxIsoPacketSize method to USB::Device.
- Removed USB/TransferBuffer.* and added TransferPool class to USB
  library.
- Added getCurrent / setCurrent methods to IO::Directory to maintain
  library-wide current directory of arbitrary subtypes.
- Added code to set current directory of IO sublibrary to Vrui
  initialization.
- Added Misc::MessageLogger, a base class for centralized process-wide
  message loggers with environment-appropriate behavior.
- API change: Changed glPrintError in GL/GLPrintError.h to log to the
  global Misc::MessageLogger instead to a std::ostream.
  - Adapted Vrui::VRWindow::draw method.
- Changed several Vrui classes to use Misc::MessageLogger instead of
  printing to std::cout / std::cerr.
- Removed obsolete and #if 0-ed out code from
  Vrui::ToolManager::loadDefaultTools.
- Added USB_CONFIG_HAVE_STRERROR to USB/Config.h
- Added GLMotif::WidgetArranger, an abstract base class for widget
  positioning engines.
  - Added GLMotif::WindowWidgetArranger, a concrete arranger class for
    rectangular windows in the (x, y) plane.
- Added WidgetArranger pointer to GLMotif::WidgetManager, and added
  multiple versions of popupPrimaryWidget method using the arranger
  object.
- Added OpenGL extension classes for GL_ARB_vertex_array_object and
  GL_EXT_gpu_shader4. As per specification, functions and constants
  in GL_ARB_vertex_array_object do not have the ARB suffix.
- Added "Reset View" button to Vrui system menu. Works by calling a
  callback function, exposed by default as a virtual resetNavigation
  method in the Vrui::Application class.
- Fixed error recovery bug when reading/skipping quoted strings in
  IO::ValueSource.
- Fixed some minor directory traversal bugs in IO::ZipArchive.
- Added XInput2 extension package to Packages.System.
- Added Video::ImageExtractorY8 for 8-bit greyscale video.
- Added Y8 and GREY pixel formats to Video::V4L2VideoDevice.
- Added kernel bug fix check to Video::OculusRiftDK2VideoDevice.
- Added cluster pipe flushes to load/save callbacks in Vrui filming
  support vislet.
- Added auto and load options to Filming vislet's command line.
- Added VRWindow pointer to Vrui::InputDeviceAdapterMouse::resetKeys'
  signature to update current window.
- Added getUiManager() to Vrui core API.
- Configuration change: added uiManager tag to Vrui root section,
  pointing to section with UI manager configuration.
- Configuration change: added fullscreenToggleKey setting to Window
  sections.
- Changed how mouse-like 2D input devices are transformed into 3D input
  devices:
  - Changed signature of Vrui::InputDeviceAdapterMouse::setMousePosition
    to take two int parameters for x and y.
  - Removed windowMousePos state from Vrui::VRWindow.
  - Simplified Vrui::VRWindow::updateMouseDevice and added code to let
    the UI manager modify the mouse device position.
- Added mutual exclusion of active GUI interactors to Vrui::UIManager
  and removed it from Vrui::GUIInteractor.
- Changed Vrui::GUIInteractor to work with Vrui::UIManager.
- Removed GUI interaction state from core Vrui state.
- Added Vrui::UIManagerPlanar to lock UI components to an arbitrary
  plane.
- Removed popWidgetsOnScreen and widgetPlane elements from core Vrui
  state.
- API change: Removed getUiPlane, calcUiPoint, calcUiTransform, and
  calcHUDTransform functions from Vrui kernel API. Now handled by
  UIManager.
  - Adapted MouseNavigationTool, FiveAxisSurfaceNavigationTool,
    SixAxisNavigationTool, RevolverTool, RayMenuTool, QuikWriteTool.
- Removed eye ray option from Vrui::RayMenuTool, Vrui::WidgetTool, and
  Vrui::QuikWriteTool; can be achieved by stacking on top of an
  EyeRayTransformTool.
- Removed Vrui::RayScreenMenuTool.
- API change: Removed isUseEyeRay, getRayOffset, getInteractionPosition,
  calcInteractionRay, calcRayPoint, and calcRayTransform from
  Vrui::UserInterfaceTool. Had been replaced by methods in
  Vrui::GUIInteractor a long time ago.
  - Also removed interactionDevice element; now superfluous.
  - Adapted PanelMenuTool, SixDofInputDeviceTool, RayInputDeviceTool,
    SixAxisInputDeviceTool, PlaneSnapInputDeviceTool, WidgetTool,
    ScrollTool, DaisyWheelTool, QuikWriteTool
- Removed dependence on main viewer from RayInputDeviceTool; now uses
  ray direction as local interaction plane normal.
- Simplified getButtonDeviceRay and getValuatorDeviceRay methods in
  Vrui::Tool.
- Fixed uninitialized dragPlaneNormal bug in vertex dragging in
  Vrui::BoxRayDragger.
- Used new InputDevice::copyTrackingState method in Vrui::TransformTool.
- Minor simplification to Vrui::ButtonToValuatorTool.
- Removed superfluous #include <string> from Comm/IPv4SocketAddress.h.
- Made Comm::TCPPipe and Comm::ListeningTCPSocket IP address format-
  agnostic.
  - Added optional address family parameter to Comm::ListeningTCPSocket
    constructor.
- Removed some superfluous #includes from Vrui/Vrui.General.cpp.
- Added input device adapter for Oculus Rift HMDs using Oculus VR's
  tracking daemon.
- Added automatic screen projection to Vrui::LensProjector. New
  configuration tags: lensProjectionDist, leftLensProjectionDist,
  rightLensProjectionDist, projectScreens.
- Added VRWindow::updateViewerState to notify a window that a viewer
  has changed layout; used to update lens correction parameters.
  - Added Vrui::LensCorrector::updateViewerState.
  - Added call to updateViewerState to ViewerConfiguration vislet.
- Removed broken Oculus Rift-specific code from ViewerConfiguration
  vislet; lens shift is now handled by LensCorrector class.
- Added "Dummy" input device adapter to create non-moving input devices
  for debugging/development purposes.
- Replaced manual device tracking state copy with copyTrackingState call
  in Vrui::ToolManager's tool creation motion callback.
- Added display rotation to Vrui::LensCorrector via the displayRotation
  tag.
- Changed the dollying direction in Vrui::MouseNavigationTool to device
  ray direction to work better in multi-viewer setups.
- Removed ability to interact with GUI widgets from
  Vrui::MouseNavigationTool; can be achieved by layering a widget tool
  underneath the mouse navigation tool. Removed interactWithWidgets
  configuration option.
- Rewrote Vrui::MouseDialogNavigationTool based on
  Vrui::MouseNavigationTool.
  - Removed interactWithWidgets configurations setting.
- Rewrote Vrui::MouseSurfaceNavigationTool based on
  Vrui::MouseNavigationTool.
  - Removed interactWithWidgets configurations setting.
  - Renamed screenScalingDirection setting to scalingDirection.
  - Added configuration setting compassPos to position the virtual
    compass.
- Added animationFrameInterval state to Vrui state and function
  Vrui::getNextAnimationFrameTime() to Vrui kernel.
  - Removed hard-coded animation time intervals from all Vrui components
    and applications.
- Added -f command line option for fullscreen on startup, -d option to
  disable window decorations, window position initialization, and full-
  screen toggle key (F11) to XBackground.
- Added XInput2 X11 protocol extension (for multitouch screens) to system
  packages and internal Vrui configuration header.
- Added support for multitouch screens to Vrui's input device
  architecture:
  - Added Vrui::InputDeviceAdapterMultitouch to convert from X11
    multitouch events to multiple screen-based Vrui input devices.
  - Added initialization of XInput2 extension to Vrui::VRWindow.
  - Added event handling for XInput2 multitouch events to
    Vrui::VRWindow::processEvent.
  - API change: Changed name and interface of
    Vrui::VRWindow::updateMouseDevice to updateScreenDevice, and
    windowPos from int to Scalar.
    - Updated Vrui::InputDeviceAdapterMouse accordingly.
  - Added multitouch adapter creation to Vrui::InputDeviceManager.
  - Changed event mask source in GLWindow::disableMouseEvents().
  - Fixed isEventForWindow method in GLWindow to account for
    XGenericEventCookies.
  - Added Vrui::MultitouchFirstPersonNavigationTool for 1:1 scale walk-
    through navigation using multitouch screens.
- Replaced cout output in Vrui::InputDeviceManager with MessageLogger
  calls.
- Changed Vrui::MultiDeviceNavigationTool to new configuration method.
- Removed remnant code from Vrui::MultiDeviceNavigationTool that locked
  the rotation axis to the "up" direction in navigational space.
- Added peekApplicationTime function to internal Vrui kernel API to
  allow input device adapters to estimate the time stamp of the next
  Vrui frame.
- Changed RayInputDeviceTool to set grabbed device's selection ray to
  grabbing device's.
- Changed RayInputDeviceTool's default rotation factor to displaySize/4.
- Added setForegroundColor / getForegroundColor functions to Vrui kernel
  API, and foregroundColor configuration option to root configuration
  section.
- Changed Vrui::ScaleBar, Vrui::SixAxisNavigationTool,
  Vrui::PlaneSnapInputDeviceTool, Vrui::MeasurementTool,
  Vrui::MouseSurfaceNavigationTool, Vrui::MouseDialogNavigationTool,
  Vrui::FiveAxisNavigationTool, Vrui::MouseNavigationTool,
  Vrui::AnnotationTool, Vrui::ValuatorWalkSurfaceNavigationTool,
  Vrui::WalkSurfaceNavigationTool, Vrui::ScreenLocatorTool,
  Vrui::MouseTool, Vrui::QuikWriteTool, and Vrui::VRWindow to use
  Vrui::getForegroundColor().
- Added VisionTest to example programs; renders a standard test chart
  to measure the user's visual acuity through a VR display.
- Added Vrui::resetNavigationFunction to Vrui internal API.
- Added home key to Vrui::VRWindow as shortcut to reset the navigation
  transformation via an application-provided callback.
  - Added tag "homeKey" to VRWindow configuration section.
- Changed default position and orientation of Vrui::Viewer's head light
  to configured mono eye position and view direction, respectively.
- Added [min, max] frame time range to display when exiting burn mode.
- Added configuration option for cubic sampling during lens distortion
  correction to Vrui::LensCorrector.
- Fixed lens correction and FoV calculations based on closer examination
  of Oculus SDK. Seems to basically work now, minus potential issue in
  chromatic aberration correction.
- Moved FileSelectionHelper class from Vrui namespace into GLMotif
  namespace to make it available to lower-level libraries.
- Changed all uses of Vrui::FileSelectionHelper in Vrui library to
  GLMotif::FileSelectionHelper.
  - Did some minor improvement to Vrui tool classes using file selection
    helpers by making such on-demand singleton objects.
- Changed output operation for Geometry::Rotation to normalize rotation
  angle to the [0, +pi] range.
- Added more convenience methods to Misc::MessageLogger and simplified
  all uses within Vrui libraries.
- Added Vrui-specific child class of Misc::MessageLogger to send "user"
  messages to dialog windows.
- Improved error handling in VruiState::loadViewpointFile.
- Added Video::LensDistortion, a class encapsulating the lens distortion
  correction formula also used in OpenCV.
  - MYVIDEO package now depends on MYGEOMETRY package.
- Added dollyCenter and scaleCenter settings to
  Vrui::MouseNavigationTool and Vrui::MouseDialogNavigationTool to
  select center point of dollying and scaling operations.
- Fixed template bug (3 instead of dimensionParam) in
  Geometry::PCACalculator. Fortunately class was only defined up to 3.
- Added rounding to RGB-greyscale color conversion in
  Video::ImageExtractorRGB8.
- Fixed unescaped % conversion tags in error messages in
  Video::ImageSequenceVideoDevice.
- Changed camera name exported by custom Rift DK2 camera driver to
  "Oculus Rift DK2 Tracking Camera" to avoid confusion with kernel
  driver.
- Cleaned up memory leaks in exception handling for rank-deficient
  matrices in Math::Matrix.
- Modifications to Images::Image:
  - Made reference counting thread-safe; added Threads library to
    dependencies of Images library.
  - Added replacePixels and replacePixelRow methods that do not copy
    from a previously shared image representation.
- Added background image buffering to Vrui::TheoraMovieSaver to ensure
  smooth recording even at larger (1280x720@30Hz) window sizes.
- Took out code preventing window size changes in non-panned mode from
  Vrui::VRWindow.
- Improved behavior of panning VR windows.
- Automatically set Vrui install paths in makefiles included in Vrui
  package.
- Made evil "blinders" hack in Vrui/Internal/Vrui.General.cpp semi-
  official.
- Use GLClipPlaneTracker::pause to disable clip planes at end of
  VruiState::display in Vrui/Internal/Vrui.General.cpp.
- Added vislet class FrameRateViewer to draw a live frame time graph,
  currently pretty ugly.
- Changed initialization sequence of GLContext class to support display
  autodetection across multiple X screens. Updated GLWindow, VRWindow,
  and Vrui.Workbench.cpp accordingly.
- Fixed frame time interval calculation during burn mode.
- Changed Vrui::getOutputConfiguration to search across all screens
  attached to the X display.
- Changed window initialization sequence in Vrui.Workbench.cpp for
  better support of multiple X screens.
- Added explicit tracking type specification and UI manager projection
  flag to Vrui::InputDeviceAdapterHID to support ray-based interaction
  on 6-DOF source devices such as head trackers.
- Added virtual projectRay method to Vrui::UIManager.
- Changed hotspot calculation in Vrui::RayMenuTool to work better with
  different UI layout policies.
- Fixed shutdown core dump in cluster environments by adding explicit
  release of cluster-based current directory to VruiState::~VruiState.
- Added getRender/setRender methods to Vrui::ToolKillZone.
- Added toggle button to show/hide tool kill zone to input device
  submenu in Vrui's system menu.
- Minor improvements to Vrui::UIManagerPlanar.
- Added Vrui::UIManagerSpherical.
- Moved widget manager and UI manager up in Vrui initialization sequence
  to make them available for input device adapter initialization.
- Added uninstallation target to Vrui makefile.
  - Added support scripts CleanDir.sh and CleanDirIfEqual.sh to Vrui
	  build system.
- Changed default installation directory for Vrui to /usr/local, now
  that there is a working "make uninstall", and edited README.
- Rebased all reference-counted classes from Misc::RefCounted to
  Threads::RefCounted.
- Added readSomeData and writeSomeData methods to IO::File to support
  non-blocking file I/O.
  - Added new protected virtual method writeDataUpTo to IO::File.
  - Implemented new virtual method in all derived classes.
- Cleaned up error handling in classes derived from IO::File; all thrown
  errors are now derived from IO::File::Error.
- Added some new options, selectable colors, and help text to
  XBackground.
- Simplified Vrui::VRWindow::updateScreenDevice.
- Changed Math::BrokenLine to negate mapping result if min>max.
- Added Vrui::ScreenMouseTool, a tool class to create a virtual mouse
  device that moves inside a screen controlled by two valuators.
- Fixed bug that caused crashes when tearing down input graphs with
  tools binding to input devices from multiple levels.
- Added triggerFeatureCallback method to Vrui::InputDevice to implement
  input graph priority updates.
- Removed #include <iostream> from Vrui/Internal/Vrui.General.cpp.
- Vrui::init prints error if configuration file requested via
  -mergeConfig is not found in any location.
- Added more output to Vrui's verbose mode:
  - Exposed vruiVerbose variable in Vrui/Internal/Vrui.h.
  - Vrui::getOutputConfiguration prints list of output names if one is
    requested, and prints error if none matches request.
  - Vrui::VRWindow prints initial window position and size, panning
    domain, and screen size.
- Fixed window initialization code in GLWindow; position detection
  finally works reliably.
- Added custom message dialogs and re-routing of user messages to
  console during Vrui start-up to Vrui::MessageLogger and
  Vrui/Internal/Vrui.General.cpp.
- Made Misc::MessageLogger convenience method namespace-global.
- Replaced calls to Vrui::showErrorMessage inside Vrui with
  Misc::MessageLogger equivalents.
- Re-routed input graph loading errors from console to user in
  Vrui::InputGraphManager.
- Clean-up of event passing in GLMotif to improve pop-up menu behavior:
  - GLMotif::Event::overrideTargetWidget now returns previous target
    widget.
  - Added clarifying comments to GLMotif/Widget.h.
  - Cleaned up event handling in GLMotif::WidgetManager.
    - All events go to grabbing widget, not target widget.
    - All button event handling methods return true if the event was
      handled by someone.
  - Simplified exception handling in GLMotif::Container.
  - Completely redid event handling in GLMotif::PopupMenu,
    GLMotif::Menu, and GLMotif::CascadeButton. Sub-menu interaction now
    works a lot better.
  - GLMotif::Menu and GLMotif::SubMenu are now obsolete and deprecated.
    Menus and sub-menus are constructed identically, as RowColumn-
    derived containers inside a PopupMenu shell.
  - Added convenience features to GLMotif::PopupMenu to automatically
    manage the menu root container. Widgets directly added to a
    PopupMenu are automatically redirected to the root menu.
    - Added important methods of GLMotif::Menu API to
      GLMotif::PopupMenu.
  - Removed GLMotif::Menu and GLMotif::SubMenu from Vrui sources and
    applications.
- Added ability to add non-toggle button children to GLMotif::RadioBox,
  which will be ignored during event processing.
- Added inheritance of layout parameters from parent to
  GLMotif::RowColumn to simplify creating nested layouts.
- Added Math/Algorithms.h as a place for common numerical algorithms.
  - Added algorithm to solve cubic equations.
- Now distributing vruiVerbose flag across cluster.
- Fixed window initialization code in GLWindow when no window manager is
  present.
- Fixed interpolation code for 3D rotations in
  Geometry::LinearInterpolator.
- Added copy constructor and assignment operator to Misc::FdSet.
- Created initial (experimental) version of centralized run-loop-like
  object in Threads::EventDispatcher.
- More detailed error messages in Comm::TCPSocket constructor.

Vrui-4.1-001:
- Improved documentation in USB/Context.h.
- Reworked internal udev abstraction classes used in raw HID management.
- Added Math::Complex to Math library to represent complex numbers based
  on arbitrary scalar types.
- Fixed bug in tool menu creation for abstract tool classes in
  Vrui::ToolManager.
- Improvements to generic math library:
  - Added typedefs FieldScalar and PrecisionScalar to Math::Constants to
    identify an embedding field type and an embedding type for high-
    precision calculations such as matrix inversions.
  - Added specialization of Math::Constants class for Math::Complex.
  - Added Math::Complex to Misc::Marshaller and Misc::ValueCoder
    specializations.
- Fixed GLMotif::ListBox::getSelectionChangedCallbacks(), which returned
  wrong callback list. Found by David Lonie.
- Fixed menu creation bug in Vrui::VisletManager.
- Added new class Images::TextureSet to simplify handling of OpenGL
  texture images.
- Added class GLEXTTextureArray for GL_EXT_texture_array OpenGL
  extension.
- Expanded GLScalarLimits functionality:
  - Added OpenGL scalar type constants.
  - Added AccumulatorScalar typedef.
  - Added static fromAccumulator() method.
- API change: major changes to Images::Image class hierarchy.
  - Updated Images::RGBAImage to newest Images::Image API.
  - Added texSubImage3D to Images::Image and glTexSubImage3D to
    Images::RGBImage and Images::RGBAImage to support 3D textures or 2D
    texture arrays.
  - Added new non-templatized base class Images::BaseImage taking care
    of memory management and OpenGL interaction.
  - Moved most functionality of Images::Image and Images::RGBImage and
    Images::RGBAImage into Images::BaseImage.
  - Removed pixel type conversion copy constructors and assignment
    operators for being fundamentally unsafe.
- Added conversion function to Y'CbCr color space to all ImageExtractor
  classes in Video library.
- Added userData pointer to callbacks in Threads::EventDispatcher.
- Replaced use of atomic reference counter in USB::Context with a mutex,
  as atomic ref count could not prevent creation race condition.
- Added getPropertyValue() method to RawHID::UdevDevice.
- Added class RawHID::DeviceMonitor to monitor hot-plug events on raw
  HID devices.
- Added a detailed constructor to RawHID::Device to enable creating a
  Device directly from a DeviceMonitor's AddEvent callback structure.
- Added device node file name to RawHID::Device's state to simplify
  writing hot-plug event handlers.
- Added Threads library to dependencies of RawHID library in
  BuildRoot/Packages.
- Added reader interface to IO::VariableMemoryFile to allow reading back
  previously-written data up to the most recent flush().
- Added class Misc::Pipe as a thin RAII wrapper around UNIX unnamed
  pipes.
- Fixed documentation bug in IO::ValueSource: matchString stops reading
  before first mismatch; isString reads an entire string from the
  source.
- Added missing function instantiations of Math::Interval<>::intersect
  and fixed typo in said function.
- Changed GLMotif::WidgetManager such that any attributes associated
  with a widget are deleted at the time the widget is deleted.
- Added value range check to GLMotif::Slider.
- Used widget attributes to associate control IDs and menu entry IDs
  with control widgets in Video::V4L2VideoDevice's control panel.
  - Replaced regular GLMotif::Sliders with GLMotif::TextFieldSliders in
    integer video device controls.
  - Fixed use of regular vs. extended controls depending on control
    class.
- Added error message logging to Video::V4L2VideoDevice's background
  streaming thread.
- Improved error handling in Video::V4L2VideoDevice; can now recover
  from streaming failures.
- Added saveConfiguration() method to Video::VideoDevice interface.
- Added getVersionNumber and getSerialNumber methods to
  Video::OculusRiftDK2VideoDevice.
- Fixed frame rate bug in Video::OculusRiftDK2VideoDevice video format
  enumerator; set counter twice instead of denominator.
- Now returning newly-created widget in GLMotif::DropdownBox::addItem().
- Added setImage method to Images::TextureSet::Texture.
- Simplified time difference calculations in Misc::Timer.
- Added implementation of setEnabled() method to
  GLMotif::TextFieldSlider.
- Added X11 error handlers to Vrui.Workbench.cpp.
- Fixed early event handling to detect initial window size in
  GLWindow in case of multiple windows sharing an OpenGL context.
- Moved vsync setup in Vrui::VRWindow after glXMakeCurrent to fix
  initialization bug when sharing an OpenGL context.
- Added value coder class for Math::Interval in Math/MathValueCoders.h.
- Added copy constructor to GLObject.
- Fixed Vrui::DisplayState window pointer to point to correct window
  during all rendering passes when sharing OpenGL contexts.
- Fixed handling of optional libudev library in build system.

Vrui-4.1-002:
- Added Vrui::WiggleScreenshotTool class to create wiggle stereograms.
- Changed alignment of labels in Vrui::AnnotationTool; will probably
  revert.
- Added device driver module OpenVRHost to retrieve tracking data from
  OpenVR-compatible tracking drivers, such as Valve's Lighthouse driver.
- Added usage help text to VRDeviceDaemon; triggered by -h command line
  option.
- Added option to save HMD configuration to binary file to OpenVRHost
  driver plug-in.
- Added option to load HMD configuration from binary file to
  Vrui::LensCorrector, overriding previous method of setting up lens
  correction.
- Disabled glFinish() call in Vrui::VRWindow::swapBuffers, as it pegs
  CPU utilization at 100%. Watching for side effects such as increased
  latency.
  - Disabling glFinish() does indeed increase latency, as OpenGL will
    return immediately from glXSwapBuffers and queue subsequent
    rendering calls for later frames.
  - Added lowLatency flag to VRWindow configuration to select use of
    glFinish(), as low CPU usage is better than low latency for desktop
    environments.
- Simplified calculation of frustum boundaries in
  Vrui::LensCorrector::adjustProjection.
- Added setIPD method to Vrui::Viewer.
- Added facility to inhibit a desktop environment's screen saver from a
  configuration file or inside a Vrui application:
  - Added abstract base class ScreenSaverInhibitor.
  - Added ScreenSaverInhibitorDBus using freedesktop's standard screen
    saver DBus interface
  - Added screenSaverInhibitor element to Vrui state.
  - Added inhibitScreenSaver() and uninhibitScreenSaver() functions to Vrui
    kernel API.
  - Removed old, non-working screen saver inhibition code from
    Vrui/Internal/Vrui.Workbench.cpp.
- Added main flag predictMotion to enable motion prediction in
  Vrui::InputDeviceAdapterDeviceDaemon, and renamed motionPrediction
  configuration tag to motionPredictionDelta.
- Added system-wide and per-user per-application configuration files
  named by application name to Vrui initialization sequence.
- Fixed falling direction in surface-aligned walking navigation tools.
- Added verbose Vrui output when front-buffer rendering is selected to
  Vrui::VRWindow.
- Added verbose Vrui output of render target size to
  Vrui::LensCorrector.
- Added better popup menu alignment method to Vrui::RayMenuTool;
  configurable via alignMenuWithPointer tag and enabled by default.
- Added missing XFlush() calls after X protocol messages in
  GLWindow::hideCursor and GLWindow::showCursor.
- Added mouse idle detection with configurable time-out to
  Vrui::InputDeviceAdapterMouse.
- Added a bunch of options to VruiCalibrator example program to make it
  more useful for HMD calibration checks. See source code for now.
- Added configuration section for HTC Vive.
- Added patch configuration files to fake the presence of an Oculus Rift
  DK2 or an HTC Vive.
- Added patch configuration file to add a control window to head-mounted
  displays.

Vrui-4.2-001:
- Added initial version of TrackingTest to Vrui utilities.
- Made CAVERenderer vislet compatible with non-standard environment
  layouts.
- Added deviceUpDirection element and getUpDirection() method to
  Vrui::Viewer.
- Added getDeviceViewDirection() and getDeviceUpDirection() methods to
  Vrui::Viewer.
- Changed location of per-application configuration files to
  Applications subdirectory inside Vrui configuration file directories.
- Moved first call to application's resetNavigation method in
  Vrui.Workbench.cpp after window initialization so that application has
  last word over navigation caused by panning window resizes.
- Generalized implementation of screen protectors to support arbitrary
  shapes.
  - Removed protectScreens flag and configuration tag from
    Vrui::VRWindow.
  - Removed protector penetration checking and grid rendering code from
    Vrui::VRWindow.
  - Added new class Vrui::ScreenProtectorArea.
  - Added protectScreen tag to screen configuration sections.
  - Added screenProtectorAreas tag to Vrui root configuration section.
  - Renamed screenProtectors tag in Vrui root configuration section to
    screenProtectorDevices.
  - Added screenProtectorGridColor and screenProtectorGridSpacing tags
    to Vrui root configuration section.
  - Added penetration testing to Vrui::VruiState::update method.
  - Added protector grid rendering to Vrui::VruiState::display method.
  - Added display list to hold screen protector grid renderings to
    Vrui::VruiState::DisplayMapper::DataItem.
- Added frameInterval element to Vrui::OutputConfiguration structure in
  Vrui/Internal/GetOutputConfiguration.h.
- Temporarily added extra verbose output to
  Vrui::getOutputConfiguration().
- Added openvr_driver.h from OpenVR SDK as contributed source to
  simplify building OpenVRHost VRDeviceDaemon module.
  - Changed OPENVR_BASEDIR in makefile to embedded directory, therefore
    enabling OpenVR support by default.
- Added success indicators to several GLWindow methods that rely on
  optional window manager/GLX features, or error output via
  Misc::MessageLogger where infeasible.
  - Added logging of said results in Vrui verbose mode.
- Added support for GLX_NV_delay_before_swap OpenGL extension to
  GLWindow.
  - Added new methods canPreVsync() and waitForPreVsync() to GLWindow.
- Added preSwapDelay tag to Vrui::VRWindow for pre-vsync lens distortion
  correction in front-buffer rendering mode.
- Complete overhaul of VRDeviceDaemon internal architecture, replacing
  multithreaded I/O with event-driven I/O based on the evolving
  Threads::EventDispatcher prototype.
  - Added callbacks as update notification option to VRDeviceManager.
  - Overhaul fixes hang issue when devices never send updates.
- Renamed classes and methods in Threads::EventDispatcher in preparation
  for additional event types.
- Fixed bug in Vrui::InputDeviceAdapterDeviceDaemon: don't call
  getPacket() after startStream(); startStream already waits for packet.
  - Applied same change to DeviceTest utility.
- Made trackerPostTransformations array in VRDevice class protected to
  save some transformation work in the OpenVRHost driver module.
- Fixed tracker calibration code in VRDevice to adjust linear velocity
  based on current angular velocity and post-transformation origin point
  translations.
- Removed redundant state updates from VRDeviceManager::updateState
  method.
- Improved OpenVRHost device driver module:
  - Streamlined state updates by always updating at head tracker rate.
  - Automatically create virtual devices for HMD and all configured
    controllers.
  - Reduce transformation work by offloading local tracker
    transformations to VRDevice post-tracker transformations.
- Fixed initialization of VRDeviceServer::listenSocket.
- Added configuration options for OpenVR and SteamVR to Vrui makefile.
  - Added RunViveTracker.sh script to run VRDeviceDaemon in an
    environment set up to load the OpenVRHost device driver module (due
    to weird OpenVR dynamic linking requirements).
- Changed multiple classes to catch all exceptions potentially thrown in
  destructors, as that is not allowed.
  - Comm::TCPPipe.
- Added new Vrui environment setup utility, RoomSetup.
- Added patchFile method to Misc::ConfigurationFile, to replace the
  value of a fully-qualified tag with minimal changes to the overall
  file, i.e., retaining tag/section order, comments, and white space.
- Fixed several bugs in per-user configuration file handling in
  Vrui/Internal/Vrui.Workbench.cpp.
- Fixed a bug in IO::File::readSomeData; didn't reset read buffer
  pointers on empty buffer before reading.
- Put workaround for buffered read problem into VRDeviceServer: process
  commands in callback until read buffer is empty.
- Changing Vrui's input device handling architecture to support
  reprojection for perceived latency reduction in head-mounted displays.
  - Changed parameter of
    Vrui::InputDeviceManager::findInputDeviceAdapter to const
    InputDevice*.
  - Added findInputDevice method to Vrui::InputDeviceAdapter.
  - Added peekTrackerState method to Vrui::InputDeviceAdapter to read
    up-to-date tracking data at any point during a frame.
    - Added implementations of said method to
      Vrui::InputDeviceAdapterDeviceDaemon,
      Vrui::InputDeviceAdapterTrackd, Vrui::InputDeviceAdapterVisbox,
      and Vrui::InputDeviceAdapterOVRD.
  - Added getHeadDevice method to Vrui::Viewer.
  - Added peekHeadTransformation method to Vrui::Viewer.
  - Added initial implementation of reprojection to Vrui::LensCorrector,
    but results are not good.
- Fixed makefile:
  - Fixed name of uninstall rule.
  - Added installudevrules and uninstalludevrules rules.
    - Added UDEVRULEDIR variable to put udev rules into
      /usr/lib/udev/rules.d for system installations.
  - Improved automatic detection of SteamVR directory structure.
- Added configuration options for OpenVRHost device driver module to
  VRDeviceDaemon/Config.h.
- Added streaming of HMD configuration structures from a VRDeviceDaemon
  to VRDeviceClients to support dynamic configuration changes such as
  hardware IPD dials, eye relief adjustments, or real-time pupil
  tracking.
  - Created new internal class Vrui::HMDConfiguration.
  - Bumped version number of VRDeviceProtocol to 4.
    - Added new message ID HMDCONFIG_UPDATE where three LSBs identify
      which component of a configuration has changed.
    - Changed parameter of VRDevicePipe::writeMessage from MessageId to
      MessageIdType
    - HMDCONFIG_UPDATE messages are sent from server to client in
      streaming mode.
  - Added array of HMD configurations and configuration change callbacks
    to Vrui::VRDeviceClient.
  - Made state and HMD configuration locking methods in
    Vrui::VRDeviceClient const.
  - Expanded interface of Vrui::InputDeviceAdapterDeviceDaemon:
    - Added getDeviceClient method.
    - Added findTrackerIndex method.
    - Added findHmdConfiguration method to retrieve an HMD configuration
      associated with an input device.
  - Added frame callbacks and addFrameCallback function to Vrui kernel
    API.
  - Enabled dynamic HMD configuration changes in Vrui::LensCorrector,
    including visual feedback during changes via a dialog box.
    - Added code to move the screens representing an HMD to Vrui to
      properly support applications that use viewers and screens as a
      basis for frustum culling.
  - Added listing of HMD configurations and configuration change
    tracking to DeviceTest utility.
  - Moved deviceManager element in VRDevice to protected section.
  - Added HMD configuration management to VRDeviceManager.
  - Added HMD configuration streaming to VRDeviceServer.
  - Changed HMD configuration handling in OpenVRHost from file export to
    VRDeviceManager/VRDeviceServer-based streaming.
- Fixed frame time calculation in Vrui::VRWindow when in burn mode.
- Created LatencyTester vislet to measure the frame-to-photon latency of
  any Vrui application using the latency tester Oculus shipped with the
  Rift DK1.
- Added overloaded versions of glUniformARB for GLColor types to
  GL/GLColorTemplates.h.

Vrui-4.2-002:
- Slightly improved SteamVR autodetection in makefile.
- SteamVR just updated its internal OpenVR API, so Vive driver no longer
  works. :( Starting to fix it, but am getting segfaults from
  driver_lighthouse.so
  - Fixed it -- added new virtual method bool ContinueRunFrame(void) to
    the end of vr::IServerDriverHost.
  - One remaining issue: Lighthouse driver crashes on shutdown before
    turning off the headset's screens.
- Added settings for OpenVR drivers used by OpenVRHost device daemon
  module to VRDevices.cfg.
- Improved SteamVR auto-detection in Vrui makefile.

Vrui-4.2-003:
- No longer need quotes around image file names in Vrui::CAVERenderer
  configuration.
- Fixed missing path to libSDL2.so packaged with Steam run-time in
  RunViveTracker.sh and makefile configuration.

Vrui-4.2-004:
- Breaking very long lines in RoomSetup to stay within
  Misc::ConfigurationFile's line length limit.

Vrui-4.2-005:
- Split configuration settings for OpenVRHost VRDeviceDaemon module into
  separate VRDevices/OpenVRHost-Config.h header file for improved build.
- Added dependency to remake RunViveTracker.sh when Steam paths change.
- Fixed handling of undefined navigation space units in Vrui::ScaleBar.
- Added TouchpadButtonsTool to transform a clickable touchpad into a set
  of buttons.
- Added -noAlign command line option to make CAVERenderer vislet work in
  CAVE as it used to.
- Added toggle button to Device sub-menu of Vrui system menu to
  temporarily disable screen protectors.
- Minor fixes to conditional compilation based on system library
  availability in makefile.
  - LatencyTester vislet made conditional upon libudev availability.
- Fixed Vrui/Internal/GetOuputConfiguration.cpp to obey screen index
  requested by caller.
- Turned off warpReproject by default and added description to Vrui
  configuration file reference.
- Added missing peekTrackerState method to
  Vrui::InputDeviceAdapterDummy.
- Fixed patch configuration file for fake HMDs.
- Moved Vrui::KeyMapper and Vrui::getOutputConfiguration to public Vrui
  interface as they are included by public Vrui/VRWindow.h.
- Improved UI hotspot calculation for projected input devices in
  Vrui::GUIInteractor and Vrui::RayMenuTool.
- Changed Vrui::RayMenuTool to only offset menu positions for 6-DOF
  devices.
- Added interaction direction tracking to Vrui::UIManager.
- Added alignUiWithPointer setting to Vrui::UIManagerFree to align UI
  components with the bisector between the viewing direction and the
  current pointing direction instead of just the viewing direction for
  improved interaction. Defaults to true.
  - Removed alignMenuWithPointer setting from Vrui::RayMenuTool.
- Removed deprecated log routing functionality from RawHid::UdevContext.
- Fixed broken auto-detection of libudev in BuildRoot/Packages.System.
  - Renamed UDEV package to LIBUDEV.

Vrui-4.2-006:
- Improved Vrui's X11 protocol error handler with detailed messages; no
  longer forcing exit on errors.
- Added missing OpenVRHost-Config.h to VRDeviceDaemon/VRDevices in
  release package.
- Added work-around for displays reporting a zero physical size to
  Vrui::getOutputConfiguration; uses fixed resolution of 96 dpi to
  calculate physical size from domain size.

Vrui-4.3-001:
- Put some evil hacks and work-arounds for better UI alignment into
  Vrui::UIManager, Vrui::UIManagerFree, and Vrui::WidgetTool. Next minor
  version update will change UI alignment architecture.
- Fixed dependence on "standard" z-up physical coordinate systems in
  Vrui::MouseSurfaceNavigationTool and Vrui::FPSNavigationTool.
- Added sqrDist method to Geometry::Box to calculate squared Euclidean
  distance between box and point.
- Improvements to Vrui::SketchingTool:
  - Simpler handling of curve point insertion.
  - New sketch mode for simple broad brush strokes.
  - New eraser mode to selectively delete sketching objects.
  - Disabled snapping of curves to their starting points.
- Updated Linux version of Vrui::InputDeviceAdapterHID to support
  positioned input devices such as touchscreen styluses.
  - Added view-aligned ray direction to positioned input devices.
- Added support for vsync control on Mesa-based OpenGL implementations
  via the GL_MESA_swap_control extension.
- Added palm rejection to Vrui::InputDeviceAdapterMultitouch:
  - Changed signatures of touch event methods to support touch contact
    size estimation.
  - Added maxContactArea setting to set the maximum area for contacts to
    be considered fingers.
- Added infinity constant to Math::Constants<float> and
  Math::Constants<double>.
- Forced use of eye rays in Vrui::GUIInteractor when the driving device
  does not have a pointing direction.
- Added sets of mutually exclusive buttons to Linux version of
  Vrui::InputDeviceAdapterHID.
- Separated sketching objects by type in Vrui::SketchingTool
  (experimental, may revert or improve later).
- Added Vrui::ScriptExecutorTool to run external programs or scripts as
  child processes of a Vrui application.
- Fixed mouse idle detection in Vrui::InputDeviceAdapterMouse if the
  mouse is never moved at all.
- Fixed turning off of screen protection in
  Vrui/Internal/Vrui.General.cpp.
- Added enough accessors to Images::TextureSet::Texture to clone
  existing textures.
- Made slight re-arrangement in SceneGraph::TransformNode::update().
- Moved Vrui's input device data saver to earlier in Vrui shutdown
  sequence to avoid recording audio while frame savers wind down.
- Added output of total recording time to Vrui::InputDeviceDataSaver for
  convenience.
- Added separate status pipe to Cluster::TCPPipe classes to support
  parallel reading and writing in coupled mode.
- Major improvement to user experience in scaling mode in Vrui's two-
  handed navigation tool.
- Added new Geometry::ElevationGrid class to calculate ray intersections
  on regular integer-lattice 2.5D elevation grids.
- Added methods with on-the-fly type conversion to Misc::ArrayMarshaller
  classes.
- Started overhaul of VR device driver client/server protocol to provide
  improved device pose prediction, battery states for wireless devices,
  and tracking quality flags.
  - Fixed wire data type sizes in Vrui::VRDeviceState.
  - Added device tracking status flags to Vrui::VRDeviceState.
  - Fixed wire data type sizes in Vrui::HMDConfiguration.
  - Added ipd field to move update bundling to Vrui::HMDConfiguration.
  - Fixed wire data type sizes in Vrui::VRDeviceDescriptor.
  - Added hasBattery flag to Vrui::VRDeviceDescriptor.
  - Added class Vrui::BatteryState to represent and transmit devices'
    battery states.
  - Added battery state update message to Vrui::VRDevicePipe.
  - Added battery state management to VRDeviceManager.
  - Added virtual initialize() method, called immediately after
    constructor, to VRDevice class to support post-constructor
    initialization.
    - Added call to VRDevice::initialize() method to device driver
      module initialization in VRDeviceManager.
  - Added return of virtual device index to addVirtualDevice methods in
    VRDevice and VRDeviceManager.
  - Added disableTracker methods to VRDevice and VRDeviceManager.
  - Added valid flag transmission and initial battery state tracking to
    VRDeviceServer.
  - Added new conditional VRDEVICEDAEMON_DEBUG_PROTOCOL to
    VRDeviceServer.
	- Several changes to Vrui::VRDeviceClient:
	  - Started adding support for time synchronization with remote
	    servers.
	  - Added detection of local connection, to side-step timer
	    synchronization and potentially use shared-memory exchanges in the
	    future.
	  - Added handling of tracking status flags.
	  - Added device battery status handling and callbacks.
	  - Removed sub-state locking from callback management methods; expect
	    relevant states to be locked already.
	- Added tracking status flag and battery state tracking to DeviceTest
	  utility.
  - Adapted OpenVRHost device driver module to new OpenVR driver ABI.
  - Minor API fix-ups in DummyDevice and RemoteDevice device driver
    modules.
  - Added initialization of tracker valid flags to true in
	  Vrui::VRDeviceClient when talking to legacy device servers.
- Added alignToEnvironment configuration file setting to
  Vrui::CAVERenderer vislet.
- Brought caveman.geology.ucdavis.edu Vrui configuration file section
  up-to-date.
  - Changed type of microsecond time stamps from unsigned to signed 32-
    bit integer to simplify calculations.
  - Added getTimeStamp methods for current and offset time to
    VRDeviceManager.
    - Changed VRDevice::TrackerState shortcut to use VRDeviceManager's
      getTimeStamp() method.
  - Added handling of time-offset device states to OpenVRHost module.
  - Added battery state streaming to VRDeviceServer and cleaned up
    communications code and error handling.
  - Added reception of initial battery states to Vrui::VRDeviceClient.
- Set controllers' battery flag to true on initialization in OpenVRHost
  device driver module.
- Added missing initialization for lastFrame to Vrui::VruiState
  constructor.
- Improved mouse idle detection in Vrui::InputDeviceAdapterMouse by
  ignoring events that don't change the mouse cursor position.
- Fixed ray direction calculation during initialization in
  Vrui::InputDeviceAdapterHID.
- Forced color space in Images::readJPEGImage to RGB.
- Added Vrui::ObjectSnapperTool, a generic transformation tool class to
  snap virtual input devices to application objects.
  - Added object snapper tool class to Vrui's default tools in
    Vrui::ToolManager.
- Added default assignment of source input device to Vrui::TransformTool
  constructor.
  - Removed assignments of source device from all tool classes where it
    matches the new default.
- Added tracker snapping to Vrui TrackingTest utility.
- Started improving latency mitigation scheme for head-mounted VR.
  - Added vsync time tracking to predict next display exposure time and
    predict state of motion input devices at that time.
    - Whichever VR window has vsync enabled drives time prediction.
  - Vsync prediction controlled by several configuration tags:
    - predictVsync: boolean, main switch
    - vsyncInterval: number, synched display's frame interval in seconds
    - postVsyncDisplayDelay: lag time from vsync to current frame being
      shown by the display, in seconds
  - Added vsync() method to Vrui's internal kernel interface
    - Added call to vsync method to Vrui::VRWindow.
  - Added predictDeviceState flag and prediction time point to
    Vrui::InputDeviceManager, and methods to control/query them.
  - Added motion prediction to InputDeviceAdapterDeviceDaemon.
  - Fixed calculation of reprojection rotation during post-rendering
    lens correction warping.
  - Added doesReproject method to Vrui::LensCorrector.
  - Improved handling of pre-swap delay and lens correction warping for
    double-buffered windows.
  - Fixed warp reprojection overall, bringing display stability on par
    with SteamVR on Windows.
- Added multicast support features to Comm::UDPSocket:
  - Added default port to Comm::IPv4SocketAddress default constructor.
  - Added multicast configuration methods to Comm::UDPSocket.
  - Removed unused include files from Comm/UDPSocket.h.
  - Reused functionality from Comm::IPv4Address and
    Comm::IPv4SocketAddress in Comm::UDPSocket and improved error
    messages.
- Added readGenericImageFile function to Images/ReadImageFile.h to pave
  the way for more flexible image file handling. Images::readImageFile
  and Images::readTransparentImageFile are now obsolete and deprecated.
  - Replaced image loader function in SceneGraph::ImageTextureNode.
- Added getRowStride method to Images::BaseImage.
- Added getInternalFormat method to Images::BaseImage to guess an
  internal texture storage format compatible with a given image.
- Added readGenericPNMImage to Images/ReadPNMImage.h, making the other
  functions obsolete and deprecated.
- Added readGenericPNGImage to Images/ReadPNGImage.h, making the other
  functions obsolete and deprecated.
- Added readGenericJPEGImage to Images/ReadJPEGImage.h, making the other
  functions obsolete and deprecated.
- Added interface for readGenericTIFFImage to Images/ReadTIFFImage.h,
  but implementation will have to wait. I hate TIFF.
- Changed elementwise constructor of Images::BaseImage to public.
- Added simplified glTexImage2D method to Images::BaseImage that guesses
  an appropriate internal texture storage format.
- Replaced Images::RGBImage with Images::BaseImage in GLMotif::Image.
  - Pulled change through to GLMotif::ScrolledImage.
- Added protectScreens configuration setting to Vrui::VRWindow to
  disable screen protection for selected windows, to make secondary
  views look better.
- Added updateVisletMenu method to Vrui::VisletManager to ensure the
  state of vislet toggle buttons always mirrors actual vislet state.
  - API change: made Vrui::Vislet::active private to force use of
    accessor methods to keep vislet state in line with menu state.
- Updated contributed openvr_driver.h to newest github version.
- Fixed export of screen protector boundaries in Vrui's RoomSetup
  utility.
- Added option to override input device's server-supplied selection ray
  from configuration file to Vrui::InputDeviceAdapterDeviceDaemon.
- Changed default local transformation for Vive controllers in
  VRDevices.cfg to improve interaction comfort.
- New rule: Tracked controller's local coordinate systems are aligned
  such that the origin corresponds to the most comfortable hot spot, the
  Y axis points in the most comfortable pointing position, the X axis
  points to the right, and Z is defined by the right-hand rule.
- Added hilt transform to Vrui::JediTool to align tool with controller's
  handle. Prototype for more general alignment method for hand-held
  virtual tools in the future.
  - Also added a simple 3D model to render the hilt as long as the tool
    exists.
- Changed default controller type in RoomSetup utility to "from driver,"
  and added editing capability to "custom" controller type.
- Fixed makefile to hard-code SteamVR dynamic link paths into
  VRDeviceDaemon if SteamVR is detected.
  - VRDeviceDaemon -rootSection Vive now works without setting up
    LD_LIBRARY_PATH.
  - Removed superfluous run-time directories from RunViveTracker.sh
    script.
- Added sections on HTC Vive support to README file.

Vrui-4.4-001:
- Added option to disable screen protection on per-window basis to
  Vrui::VRWindow and Vrui/Vrui.General.cpp.
  - Set via protectScreens flag in a window's configuration section.
- Added visualization of tracking history and PCA-derived error
  ellipsoids to Vrui TrackingTest utility.
- Fixed bug in ray intersection routines in Geometry::Cylinder and
  Geometry::Cone; intersection results were always reported as valid.
  - Added setParameter method to Geometry::HitResult.
  - Added setParameterAndDirection method to Geometry::SolidHitResult.
  - Added setPart methods to Geometry::Cylinder::HitResult and
    Geometry::Cone::HitResult.
    - API change: Fixed typo in MANTLE part name in both classes.
- Added Geometry/AlignPoints.h with several namespace-global functions
  to align pair-matched point sets using several types of
  transformations.
- Fixed memory leak in Math::Matrix::jacobiIteration().
- Added default server name "localhost:8555" to Vrui's DeviceTest
  utility.
- Added parameter to select number of Levenberg-Marquardt iterations
  to alignment functions in Geometry/AlignPoints.h.
- Temporary fix for shut-down deadlocks in USB::Context destructor: Use
  time-outs and a continuation flag instead of canceling the event
  handling thread to avoid deadlocks in libusb_exit. Should ideally
  integrate event handling into main runloop.
- Added progress reports to Vrui movie savers when main application has
  already ended.
- Added "glow" light sources to JediTool.
- Fixed calculation of distances between vertices and light sources in
  GLLightTracker's light accumulation functions for attenuated light
  sources when sources and/or vertices have non-unity homogeneous
  weights.
- Added configure/saveState methods to Vrui::SketchingTool.
- Made Vrui::JediTool a bit more awesome with a full-persistence blade.
- Added GLMotif::Texture, a base class for widgets displaying a
  potentially dynamic texture image generated on demand via a virtual
  method.
- Rebased existing GLMotif::Image widget to GLMotif::Texture base class.
- Changed GLMotif::NewButton to set the border size of its child widget
  to zero upon insertion.
- Made GLFrameBuffer wrapper class functional for the first time. Might
  actually turn out useful.
  - Added GLFrameBuffer class to GLSupport library.
- Added choleskyDecomposition method to Math::Matrix class.
  - Added failsafe for slightly non-positive definite matrices that
    works for UKF, but is probably not a good idea.
- Forgot to update timeStamp variable in
  Vrui::InputDeviceAdapterPlayback which caused missing frames snapshots
  during long frame times.
- Fixed wrong delete operator in Geometry::BSpline::~BSpline.
- Fixed method visibility and use of unsized integer types in
  Misc/CompoundMarshallers.h, which had apparently never been used.
- Slightly improved verbose output and error messaging during Vrui
  initialization and main loop, especially for cluster setups.
- Added prototype of timer event handling to Threads::EventDispatcher.
- Changed Vrui initialization sequence such that total number of windows
  is known to application and vislet constructors.
- Added windowIndex field with current window's cluster-wide index to
  Vrui::DisplayState structure.
  - Added windowIndex field to Vrui::VRWindow.
  - Added initialization of windowIndex to Vrui's startDisplay function.
- Improved OpenVR driver dso wrapper to again power off controllers when
  VRDeviceDaemon exits.
- Added low-level support for haptic feedback and device power
  management to VR device daemon protocol.
  - Upped VR protocol version to 6.
  - Added list of haptic features to virtual device descriptors.
  - Added -powerOff <power feature index> and -haptic <haptic feature
    index> <pulse duration> command line options to Vrui's DeviceTest
    utility.
- Removed a couple of warnings regarding string buffer sizes brought up
  by new g++ 7.2.1 from GLMotif/WidgetManager.h,
  Sound/Linux/ALSAAudioCaptureDevice.cpp,
  Vrui/Internal/InputDeviceAdapterPlayback.cpp, 
  Vrui/Internal/InputDeviceAdapterHID.cpp, 
  Vrui/Internal/InputDeviceAdapterMultitouch.cpp and
  Vrui/Internal/Vrui.Workbench.cpp.
- Fixed application of point transformation to non-subdivided quads in
  SceneGraph::QuadSetNode.
- Added device name matching to Vrui::InputDeviceAdapterHID to address
  multiple devices sharing the same vendor/product ID.
- Added process functions to Threads::EventDispatcher.
- Started adding IO::XMLSource, a low-level XML file parser class
  layered on top of an IO::File abstraction.
  - Started adding Misc::Trie, a class to represent dictionaries
    associating strings with data values.
- Created VRTOOLS_IGNORE_SOURCES variable in makefile and disabled
  FPSArm tool for now.

Vrui-4.5-001:
- Added new class GLVertexBuffer to represent OpenGL vertex buffer
  objects templatized by the type of vertex structure they contain.
- Added nan to Math::Constants definitions for floating-point numbers.
- Significant overhaul of Images library to support more image file
  types and image formats in the future:
  - Added Images/ReadBILImage.h with functions to read images in BIP/
    BIL/BSQ format to Images library.
  - Added function to read an image file based on directory and
    directory-relative file name to Images/ReadImageFile.h.
  - Added support for BIP/BIL/BSQ images to Images::readGenericImageFile
    function.
  - Refactored filename-based functions in Images/ReadImageFile to use
    the current directory to open file, to support reading images
    directly from ZIP archives or over cluster pipes, for example.
  - Added basic image processing methods to Images::BaseImage to support
    simple common image format conversions in image reading functions.
  - Marked readImageFile and readTransparentImageFile functions in
    Images/ReadImageFile.h as deprecated and replaced with
    implementations based on readGenericImageFile and new image
    processing methods in Images::BaseImage.
  - Removed requirement for seekable files in Images::readCursorFile.
  - Implemented Images::readGenericTIFFImage function. Does currently
    not support tiled TIFF images.
  - Fixed exception message in Images/GetImageFileSize.cpp.
- Improved BIL elevation grid reader in
  SceneGraph/Internal/LoadElevationGrid.cpp by reading grid origin and
  size from header file, and removed requirement for seekable grid files
  for move to directory-based VRML file loader.
- Added glTexImage2DMipmap method to Images::BaseImage, which uses
  hardware acceleration when available.
- Removed uses of Images::RGBImage from libraries where actual format
  is irrelevant:
	- Autostereo view map representation and upload in Vrui::VRWindow.
	- Lightsaber texture image in Vrui JediTool.
	- Wall and floor images in Vrui CAVERenderer vislet.
	  - Also replaced mipmap generation code with
	    Images::BaseImage::glTexImage2DMipmap().
	- Moved SceneGraph::loadElevationGrid to use generic images for
	  improved utility.
- Changed frame loading code in Video::ImageSequenceVideoDevice to use
  directory-based Images::readImageFile function.
- Flipped order of include files X11/keysym.h and X11/Xlib.h in
  Calibration/XBackground.cpp to work with newest XQuartz on Mac OS X.
- Changed invocation of jpeg_read_header to work with jpeg9b library,
  by replacing "true" with "TRUE", in Images/GetImageFileSize.cpp and
  Images/ReadJPEGImage.cpp.
- Marked some unused future-proofing helper functions in
  VRDeviceDaemon/VRDevices/OpenVRHost.cpp as inline to turn off compiler
  warnings.
- Optimized absolute path handing in IO::StandardDirectory and
  Cluster::StandardDirectory.
- Fixed window position tracking in GLWindow yet again, triggered by a
  recent bug fix in Xorg, and may finally have it correct now.
- Added IO::UTF8, a helper class to decode/encode Unicode characters
  from/to UTF-8 encoded strings or files.
- Added the high-level part of the IO library's XML processor,
  IO::XMLDocument, which represents an entire XML document as a tree of
  nodes.
- Added code to calculate display position of lens center, and (disabled)
  code to calculate display's visible resolution, to Vrui's DeviceTest 
  utility.
- Changed build system files BuildRoot/SystemDefinitions and
  BuildRoot/Packages.System to catch up with recent Mac OS X.
- Added a couple of useful tracking quality measurement features to
  Vrui's TrackingTest utility.
- Added convenience accessor functions to USB::TransferPool::Transfer
  class.
- Fixed handling of paletted PNG images in Images/ReadPNGImage.cpp.
- Updated OpenVRHost device daemon module to current release of SteamVR,
  added support for touchpad touch button.
- Changed deinitialization order in VRDeviceDaemon.cpp to avoid race
  condition in OpenVRHost module shut-down.
- Added visual feedback when touchpad is touched to
  Vrui::TouchpadButtonsTool.
- Fixed enumeration of forwarded features in Vrui::TouchpadButtonTool
  such that only the currently touched button slot is returned.
- Changed tool kill zone behavior in Vrui::InputGraphManager such that
  only the most recently activated tool is deleted.
- Added enable states to input devices and tools to handle dynamic input
  devices and temporary tracking drop-outs:
  - Added enable flags for input devices and tools, as well as methods
    to change device states and state change callbacks, to
    Vrui::InputGraphManager.
  - Added enable flag and device state change callback to
    Vrui::VRScreen and Vrui::Viewer.
  - Added render capability check to Vrui::VRWindow.
  - Added tracking state checking to
    Vrui::InputDeviceAdapterDeviceDaemon.
- Changed OpenVRHost device driver module to always send state updates
  even when tracking data is not valid, to notify clients of changes.

Vrui-4.5-002:
- Added configuration setting "userMessagesToConsole" to Vrui root
  section.
- Changed load() method in Vrui::VRDeviceDescriptor to retain already-
  configured descriptor state.
- Virtual device descriptors configured in VRDevices.cfg now get
  configuration section name as default device name.
- Added override of automatic virtual device descriptors based on named
  configuration file sections to OpenVRHost VRDeviceDaemon module.
- Added new FindHMD Vrui utility to auto-detect connected HMDs and find
  the video output ports to which they are connected, to simplify
  managing HMDs via shell scripts.
  - Changed OnVive.sh shell script to use FindHMD utility.
- Slightly modified ControlWindow.cfg patch configuration file for
  better defaults.

Vrui-4.5-003:
- Added -setConfig <tag>[=<value>] command line option to Vrui to
  override configuration settings from command line.
- Fixed OnVive.sh shell script by directing HMD window to Vive's
  detected video output port.
- Fixed ssh command line for cluster startup to take fully-qualified
  name based on /proc file system on Linux.

Vrui-4.5-004:
- Improved rendering performance of SceneGraph::CurveSetNode by
  replacing per-curve GL_LINE_STRIPs with single indexed GL_LINES array.
- Fixed -addToolClass Vrui command line option:
  - Added addClass() method to Vrui::ToolManager that loads a tool class
    from DSO and adds it to the tool selection menu.
  - Call tool manager's new addClass() method from Vrui::init() function
    in Vrui/Internal/Vrui.Workbench.cpp.
- Added DebugTool tool class to mess with internal Vrui settings.
  Currently set up to toggle input device motion prediction and warp
  reprojection.
  - Added debug flag to disable motion prediction to
    Vrui::InputDeviceAdapterDeviceDaemon.
  - Added debug flag to disable reproject during warp to
    Vrui::LensCorrector.
- Added device battery state tracking and warnings when devices enter
  low battery state to Vrui::InputDeviceAdapterDeviceDaemon.
  - Added initial update of device battery states to
    Vrui::VRDeviceClient::startStream method.
- Added hysteresis to IPD update dialog in Vrui::LensCorrector to avoid
  repeatedly showing IPD dialog when IPD dial on headset is loose.

Vrui-4.6-001:
- Removed redundant (and leaky) creation of menu shell in
  Vrui::VruiState::buildDialogsMenu.
- Changed GLMotif::PopupMenu::removeEntry(int) method to return the
  removed widget so that the caller can delete it.
- Changed shutdown order in Video::V4L2VideoDevice::stopStreaming to
  remove need for thread cancellation and leave device in clean
  state in case of errors.
- Added verbose output about OLED response correction to
  Vrui::LensCorrector.
- Added ViewerComponent class to Video library to simplify development
  of applications that stream video from cameras to OpenGL textures.
- Added new position/size change callback list and associated callback
  struct to GLWindow, created base callback struct with window pointer,
  and changed close event to use that structure.
- Added new application call-in prepareMainLoop function to Vrui kernel
  interface, to be called immediately before Vrui's application main
  loop starts, i.e., display and sound sub-systems are initialized.
  - Set with setPrepareMainLoopFunction() in Vrui kernel interface.
  - Added new virtual prepareMainLoop() method to Vrui::Application
    class.
- Changed Misc::stringPrintf, defined in Misc/StringPrintf.h, to use a
  stack-allocated buffer as first target instead of a static buffer to
  make the function re-entrant and thread-safe.
- Added Misc/PrintfTemplateTests.h, defining namespace-global functions
  to test the validity and safety of printf-style templates used to
  generate numbered file names, for example.
  - Changed Vrui::ImageSequenceMovieSaver and
    Vrui::InputDeviceAdapterPlayback to use new functions from
    Misc/PrintfTemplateTests.h.
- Changed compatibility check in Images::BaseImage copy constructor to
  mirror assignment operator; no difference in functionality.
- Added "Align View" submenu to Vrui system menu's "View" submenu to
  align the current view to any combination of primary axes.
- Added convenience snapPoint method to Vrui::ObjectSnapperTool class
  to reduce burden of developing snapping functionality in applications.
- Added calcHUDTransform method to Vrui::UIManager to better place non-
  interactive UI components such as floating displays or labels.
  - Implemented calcHUDTransform method in classes derived from
    Vrui::UIManager:
    - Vrui::UIManagerPlanar
    - Vrui::UIManagerSpherical
    - Vrui::UIManagerFree
- Changed Vrui::InputGraphManager, Vrui::AnnotationTool, and
  Vrui::RevolverTool to use calcHUDTransform instead of calcUITransform.
- Added new generic minimization classes GaussNewtonMinimizer and
  LevenbergMarquardtMinimizer to Math library. Class
  LevenbergMarquardtMinimizer in Geometry library is now obsolete and
  will be removed.
- Added generic RanSaC class to Math library to implement "RANdom SAmple
  Consensus" model fitting.
- Added new PointAlignerONTransform, PointAlignerOGTransform,
  PointAlignerATransform, and PointAlignerPTransform point alignment
  classes and generic PointAligner base class to Geometry library.
- Added RanSaCPointAligner, an adapter class to optimize point
  alignments using various transformation types via RanSaC, to the
  Geometry library.
- Added AlignPoints application to Vrui utilities.
- Added virtual clone() method to base function call in
  Misc/FunctionCalls.h.
- API change: Changed Math::SimplexMinimizer to be compatible with other
  minimization classes in the Math library.
- Added Math::Minimizer as common base class for least-squares
  minimization classes, providing shared types and a callback mechanism.
  - Derived all minimization classes from Math::Minimizer and added
    progress callback handling.
- Added openFileDirectory method to IO::Directory class to open the
  directory containing the given file.
- Added getPixelRow method to Images::BaseImage.
- Fixed handling of PNG image files with tRNS chunks and/or 16-bit pixel
  components in Images/ReadPNGImage.cpp.

Vrui-4.6-002:
- Modified SteamVR auto-detection code in makefile yet again; maybe it
  works this time.
- Updated OpenVRHost device driver module to new OpenVR driver ABI as of
  08/26/2018.
  - Updated contributed openvr_driver.h header file.

Vrui-4.6-003:
- Fixed some problems with SteamVR auto-detection and configuration code
  in makefile, thrown up by default Steam installation under Ubuntu
  16.10.
- Added experimental support for Vive Pro to Vive root section in
  Vrui.cfg and OnVive.sh start-up script.

Vrui-4.6-004:
- Added missing #include <stdio.h> in Video/ViewerComponent.cpp.

Vrui-4.6-005:
- Updated OpenVR driver API to newest SteamVR release (1.1.3b,
  11/27/2018).
- Changed run-time library search paths and configuration in
  RunViveTracker.sh to work around change of interpretation of
  -Wl,-rpath linker parameter in newer Ubuntu versions.
- Improvements to RoomSetup utility:
  - Added control panel to define horizontal surfaces, for example desks
    to put down controllers.
  - Added adjustment of default control window configuration file
    fragment to new display center and forward direction.
- Fixed Vive Pro / OG Vive detection code in OnVive.sh.
- Added Vrui::LensCorrector::cleanup method to unbind pre-distortion
  frame buffer between rendering and warping for delayed warp, to fix
  rendering errors with shared OpenGL contexts.

Vrui-5.0-001:
- Replaced GLVertexBuffer class with a set of actually useful
  abstractions for templatized vertex and index buffers based on a
  common base class.
- Improved error handling in Comm::HttpFile with new exception classes
  and HTTP status code parsing.
- Added new Comm::HttpDirectory class to abstract access to remote
  resources over HTTP/1.1.
  - Added namespace-global Comm::openDirectory function handling remote
    HTTP directories based on "http://" directory name prefix.
- Added new Cluster::HttpDirectory class for cluster-transparent access
  to remote resources over HTTP/1.1.
  - Added support for cluster-transparent HTTP directories to
    Cluster/OpenFile.h.
- API change: Massive overhaul to file I/O abstraction layer provided by
  IO, Comm, and Cluster libraries:
  - New classes IO::Opener, Comm::Opener, and Cluster::Opener to provide
    simple file and directory opening services with support for advanced
    features such as remote file access, on-the-fly decompression, etc.
  - Functions in IO/OpenFile.h reimplemented through IO::Opener class.
  - IO/OpenFile.cpp disappeared.
  - Comm/OpenFile.h/.cpp, Cluster/OpenFile.h/.cpp, and
    Vrui/OpenFile.h/.cpp now redundant and removed.
  - New Comm/OpenPipe.h to provide simple pipe connection services
    implemented by Comm::Opener class.
    - Cluster/OpenPipe.h/.cpp now redundant and removed.
  - Simple update procedure to applications:
    - Replace #include <Comm/OpenFile.h>, #include <Cluster/OpenFile.h>,
      #include <Vrui/OpenFile.h> with #include <IO/OpenFile.h>.
    - Replace Comm::openFile etc., Cluster::openFile etc., and
      Vrui::openFile etc. with IO::openFile etc.
    - Replace #include <Cluster/OpenPipe.h> with
      #include <Comm/OpenPipe.h> and Cluster::openPipe with
      Comm::openPipe, removing the multiplexer argument.
    - Suggested change: Replace explicit new Comm::TCPPipe etc. with
      Comm::openTCPPipe to get automatic cluster sharing in cluster
      environments.
- Added option to use IO library's current directory as initial
  directory for GLMotif::FileSelectionHelper objects by omitting
  directory parameter.
  - Removed subsequently redundant IO::openDirectory calls from several
    Vrui sources.
- API change: Improved API of functions in Misc/PrintfTemplateTests.h to
  take additional conversion types and return conversion location and
  size.
  - Adapted several Vrui sources accordingly.
- Added option to specify acknowledgment button label to
  Vrui::showErrorMessage.
- API change: Massive overhaul to image reading component of Images
  library, simplifying usage and providing new functionality.
  - Applications using Images::readGenericImageFile functions should be
    mostly unaffected, but there are changes in Images/ReadImageFile.h.
  - Adapted several Vrui sources in accordingly.
- Fixed bug in Comm::HttpFile: Forgot to disable buffer read-through,
  causing errors when reading PNG images, oddly.
- Added Images/ImageFileFormats.h with types and functions to
  communicate and detect image file formats.
- Changed Images/GetImageFileSize.h and Images/ReadImageFile.h to use
  Images/ImageFileFormats.h.
- API change: Renamed function canReadImageFileType in
  Images/ReadImageFile.h to canReadImageFileFormat.
  - Adapted some Scenegraph and Vrui sources.
- API change: Replaced crusty old functions in Images::writeImageFile.h
  with new shiny functions based on abstractions from the IO library.
  - Applications should be minimally affected.
- On-going effort to remove obsolete Misc::File class from all Vrui
  sources:
  - Changed functions in Images/WriteImageFile.h to use IO abstractions.
  - Changed Vrui::ViewpointSaverTool to use IO abstractions.
  - Changed Vrui::ViewpointFileNavigationTool to use IO abstractions.
  - Changed screenshot projection saver in Vrui::VRWindow to use IO
    abstraction.
  - Finally removed obsolete and broken KinectRecorder and
    KinectPlayback classes from Vrui/Internal.
- Added support for tiled TIFF images to Images::readGenericTIFFImage.
- Added pseudo-HTTPS support into HTTP-related I/O abstraction classes.
- Fixed window positioning code in XBackground utility.
- Added support for incremental device state updates to VRDeviceDaemon
  client/server protocol:
  - Added new message types and incremented protocol version number to 7
    in Vrui::VRDevicePipe.
  - Added handling of new incremental update messages to
    Vrui::VRDeviceClient.
  - Replaced old callback mechanism in VRDeviceManager with new abstract
    VRStreamer class.
  - Added backwards-compatible support for incremental status updates to
    VRDeviceManager and VRDeviceServer.
- Inserted reference shortcuts to tos and froms point lists in Vrui's
  AlignPoints utility to get around a strange compiler error on
  gcc 8.1.1.
- Replaced all by-value catches of exception classes derived from
  std::runtime_error with by-constant-reference catches.
- Added TransformCalculator, a simple program to combine
  transformations, to Vrui utilities.
- Added presence flags for origin and cell size to BIL image file
  metadata defined in Images/ReadBILImageFile.cpp and changed
  SceneGraph/Internal/LoadElevationGrid.cpp to use new flags.
- Added TransformCalculator utility to convert between VRML and Vrui
  representations of transformations and concatenate or invert
  transformations.
- Fixed #include order in Vrui/Vislets/CAVERenderer.cpp.
- Added Vrui::Vislets::FoVRenderer, a simple FoV boundary rendering
  vislet.
- Added getNumButtons and getNumValuators helper methods to Vrui::Tool.
- Added prepareMainLoop methods to Vrui::InputDeviceAdapter and
  Vrui::InputDeviceManager to create a place where adapters can perform
  one-time setup operations after Vrui is fully initialized.
- Added prepareMainLoop method to Vrui::InputDeviceDataSaver.
- Added calls to InputDeviceDataSaver::prepareMainLoop and
  InputDeviceManager::prepareMainLoop to Vrui's prepareMainLoop
  function.
- Moved to version 5 of input device data file format by including
  device valid flags.
  - Changed Vrui::InputDeviceDataSaver and
    Vrui::InputDeviceAdapterPlayback accordingly.
- Replaced hard-coded wait interval for subsequent mouse wheel ticks in
  Vrui::InputDeviceAdapterMouse by Vrui animation time step.
- Added hack to save mouse event data (enabled via SAVE_MOUSEMOVEMENTS)
  to Vrui::VRWindow.
- Added return of previous tracking device to
  Vrui::VRScreen::attachToDevice, Vrui::Viewer::attachToDevice,
  and Vrui::Viewer::detachFromDevice, and added ability to detach from
  device by passing null into Vrui::Viewer::attachToDevice, in which
  case the viewer retains its previous head transformation.
- Added Vrui::MouseCameraTool, a class to manipulate a virtual camera,
  i.e., a combination of a screen and a viewer, using a pointing input
  device. Orthogonal to functionality provided by navigation tools and
  useful for VR environment with multiple screens.
- Reordered Vrui state initialization and made changes to
  Vrui::InputDeviceDataSaver and Vrui::InputDeviceAdapterPlayback to
  keep the Vrui application timer exactly in sync between recording and
  playback.
  - Added new internal Vrui API function synchronize(double timeStamp).
- Changed VruiState::prepareMainLoop so that the result of
  Vrui::getFrameTime() on the first Vrui frame is exactly 0.0.
- Added callback mechanism to Vrui::VRScreen to notify interested
  parties of screen events such as changes to a screen's size.
  - Added screen size event handling to Vrui::VRWindow, primarily to
    work with Vrui::MouseCameraTool tool class.
- Changed Vrui shutdown sequence so that all tools are destroyed before
  the main loop returns, to handle cases where tools hold application
  state.
  - Added destroyTools() method to Vrui::ToolManager.
  - Call ToolManager::destroyTools in VruiState::finishMainLoop.
- Added a pause/resume key for movie recording to Vrui::VRWindow, but
  pausing after the first resume doesn't actually pause because the most
  recent frame will be saved repeatedly.
  - Added warning reminding the user to press the pause button once to
    start recording. 
- Added new gamma curve value mapping to GLMotif::TextFieldSlider, with
  gamma value set by new setGammaExponent(...) methods.
- Fixed sound recording when saving a movie from a VR window to make
  recording stop when the user quits the application, not later when all
  movie frames are done writing.
- Added baseDirectory settings to Vrui::InputDeviceDataSaver and
  Vrui::InputDeviceAdapterPlayback to simplify recording and playback
  configuration.
- Added movieBaseDirectory setting to Vrui::MovieSaver to simplify
  recording configuration.
- Major updates to SceneGraph library:
  - Added mechanism to communicate vertex property needs of a shape's
    appearance node to the same shape's geometry node:
    - New methods requiresTexCoords, requiresColors, requiresNormals
      in SceneGraph::AppearanceNode.
    - New method requiresNormals in SceneGraph::MaterialNode.
    - New protected elements needTexCoords, needColors, needNormals in
      SceneGraph::GeometryNode.
    - New methods mustProvideTexCoords, mustProvideColors,
      mustProvideNormals in SceneGraph::GeometryNode.
  - Added implementation of VRML 2.0 IndexedFaceSet node type that
    covers most cases.
    - Does not yet use creaseAngle field when generating normal vectors.
    - Does not yet handle non-convex faces.
    - Does not yet handle vertex transformations.
  - Added mechanism to skip unrecognized node types to parsers in
    SceneGraph::VRMLFile.
  - Added VRML 2.0 Collision node type with dummy implementation.
  - Added setUrl method to SceneGraph::ImageTextureNode.
  - Added meta node type SceneGraph::MeshFileNode which reads a mesh
    file in a variety of formats and represents it as a sub-scene graph.
    - Added reader to represent a PLY mesh file as shape node containing
      a single indexed face set or point set.
    - Added reader a Wavefront OBJ mesh file as a list of shape nodes
      containing indexed face sets, indexed line sets, or point sets.
  - Several API changes in SceneGraph::VRMLFile:
    - Added base directory so that nodes can resolve relative URLs at
      later times.
    - Removed cluster multiplexer element.
    - Removed getFullUrl method.
  - Adapted all scene graph node classes using external URLs to new
    SceneGraph::VRMLFile interface.
  - Adapted code using SceneGraph::VRMLFile.
- Changes to the IO libraries to support new features in
  SceneGraph::VRMLFile:
  - Added new iterator-based hasExtension and hasCaseExtension functions
    to Misc/FileNameExtensions.h.
    - Minor implementation tweaks in Misc/FileNameExtensions.cpp.
  - Added openSeekableFile virtual method to IO::Directory.
  - Added iterator-based constructor to IO::StandardDirectory.
  - Added iterator-based virtual openDirectory method to IO::Opener.
  - Added openFileDirectory virtual method to IO::Opener.
  - Added IO::openFileDirectory function to IO/OpenFile.h.
  - Added checkHttpPrefix static methods to Comm::HttpFile to simplify
    protocol detection and URL handling.
  - Added getResourcePath method to Comm::HttpFile.
  - Added iterator-based splitUrl method to Comm::HttpFile.
  - Added iterator-based constructor to Comm::HttpDirectory; split
    common code into private init() method.
  - Added new virtual methods from IO::Opener to Comm::Opener.
    - Simplified Comm::Opener implementation with new URL processing
      methods from HttpFile.
  - Added iterator-based constructors to Cluster::StandardDirectory and
    derived classes.
  - Added iterator-based constructor to Cluster::HttpDirectory.
  - Added new virtual methods from IO::Opener to Cluster::Opener.
- Added new Misc::MallocAllocator class to experiment with allocation
  strategies in containers.
  - Added destroy convenience method to Misc::PoolAllocator.
  - Added derived Misc::FPoolAllocator class with single template
    argument to be compatible with other allocators.
- Added Misc::RedBlackTree, which isn't actually a red-black tree
  (psych!) but a regular old binary search tree until further notice.
- Fixed catch statement in Vrui/Vislets/LatencyTester.cpp.
- Finished ALSA-based implementation of abstract
  Sound::AudioCaptureDevice class.
- Added handling of GeoTIFF images and extraction of most relevant
  GeoTIFF georeferencing data to Images/ReadTIFFImage.cpp.
  - Added new (internal) Images/GeoTIFF.h header.
- Added ability to use georefencing information from GeoTIFF images
  to properly locate a SceneGraph::ElevationGridNode.
- Added fields to create the color field of a SceneGraph::ColorNode by
  applying a color map to the entries of a colorScalar field.
- Encapsulated helper classes in GL/GLGeometryVertex.icpp in GLGeometry
  namespace to avoid clashes with GLVertex class.
- Added missing time-out handling to device update in
  Vrui::InputDeviceAdapterMultitouch.
- Fixed navigation scale factor in Vrui::MultiDeviceNavigationTool.
- Added Switch node type to SceneGraph library.
- Fixed parameter type of SceneGraph::ImageTextureNode::setUrl method.
- Reduced texture binding overhead in SceneGraph library by adding
  bindTexture methods to SceneGraph::RenderState class.
  - Adapted SceneGraph::ImageTextureNode, SceneGraph::TextNode, and
    SceneGraph::LabelSetNode.
- Added openDevice() convenience method to Sound::AudioCaptureDevice.
  - Finished implementation of non-streaming capture interface.
- Added DeviceRenderer vislet to render devices using "fancy glyphs"
  represented as scene graphs.
  - Added Share/Resources directory to Vrui package.
    - Put ViveController.wrl, a scene graph to render a Vive controller,
      to the Resources directory.
- Added descriptive error strings to exceptions in Comm::UDPSocket.
- Started adding support for Threads::EventDispatcher to
  Sound::ALSAPCMDevice.
- Added error checking and exceptions to read and write methods of
  Misc::Pipe.
- Some API clean-up in Comm library:
  - Added constructor for and method to retrieve IPv4 address as integer
    in host byte order to Comm::IPv4Address.
  - Created new Comm::IPSocketAddress class to represent IP address /
    port pairs for IP versions 4 and 6.
  - Added getAddress() method to Comm::UDPSocket; getPortId() method now
    obsolete and deprecated.
  - Added constructor and connect method using Comm::IPv4SocketAddress
    to Comm::TCPSocket.
  - Changed getAddress() and getPeerAddress() methods in Comm::TCPSocket
    to return Comm::IPv4SocketAddress objects.
    - Removed previous methods to retrieve socket and peer address
      components.
- Added TextureTransform node class to SceneGraph library.
  - Added parsers for new field types required by TextureTransform nodes
    to SceneGraph::VRMLFile.
- Added mip-mapping support through new mipmapLevel field to
  SceneGraph::ImageTextureNode.
- Fixed rendering of "polar caps" in latitude/longitude mode to
  SceneGraph::SphereNode.
- Added support for texture transformations and OpenGL state saving to
  SceneGraph::GLRenderState class.
- Added local scopes to functions in Vrui/SceneGraphSupport.cpp to
  correctly work with texture transform support in
  SceneGraph::GLRenderState.
- Added MaterialLibrary node type to SceneGraph library to support
  sharing of material property data between multiple MeshFile nodes.
  - Added pointer type definition to SceneGraph/ImageTextureNode.h.
  - Added materialLibrary field to MeshFile node.
  - Added new SceneGraph/Internal/ReadMtlFile.h header defining a helper
    function to read Wavefront OBJ material library files.
    - Split OBJValueSource from SceneGraph/Internal/ReadObjFile.cpp
      into own SceneGraph/Internal/OBJValueSource.h header.
  - Rewrote SceneGraph/Internal/ReadObjFile.cpp to use material library
    nodes and readMtlFile function.
- Added setFrontFace method to SceneGraph::GLRenderState.
  - Must now be called by all geometry node types; work in progress.
- Added getNode method to SceneGraph::VRMLfile to retrieve named nodes
  after parsing.
- Added new node type ONTransform to SceneGraph library, for orthonormal
  transformations with a simple field interface suited for programmatic
  control.
- Added new share/Resources subdirectory containing scene graphs etc.
  - Changed Vrui::DeviceRenderer vislet to load device scene graphs from
    Resources directory by default.
- Added new Video::ImageExtractorYpCbCr image extractor class to short-
  circuit multiple color space conversions in the Kinect library.
- Fixed base directory handling bug in Vrui::InputDeviceDataSaver.
- Fixed more by-value catches in Math/GaussNewtonMinimizer.icpp and
  Geometry/GeoCoordinateSystem.cpp.
- Changed negotiation of window visual types between Vrui::VRWindow and
  window group creation in Vrui/Internal/Vrui.Workbench.cpp to support
  mixing different window types in a single window group.
- Changed resetNavigation method in TrackingTest utility to center on
  current tracking data; added menu entry to go to physical space; added
  handling of tracker valid flags.
- Changed input device arguments of query functions in
  Vrui::InputGraphManager to const; inlined query methods.
- Added raw quaternion output option to DeviceTest utility, selected by
  "-q" command line option.
- Improved code in getAngle() and getScaledAxis() methods in class
  Geometry::Rotation.
- Added getEntry method to GLMotif::PopupMenu to complement other index-
  based entry management methods.
- Improved error messages in IO::FileManager.
- Added mutual exclusion of rotation and scaling to
  Vrui::MultiDeviceNavigationTool, controlled by new mutualExclusion
  configuration file setting.
- Added flag to Vrui::ToolManager to call newly-created tools' frame
  methods while inside Vrui's main loop.
  - Added Vrui::ToolManager::enterMainLoop method.
  - Added call to Vrui::ToolManager::enterMainLoop to Vrui's
    prepareMainLoop function.
- Added new Vrui kernel functions to temporarily go to navigational or
  physical space during rendering.
  - Replaced code to do same in several Vrui classes with new functions.
- Added check to exclude disabled devices from screen protection to
  VruiState::update method.
- Removed some redundant calls to kernel API from kernel implementation in
  Vrui/Internal/Vrui.General.cpp.
- Added check to exclude disabled devices from rendering to
  Vrui::DeviceRenderer vislet.
- Added Vrui kernel function getAppConfigurationSection, which returns a
  root section of Vrui's main configuration file named for the current
  application.
- Extract Vrui application name earlier during Vrui::init, send it
  across cluster pipe, use it to open configuration files and access
  application storage.
- Added GLMotif::PopupMenu::addSeparator method to simplify building
  menus.
- Fixed some comments in SceneGraph/ShapeNode.cpp.
- Added code to clear current shapes when updating a
  SceneGraph::MeshFileNode.
- Changed parameter type of error string in
  SceneGraph::VRMLFile::ParseError to constant reference.
- Changes to SceneGraph::GLRenderState in preparation for custom shader
  support in the scene graph architecture:
  - Corrected color type in SceneGraph::GLRenderState; had forgotten
    fourth component.
  - Added current shader program to tracked OpenGL state.
  - Added bindShader() and disableShaders() methods.
- Added getProgramObject() method to GLShader to work with shader
  tracking in SceneGraph::GLRenderState.
- Added GL_NV_primitive_restart OpenGL extension.
- Added GL_ARB_conservative_depth OpenGL extension.
- Fixed many, many bugs in IO::XMLSource and IO::XMLDocument. It appears
  these had never been used.
- Added new header GL/GLShaderSupport.h with helper functions to
  simplify common management tasks involving GLSL shaders.
- Added code to detach shader objects from program objects immediately
  after linking to glLinkShader functions in
  GL/Extensions/GLARBShaderObject.
- Fixed bug when cleaning up after OpenAL errors in startSound function
  in Vrui.Workbench.cpp.
- Added clear() method to GLPolylineTube to re-use objects with dynamic
  polylines.
  - Fixed buffer management to work properly if the polyline is
    currently empty.
- Added convenience functions to load VRML files into new group nodes
  to SceneGraph/VRMLFile.h.
- Added check for empty tool bindings to
  Vrui::InputGraphManager::loadInputGraph to provide an official way to
  disable a tool binding section from a patch configuration file.
- Added Math::nudgeUp and Math::nudgeDown functions for integer and
  floating-point types to Math/Algorithms.h.
- Added vislet ImageViewer to display images in a zoomable and
  scrollable GLMotif popup window.
- Added new filter class IO::Base64Filter for read/write access to
  base64-encoded files using the A-Za-z0-9+/ encoding scheme.
- Added new methods to XML abstraction classes in IO library:
  - IO::XMLCharacterDatas::getData()
  - IO::XMLElement::getAttributes() (const and non-const)
  - Multiple new methods to simplify parsing XML files to IO::XMLSource:
		- putback, skipWhitespace, skip, skipElement, skipToTag,
		  skipToElement.
  - IO::XMLSource::readBase64 method to read base64-encoded binary data
    embedded in XML files via an IO::File abstraction.
- Changed IO::GzipFilter's file opening constructor to use IO::openFile
  instead of an explicit IO::StandardFile constructor.
  - Added support for reading both zlib or gzip headers in compressed
    files.
- Added utility to transform points according to the non-linear
  transformation defined by a PointTransformNode read from a scene graph
  file.
- Fixed wrong return type in SceneGraph::GLRenderState::getTransform().
- Added setEmissiveColor method to SceneGraph::GLRenderState to fix some
  issues with material handling; changed to new method in attribute node
  classes and removed color references from geometry node classes.
- Added new setUrl method relative to current directory to
  SceneGraph::ImageTextureNode to simplify programmatic scene graph
  creation.
- Created new SceneGraph::BaseAppearanceNode class to serve as common
  base class for multiple appearance node classes.
- Added optional elevation angle ribbon to FPSNavigationTool's HUD.
- Corrected initialization code in GL/GLShaderSupport.cpp.
- Added new class GLSphereRenderer to render sets of spheres via
  impostor quads and ray casting.
- Added new boolean flag drawSpheres to SceneGraph::PointSetNode to draw
  points as spheres using impostors.
- Added new class GLCylinderRenderer to render sets of cylinders via
  impostor quads and ray casting.
- Fix in SceneGraph::GLRenderState: Set current color to emissive
  material property when disabling materials.
- Added safeguard for blocked audio devices and exception handling in
  recording thread to Sound::SoundRecorder.
- Added exception handling to Vrui::InputDeviceDataSaver when starting
  sound recording.
- Added movieSaverAutostart configuration option to Vrui::VRWindow to
  start recording immediately.
- Added glLinkAndTestShader helper function to
  GL/Extensions/GLARBShaderObjects.h.
- Added GLMotif widget implementing Quikwriting algorithm in preparation
  for text input request functionality in GLMotif::WidgetManager.
- Added mechanism for GLMotif widgets to request text input from the
  widget manager, which could pop up virtual keyboards etc.
  - Added new abstract class GLMotif::TextEntryMethod.
    - Added concrete implementation GLMotif::QuikwritingTextEntryMethod.
    - Added concrete implementation Vrui::KeyboardTextEntryMethod.
  - Added new text entry request methods to GLMotif::WidgetManager.
  - Added code in Vrui::VruiState::initialize to create text entry
    methods.
- Added value type to GLMotif::TextField to distinguish between alpha-
  numerical, unsigned integer, integer, and float text fields.
- Added GLMotif/Config.h to hold configuration data for the GLMotif
  library, currently the location of Quikwriting textures.
- Replaced deprecated libusb_set_debug in USB/Context.cpp with
  libusb_set_option.
- Added new configuration option textEntryMethod to Vrui root section,
  to select Vrui's text entry method. Current options: Keyboard
  (requires mouse input device adapter), Quikwriting.
- Added configuration option for new libusb_set_option function to
  USB/Config.h, using it in USB/Context.cpp.

Vrui-5.0-002:
- Added optional timeout parameter to Comm::HttpFile constructors.
- Created new class Comm::TLSPipe to represent TLS-secured TCP
  connections.
- Added configuration header Comm/Config.h to Comm library.
  - Contains flag whether OpenSSL exists on system.
- Added proper support for HTTPS protocol to Comm::HttpFile using new
  Comm::TLSPipe class.
- Added error messages for requesting HTTPS connections in cluster mode
  to Cluster::Opener class.
- Added JSON entity and file parsing classes to IO library.
- Added interactive flag to selection changed and value changed callback
  data structures in GLMotif::ListBox to distinguish events due to
  direct user interaction from those due to method calls.
- Added new MeasurePoints application to Vrui utilities.
- Fixed dollying direction in Vrui::MouseNavigationTool's center dolly
  mode to be in line with display center and main viewer.

Vrui-5.1-001:
- Added per-user configuration with options to show secondary window
  and/or fancy controller models to OnVive.sh.
- Changed popup thickness calculation in GLMotif::Popup.
- Changed names of convenience functions in IO/JsonEntityTypes.h.
  - Added function to retrieve an object property.
- Added option to print the display position and size of a found HMD to
  FindHMD Vrui utility.
- Improved user interface for MeasurePoints Vrui utility.
- Oops, flipped dollying direction in Vrui::MouseNavigationTool.
- Added missing #include <stddef.h> to Misc/StandardHashFunction.h.
- Added isBlocking and setBlocking methods to Comm::ListeningTCPSocket.
- Added isValid method to IO::UTF8 class to check if a string segment is
  a valid UTF-8 encoding.
- Large changes to Threads::EventDispatcher as it's finally being used
  for reals:
  - Added setIOListenerEventTypeMask and
    setIOListenerEventTypeMaskFromCallback methods.
  - Also major code clean-up in same.
  - Added ReadWrite event type mask shortcut.
  - Added handling of custom signals, implemented as special messages
    on the dispatcher's self-pipe.
  - Can now read multiple self-pipe messages in one call to
    dispatchNextEvent.
  - Added static wrapMethod template functions to directly register
    class methods as callbacks.
  - Changed behavior of I/O listeners: Multiple simultaneous events will
    be handled by a single callback call; event type parameter is now
    event type mask with bit-wise or of active events.
  - Moved handling of timer events to before wait fd sets are created;
    otherwise changes from within timer event callbacks would not be
    reflected on next select(). Oops.
  - Large changes to timer event handling:
    - All dispatches of elapsed timer events happen conceptually at the
      same time.
    - New getCurrentTime() method for event callbacks of all types.
    - Timer callback that elapsed multiple times since last
      dispatchNextEvent is only called once.
      - Working on telling it how many elapses it missed.
    - Current time is updated again after returning from select() call.
- Added constructors for IPv4 and IPv6 addresses to
  Comm::IPSocketAddress.
- Finished implementation of event-driven I/O in Sound::ALSAPCMDevice.
- Fixed bug in IO::File: flushReadBuffer must also reset haveEof flag,
  as it is an admission from the derived class that more data can
  potentially be read.
- Added hash method to Comm::IPv4SocketAddress.
- Added access methods for IPv4 and IPv6 addresses to
  Comm::IPSocketAddress.
- Added new class Misc::RingBuffer for dynamically-growing ring buffers.
- Added a new createObject method to Plugins::ObjectLoader that takes an
  additional argument of arbitrary type.
- Added non-blocking option to and improved read/write interfaces in
  Misc::Pipe.
- Added change notification callbacks to several Vrui components:
  - Added environmentDefinitionChangedCallback to get notified when the
    definition of Vrui's physical environment (display center etc.)
    changes.
  - Added configChangedCallback to Vrui::Viewer to get notified when a
    viewer changes configuration (head tracking state, eye positions,
    etc.).
- Added a convenience setEnabled method to Vrui::InputGraphManager.
- Changed processing order in Vrui::InputDeviceAdapterDeviceDaemon and
  Vrui::InputDeviceAdapterPlayback such that disabled input devices have
  their tracking state updated immediately before they are re-enabled in
  the input graph manager.
- Added tracker state and device ray change tracking and device ray
  change callbacks to Vrui::InputDevice.
  - Added new combined Vrui::InputDevice::setTrackingState method.
- Added change tracking to Vrui::InputDeviceAdapterMouse to only set the
  mouse device's transformation if the mouse position changed.
- Changed interface of Vrui::UIManager::projectDevice method to avoid
  multiple calls to Vrui::InputDevice::setTransformation in a single
  frame.
  - Changed implementation of Vrui::UIManagerPlanar::projectDevice and
    Vrui::UIManagerSpherical::projectDevice.
  - Adapted code in Vrui::VRWindow and Vrui::InputDeviceAdapterHID.
- Some changes to error handling / exceptions throughout code base:
  - Added new printStdErrMsgReentrant to Misc/ThrowStdErr.h that writes
    into a caller-supplied buffer.
  - Made static message buffer non-static in Misc::throwStdErr (duh).
  - Changed most uses of Misc::printStdErrMsg, except in constructors of
    custom exception classes, to re-entrant version. Need std::string-
    based version for that.
- Made Vrui::MessageLogger thread-safe, which it should have been from
  the very beginning. Oopsie.
- Minor change in Vrui::SoundContext::makeCurrent to check for potential
  issue; was nothing.
- Added finishMainLoop callback to Vrui kernel, to call applications
  immediately after the main loop finishes, before graphics and sound
  systems and tool manager are shut down.
  - Added virtual finishMainLoop method to Vrui::Application.
- Added Sound::WAVFile to read/write audio files in WAV format.
- Added getModuleConfigurationSection function to Vrui kernel interface
  to return a configuration file section holding environment-specific
  settings for a module of an arbitrary name.
- Changed Misc::MessageLogger to direct user messages to stderr and log
  and console messages to stdout.
- Changed config access in Vrui::SoundContext constructor so that quotes
  are no longer required around OpenAL device names.
- Fixed a bug in device battery state update handling in
  Vrui::InputDeviceAdapterDeviceDaemon.
  - Also removed batching and synchronous handling of errors and
    warnings; Misc::MessageLogger and its derivatives are now fully
    thread-safe.
- Cosmetic changes to Misc::CallbackList::removeCli during debugging.
- Removed constness of widget parameter in text entry request methods
  in GLMotif::WidgetManager and GLMotif::TextEntryMethod.
  - Adapted GLMotif::QuikwritingTextEntryMethod and
    Vrui::KeyboardTextEntryMethod.
- Slight changes to event handling model in GLMotif::WidgetManager to
  support additional use cases.
  - A pointer-grabbing widget can release the grab from inside
    findRecipient, which will toss the call back to the widget manager.
- Changed behavior of Quikwriting text entry method to finally be
  usable.
- Forgot that Vrui::getUiStyleSheet() exists! Removed several trips
  through Vrui::getWidgetManager() and related #includes from several
  sources.
- Started adding proper settings dialog to Vrui.
  - Added callback to Vrui::CoordinateManager when the measurement unit
    is changed.
    - Added forgotten call to user coordinate transform changed
      callbacks when the user coordinate transform is changed.
    - Added response to measurement unit changes to Vrui::ScaleBar.
    - Added setGain method to Vrui::Listener to adjust overall sound
      volume during run-time.
- Added new Vrui kernel functions:
  - Vrui::getSettingsPager returns the pager widget where applications
    or modules can add their own settings pages to Vrui's settings
    dialog.
  - Vrui::addShowSettingsDialogButton adds a button to pop up a dialog
    with application or module settings to the Vrui system menu.
  - Vrui::removeShowSettingsDialogButton removes a previously-added
    button from the Vrui system menu and deletes it.
- Copied top-level widget popping-up, moving, or showing behavior from
  Vrui system menu's "Dialogs" sub-menu to Vrui::popupPrimaryWidget
  function.
- Added boolean startup and shutdown flags to Vrui::Vislet::enable and
  Vrui::Vislet::disable methods, respectively, to simplify vislet
  management.
  - Vrui::Vislet::disable is called with shutdown flag set to true after
    Vrui's main loop terminates even if the vislet is already disabled
    at that time.
  - Adapted all Vrui vislet classes to new API.
- Added decrement operators to Misc::RingBuffer::iterator.
- Added pop_back method to Misc::RingBuffer (yes, that is useful).
- Added callback when a navigation tool is activated or deactivated to
  Vrui kernel API.
- Replaced old useless "Push View" and "Pop View" buttons in Vrui system
  menu with new useful "Undo View" and "Redo View" buttons.
- Added timeout for mouse wheel operations to Vrui::MouseNavigationTool.
- Added support for versioned plug-ins to Plugins::ObjectLoader. Version
  numbers are placed in DSO name templates via %u conversions.
- Split Images::TIFFReader helper class from Images/ReadTIFFImage.cpp
  into its own header/source files to allow advanced uses by special
  applications such as pixel streaming.
  - Also moved Images::GeoTIFFMetadata into its own header.
  - Adapted functions in Images/ReadTIFFImage.cpp.
  - Adapted TIFF support in SceneGraph/Internal/LoadElevationGrid.cpp.
- Fixed Images::readGenericImageFile functions in
  Images/ReadImageFile.cpp; had missing break statements after BIL
  branches.
- Added .img as a determining file extension for BIP/BIL/BSQ images.
- Added new readGenericImageFile function to Images/ReadBILImage.h that
  takes a prepared BIL file layout and an open file.
- Added option to add/remove characters from QUOTEDSTRING class to
  IO::ValueSource and slightly improved reading of quoted strings.
- Redirected PNG library warnings from Images/ReadPNGImage.cpp from user
  to console to avoid having hundreds of pop-ups.
- Improved OBJ file parser in SceneGraph/Internal/ReadObjFile.cpp.
- Added texture image sharing via URL hashing to SceneGraph/Internal/
  ReadMtlFile.cpp, significantly reducing memory usage and load times on
  complex OBJ files.
- Added boolean disableTextures field to SceneGraph::MaterialNode and
  SceneGraph::MeshFileNode.
  - Added disableTextures flag to SceneGraph::readMtlFile.
- Fixed bug in material creation in readMtlFile that made everything
  white.
- Clamp shininess in SceneGraphNode::MaterialNode to 1.0 to avoid OpenGL
  errors.
- Added isWs() and getCharAndPeekc() methods to IO::ValueSource to
  simplify writing parsing state machines.
- Added mesh group merging to SceneGraph/Internal/ReadObjFile.cpp,
  significantly increasing performance for meshes with many small face
  groups sharing material properties.
- Fixed VRML format checker in SceneGraph::VRMLFile; forgot that header
  line is also a comment and can contain extra stuff.
- Added leveling buttons to align any of the three primary axes with the
  environment's up direction.
- Lighthouse driver now exports Vive tracker's power button as a usable
  button. Adapted OpenVRHost device driver module accordingly.
- Added button to add calibration sample to calibration dialog in
  MeasurePoints Vrui utility.
- Added lighting control panel with optional Sun light source to Vrui
  settings dialog.
- Added locateNumberedFile method to Misc::FileLocator; takes a template
  with a single %u conversion and returns the file with the highest
  number.
- Factored non-template code out of Plugins/ObjectLoader.icpp into
  Plugins/ObjectLoader.cpp.
- API change: replaced std::string argument in
  Plugins::ObjectLoader::ObjectLoader with const char*.
- Improved support for versioned DSOs in Plugins::ObjectLoader.
- Added an optional command pipe to control running Vrui applications
  from outside.
  - Added command handlers for important viewer configuration parameters
    to Vrui::Viewer.
- Simplified inverse lens distortion correction formula in
  Video::LensDistortion, was still in development mode.
- Changed type of texture transformation in SceneGraph library to full
  affine transformation.
- Added mipmapping support to GLMotif::Texture and GLMotif::Image
  classes.
- Removed extraneous pixel pipeline setup from
  Images::BaseImage::glTexImage2DMipmap.
- Added drag scrolling (by pulling the image with a pointer) to
  GLMotif::ScrolledImage.
- Fixes to Vrui ImageViewer vislet:
  - Corrected placement of zoom in/out buttons
  - Enabled mipmapping
  - Enabled drag scrolling
- Minor improvement to ray intersection code in GLMotif::Widget.
- Changed GLMotif::Event::setTargetWidget method to reject ray
  intersections with negative lambda.
  - Also minor code clean-up.
- Changed GLMotif::WidgetManager::findPrimaryWidget method to return
  ray parameter to closest intersected widget.
- Changed Vrui::GUIInteractor to draw interaction ray only to pointed-at
  widget.
- Improved behavior of GLMotif::CascadeButton when the pointer is moving
  towards the popup.
- Improved popup positioning in GLMotif::CascadeButton.
- Added minimum popup thickness to GLMotif::StyleSheet.
- Fixed zRange calculation for GLMotif::Popup and GLMotif::PopupWindow
  to guarantee minimum thickness and containment of child widgets.
- Fixed interaction in Quikwriting text entry method by resetting
  gesture state between invocations.

Vrui-5.1-002:
- Added $HOME/ to Vrui user configuration directory in OnVive.sh.
- Added options to print xrandr command lines to enable/disable an HMD
  to FindHMD utility.
- Changed string buffer lengths in
  VRDeviceDaemon/VRDevices/Linux/HIDDevice.cpp.
- Updated Contributed/OpenVR/headers/openvr_driver.h to current version
  compatible with SteamVR version 1.7.15.
- Updated VRDeviceDaemon/VRDevices/OpenVRHost to current OpenVR version.
- Improved RunViveTracker.sh script to automatically enable/disable the
  HMD's display.
- Improved OnVive.sh script to work with Vive and Vive Pro.
  - Renamed OnVive configuration file to OnVive.conf
- Updated udev rule file to work with Vive Pro.
- Added quit command to Vrui command pipe parser.
- Put in fix for dropped X events in multi-window continuous-update
  mode, but still no idea what the actual problem is.

Vrui-5.1-003:
- Added map property mask to SceneGraph::ElevationGridNode to be able to
  override map parameters provided in DEM image files.
  - Added property mask check code to
    SceneGraph/Internal/LoadElevationGrid.cpp.
- Fixed RunViveTracker.sh script:
  - Bad path to XBackground
  - Wrong return code check in GetViveType
- Added rewind() method to IO::VariableMemoryFile.
- Re-enabled Threads::TripleBuffer::getMostRecentValue method.

Vrui-5.2-001:
- Added virtual updateVariables method to GLMotif::Widget to support
  widgets that track application variables.
  - Added forwarding implementations of updateVariables to
    GLMotif::Container.
- Created new GLMotif::VariableTracker class to use as base or elements
  for widgets that track application variables.
- Rebased GLMotif::Popup and GLMotif::PopupWindow to
  GLMotif::SingleChildContainer to remove some common code.
- Added special implementations of updateVariables to
  GLMotif::SingleChildContainer, GLMotif::RowColumn, and GLMotif::Pager.
- Added variable tracking via GLMotif::VariableTracker to
  GLMotif::ToggleButton, GLMotif::RadioBox, GLMotif::DropdownBox,
  GLMotif::TextField, GLMotif::Slider, and GLMotif::TextFieldSlider.
  - Restructured GLMotif::RadioBox to simplify variable tracking.
- Made changes to GLMotif::TextField:
  - Split member template instantiations into GLMotif/TextField.icpp
    source file.
  - Used known string lengths for more efficient setString() calls.
- API change: Changed value type in GLMotif::Slider from GLfloat to
  double.
- Fixed slider increment/decrement and dragging interaction with
  notches in GLMotif::Slider.
- Changed behavior of GLMotif::DropdownBox::setSelectedItem: Item index
  is silently limited to valid range.
- Added PolygonTriangulator class to Geometry library.
- Changed parameter and return types for strings to const std::string&
  in Video::VideoDevice.
- Added getDeviceName method to Video::ViewerComponent.
- Added option to render circular FoV indicators to FoVRenderer vislet.
- Added class Misc::Vector to handle variable arrays in a type-
  independent manner.
- Forgot to update slider value in GLMotif::Slider::updateVariables.
- Forgot to implement GLMotif::CascadeButton::updateVariables.
- Added custom track() method to GLMotif widget classes derived from
  GLMotif::VariableTracker to simplify widget creation.
- Reordered GLMotif::TextField::setValue methods and added support for
  std::string values.
- Fixed assignment operator in Misc::Vector.
- Added tracking of color variables to GLMotif::HSVColorSelector, did
  some minor refactoring.
- Added argument list and description strings to
  Vrui::addPipeCommandCallback method.
- Added Vrui-level pipe commands:
  - listCommands lists defined commands
  - loadView loads a viewpoint file
  - loadInputGraph loads an input graph file
  - saveScreenshot saves a screenshot from a selected window
- Replaced waiting for Esc on stdin for window-less Vrui applications
  with general command parsing from stdin.
- Replaced viewer name with "Viewer(<viewer name>)" prefix in
  Vrui::Viewer pipe commands.
- Added "active" flag to Vrui::ToolKillZone to temporarily disable tool
  deletion.
  - Added boolean killZoneActive setting to tool manager configuration
    file section.
  - Added "Tool Kill Zone Active" toggle to Vrui device menu.
- Added missing #include <stddef.h> to Images/BaseImage.h
- Added constructor and write() methods for binary files in internal
  format to Images::BaseImage.
- Added ability to write JPEG images to Images::writeImageFile
  functions in Images/WriteImageFile.h, currently with default 90%
  quality setting.
- Added new Misc::CommandDispatcher class to dispatch commands read from
  files or pipes.
  - Replaced Vrui's pipe command dispatcher with Misc::CommandDispatcher
- Replaced haptic tick parameters in Vrui's device daemon client/server
  protocol with duration in milliseconds, frequency in Hertz, and
  relative amplitude in [0, 256). Updated protocol to version 8.
  - Updated DeviceTest and MeasurePoints utilities to new haptic tick
    parameters.
- Added initial support for haptic feedback to Vrui:
  - Added hapticTick method to Vrui::InputDeviceManager.
  - Added addHapticFeature method to Vrui::InputDeviceManager to let
    input device adapters associate input devices with haptic features.
  - Added haptic feedback support through Vrui::VRDeviceClient to
    Vrui::InputDeviceAdapterDeviceDaemon.
- Added new Geometry::Ray::offset method to move a ray's origin along
  its direction.
  - Used new offset method in Vrui::InputDevice::getRay and
    Vrui::ClipPlaneManager::clipRay.
- Added by-reference read method to Misc::Marshaller template class and
  all specializations to avoid unnecessary copy operations.
  - Updated uses of Misc::Marshaller throughout libraries:
    - Cluster::StandardDirectory
    - Vrui::VRDeviceState; also used by-reference reads in
      implementation
    - Vrui::VRDeviceDescriptor; also cleaned up network encoding.
- Added namespace-global read/write convenience functions to
  Misc/Marshaller.h.
  - Updated clients throughout libraries:
    - Vrui::InputDeviceAdapterDeviceDaemon
    - Vrui::MultipipeDispatcher
    - Vrui/Utilities/DeviceTest.cpp
- Replaced native types with sized types from Misc/SizedTypes.h in wire
  interface of Misc::StringMarshaller functions.
- Removed superfluous #include <Misc/StringMarshaller.h> from
  GLMotif::FileSelectionDialog.cpp
- Fixed string reserve() in Misc/StringMarshallers.h; don't need to
  include NUL character.
- API CHANGE: No longer including Misc/ConfigurationFile.icpp from
  Misc/ConfigurationFile.h; clients that want pipe functionality need to
  do so themselves.
  - Added #include <Misc/ConfigurationFile.icpp>:
    - Vrui/InputGraphManager.cpp
    - Vrui/Internal/Vrui.Workbench.cpp
    - Vrui/Vislets/Filming.cpp
  - Added some missing include files elsewhere raised by change:
    - Vrui/VRScreen.cpp: #include <string.h>
    - Vrui/Internal/InputDeviceAdapterMouse.cpp: #include <string.h>
    - Vrui/Internal/InputDeviceAdapterPlayback:
      #include <Misc/StringMarshaller.h>
- New failure behavior in SceneGraph::InlineNode: Errors during
  dependent scene graph parsing cause error message and node remaining
  empty.
- Added clamp() function to Misc/Utility.h.
- Added initial version of generic IK avatar support to Vrui via classes
  Vrui::IKAvatar and Vrui::IKAvatarDriver.
- Added Vrui::Vislets::IKAvatarRenderer vislet class to render an IK
  avatar for the local user.
- Added IKAvatar directory with avatar VRML files to Share/Resources
  subdirectory.
  - Added IKAvatar directory and avatar VRML files to install rule in
    makefile.
- Added configuration section for IK avatar to Desktop and Vive root
  sections in Vrui.cfg.
- Added support for Misc::Vector to Misc/CompoundValueCoders.h and
  Misc/CompoundMarshallers.h.
- Added data() method to Misc::Vector.
- Fixed const error in element accessor in Misc::Vector.
- Reduced default tesselation of SceneGraph::SphereNode because it was
  too damn high.
- Fixed configuration code in Vrui::IKAvatarDriver.
- Added state tracking of enabled vertex arrays and bound vertex and
  index buffers to SceneGraph::GLRenderState.
  - Updated scene graph node classes to use new capabilities:
    - PointSetNode, QuadSetNode, CurveSetNode, IndexedLineSetNode,
      TSurfFileNode, IndexedFaceSetNode, ElevationGridNode.
- Added support for GL_NV_primitive_restart extension to
  SceneGraph::ElevationGridNode.
- Added missing #include <stddef.h> to GL/GLBuffer.h
- Fixed installation problem of Resources subdirectory by installing
  only .wrl files; need to find permanent fix.
- Fixed bug in GLMotif::RadioBox::setSelectionMode when no button was
  selected.

Vrui-6.0-001:
- Added invalidateMousePosition method to Vrui::InputDeviceAdapterMouse.
- Finally fixed Vrui::MouseCameraTool.
- Added tracking of GLMaterial objects to GLMotif::MaterialEditor.
- Removed unused hmdSize array from createXrandrCommand function in
  Vrui/Utilities/FindHMD.cpp.
- Improved printing of identity rotations in Geometry/OutputOperators.
- Added some helpful explicit casts in Vrui/VRWindow.cpp.
- Fixed missing implementation of UIManagerFree::projectDevice.
- Added ability to remove tool classes at run-time to Vrui::ToolManager.
- Added Misc::RGB and Misc::RGBA classes to replace GL/GLColor classes
  in the future, to disentangle color representation and handling from
  OpenGL support.
  - Added Misc::ColorComponentTraits class to define values and
    behaviors for canonical OpenGL color component types.
  - Added Misc/ConvertColorComponent.h with namespace-global functions
    to convert between different color scalar types. Supporting the
    canonical OpenGL set, of course.
- Added version of readCppString to read into existing std::string to
  Misc/StringMarshallers.h.
- Added value coder classes for Misc::RGB and Misc::RGBA to
  Misc/ColorValueCoders.h.
- Removed two uses of hashtable[source]=dest from Cluster::Multiplexer
  to get rid of "potentially uninitialized" compiler warnings.
- Put conditional into makefile to only build FindHMD if XRANDR is
  supported.
- Added Misc/VarIntMarshaller with namespace-global functions to
  serialize unsigned integers using a variable number of bytes.
- API CHANGE: Removed Misc/VarInt.h and replaced it with
  Misc/VarIntMarshaller.h, offering the same functionality at better
  efficiency.
  - Replaced use of Misc::writeVarInt / Misc::readVarInt in
    Vrui::TextEventDispatcher with new functions.
- API CHANGE: Removed the ability to serialize null strings from C-style
  functions in Misc/StringMarshaller.h, because that was a dumb idea.
  - Fixed code using that dumb idea in Vrui::InputGraphManager and
    Vrui::Filming.
- Binary representation change: string serialization now uses VarInt
  length fields in Misc/StringMarshaller.h and
  Misc::Marshaller<std::string>.
- Added constants for "long long" and "unsigned long long" types to
  Math::Constants to support 32-bit architectures slightly better.
- Added configurable timeout to Vrui::Lenscorrector's IPD display
  dialog, via ipdDisplayTimeout configuration file setting.
- Added method Sound::WAVFile::readMonoAudioFrames to downmix multi-
  channel WAV files to mono on-the-fly.
- Fixed sound support in HTC Vive / Vive Pro mode in Vrui.cfg and
  OnVive.sh.
- Replaced command line construction in OnVive.sh with Bash arrays.
- Added default reference distance and roll-off factor, to be queried by
  clients configuring OpenAL sources, to Vrui::SoundContext.
  - Mirrored same parameters in ALContextData for easier access to sound
    methods.
- Added orientation snapper tool to Vrui to align an input device's
  orientation with physical space's primary axes.
- Bumped VRDeviceDaemon network protocol to version 9 to accommodate new
  variable-length string length tags; put compatibility code into
  Vrui::VRDeviceDescriptor.
- Added T-pose calibration method configureFromTPose to
  Vrui::IKAvatarDriver.
- Reduced mutex lock time in Vrui::MessageLogger::frameCallback.
- Added Vrui::InputDeviceManager::hasHapticFeature method.
- Added haptic feedback for devices entering or exiting the tool kill
  zone to frame processing code in Vrui/Internal/Vrui.General.cpp.
- Added option to always show the screen protection grids to Vrui System
  menu Devices sub-menu.
- Improved frame rate display for window-less Vrui processes.
- Fixed pelvis inversion error, improved pelvis positioning, improved
  knee alignment in Vrui::IKAvatarDriver.
- Added HMD screen saver feature by handling face detector sensors found
  in most HMDs, through new enableButtonDevice, enableButton, and
  invertEnableButton configuration tags in window sections.
- Improved support for UTF-8 encoded strings by adding Misc::UTF8 class
  with static methods and re-implementing IO::UTF8 using Misc::UTF8.
- Added escape sequence handling to quoted tokens in IO::TokenSource,
  currently using '\' as hard-coded escape character.
- Removed single quotes as string quotes in SceneGraph::VRMLFile, as the
  VRML specification only allows double quotes.
- Added missing #include <stdlib.h> to Misc/Vector.h.
- Simplified raw memory handling in Misc::PriorityHeap.
- Added empty() method to Geometry::PolygonTriangulator to avoid crashes
  when attempting to triangulate empty edge sets.
- Added factory pointer-based releaseClass methods to
  Plugins::FactoryManager and Vrui::ToolManager.
- Added boolean "filter" field to SceneGraph::ImageTextureNode to
  disable bi- or tri-linear texture interpolation.
- Added new scene graph node type DOGTransformNode for double-precision
  orthogonal transformations.
- Made root scene graph node in Vrui::IKAvatar persistent to simplify
  scene graph management.
  - Added non-const getSceneGraph method.
- Added getLockFeetToNavSpace method to Vrui::IKAvatarDriver, and
  configuration file setting for same.
- Added FancyFontStyleNode and FancyTextNode to SceneGraph library to
  render proper 3D text; set up to replace old FontStyleNode and
  TextNode.
- Added BillboardNodePointer declaration to SceneGraph/BillboardNode.h.
- Fixed IK avatar scaling work-around in Vrui::IKAvatar and
  Vrui::IKAvatarDriver.
  - Removed Vrui::IKAvatarDriver::configureAvatar because it was dumb.
- Fixed idling and hangup problem with console input. To background a
  Vrui application, close stdin first via Ctrl-D, then Ctrl-Z and bg.
- Added addSynchronousIOCallback and removeSynchronousIOCallback to Vrui
  kernel interface to watch for pending data on arbitrary file
  descriptors from Vrui's main loop.
- Added configuration header SceneGraph/Config.h, currently containing
  font file locations and names for FancyFontStyle nodes.
- Brought build system in line with development branch, necessitating
  move to Vrui-6.x.
- Added StripPackages.c utility to BuildRoot and added rules for build
  utilities to makefile.
- Updated OpenVRHost VRDeviceDaemon module to SteamVR version 1.9.15;
  alas, crashes with newest version 1.10.32.
- Another build system overhaul to keep debug and release versions of
  libraries, plug-ins, and executables separate.
  - Set both debug and release versions of target directories in
    BuildRoot/SystemDefinitions.
  - Put debug and release versions into package configuration files and
    override them from configuration scripts.
  - Removed all per-source -D definitions from makefile, replaced with
    new configuration header settings.
    - Affected Vrui/ToolManager.cpp, Vrui/VisletManager.cpp,
      Vrui/Internal/Vrui.Workbench.cpp, and
      VRDeviceDaemon/VRDeviceManager.cpp.
- Updated openvr_driver.h in Contributed/OpenVR/headers to newest
  version from github.
  - Added -DDEBUG to CFLAGS if DEBUG is defined in
    BuildRoot/SystemDefinitions.
- Added getRootSectionName function to Vrui kernel API.
- Added getRecordingDeviceName method to Vrui::SoundContext.
- Added error check on alcCloseDevice to Vrui::SoundContext destructor.
- Added missing initialization of state-tracking variables in
  SceneGraph/FancyFontStyleNode.cpp.
  - Also improved error handling related to bad explicit font URLs.
- Removed IK avatar driver configuration from Vrui.cfg and created own
  IKAvatar.cfg configuration file in global and per-user configuration
  directories.

Vrui-7.0-001:
- Fixed error message in Vrui resetView command callback in
  Vrui/Internal/Vrui.General.cpp.
- Fixed initial upload of navigation-space modelview matrix to OpenGL in
  VruiState::display.
  - This needs to be addressed everywhere glLoadMatrix/glMultMatrix is
    used.
- Minor optimization in Vrui::AnnotationTool::buttonCallback. Will have
  to be rewritten to pick in physical space, to minimize accuracy
  issues.
- Added time-out to automatically close dialogs opened by
  Vrui::showErrorMessage.
  - Removed duplicate code from Vrui::MessageLogger; now using
    Vrui::showErrorMessage to pop up message dialogs.
- Fixed order of manager destruction in VruiState destructor in
  Vrui/Internal/Vrui.General.cpp.
- Fixed library dependencies in BuildRoot/Packages.Vrui.
- Improved way hardware parameters are initialized in
  Sound::ALSAPCMDevice.
- Finished implementation of Video::ImageExtractorYV12.
  - Added support for planar Y'CbCr 4:2:0 video formats to
    Video::V4L2VideoDevice.
- Improved snapping support in TrackingTest Vrui utility.
- Working towards fixing build system over- and under-linking issues.
- Finally fixed statistics calculation in "burn mode" in Vrui::VRWindow
  by using a fixed-time spin-up phase.
- Added OpenGL extension class GLARBPixelBufferObject.
- Added subclass GLContext::Properties to encapsulate how OpenGL context
  creation is done (visuals vs FBConfigs).
  - Changed GLWindow constructors to take a GLContext::Properties object
    instead of a visual property list.
  - Changed Vrui::VRWindow::initContext method to use a
    GLContext::Property object instead of a visual property list.
- Improved inner loop instrumentation code in
  Vrui/Internal/Vrui.Workbench.cpp.
- Created experimental GLUploadContext class to support buffer content
  upload from background threads.
  - Added getContext() method returning GLX context handle to GLContext.
  - Added getContext() method returning GLContext object to
    GLContextData.
- Moved buffer resizing code in Misc::RingBuffer to private method to
  improve inlining.
- API change: Replaced Video::LensDistortion class with improved version
  from Calibration project.
- Added IntrinsicParameters class from Calibration project to Video
  library.
- Added putBackInBuffer method to IO::File to (partially) undo a
  previous readInBuffer call.
- Fixed Images::readJPEGImage to put back unread data at the end of an
  image file to support multi-image input streams.
- Added writeElements method to Misc::FixedArray to copy an array object
  to a C-style array with optional type conversion.
- Added openVideoDevice convenience method to Video::VideoDevice.
- Added HMDCameraViewer vislet.
- Fixed error message in Video::ViewerComponent constructor.
- Added Misc::RingBuffer::clear method with optional buffer resize.
- Fixed description of Vrui::Vislet::disable method for shutdown case.
- Addressed loss of precision and resulting rendering jitter from matrix
  uploads by replacing sequences of glRotate/glScale/glTranslate with
  computation of final matrix on CPU side and uploading the results as
  4x4 matrices.
  - Added new elements mvpGl and mvnGl, which hold 4x4 column-major
    matrices representing the physical-space and navigational-space
    modelview matrices, respectively, to Vrui::DisplayState.
  - Changed all parts of Vrui that directly uploaded either modelview
    matrix to OpenGL.
  - Re-implemented matrix uploads in SceneGraph::RenderState to use
    temporary 4x4 matrices as well.
- Fixed HMD screen blackout: use black instead of Vrui's background
  color.
- Added calcFloorPoint function to Vrui kernel interface.
- API CHANGE: Removed projectToFloor method from
  Vrui::SurfaceNavigationTool; replaced by new calcFloorPoint function.
  - Updated concrete surface-aligned navigation tool classes.
- Several improvements and fixes to ValuatorWalkSurfaceNavigationTool.
- Reset total number of Vrui windows to 0 when shutting down graphics
  sub-system in Vrui.Workbench.cpp to avoid shut-down problems.
- Fixed non-editable text fields requesting text entry when clicked in
  GLMotif::TextField.
- Added setFont method to GLNumberRenderer class and added font state
  management.
  - Improved number renderer management in
    Vrui::WalkSurfaceNavigationTool and
    Vrui::ValuatorWalkSurfaceNavigationTool.
- Common-case optimizations:
  - Added addScaled and subtractScaled methods and namespace-global
    functions to Geometry::Point and Geometry::Vector.
- Large-scale fixes to Vrui's cluster mode due to synchronization
  failures introduced in previous releases:
  - Fixed bug when constructing error messages in
    Cluster::StandardFileSlave constructor.
  - Added "Manual" option to Vrui multipipeRemoteCommand setting to let
    users start Vrui processes on cluster nodes manually.
  - Synchronize selection of text entry methods in Vrui::initialize.
  - Fixed path assembly bug in Cluster::StandardDirectory::openFile.
  - Moved loading of cursor image file in Vrui::GlyphRenderer from
    initContext method to constructor; replaced cursorImageFileName
    element with Images::RGBAImage cursorImage element.
- Added -printBatteryStates option to DeviceTest utility to print all
  devices' battery states and exit.
- Added airborne flag to Vrui::FPSNavigationTool and changed fall
  detection to allow walking down slopes.
- Fixed bounding box calculation bug in SceneGraph::IndexedLineSet:
  only consider points that are used by polylines.
- Added pre-calculated bounding box to SceneGraph::IndexedFaceSet.
- Changed SceneGraph::GeodeticToCartesianTransformNode to use a double-
  precision transformation internally.
- Move to make transformations in SceneGraph library double-precision
  - Promoted double-precision orthogonal transformations to namespace-
    wide geometry types
  - API change: Removed DOGTransform typedef in
    SceneGraph::GLRenderState.
  - API change: changed transform derived element to DOGTransform in
    SceneGraph::TransformNode; changed accessor accordingly.
  - Changed derived elements in SceneGraph::BillboardNode to double-
    precision.
  - Adapted SceneGraph::GeodeticToCartesianTransformNode,
    SceneGraph::ONTransformNode, and SceneGraph::DOGTransformNode.
  - Adapted Vrui::DeviceRenderer vislet.
- Added method to calculate the bounding box of an indexed point set to
  SceneGraph::PointTransformNode.
  - Updated SceneGraph::AffinePointTransformNode,
    SceneGraph::GeodeticToCartesianPointTransformNode, and
    SceneGraph::UTMPointTransformNode.
  - Used new method in SceneGraph::IndexedLineSetNode and
    SceneGraph::IndexedFaceSetNode.
- Removed TSurfFileNode from SceneGraph library because it is obsolete;
  mesh file readers should be implemented under
  SceneGraph::MeshFileNode.
- Added first stage of collision detection to SceneGraph library:
  - Created new class SceneGraph::SphereCollisionQuery.
  - Added testCollision() method to SceneGraph::GraphNode and
    SceneGraph::GeometryNode.
  - Implemented collision methods for common node types.
- Added camera viewer option to OnVive.sh and added HMDCameraViewer
  configuration file with settings for HTC Vive Pro; requires custom
  calibration.
- Made resource file names in several Vrui classes relative to sub-
  directories under Vrui's share directory:
  - lightsaberImageFileName in Vrui::JediTool is relative to Textures
    directory.
  - Intrinsic parameter file names in Vrui::HMDCameraViewer vislet are
    relative to Resources directory.
  - Device model scene graph names in Vrui::DeviceRenderer vislet are
    relative to Resources directory.
  - Adapted configuration files accordingly.
- Added collaboration support in ShowEarthModel example program to
  makefile.
- Fixed makefile bugs:
  - Added missing IntrinsicParameters file to Video library.
  - Added dependency on Video library to HMDCameraViewer vislet.
  - Broken dependency file generation for position-independent code.
- Renamed OnVive.sh start-up script to OnVive.
- Added options to enable/disable reprojection and black smear
  correction to OnVive script.
- Changed Tiff package definition in BuildRoot/Packages.System to
  account for non-standard location of header files in Linux Mint 20.
- Fixed a major problem with dynamic run-time paths in linking.

Vrui-7.0-002:
- Fixed more wrong rpath linker options in makefile.
- Added missing initializations to Vrui::HMDConfiguration.
- Major updates to OpenVRHost VRDeviceDaemon driver module:
  - Changed disambiguation method in Lighthouse driver from tdm to auto
    to support Lighthouse v2.0.
  - Updated to work with current SteamVR release 1.15.19.
  - Updated OpenVR header file to version 1.14.15, which is not exactly
    compatible with SteamVR 1.15.19, but one makes do.
  - Added verbosity setting to control the amount of driver details
    being printed.
- Replaced patchFile method in Misc::ConfigurationFile.
  - Adapted RoomSetup utility to new patchFile method
- Added -ignore <device name> command line option to RoomSetup utility
  to ignore devices that might have "stuck" buttons.

Vrui-8.0-001:
- Improved handling of verbose output in Vrui.Workbench.cpp.
- Added support for head-related transfer functions to
  Vrui::SoundContext.
  - New configuration settings useHrtf and hrtfModel.
- Added sound() method to Vrui::Tool interface, after all these years!
  - Added alRenderTools method to Vrui::InputGraphManager.
  - Call Vrui::InputGraphManager::alRenderTools from sound function in
    Vrui/Vrui.General.cpp.
  - Added humming sound to Vrui::JediTool.
- Added gcd (greatest common divisor) and lcm (least common multiple)
  functions to Math/Math.h.
- Added implementation of Math::abs for long integers to Math/Math.h.
- Adjusted floor plane in Desktop configuration so that viewer is
  standing up.
- Added GLMotif::ColorSwatch and GLMotif::ColorPalette widgets to
  display and edit palettes of colors.
- Added flip() method to Geometry::Plane.
- Changed IO::File::readUpTo method to bypass the file's read buffer if
  possible and avoid all memory copies in most cases.
- Added IO::VariableMemoryFile::readFile method for copy-less caching of
  all file types that allow buffer read-through.
  - Also finished IO::VariableMemoryFile::Reader class for parallel
    reads from the same file. Caveat: IO::File's API allows read buffer
    manipulation which can cause havoc in parallel reads. It works in
    all important use cases, though.
- Changed copyright notices on GL/GLPolylineTube.h and
  GL/GLPolylineTube.cpp to reflect the class's move to GLGeometry
  library.
- Added GLFrustum::setFromGL method using given a modelview matrix as an
  orthogonal transformation.
  - Added private setFromGL method to do the common legwork.
- Added transformation and common state management methods akin to 
  SceneGraph::GLRenderState to ALContextData.
  - Added get/setListenerPosition and get/setUpVector method to set and
    query state in current "modelview" coordinates.
  - Added setup code for new ALContextData state to
    Vrui::SoundContext::draw method.
- Added state management to allow lazy updates of OpenGL's modelview
  matrix to SceneGraph::GLRenderState, scene graph nodes that use the
  modelview matrix must call uploadModelview before issuing OpenGL
  commands.
  - Added calls to GLRenderState::uploadModelview to all scene graph
    nodes that need them.
- Added SceneGraph::OGTransform to simplify maintenance of scene graphs
  moving towards a scene graph-centric Vrui.
- Remove haveExplicitBoundingBox flag from SceneGraph::GroupNode and
  replaced explicitBoundingBox with a pointer, null indicating that
  there is no explicit bounding box.
  - Adapted all node classes derived from GroupNode.
- Added removeFirstValue method to SceneGraph::MF<Value> multi-valued
  fields.
- Included <Geometry/Box.h> in SceneGraph/AffinePointTransformNode.h.
- Fixed all SceneGraph::GroupNode-derived node classes to call parent's
  update method inside their own update method. Oops.
- API changes to SceneGraph:
  - Made children field of SceneGraph::GroupNode protected; correct way
    for clients to add/remove children is to use the addChildren /
    removeChildren fields or call the new addChild / removeChild /
    removeAllChildren methods.
    - Adapted client code everywhere.
  - Changed root parameter of method SceneGraph::VRMLFile::parse from
    SceneGraph::GroupNodePointer to SceneGraph::GroupNode&.
    - Adapted client code everywhere.
  - Changed newShape parameter of SceneGraph::MeshFileNode::addShape
    from SceneGraph::ShapeNodePointer to SceneGraph::ShapeNode&.
    - Fixed client classes.
  - Removed getStaticClassName method in all node classes and replaced
    with public static className element.
- Added removeAllChildren and getChildren methods to
  SceneGraph::GroupNode.
- Improved update methods in SceneGraph::ArcInfoExportFileNode and
  SceneGraph::ESRIShapeFileNode.
- Added OpenAL sound processing pass to SceneGraph::GraphNode as
  alRenderAction method.
  - SceneGraph library now depends on ALSupport library.
- Started adding support for optimized multiple processing/rendering
  passes to SceneGraph library.
  - Current passes: collision detection, OpenGL opaque, OpenGL
    transparent, OpenAL
  - Added passMask bitmask element to SceneGraph::GraphNode to
    efficiently cull sub-graphs that do not participate in the current
    processing path.
    - Added setPassMask, getPassMask, participatesInPass methods.
    - Added updatePassMask method to force a node to update the pass
      mask of its entire sub-graph.
    - Added update result codes to notify callers in which way a node's
      pass mask changed due to an update.
  - Added return value to Node::update method to indicate whether a
    change to a node's state requires cascading updates towards the root
    of the scene graph.
  - Added Node::cascadingUpdate to notify a node that one of the nodes
    it references underwent an update that might affect the parent node.
  - Added MaterialNode::CascadeTransparencyChanged update result.
  - Added get/setRenderPass methods to SceneGraph::GLRenderState to aid
    in managing multiple OpenGL rendering passes.
    - Slightly improved OpenGL state tracking and added rendering pass
      tracking.
    - Added resetState method returning all changed OpenGL state back to
      the state when the object was created, same as destructor.
  - Added tracking of OpenGL blend function during transparent rendering
    to SceneGraph::GLRenderState.
  - Added pass mask checking to rendering functions in
    Vrui/SceneGraphSupport.h.
- Added setTransform shortcut methods to SceneGraph library's
  ONTransformNode, OGTransformNode, and DOGTransformNode classes.
- Fixed transparency handling and normal requirement check in
  SceneGraph::MaterialNode.
- Added scene graph manager to Vrui, to start integrating a central
  scene graph into Vrui's update and rendering loop.
  - Created Vrui::SceneGraphManager in Vrui/SceneGraphManager.h.
  - Added getSceneGraphManager() function to Vrui kernel interface.
  - Made Vrui::InputGraphManager dependent on Vrui::SceneGraphManager by
    calling methods to add/remove input devices or change input device
    states.
  - Added sceneGraphManager to VruiState and added calls to set the
    navigation transformation, update input devices, and call the
    rendering pass methods.
  - Internal VruiState::updateNavigationTransformation method updates
    the navigation transformation inside the scene graph manager.
  - VruiState::display calls scene graph manager at the border between
    the opaque and transparent rendering passes.
  - Scene graph manager is referenced by Vrui::InputGraphManager and
    receives input device state change and destruction notifications.
  - Moved independent scene graphs from Vrui::DeviceRenderer and
    Vrui::SceneGraphViewer vislets to central scene graph.
  - Moved application display function to central scene graph via a
    custom node class.
- Added setAndFindEntry method to Misc::HashTable to avoid wasteful
  pattern of setEntry followed immediately by findEntry.
- API change: Remove disableNavigationTransformation function from Vrui
  kernel API to remove a lot of never-used code; if necessary, same
  functionality can be achieved by permanently activating a fake
  navigation tool.
  - Removed navigationEnabled parameters from
    Vrui::LightsourceManager::setLightsources and
    Vrui::ClipPlaneManager::setClipPlanes.
- Removed obsolete 3D video playback code from
  Vrui::InputDeviceAdapterPlayback.
- Improved rendering of the screen protector grid in Vrui.General.cpp.
- Provided way to start clip planes in paused mode, which might end up
  unneccessary:
  - Added enable flag to GLClipPlaneTracker::enableClipPlane methods.
  - Added enable flag to Vrui::ClipPlaneManager::setClipPlanes method.
- Added child node encapsulating clipped geometry to navigational-space
  scene graph in Vrui::SceneGraphManager; navigational-space nodes are
  by default directed to clipped sub-graph; new methods to manage nodes
  in unclipped sub-graph.
- Removed unnecessary virtual methods from
  SceneGraph::ON/OG/DOGTransformNode classes.
- Moved CAVERenderer vislet's rendering to scene graph by deriving
  vislet class from SceneGraph::GraphNode.
- Fixed blending function in SceneGraph::GLRenderState::resetState.
- Added SceneGraph::ALRenderState to support OpenAL rendering traversals
  of scene graphs with transformation stack and source persistency
  management.
  - Replaced ALContextData& contextData parameter in
    SceneGraph::GraphNode::alRenderAction with
    ALRenderState& renderState.
    - Fixed all node classes using old signature.
- Added SceneGraph::TraversalState as a common base class for
  SceneGraph::GLRenderState and SceneGraph::ALRenderState.
  - Factored out billboard transformation calculation in
    SceneGraph::BillboardNode into new calcBillboardTransform method.
- Added declarations of common OpenAL types and definitions of most
  common constants and enumerants to AL/Config.h in case OpenAL library
  is not found to avoid lots of ugly bracketing.
- Added SceneGraph::AudioClipNode and SceneGraph::SoundNode to provide
  basic VRML 97-ish sound capabilities.
  - SceneGraph library now depends on Sound library.
- Added sound processing to Vrui's central scene graph:
  - Added alRenderAction method to Vrui::SceneGraphManager.
  - Added SceneGraph::ALRenderState object to Vrui::SoundContext.
  - Changed parameter of VruiState::sound from ALContextData& to
    SceneGraph::ALRenderState&.
- Added SceneGraph::ALRenderState::sourceMaxDistance method.
- Added shutdown method to ALObject::DataItem to allow clean destruction
  of OpenAL resources that bind other resources, such as sources binding
  buffers.
  - Added loop calling all shutdown methods of ALObject::DataItem
    objects before deleting them in ALContextData destructor.
- Added version update to SceneGraph::ImageTextureNode::setUrl method.
- Removed wrong dependency on PTHREADS from OPENAL in
  BuildRoot/Packages.System.
- Added dependency on OPENAL to MYSCENEGRAPH in BuildRoot/Packages.Vrui.
- Added setPredictionTimeNow method to Vrui::InputDeviceManager to
  provide a reasonable time base for velocity estimation etc. when
  prediction is disabled.
  - Call new method from the top of VruiState::update.
- Created new Misc::ArrayIterator and Misc::ArrayConstIterator classes
  to serve as iterators for containers using C-style arrays for internal
  storage.
  - Use Misc::Array(Const)Iterator in Misc::Vector.
- Changed array growth formula in Misc::Vector for decent speed-up.
- Created Misc::SimpleSet for simple (non-unique) sets with add/remove
  methods.
- Created Misc::SimpleObjectSet for simple (non-unique) sets of new-
  allocated objects with add/remove methods; object pointers are de-
  referenced transparently.
- Moved concrete image extractor classes in Video library to Internal
  subdirectory.
  - Removed internal headers and concrete video device headers from
    installation.
- Replaced #include <math.h> with #include <Math/Math.h> and floor with
  Math::floor in GLMotif/ScrollBar.cpp and GLMotif/ListBox.cpp.
- Replaced sinf/cosf/sqrtf with Math::... in SceneGraph/SphereNode.cpp
  and math.h with Math/Math.h.
- Removed #include <math.h> from Vrui/Internal/Vrui.General.cpp.
- Forward-declared OpenAL structures in Vrui/SoundContext.h to avoid
  direct dependency on OpenAL.
- Added missing getButtonFunction method to Vrui::DaisyWheelTool class.
- Removed superfluous destructor from Vrui::PlaneProjectorTool class.
- Added missing check for valid tracker indices in
  OpenVRHost::TrackedDevicePoseUpdated.
- Moved build system to new transitive linking scheme that minimizes
  over-linking.
  - Adapted makefiles in ExamplePrograms, ExamplePrograms/MeshEditor,
    and ExamplePrograms/VRMLViewer.
- Added new VRUIALL meta-package to include all Vrui component libraries
  in one go.
- Added MYMISC to MYGLXSUPPORT inline dependencies.
- Fixed handover from scene graph rendering to old-style rendering in
  VruiState::display method.
- Fixed handling of multiple tool stacks in
  Vrui::InputGraphManager::showToolStack method.
- Completed CAVERenderer vislet's move to scene graph; fixed missed
  optimizations; load screen textures relative to share/Textures
  directory.
  - Added MYIO dependency for CAVERenderer to makefile.
- Added inline dependencies on MYMISC (for Misc::ValueCoder) to MYMATH,
  MYGEOMETRY, and MYGLSUPPORT packages.

Vrui-8.0-002:
- Changed Vrui::Listener to read listener gain from configuration file
  in dB, changed Vrui/Internal/Vrui.General.cpp to properly initialize
  global gain slider in Vrui settings dialog.
- Added inline dependency on THEORA to MYVIDEO.
- Added type shortcut for video device and video data format lists to
  Video/VideoDevice.h.
