PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlus3dConnexionTracker.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 
10 #include "vtkMatrix4x4.h"
11 #include "vtkObjectFactory.h"
12 #include "vtkPlusDataSource.h"
13 #include "vtkTransform.h"
14 #include "vtkXMLDataElement.h"
15 #include "vtkXMLUtilities.h"
16 #include "vtksys/SystemTools.hxx"
17 #include <deque>
18 #include <math.h>
19 #include <sstream>
20 
21 #if ( _MSC_VER >= 1300 ) // Visual studio .NET
22 #pragma warning ( disable : 4311 )
23 #pragma warning ( disable : 4312 )
24 # define vtkGetWindowLong GetWindowLongPtr
25 # define vtkSetWindowLong SetWindowLongPtr
26 # define vtkGWL_USERDATA GWLP_USERDATA
27 # define GWL_USERDATA_TYPE LONG_PTR
28 #else // regular Visual studio
29 # define vtkGetWindowLong GetWindowLong
30 # define vtkSetWindowLong SetWindowLong
31 # define vtkGWL_USERDATA GWL_USERDATA
32 # define GWL_USERDATA_TYPE LONG;
33 #endif //
34 
35 
37 
38 //-------------------------------------------------------------------------
40  : Mutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
41  , SpaceNavigatorTool(NULL)
42  , LatestMouseTransform(vtkMatrix4x4::New())
43  , DeviceToTrackerTransform(vtkMatrix4x4::New())
44  , OperatingMode(JOYSTICK_MODE)
45  , CaptureWindowClassName("")
46  , CaptureWindowHandle(0)
47  , RegisteredRawInputDevices(NULL)
48  , NumberOfRegisteredRawInputDevices(0)
49 {
51 
52  this->TranslationScales[0] = 0.001;
53  this->TranslationScales[1] = 0.001;
54  this->TranslationScales[2] = 0.001;
55  this->RotationScales[0] = 0.001;
56  this->RotationScales[1] = 0.001;
57  this->RotationScales[2] = 0.001;
58 
59  // Although there is a callback function, it is not called regularly (when the joystick is moved
60  // then it is called too frequently, other times it's not called at all), so we use the capture
61  // thread to provide regular transform updates
62  this->StartThreadForInternalUpdates = true;
63  this->AcquisitionRate = 125;
64 }
65 
66 //-------------------------------------------------------------------------
68 {
69  if (this->Recording)
70  {
71  this->StopRecording();
72  }
74  if (this->DeviceToTrackerTransform != NULL)
75  {
76  this->DeviceToTrackerTransform->Delete();
77  this->DeviceToTrackerTransform = NULL;
78  }
79  if (this->LatestMouseTransform != NULL)
80  {
81  this->LatestMouseTransform->Delete();
82  this->LatestMouseTransform = NULL;
83  }
84 }
85 
86 //-------------------------------------------------------------------------
88 {
89  // Get a list of all attached raw input devices
90  UINT nDevices = 0;
91  if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
92  {
93  LOG_ERROR("No RawInput devices attached");
94  return PLUS_FAIL;
95  }
96  PRAWINPUTDEVICELIST pRawInputDeviceList = NULL;
97  if ((pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)) == NULL)
98  {
99  LOG_ERROR("Error allocating memory for device list");
100  return PLUS_FAIL;
101  }
102 
103  // Now get the data on the attached devices
104  if (GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST)) == -1)
105  {
106  LOG_ERROR("Error getting raw input device list");
107  free(pRawInputDeviceList);
108  return PLUS_FAIL;
109  }
110 
111  this->RegisteredRawInputDevices = (PRAWINPUTDEVICE)malloc(nDevices * sizeof(RAWINPUTDEVICE));
112  this->NumberOfRegisteredRawInputDevices = 0;
113 
114  // Look through device list for RIM_TYPEHID devices with UsagePage == 1, Usage == 8
115  for (UINT i = 0; i < nDevices; i++)
116  {
117  if (pRawInputDeviceList[i].dwType == RIM_TYPEHID)
118  {
119  UINT nchars = 300;
120  TCHAR deviceName[300];
121  if (GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, deviceName, &nchars) >= 0)
122  {
123  LOG_DEBUG("Device[" << i << "]: handle=" << pRawInputDeviceList[i].hDevice << " name = " << deviceName);
124  }
125 
126  RID_DEVICE_INFO dinfo;
127  UINT sizeofdinfo = sizeof(dinfo);
128  dinfo.cbSize = sizeofdinfo;
129  if (GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &dinfo, &sizeofdinfo) < 0)
130  {
131  continue;
132  }
133  if (dinfo.dwType != RIM_TYPEHID)
134  {
135  continue;
136  }
137 
138  RID_DEVICE_INFO_HID* phidInfo = &dinfo.hid;
139  LOG_DEBUG("VID = " << phidInfo->dwVendorId);
140  LOG_DEBUG("PID = " << phidInfo->dwProductId);
141  LOG_DEBUG("Version = " << phidInfo->dwVersionNumber);
142  LOG_DEBUG("UsagePage = " << phidInfo->usUsagePage);
143  LOG_DEBUG("Usage = " << phidInfo->usUsage);
144 
145  // Add this one to the list of interesting devices?
146  // Actually only have to do this once to get input from all usage 1, usagePage 8 devices
147  // This just keeps out the other usages.
148  // You might want to put up a list for users to select amongst the different devices.
149  // In particular, to assign separate functionality to the different devices.
150  if (phidInfo->usUsagePage == 1 && phidInfo->usUsage == 8)
151  {
152  this->RegisteredRawInputDevices[this->NumberOfRegisteredRawInputDevices].usUsagePage = phidInfo->usUsagePage;
153  this->RegisteredRawInputDevices[this->NumberOfRegisteredRawInputDevices].usUsage = phidInfo->usUsage;
154  this->RegisteredRawInputDevices[this->NumberOfRegisteredRawInputDevices].dwFlags = RIDEV_INPUTSINK;
155  this->RegisteredRawInputDevices[this->NumberOfRegisteredRawInputDevices].hwndTarget = this->CaptureWindowHandle;
156  this->NumberOfRegisteredRawInputDevices++;
157  }
158  }
159  }
160 
161  free(pRawInputDeviceList);
162 
163  // Register for input from the devices in the list
164  if (RegisterRawInputDevices(this->RegisteredRawInputDevices, this->NumberOfRegisteredRawInputDevices, sizeof(RAWINPUTDEVICE)) == FALSE)
165  {
166  LOG_ERROR("Error calling RegisterRawInputDevices");
167  return PLUS_FAIL;
168  }
169 
170  return PLUS_SUCCESS;
171 }
172 
173 //-------------------------------------------------------------------------
175 {
176  if (this->RegisteredRawInputDevices)
177  {
178  for (UINT i = 0; i < this->NumberOfRegisteredRawInputDevices; i++)
179  {
180  this->RegisteredRawInputDevices[i].dwFlags = RIDEV_REMOVE;
181  this->RegisteredRawInputDevices[i].hwndTarget = NULL;
182  }
183  if (RegisterRawInputDevices(this->RegisteredRawInputDevices, this->NumberOfRegisteredRawInputDevices, sizeof(RAWINPUTDEVICE)) == FALSE)
184  {
185  LOG_ERROR("Error unregistering input devices");
186  }
187  free(this->RegisteredRawInputDevices);
188  this->RegisteredRawInputDevices = NULL;
189  this->NumberOfRegisteredRawInputDevices = 0;
190  }
191 }
192 
193 //----------------------------------------------------------------------------
194 LONG FAR PASCAL vtkPlus3dConnexionTrackerWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
195 {
197  switch (message)
198  {
199  case WM_INPUT:
200  self->ProcessDeviceInputEvent(lParam);
201  break;
202  case WM_DESTROY:
203  LOG_TRACE("WM_DESTROY");
204  self->OnCaptureWindowDestroy();
205  break;
206  }
207  return DefWindowProc(hwnd, message, wParam, lParam);
208 }
209 
210 //----------------------------------------------------------------------------
212 {
213  LOG_TRACE("WM_INPUT lParam=" << lParam);
214 
215  RAWINPUTHEADER header;
216  UINT size = sizeof(header);
217  if (GetRawInputData((HRAWINPUT)lParam, RID_HEADER, &header, &size, sizeof(RAWINPUTHEADER)) == -1)
218  {
219  LOG_ERROR("Error from GetRawInputData(RID_HEADER)");
220  return;
221  }
222 
223  LOG_TRACE("rawEvent.header: hDevice = " << header.hDevice);
224 
225  // Set aside enough memory for the full event
226  size = header.dwSize;
227  LPRAWINPUT event = (LPRAWINPUT)malloc(size);
228  if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, event, &size, sizeof(RAWINPUTHEADER)) == -1)
229  {
230  LOG_ERROR("Error from GetRawInputData(RID_INPUT)");
231  return;
232  }
233  if (event->header.dwType != RIM_TYPEHID)
234  {
235  // not a human interface device message
236  return;
237  }
238 
239  static BOOL bGotTranslation = FALSE;
240  static BOOL bGotRotation = FALSE;
241  static int all6DOFs[6] = {0};
242  LPRAWHID pRawHid = &event->data.hid;
243 
244 #ifdef SHOW_DETAILS
245  LOG_TRACE("rawInput count: " << pRawHid->dwCount << " size: " << pRawHid->dwSizeHid);
246  for (UINT i = 0; i < pRawHid->dwSizeHid; i++)
247  {
248  LOG_TRACE("value: " << pRawHid->bRawData[i]);
249  }
250 #endif
251 
252  // Translation and rotation values come in separate messages
253  if (pRawHid->bRawData[0] == 1)
254  {
255  // translation
256  all6DOFs[0] = (pRawHid->bRawData[1] & 0x000000ff) | ((signed short)(pRawHid->bRawData[2] << 8) & 0xffffff00);
257  all6DOFs[1] = (pRawHid->bRawData[3] & 0x000000ff) | ((signed short)(pRawHid->bRawData[4] << 8) & 0xffffff00);
258  all6DOFs[2] = (pRawHid->bRawData[5] & 0x000000ff) | ((signed short)(pRawHid->bRawData[6] << 8) & 0xffffff00);
259  bGotTranslation = TRUE;
260  }
261  else if (pRawHid->bRawData[0] == 2)
262  {
263  // rotation
264  all6DOFs[3] = (pRawHid->bRawData[1] & 0x000000ff) | ((signed short)(pRawHid->bRawData[2] << 8) & 0xffffff00);
265  all6DOFs[4] = (pRawHid->bRawData[3] & 0x000000ff) | ((signed short)(pRawHid->bRawData[4] << 8) & 0xffffff00);
266  all6DOFs[5] = (pRawHid->bRawData[5] & 0x000000ff) | ((signed short)(pRawHid->bRawData[6] << 8) & 0xffffff00);
267  bGotRotation = TRUE;
268  }
269  else if (pRawHid->bRawData[0] == 3)
270  {
271  // buttons
272  LOG_TRACE("Button status: " << (unsigned char)pRawHid->bRawData[3] << ", " << (unsigned char)pRawHid->bRawData[2] << ", " << (unsigned char)pRawHid->bRawData[1]);
273  }
274 
275  if (bGotTranslation && bGotRotation)
276  {
277  bGotTranslation = bGotRotation = FALSE;
278  LOG_TRACE("all6DOFs: " << all6DOFs[0] << "," << all6DOFs[1] << "," << all6DOFs[2] << "," << all6DOFs[3] << "," << all6DOFs[4] << "," << all6DOFs[5]);
279  vtkSmartPointer<vtkTransform> currentTransform = vtkSmartPointer<vtkTransform>::New();
280  currentTransform->Identity();
281  currentTransform->Translate(all6DOFs[0]*this->TranslationScales[0], all6DOFs[1]*this->TranslationScales[1], all6DOFs[2]*this->TranslationScales[2]);
282  currentTransform->RotateX(all6DOFs[3]*this->RotationScales[0]);
283  currentTransform->RotateY(all6DOFs[4]*this->RotationScales[1]);
284  currentTransform->RotateZ(all6DOFs[5]*this->RotationScales[2]);
285 
286  {
287  igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
288  currentTransform->GetMatrix(this->LatestMouseTransform);
289  }
290  }
291 
292 }
293 
294 //-------------------------------------------------------------------------
296 {
297  // get necessary process info
298  HINSTANCE hinstance = GetModuleHandle(NULL);
299 
300  const char CAPTURE_WINDOW_CLASS_NAME_PREFIX[] = "3dConnexionTracker capture window";
301 
302  if (this->CaptureWindowClassName.empty())
303  {
304  this->CaptureWindowClassName = CAPTURE_WINDOW_CLASS_NAME_PREFIX;
305  }
306 
307  // set up a class for the main window
308  WNDCLASS wc;
309  wc.lpszClassName = this->CaptureWindowClassName.c_str();
310  wc.hInstance = hinstance;
311  wc.lpfnWndProc = reinterpret_cast<WNDPROC>(&vtkPlus3dConnexionTrackerWinProc);
312  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
313  wc.hIcon = NULL;
314  wc.lpszMenuName = NULL;
315  wc.hbrBackground = NULL;
316  wc.style = CS_HREDRAW | CS_VREDRAW;
317  wc.cbClsExtra = sizeof(void*);
318  wc.cbWndExtra = 0;
319 
320  bool registrationSuccessful = false;
321  const int MAX_WINDOW_CLASS_REGISTRATION_ATTEMPTS = 32;
322  for (int i = 1; i <= MAX_WINDOW_CLASS_REGISTRATION_ATTEMPTS; i++)
323  {
324  if (RegisterClass(&wc))
325  {
326  registrationSuccessful = true;
327  break;
328  }
329  // try with a slightly different name at each registration attempt
330  std::ostringstream windowName;
331  windowName << CAPTURE_WINDOW_CLASS_NAME_PREFIX << " " << i << std::ends;
332  this->CaptureWindowClassName = windowName.str();
333  wc.lpszClassName = this->CaptureWindowClassName.c_str();
334  }
335  if (!registrationSuccessful)
336  {
337  LOG_ERROR("Initialize: failed to register 3dConnexionTracker capture window class (" << GetLastError() << ")");
338  return PLUS_FAIL;
339  }
340 
341  this->CaptureWindowHandle = CreateWindow(this->CaptureWindowClassName.c_str(), "Plus 3dConnexion capture window", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, hinstance, NULL);
342  if (!this->CaptureWindowHandle)
343  {
344  LOG_ERROR("Initialize: failed to create window (" << GetLastError() << ")");
345  return PLUS_FAIL;
346  }
347 
348  // set the user data to 'this'
349  vtkSetWindowLong(this->CaptureWindowHandle, vtkGWL_USERDATA, (GWL_USERDATA_TYPE)this);
350 
351  return PLUS_SUCCESS;
352 }
353 
354 //-------------------------------------------------------------------------
356 {
357  Disconnect();
358  this->CaptureWindowHandle = NULL;
359 }
360 
361 //----------------------------------------------------------------------------
363 {
364  if (this->CaptureWindowHandle)
365  {
366  DestroyWindow(this->CaptureWindowHandle);
367  this->CaptureWindowHandle = 0;
368  }
369 
370  if (!this->CaptureWindowClassName.empty())
371  {
372  // Window class name is valid
373  UnregisterClass(this->CaptureWindowClassName.c_str(), GetModuleHandle(NULL));
374  this->CaptureWindowClassName.clear();
375  }
376 
377 }
378 
379 //-------------------------------------------------------------------------
381 {
382  LOG_TRACE("vtkPlus3dConnexionTracker::Connect");
383 
385  {
386  LOG_ERROR("Failed to create capture window");
387  return PLUS_FAIL;
388  }
389  if (RegisterDevice() != PLUS_SUCCESS)
390  {
391  LOG_ERROR("Failed to register the 3dConnexion device");
393  return PLUS_FAIL;
394  }
395 
396  this->SpaceNavigatorTool = NULL;
397  this->GetToolByPortName("SpaceNavigator", this->SpaceNavigatorTool);
398 
399  return PLUS_SUCCESS;
400 }
401 
402 //-------------------------------------------------------------------------
404 {
405  LOG_TRACE("vtkPlus3dConnexionTracker::Disconnect");
406  this->StopRecording();
407 
410 
411  this->SpaceNavigatorTool = NULL;
412  return PLUS_SUCCESS;
413 }
414 
415 //-------------------------------------------------------------------------
417 {
418  LOG_TRACE("vtkPlus3dConnexionTracker::Probe");
419  LOG_ERROR("vtkPlus3dConnexionTracker::Probe is not implemented");
420  return PLUS_SUCCESS;
421 }
422 
423 //-------------------------------------------------------------------------
425 {
426  LOG_TRACE("vtkPlus3dConnexionTracker::InternalStartRecording");
427  return PLUS_SUCCESS;
428 }
429 
430 //-------------------------------------------------------------------------
432 {
433  LOG_TRACE("vtkPlus3dConnexionTracker::InternalStopRecording");
434  return PLUS_SUCCESS;
435 }
436 
437 //-------------------------------------------------------------------------
439 {
440  LOG_TRACE("vtkPlus3dConnexionTracker::InternalUpdate");
441 
442  const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
443 
444  if (this->SpaceNavigatorTool != NULL)
445  {
446  {
447  igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
448  switch (this->OperatingMode)
449  {
450  case MOUSE_MODE:
451  this->DeviceToTrackerTransform->DeepCopy(this->LatestMouseTransform);
452  break;
453  case JOYSTICK_MODE:
454  {
455  vtkSmartPointer<vtkMatrix4x4> cumulatedTransform = vtkSmartPointer<vtkMatrix4x4>::New();
456  vtkMatrix4x4::Multiply4x4(this->LatestMouseTransform, this->DeviceToTrackerTransform, cumulatedTransform);
457 
458  // Perform the translation in the tracker coordinate frame
459  cumulatedTransform->Element[0][3] = this->DeviceToTrackerTransform->Element[0][3] + this->LatestMouseTransform->Element[0][3];
460  cumulatedTransform->Element[1][3] = this->DeviceToTrackerTransform->Element[1][3] + this->LatestMouseTransform->Element[1][3];
461  cumulatedTransform->Element[2][3] = this->DeviceToTrackerTransform->Element[2][3] + this->LatestMouseTransform->Element[2][3];
462 
463  this->DeviceToTrackerTransform->DeepCopy(cumulatedTransform);
464  }
465  break;
466  default:
467  LOG_ERROR("Operating mode is invalid: " << this->OperatingMode);
468  }
469  }
470 
471  // This device has no frame numbering, so just auto increment tool frame number
472  unsigned long frameNumber = this->SpaceNavigatorTool->GetFrameNumber() + 1 ;
473  ToolTimeStampedUpdate(this->SpaceNavigatorTool->GetId(), this->DeviceToTrackerTransform, TOOL_OK, frameNumber, unfilteredTimestamp);
474  }
475 
476  return PLUS_SUCCESS;
477 }
478 
479 //----------------------------------------------------------------------------
480 PlusStatus vtkPlus3dConnexionTracker::ReadConfiguration(vtkXMLDataElement* rootConfigElement)
481 {
482  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement);
483 
484  if (deviceConfig->GetAttribute("Mode"))
485  {
486  if (STRCASECMP(deviceConfig->GetAttribute("Mode"), "MOUSE") == 0)
487  {
488  this->OperatingMode = MOUSE_MODE;
489  }
490  else if (STRCASECMP(deviceConfig->GetAttribute("Mode"), "JOYSTICK") == 0)
491  {
492  this->OperatingMode = JOYSTICK_MODE;
493  }
494  else
495  {
496  LOG_ERROR("Unknown Mode: " << deviceConfig->GetAttribute("Mode") << ". Valid options: MOUSE, JOYSTICK.");
497  }
498  }
499 
500  double translationScales[3] = {0.001, 0.001, 0.001};
501  int translationScalesComponentRead = deviceConfig->GetVectorAttribute("TranslationScales", 3, translationScales);
502  if (translationScalesComponentRead == 1)
503  {
504  this->TranslationScales[0] = translationScales[0];
505  this->TranslationScales[1] = translationScales[0];
506  this->TranslationScales[2] = translationScales[0];
507  }
508  else if (translationScalesComponentRead == 3)
509  {
510  this->TranslationScales[0] = translationScales[0];
511  this->TranslationScales[1] = translationScales[1];
512  this->TranslationScales[2] = translationScales[2];
513  }
514  else if (translationScalesComponentRead > 0)
515  {
516  LOG_ERROR("TranslationScales vector has " << translationScalesComponentRead << " components. Valid number of components: 1 or 3");
517  }
518 
519  double rotationScales[3] = {0.001, 0.001, 0.001};
520  int rotationScalesComponentRead = deviceConfig->GetVectorAttribute("RotationScales", 3, rotationScales);
521  if (rotationScalesComponentRead == 1)
522  {
523  this->RotationScales[0] = rotationScales[0];
524  this->RotationScales[1] = rotationScales[0];
525  this->RotationScales[2] = rotationScales[0];
526  }
527  else if (rotationScalesComponentRead == 3)
528  {
529  this->RotationScales[0] = rotationScales[0];
530  this->RotationScales[1] = rotationScales[1];
531  this->RotationScales[2] = rotationScales[2];
532  }
533  else if (rotationScalesComponentRead > 0)
534  {
535  LOG_ERROR("RotationScales vector has " << rotationScalesComponentRead << " components. Valid number of components: 1 or 3");
536  }
537 
538  return PLUS_SUCCESS;
539 }
540 
541 //----------------------------------------------------------------------------
542 PlusStatus vtkPlus3dConnexionTracker::WriteConfiguration(vtkXMLDataElement* rootConfigElement)
543 {
544  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(trackerConfig, rootConfigElement);
545 
546  switch (this->OperatingMode)
547  {
548  case MOUSE_MODE:
549  trackerConfig->SetAttribute("Mode", "MOUSE");
550  break;
551  case JOYSTICK_MODE:
552  trackerConfig->SetAttribute("Mode", "JOYSTICK");
553  break;
554  default:
555  LOG_ERROR("Cannot write unknown operating mode into config file: " << this->OperatingMode);
556  }
557 
558  trackerConfig->SetVectorAttribute("TranslationScales", 3, this->TranslationScales);
559  trackerConfig->SetVectorAttribute("RotationScales", 3, this->RotationScales);
560 
561  return PLUS_SUCCESS;
562 }
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
#define vtkGWL_USERDATA
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
bool RequirePortNameInDeviceSetConfiguration
for i
double AcquisitionRate
#define vtkSetWindowLong
#define PLUS_FAIL
Definition: PlusCommon.h:43
virtual PlusStatus Disconnect()
#define FALSE
Definition: ATC3DGm.h:220
PlusStatus ReadConfiguration(vtkXMLDataElement *config)
Interface for 3D Connexion 3D mouse devices.
const char ** deviceName
Definition: phidget22.h:1316
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus StopRecording()
#define GWL_USERDATA_TYPE
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
bool StartThreadForInternalUpdates
LONG FAR PASCAL vtkPlus3dConnexionTrackerWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
PlusStatus WriteConfiguration(vtkXMLDataElement *config)
#define TRUE
Definition: ATC3DGm.h:219
const char * message
Definition: phidget22.h:2457
vtkStandardNewMacro(vtkPlus3dConnexionTracker)
#define vtkGetWindowLong
int BOOL
Definition: ATC3DGm.h:446