You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/Rendering/OpenGL/vtkTDxUnixDevice.cxx

271 lines
8.4 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkTDxUnixDevice.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkTDxUnixDevice.h"
#include <cassert>
#include <X11/Xlib.h> // Needed for X types used in the public interface
// Display *DisplayId; // Actually a "Display *" but we cannot include Xlib.h
// Window WindowId; // Actually a "Window" but we cannot include Xlib.h
#define SGI // Used in xdrvlib.h to define ParameterCheck
// xdrvlib.h does not have the usual __cplusplus extern "C" guard
extern "C" {
#include "xdrvlib.h" // Magellan X-Window driver API.
}
#include "vtkTDxMotionEventInfo.h"
#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkMath.h"
vtkStandardNewMacro(vtkTDxUnixDevice);
// ----------------------------------------------------------------------------
// Description:
// Default constructor. Just set initial values for
// DisplayId (0), WindowId (0)), TranslationScale (1.0),
// RotationScale (1.0).
vtkTDxUnixDevice::vtkTDxUnixDevice()
{
this->DisplayId=0;
this->WindowId=0;
this->TranslationScale=1.0;
this->RotationScale=1.0;
this->Interactor=0;
// this->DebugOn();
}
// ----------------------------------------------------------------------------
// Description:
// Destructor. If the device is not initialized, do nothing. If the device
// is initialized, close the device.
vtkTDxUnixDevice::~vtkTDxUnixDevice()
{
if(this->Initialized)
{
this->Close();
}
}
// ----------------------------------------------------------------------------
// Description:
// Get the ID of the X Display. Initial value is 0.
vtkTDxUnixDeviceDisplay *vtkTDxUnixDevice::GetDisplayId() const
{
return this->DisplayId;
}
// ----------------------------------------------------------------------------
// Description:
// Get the ID of the X Window. Initial value is 0.
vtkTDxUnixDeviceWindow vtkTDxUnixDevice::GetWindowId() const
{
return this->WindowId;
}
// ----------------------------------------------------------------------------
// Description:
// Set the ID of the X Display.
// \pre not_yet_initialized: !GetInitialized()
void vtkTDxUnixDevice::SetDisplayId(vtkTDxUnixDeviceDisplay *id)
{
assert("pre: not_yet_initialized" && !this->GetInitialized());
if(this->DisplayId!=id)
{
this->DisplayId=id;
this->Modified();
}
}
// ----------------------------------------------------------------------------
// Description:
// Set the ID of the X Window.
// \pre not_yet_initialized: !GetInitialized()
void vtkTDxUnixDevice::SetWindowId(vtkTDxUnixDeviceWindow id)
{
assert("pre: not_yet_initialized" && !this->GetInitialized());
if(this->WindowId!=id)
{
this->WindowId=id;
this->Modified();
}
}
// ----------------------------------------------------------------------------
// Description:
// Initialize the device with the current display and window ids.
// It updates the value of GetInitialized().
// Initialization can fail. You must look for the value of
// GetInitialized() before processing further.
// \pre not_yet_initialized: !GetInitialized()
// \pre valid_display: GetDisplayId()!=0
// \pre valid_window: GetWindowId()!=0
// \pre valid_interactor: GetInteractor()!=0
void vtkTDxUnixDevice::Initialize()
{
assert("pre: not_yet_initialized" && !this->GetInitialized());
assert("pre: valid_display" && this->GetDisplayId()!=0);
assert("pre: valid_window" && this->GetWindowId()!=0);
int status=MagellanInit(static_cast<Display *>(this->DisplayId),
static_cast<Window>(this->WindowId));
this->Initialized=status==1;
}
// ----------------------------------------------------------------------------
// Description:
// Close the device. This is called by the destructor.
// You don't have to close the device explicitly, as the destructor do it
// automatically, but you can.
// \pre initialized: GetInitialized().
// \post restored: !GetInitialized()
void vtkTDxUnixDevice::Close()
{
assert("pre: initialized" && this->GetInitialized());
vtkDebugMacro(<< "Close()" );
MagellanClose(static_cast<Display *>(this->DisplayId));
this->Initialized=false;
assert("post: restored" && !this->GetInitialized());
}
// ----------------------------------------------------------------------------
// Description:
// Translate the X11 event by invoking a VTK event, if the event came from
// the device.
// Return true if the event passed in argument was effectively an event from
// the device, return false otherwise.
// \pre initialized: GetInitialized()
// \pre e_exists: e!=0
// \pre e_is_client_message: e->type==ClientMessage
bool vtkTDxUnixDevice::ProcessEvent(const vtkTDxUnixDeviceXEvent *e)
{
assert("pre: initialized" && this->GetInitialized());
assert("pre: e_exists" && e!=0);
assert("pre: e_is_client_message" &&
static_cast<const XEvent *>(e)->type==ClientMessage);
MagellanFloatEvent info;
const XEvent *event=static_cast<const XEvent *>(e);
int deviceEvent=MagellanTranslateEvent(
static_cast<Display *>(this->DisplayId),
const_cast<XEvent *>(event),
&info,
this->TranslationScale,
this->RotationScale);
vtkDebugMacro(<< "deviceEvent=" << deviceEvent);
vtkTDxMotionEventInfo motionInfo;
int buttonInfo;
double axis[3];
bool result;
switch(deviceEvent)
{
case MagellanInputMotionEvent:
vtkDebugMacro(<< "it is MagellanInputMotionEvent");
MagellanRemoveMotionEvents(static_cast<Display *>(this->DisplayId));
motionInfo.X=info.MagellanData[MagellanX];
motionInfo.Y=info.MagellanData[MagellanY];
// On Unix, the Z axis is reversed (wrong). We want to have a
// right-handed coordinate system, so positive Z has to come towards us,
// as on Windows.
motionInfo.Z=-info.MagellanData[MagellanZ];
axis[0]=info.MagellanData[MagellanA];
axis[1]=info.MagellanData[MagellanB];
// On Unix, the Z axis is reserved (wrong).
axis[2]=-info.MagellanData[MagellanC];
motionInfo.Angle=vtkMath::Norm(axis);
if(motionInfo.Angle==0.0)
{
motionInfo.AxisX=0.0;
motionInfo.AxisY=0.0;
motionInfo.AxisZ=1.0;
}
else
{
motionInfo.AxisX=axis[0]/motionInfo.Angle;
motionInfo.AxisY=axis[1]/motionInfo.Angle;
motionInfo.AxisZ=axis[2]/motionInfo.Angle;
}
if(this->Interactor!=0)
{
this->Interactor->InvokeEvent(vtkCommand::TDxMotionEvent,&motionInfo);
}
result=true;
break;
case MagellanInputButtonPressEvent:
vtkDebugMacro(<< "it is MagellanInputButtonPressEvent");
buttonInfo=info.MagellanButton;
if(this->Interactor!=0)
{
this->Interactor->InvokeEvent(vtkCommand::TDxButtonPressEvent,
&buttonInfo);
}
result=true;
break;
case MagellanInputButtonReleaseEvent:
vtkDebugMacro(<< "it is MagellanInputButtonReleaseEvent");
buttonInfo=info.MagellanButton;
if(this->Interactor!=0)
{
this->Interactor->InvokeEvent(vtkCommand::TDxButtonReleaseEvent,
&buttonInfo);
}
result=true;
break;
default:
vtkDebugMacro(<< "it is not a Magellan event");
result=false;
break;
}
return result;
}
// ----------------------------------------------------------------------------
// Description:
// Set the sensitivity of the device for the current application.
// A neutral value is 1.0.
// \pre initialized: GetInitialized()
void vtkTDxUnixDevice::SetSensitivity(double sensitivity)
{
assert("pre: initialized" && this->GetInitialized());
MagellanApplicationSensitivity(static_cast<Display *>(this->DisplayId),
sensitivity);
}
// ----------------------------------------------------------------------------
void vtkTDxUnixDevice::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "RotationScale: " << this->RotationScale << endl;
os << indent << "TranslationScale: " << this->TranslationScale << endl;
}