diff --git a/Source/SimulationManager/CMakeLists.txt b/Source/SimulationManager/CMakeLists.txt index 7c7347266f30c565821b2470714c8bc363a9c650..fee6891be7b96f1f892d9167a9b8d70036fa5973 100644 --- a/Source/SimulationManager/CMakeLists.txt +++ b/Source/SimulationManager/CMakeLists.txt @@ -5,14 +5,6 @@ file(GLOB VTK_H_FILES VTKRenderer/imstk*.h) file(GLOB VTK_CPP_FILES VTKRenderer/imstk*.cpp) -list(APPEND ExclusionFiles "") -# Don't build with X11 if on windows or (on linux and building headless) -if(WIN32 OR (UNIX AND iMSTK_USE_VTK_OSMESA)) - list(APPEND ExclusionFiles - VTKRenderer/imstkVtkXRenderWindowInteractor2.h - VTKRenderer/imstkVtkXRenderWindowInteractor2.cpp) -endif() - file(GLOB SIMMANAGER_H_FILES imstk*.h) file(GLOB SIMMANAGER_CPP_FILES imstk*.cpp) @@ -29,8 +21,6 @@ imstk_add_library(SimulationManager ${SIMULATIONMANAGER_CPP_FILES} SUBDIR_LIST ${SIMULATIONMANAGER_SUBDIR} - EXCLUDE_FILES - ${ExclusionFiles} DEPENDS Scene Rendering diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp index d5c3ca86dede379b224e76f8fd5a0a633ac42462..ff47818924190d8ba8f2bf0b956d7b8e4099d6bd 100644 --- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp +++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp @@ -41,7 +41,7 @@ #ifdef iMSTK_USE_VTK_OSMESA #include <vtkGenericRenderWindowInteractor.h> #else -#include "imstkVtkXRenderWindowInteractor2.h" +#include <vtkXRenderWindowInteractor.h> #endif #endif @@ -65,7 +65,7 @@ VTKViewer::VTKViewer(std::string name) : AbstractVTKViewer(name), vtkSmartPointer<vtkGenericRenderWindowInteractor> iren = vtkSmartPointer<vtkGenericRenderWindowInteractor>::New(); iren->SetInteractorStyle(m_vtkInteractorStyle.get()); #else - vtkSmartPointer<vtkXRenderWindowInteractor2> iren = vtkSmartPointer<vtkXRenderWindowInteractor2>::New(); + vtkSmartPointer<vtkXRenderWindowInteractor> iren = vtkSmartPointer<vtkXRenderWindowInteractor>::New(); iren->SetInteractorStyle(m_vtkInteractorStyle.get()); #endif #endif diff --git a/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.cpp b/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.cpp deleted file mode 100644 index 7ebd5b2ad2f37946164e13fa035eb278f90f2ce7..0000000000000000000000000000000000000000 --- a/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.cpp +++ /dev/null @@ -1,885 +0,0 @@ -/*========================================================================= - - Program: Visualization Toolkit - Module: vtkXRenderWindowInteractor2.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 "imstkVtkXRenderWindowInteractor2.h" - -#include <algorithm> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <sys/time.h> - -#include "vtkActor.h" -#include "vtkCallbackCommand.h" -#include "vtkCommand.h" -#include "vtkInteractorStyle.h" -#include "vtkObjectFactory.h" -#include "vtkRenderWindow.h" -#include "vtkStringArray.h" - -#include <vtksys/SystemTools.hxx> - -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> - -#include <climits> -#include <cmath> -#include <map> -#include <set> -#include <sstream> - -vtkStandardNewMacro(vtkXRenderWindowInteractor2); - -template<int EventType> -int -XEventTypeEquals(Display*, XEvent* event, XPointer) -{ - return event->type == EventType; -} - -struct vtkXRenderWindowInteractor2Timer -{ - unsigned long duration; - timeval lastFire; -}; - -// Map between the X native id to our own integer count id. Note this -// is separate from the TimerMap in the vtkRenderWindowInteractor -// superclass. This is used to avoid passing 64-bit values back -// through the "int" return type of InternalCreateTimer. -class vtkXRenderWindowInteractor2Internals -{ -public: - vtkXRenderWindowInteractor2Internals() { this->TimerIdCount = 1; } - ~vtkXRenderWindowInteractor2Internals() = default; - - // duration is in milliseconds - int CreateLocalTimer(unsigned long duration) - { - int id = this->TimerIdCount++; - this->LocalToTimer[id].duration = duration; - gettimeofday(&this->LocalToTimer[id].lastFire, nullptr); - return id; - } - - void DestroyLocalTimer(int id) { this->LocalToTimer.erase(id); } - - void GetTimeToNextTimer(timeval& tv) - { - uint64_t lowestDelta = 1000000; - if (!this->LocalToTimer.empty()) - { - timeval ctv; - gettimeofday(&ctv, nullptr); - for (auto& timer : this->LocalToTimer) - { - uint64_t delta = (ctv.tv_sec - timer.second.lastFire.tv_sec) * 1000000 + ctv.tv_usec - - timer.second.lastFire.tv_usec; - if (delta < lowestDelta) - { - lowestDelta = delta; - } - } - } - tv.tv_sec = lowestDelta / 1000000; - tv.tv_usec = lowestDelta % 1000000; - } - - void FireTimers(vtkXRenderWindowInteractor2* rwi) - { - if (!this->LocalToTimer.empty()) - { - timeval ctv; - gettimeofday(&ctv, nullptr); - std::vector<unsigned long> expired; - for (auto& timer : this->LocalToTimer) - { - int64_t delta = (ctv.tv_sec - timer.second.lastFire.tv_sec) * 1000000 + ctv.tv_usec - - timer.second.lastFire.tv_usec; - if (delta / 1000 >= static_cast<int64_t>(timer.second.duration)) - { - int timerId = rwi->GetVTKTimerId(timer.first); - rwi->InvokeEvent(vtkCommand::TimerEvent, &timerId); - if (rwi->IsOneShotTimer(timerId)) - { - expired.push_back(timer.first); - } - else - { - timer.second.lastFire.tv_sec = ctv.tv_sec; - timer.second.lastFire.tv_usec = ctv.tv_usec; - } - } - } - for (auto exp : expired) - { - this->DestroyLocalTimer(exp); - } - } - } - - static std::set<vtkXRenderWindowInteractor2*> Instances; - -private: - int TimerIdCount; - std::map<int, vtkXRenderWindowInteractor2Timer> LocalToTimer; -}; - -std::set<vtkXRenderWindowInteractor2*> vtkXRenderWindowInteractor2Internals::Instances; - -// for some reason the X11 def of KeySym is getting messed up -typedef XID vtkKeySym; - -//------------------------------------------------------------------------------ -vtkXRenderWindowInteractor2::vtkXRenderWindowInteractor2() -{ - this->Internal = new vtkXRenderWindowInteractor2Internals; - this->DisplayId = nullptr; - this->WindowId = 0; - this->KillAtom = 0; - this->XdndSource = 0; - this->XdndPositionAtom = 0; - this->XdndDropAtom = 0; - this->XdndActionCopyAtom = 0; - this->XdndStatusAtom = 0; - this->XdndFinishedAtom = 0; -} - -//------------------------------------------------------------------------------ -vtkXRenderWindowInteractor2::~vtkXRenderWindowInteractor2() -{ - this->Disable(); - - delete this->Internal; -} - -//------------------------------------------------------------------------------ -// TerminateApp() notifies the event loop to exit. -// The event loop is started by Start() or by one own's method. -// This results in Start() returning to its caller. -void -vtkXRenderWindowInteractor2::TerminateApp() -{ - if (this->Done) - { - return; - } - - this->Done = true; - - // Send a VTK_BreakXtLoop ClientMessage event to be sure we pop out of the - // event loop. This "wakes up" the event loop. Otherwise, it might sit idle - // waiting for an event before realizing an exit was requested. - XClientMessageEvent client; - memset(&client, 0, sizeof(client)); - - client.type = ClientMessage; - // client.serial; //leave zeroed - // client.send_event; //leave zeroed - client.display = this->DisplayId; - client.window = this->WindowId; - client.message_type = XInternAtom(this->DisplayId, "VTK_BreakXtLoop", False); - client.format = 32; // indicates size of data chunks: 8, 16 or 32 bits... - // client.data; //leave zeroed - - XSendEvent(client.display, client.window, True, NoEventMask, reinterpret_cast<XEvent*>(&client)); - XFlush(client.display); - this->RenderWindow->Finalize(); -} - -void -vtkXRenderWindowInteractor2::ProcessEvents() -{ - XEvent event; - while (XPending(this->DisplayId) && !this->Done) - { - XNextEvent(this->DisplayId, &event); - this->DispatchEvent(&event); - } -} - -//------------------------------------------------------------------------------ -// This will start up the X event loop. If you -// call this method it will loop processing X events until the -// loop is exited. -void -vtkXRenderWindowInteractor2::StartEventLoop() -{ - std::vector<int> rwiFileDescriptors; - fd_set in_fds; - struct timeval tv; - struct timeval minTv; - - for (auto rwi : vtkXRenderWindowInteractor2Internals::Instances) - { - rwi->Done = false; - rwiFileDescriptors.push_back(ConnectionNumber(rwi->DisplayId)); - } - - bool done = true; - do - { - bool wait = true; - done = true; - minTv.tv_sec = 1000; - minTv.tv_usec = 1000; - XEvent event; - for (auto rwi = vtkXRenderWindowInteractor2Internals::Instances.begin(); - rwi != vtkXRenderWindowInteractor2Internals::Instances.end();) - { - if (XPending((*rwi)->DisplayId) == 0) - { - // get how long to wait for the next timer - (*rwi)->Internal->GetTimeToNextTimer(tv); - minTv.tv_sec = std::min(tv.tv_sec, minTv.tv_sec); - minTv.tv_usec = std::min(tv.tv_usec, minTv.tv_usec); - } - else - { - // If events are pending, dispatch them to the right RenderWindowInteractor - XNextEvent((*rwi)->DisplayId, &event); - (*rwi)->DispatchEvent(&event); - wait = false; - } - (*rwi)->FireTimers(); - - // Check if all RenderWindowInteractors have been terminated - done = done && (*rwi)->Done; - - // If current RenderWindowInteractor have been terminated, handle its last event, - // then remove it from the Instance vector - if ((*rwi)->Done) - { - // Empty the event list - while (XPending((*rwi)->DisplayId) != 0) - { - XNextEvent((*rwi)->DisplayId, &event); - (*rwi)->DispatchEvent(&event); - } - // Adjust the file descriptors vector - int rwiPosition = - std::distance(vtkXRenderWindowInteractor2Internals::Instances.begin(), rwi); - rwi = vtkXRenderWindowInteractor2Internals::Instances.erase(rwi); - rwiFileDescriptors.erase(rwiFileDescriptors.begin() + rwiPosition); - } - else - { - ++rwi; - } - } - - if (wait && !done) - { - // select will wait until 'tv' elapses or something else wakes us - FD_ZERO(&in_fds); - for (auto rwiFileDescriptor : rwiFileDescriptors) - { - FD_SET(rwiFileDescriptor, &in_fds); - } - int maxFileDescriptor = - *std::max_element(rwiFileDescriptors.begin(), rwiFileDescriptors.end()); - select(maxFileDescriptor + 1, &in_fds, nullptr, nullptr, &minTv); - } - } - while (!done); -} - -//------------------------------------------------------------------------------ -// Initializes the event handlers without an XtAppContext. This is -// good for when you don't have a user interface, but you still -// want to have mouse interaction. -void -vtkXRenderWindowInteractor2::Initialize() -{ - if (this->Initialized) - { - return; - } - - vtkRenderWindow* ren; - int* size; - - // make sure we have a RenderWindow and camera - if (!this->RenderWindow) - { - vtkErrorMacro(<< "No renderer defined!"); - return; - } - - this->Initialized = 1; - ren = this->RenderWindow; - - this->DisplayId = static_cast<Display*>(ren->GetGenericDisplayId()); - if (!this->DisplayId) - { - vtkDebugMacro("opening display"); - this->DisplayId = XOpenDisplay(nullptr); - vtkDebugMacro("opened display"); - ren->SetDisplayId(this->DisplayId); - } - - vtkXRenderWindowInteractor2Internals::Instances.insert(this); - - size = ren->GetActualSize(); - size[0] = ((size[0] > 0) ? size[0] : 300); - size[1] = ((size[1] > 0) ? size[1] : 300); - XSync(this->DisplayId, False); - - ren->Start(); - ren->End(); - - this->WindowId = reinterpret_cast<Window>(ren->GetGenericWindowId()); - - XWindowAttributes attribs; - // Find the current window size - XGetWindowAttributes(this->DisplayId, this->WindowId, &attribs); - - size[0] = attribs.width; - size[1] = attribs.height; - ren->SetSize(size[0], size[1]); - - this->Enable(); - this->Size[0] = size[0]; - this->Size[1] = size[1]; -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::Enable() -{ - // avoid cycles of calling Initialize() and Enable() - if (this->Enabled) - { - return; - } - - // Add the event handler to the system. - // If we change the types of events processed by this handler, then - // we need to change the Disable() routine to match. In order for Disable() - // to work properly, both the callback function AND the client data - // passed to XtAddEventHandler and XtRemoveEventHandler must MATCH - // PERFECTLY - XSelectInput(this->DisplayId, this->WindowId, - KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | - StructureNotifyMask | EnterWindowMask | LeaveWindowMask | PointerMotionHintMask | - PointerMotionMask); - - // Setup for capturing the window deletion - this->KillAtom = XInternAtom(this->DisplayId, "WM_DELETE_WINDOW", False); - XSetWMProtocols(this->DisplayId, this->WindowId, &this->KillAtom, 1); - - // Enable drag and drop - Atom xdndAwareAtom = XInternAtom(this->DisplayId, "XdndAware", False); - char xdndVersion = 5; - XChangeProperty(this->DisplayId, this->WindowId, xdndAwareAtom, XA_ATOM, 32, PropModeReplace, - (unsigned char*)&xdndVersion, 1); - this->XdndPositionAtom = XInternAtom(this->DisplayId, "XdndPosition", False); - this->XdndDropAtom = XInternAtom(this->DisplayId, "XdndDrop", False); - this->XdndActionCopyAtom = XInternAtom(this->DisplayId, "XdndActionCopy", False); - this->XdndStatusAtom = XInternAtom(this->DisplayId, "XdndStatus", False); - this->XdndFinishedAtom = XInternAtom(this->DisplayId, "XdndFinished", False); - - this->Enabled = 1; - - this->Modified(); -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::Disable() -{ - if (!this->Enabled) - { - return; - } - - this->Enabled = 0; - - this->Modified(); -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::UpdateSize(int x, int y) -{ - // if the size changed send this on to the RenderWindow - if ((x != this->Size[0]) || (y != this->Size[1])) - { - this->Size[0] = x; - this->Size[1] = y; - this->RenderWindow->SetSize(x, y); - } -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::UpdateSizeNoXResize(int x, int y) -{ - // if the size changed send this on to the RenderWindow - if ((x != this->Size[0]) || (y != this->Size[1])) - { - this->Size[0] = x; - this->Size[1] = y; - // static_cast<vtkXOpenGLRenderWindow*>(this->RenderWindow)->SetSizeNoXResize(x, y); - this->RenderWindow->SetSize(x, y); - } -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::FireTimers() -{ - if (this->GetEnabled()) - { - this->Internal->FireTimers(this); - } -} - -//------------------------------------------------------------------------------ -// X always creates one shot timers -int -vtkXRenderWindowInteractor2::InternalCreateTimer( - int vtkNotUsed(timerId), int vtkNotUsed(timerType), unsigned long duration) -{ - duration = (duration > 0 ? duration : this->TimerDuration); - int platformTimerId = this->Internal->CreateLocalTimer(duration); - return platformTimerId; -} - -//------------------------------------------------------------------------------ -int -vtkXRenderWindowInteractor2::InternalDestroyTimer(int platformTimerId) -{ - this->Internal->DestroyLocalTimer(platformTimerId); - return 1; -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::DispatchEvent(XEvent* event) -{ - int xp, yp; - - switch (event->type) - { - case Expose: - { - if (!this->Enabled) - { - return; - } - XEvent result; - while (XCheckTypedWindowEvent(this->DisplayId, this->WindowId, Expose, &result)) - { - // just getting the expose configure event - event = &result; - } - XExposeEvent* exposeEvent = reinterpret_cast<XExposeEvent*>(event); - this->SetEventSize(exposeEvent->width, exposeEvent->height); - xp = exposeEvent->x; - yp = exposeEvent->y; - yp = this->Size[1] - yp - 1; - this->SetEventPosition(xp, yp); - - // only render if we are currently accepting events - if (this->Enabled) - { - this->InvokeEvent(vtkCommand::ExposeEvent, nullptr); - this->Render(); - } - } - break; - - case MapNotify: - { - // only render if we are currently accepting events - if (this->Enabled && this->GetRenderWindow()->GetNeverRendered()) - { - this->Render(); - } - } - break; - - case ConfigureNotify: - { - XEvent result; - while (XCheckTypedWindowEvent(this->DisplayId, this->WindowId, ConfigureNotify, &result)) - { - // just getting the last configure event - event = &result; - } - int width = (reinterpret_cast<XConfigureEvent*>(event))->width; - int height = (reinterpret_cast<XConfigureEvent*>(event))->height; - if (width != this->Size[0] || height != this->Size[1]) - { - bool resizeSmaller = width <= this->Size[0] && height <= this->Size[1]; - this->UpdateSizeNoXResize(width, height); - xp = (reinterpret_cast<XButtonEvent*>(event))->x; - yp = (reinterpret_cast<XButtonEvent*>(event))->y; - this->SetEventPosition(xp, this->Size[1] - yp - 1); - // only render if we are currently accepting events - if (this->Enabled) - { - this->InvokeEvent(vtkCommand::ConfigureEvent, nullptr); - if (resizeSmaller) - { - // Don't call Render when the window is resized to be larger: - // - // - if the window is resized to be larger, an Expose event will - // be triggered by the X server which will trigger a call to - // Render(). - // - if the window is resized to be smaller, no Expose event will - // be triggered by the X server, as no new area become visible. - // only in this case, we need to explicitly call Render() - // in ConfigureNotify. - this->Render(); - } - } - } - } - break; - - case ButtonPress: - { - if (!this->Enabled) - { - return; - } - int ctrl = ((reinterpret_cast<XButtonEvent*>(event))->state & ControlMask) ? 1 : 0; - int shift = ((reinterpret_cast<XButtonEvent*>(event))->state & ShiftMask) ? 1 : 0; - int alt = ((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0; - xp = (reinterpret_cast<XButtonEvent*>(event))->x; - yp = (reinterpret_cast<XButtonEvent*>(event))->y; - - // check for double click - static int MousePressTime = 0; - int repeat = 0; - // 400 ms threshold by default is probably good to start - int eventTime = static_cast<int>(reinterpret_cast<XButtonEvent*>(event)->time); - if ((eventTime - MousePressTime) < 400) - { - MousePressTime -= 2000; // no double click next time - repeat = 1; - } - else - { - MousePressTime = eventTime; - } - - this->SetEventInformationFlipY(xp, yp, ctrl, shift, 0, repeat); - this->SetAltKey(alt); - switch ((reinterpret_cast<XButtonEvent*>(event))->button) - { - case Button1: - this->InvokeEvent(vtkCommand::LeftButtonPressEvent, nullptr); - break; - case Button2: - this->InvokeEvent(vtkCommand::MiddleButtonPressEvent, nullptr); - break; - case Button3: - this->InvokeEvent(vtkCommand::RightButtonPressEvent, nullptr); - break; - case Button4: - this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, nullptr); - break; - case Button5: - this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, nullptr); - break; - } - } - break; - - case ButtonRelease: - { - if (!this->Enabled) - { - return; - } - int ctrl = ((reinterpret_cast<XButtonEvent*>(event))->state & ControlMask) ? 1 : 0; - int shift = ((reinterpret_cast<XButtonEvent*>(event))->state & ShiftMask) ? 1 : 0; - int alt = ((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0; - xp = (reinterpret_cast<XButtonEvent*>(event))->x; - yp = (reinterpret_cast<XButtonEvent*>(event))->y; - this->SetEventInformationFlipY(xp, yp, ctrl, shift); - this->SetAltKey(alt); - switch ((reinterpret_cast<XButtonEvent*>(event))->button) - { - case Button1: - this->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, nullptr); - break; - case Button2: - this->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, nullptr); - break; - case Button3: - this->InvokeEvent(vtkCommand::RightButtonReleaseEvent, nullptr); - break; - } - } - break; - - case EnterNotify: - { - // Force the keyboard focus to be this render window - XSetInputFocus(this->DisplayId, this->WindowId, RevertToPointerRoot, CurrentTime); - if (this->Enabled) - { - XEnterWindowEvent* e = reinterpret_cast<XEnterWindowEvent*>(event); - this->SetEventInformationFlipY( - e->x, e->y, (e->state & ControlMask) != 0, (e->state & ShiftMask) != 0); - this->SetAltKey(((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0); - this->InvokeEvent(vtkCommand::EnterEvent, nullptr); - } - } - break; - - case LeaveNotify: - { - if (this->Enabled) - { - XLeaveWindowEvent* e = reinterpret_cast<XLeaveWindowEvent*>(event); - this->SetEventInformationFlipY( - e->x, e->y, (e->state & ControlMask) != 0, (e->state & ShiftMask) != 0); - this->SetAltKey(((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0); - this->InvokeEvent(vtkCommand::LeaveEvent, nullptr); - } - } - break; - - case KeyPress: - { - if (!this->Enabled) - { - return; - } - int ctrl = ((reinterpret_cast<XButtonEvent*>(event))->state & ControlMask) ? 1 : 0; - int shift = ((reinterpret_cast<XButtonEvent*>(event))->state & ShiftMask) ? 1 : 0; - int alt = ((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0; - vtkKeySym ks; - static char buffer[20]; - buffer[0] = '\0'; - XLookupString(reinterpret_cast<XKeyEvent*>(event), buffer, 20, &ks, nullptr); - xp = (reinterpret_cast<XKeyEvent*>(event))->x; - yp = (reinterpret_cast<XKeyEvent*>(event))->y; - this->SetEventInformationFlipY(xp, yp, ctrl, shift, buffer[0], 1, XKeysymToString(ks)); - this->SetAltKey(alt); - this->InvokeEvent(vtkCommand::KeyPressEvent, nullptr); - this->InvokeEvent(vtkCommand::CharEvent, nullptr); - } - break; - - case KeyRelease: - { - if (!this->Enabled) - { - return; - } - int ctrl = ((reinterpret_cast<XButtonEvent*>(event))->state & ControlMask) ? 1 : 0; - int shift = ((reinterpret_cast<XButtonEvent*>(event))->state & ShiftMask) ? 1 : 0; - int alt = ((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0; - vtkKeySym ks; - static char buffer[20]; - buffer[0] = '\0'; - XLookupString(reinterpret_cast<XKeyEvent*>(event), buffer, 20, &ks, nullptr); - xp = (reinterpret_cast<XKeyEvent*>(event))->x; - yp = (reinterpret_cast<XKeyEvent*>(event))->y; - this->SetEventInformationFlipY(xp, yp, ctrl, shift, buffer[0], 1, XKeysymToString(ks)); - this->SetAltKey(alt); - this->InvokeEvent(vtkCommand::KeyReleaseEvent, nullptr); - } - break; - - case MotionNotify: - { - if (!this->Enabled) - { - return; - } - int ctrl = ((reinterpret_cast<XButtonEvent*>(event))->state & ControlMask) ? 1 : 0; - int shift = ((reinterpret_cast<XButtonEvent*>(event))->state & ShiftMask) ? 1 : 0; - int alt = ((reinterpret_cast<XButtonEvent*>(event))->state & Mod1Mask) ? 1 : 0; - - // Note that even though the (x,y) location of the pointer is event structure, - // we must call XQueryPointer for the hints (motion event compression) to - // work properly. - this->GetMousePosition(&xp, &yp); - this->SetEventInformation(xp, yp, ctrl, shift); - this->SetAltKey(alt); - this->InvokeEvent(vtkCommand::MouseMoveEvent, nullptr); - } - break; - - // Selection request for drag and drop has been delivered - case SelectionNotify: - { - // Sanity checks - if (!event->xselection.property || !this->XdndSource) - { - return; - } - - // Recover the dropped file - char* data = nullptr; - Atom actualType; - int actualFormat; - unsigned long itemCount, bytesAfter; - XGetWindowProperty(this->DisplayId, event->xselection.requestor, event->xselection.property, - 0, LONG_MAX, False, event->xselection.target, &actualType, &actualFormat, &itemCount, - &bytesAfter, (unsigned char**)&data); - - // Conversion checks - if ((event->xselection.target != AnyPropertyType && actualType != event->xselection.target) - || itemCount == 0) - { - return; - } - - // Recover filepaths from uris and invoke DropFilesEvent - std::stringstream uris(data); - std::string uri, protocol, hostname, filePath; - std::string unused0, unused1, unused2, unused3; - vtkNew<vtkStringArray> filePaths; - while (std::getline(uris, uri, '\n')) - { - if (vtksys::SystemTools::ParseURL( - uri, protocol, unused0, unused1, hostname, unused3, filePath, true)) - { - if (protocol == "file" && (hostname.empty() || hostname == "localhost")) - { - // The uris can be crlf delimited, remove ending \r if any - if (filePath.back() == '\r') - { - filePath.pop_back(); - } - - // The extracted filepath miss the first slash - filePath.insert(0, "/"); - - filePaths->InsertNextValue(filePath); - } - } - } - this->InvokeEvent(vtkCommand::DropFilesEvent, filePaths); - XFree(data); - - // Inform the source the the drag and drop operation was sucessfull - XEvent reply; - memset(&reply, 0, sizeof(reply)); - - reply.type = ClientMessage; - reply.xclient.window = event->xclient.data.l[0]; - reply.xclient.message_type = this->XdndFinishedAtom; - reply.xclient.format = 32; - reply.xclient.data.l[0] = this->WindowId; - reply.xclient.data.l[1] = itemCount; - reply.xclient.data.l[2] = this->XdndActionCopyAtom; - - XSendEvent(this->DisplayId, this->XdndSource, False, NoEventMask, &reply); - XFlush(this->DisplayId); - this->XdndSource = 0; - } - break; - - case ClientMessage: - { - if (event->xclient.message_type == this->XdndPositionAtom) - { - // Drag and drop event inside the window - - // Recover the position - int xWindow, yWindow; - int xRoot = event->xclient.data.l[2] >> 16; - int yRoot = event->xclient.data.l[2] & 0xffff; - Window root = DefaultRootWindow(this->DisplayId); - Window child; - XTranslateCoordinates( - this->DisplayId, root, this->WindowId, xRoot, yRoot, &xWindow, &yWindow, &child); - - // Convert it to VTK compatible location - double location[2]; - location[0] = static_cast<double>(xWindow); - location[1] = static_cast<double>(this->Size[1] - yWindow - 1); - this->InvokeEvent(vtkCommand::UpdateDropLocationEvent, location); - - // Reply that we are ready to copy the dragged data - XEvent reply; - memset(&reply, 0, sizeof(reply)); - - reply.type = ClientMessage; - reply.xclient.window = event->xclient.data.l[0]; - reply.xclient.message_type = this->XdndStatusAtom; - reply.xclient.format = 32; - reply.xclient.data.l[0] = this->WindowId; - reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle - reply.xclient.data.l[2] = 0; // Specify an empty rectangle - reply.xclient.data.l[3] = 0; - reply.xclient.data.l[4] = this->XdndActionCopyAtom; - - XSendEvent(this->DisplayId, event->xclient.data.l[0], False, NoEventMask, &reply); - XFlush(this->DisplayId); - } - else if (event->xclient.message_type == this->XdndDropAtom) - { - // Item dropped in the window - // Store the source of the drag and drop - this->XdndSource = event->xclient.data.l[0]; - - // Ask for a conversion of the selection. This will trigger a SelectioNotify event later. - Atom xdndSelectionAtom = XInternAtom(this->DisplayId, "XdndSelection", False); - XConvertSelection(this->DisplayId, xdndSelectionAtom, - XInternAtom(this->DisplayId, "UTF8_STRING", False), xdndSelectionAtom, this->WindowId, - CurrentTime); - } - else if (static_cast<Atom>(event->xclient.data.l[0]) == this->KillAtom) - { - this->ExitCallback(); - } - } - break; - } -} - -//------------------------------------------------------------------------------ -void -vtkXRenderWindowInteractor2::GetMousePosition(int* x, int* y) -{ - Window root, child; - int root_x, root_y; - unsigned int keys; - - XQueryPointer(this->DisplayId, this->WindowId, &root, &child, &root_x, &root_y, x, y, &keys); - - *y = this->Size[1] - *y - 1; -} - -//------------------------------------------------------------------------------ -// void vtkXRenderWindowInteractor2::Timer(XtPointer client_data, XtIntervalId* id) -// { -// vtkXRenderWindowInteractor2Timer(client_data, id); -// } - -//------------------------------------------------------------------------------ -// void vtkXRenderWindowInteractor2::Callback( -// Widget w, XtPointer client_data, XEvent* event, Boolean* ctd) -// { -// vtkXRenderWindowInteractor2Callback(w, client_data, event, ctd); -// } diff --git a/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.h b/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.h deleted file mode 100644 index 026ea6ca1800c40bf10c02da1eadb95ed441d0b2..0000000000000000000000000000000000000000 --- a/Source/SimulationManager/VTKRenderer/imstkVtkXRenderWindowInteractor2.h +++ /dev/null @@ -1,141 +0,0 @@ -/*========================================================================= - - Library: iMSTK - - Copyright (c) Kitware, Inc. & Center for Modeling, Simulation, - & Imaging in Medicine, Rensselaer Polytechnic Institute. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0.txt - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -=========================================================================*/ - -#pragma once - -//=========================================================== -// now we define the C++ class - -#include "vtkRenderWindowInteractor.h" -#include <X11/Xlib.h> // Needed for X types in the public interface - -class vtkCallbackCommand; -class vtkXRenderWindowInteractor2Internals; - -/// -/// \class vtkXRenderWindowInteractor2 -/// -/// \brief This class exists to fix bugs in VTK 9.0, which are, as typing this -/// already merged into VTK master, this class should be deleted when upgrading -/// to yet to be released VTK 10 -/// -class vtkXRenderWindowInteractor2 : public vtkRenderWindowInteractor -{ -public: - static vtkXRenderWindowInteractor2* New(); - vtkTypeMacro(vtkXRenderWindowInteractor2, vtkRenderWindowInteractor); - void PrintSelf(ostream& os, vtkIndent indent) override; - - /** - * Initializes the event handlers without an XtAppContext. This is - * good for when you don't have a user interface, but you still - * want to have mouse interaction. - */ - void Initialize() override; - - /** - * Break the event loop on 'q','e' keypress. Want more ??? - */ - void TerminateApp() override; - - /** - * Run the event loop and return. This is provided so that you can - * implement your own event loop but yet use the vtk event handling as - * well. - */ - void ProcessEvents() override; - - //@{ - /** - * Enable/Disable interactions. By default interactors are enabled when - * initialized. Initialize() must be called prior to enabling/disabling - * interaction. These methods are used when a window/widget is being - * shared by multiple renderers and interactors. This allows a "modal" - * display where one interactor is active when its data is to be displayed - * and all other interactors associated with the widget are disabled - * when their data is not displayed. - */ - void Enable() override; - void Disable() override; - //@} - - /** - * Update the Size data member and set the associated RenderWindow's - * size. - */ - void UpdateSize(int, int) override; - - /** - * Re-defines virtual function to get mouse position by querying X-server. - */ - void GetMousePosition(int* x, int* y) override; - - void DispatchEvent(XEvent*); - -protected: - vtkXRenderWindowInteractor2(); - ~vtkXRenderWindowInteractor2() override; - - /** - * Update the Size data member and set the associated RenderWindow's - * size but do not resize the XWindow. - */ - void UpdateSizeNoXResize(int, int); - - // Using static here to avoid destroying context when many apps are open: - static int NumAppInitialized; - - Display* DisplayId; - Window WindowId; - Atom KillAtom; - int PositionBeforeStereo[2]; - vtkXRenderWindowInteractor2Internals* Internal; - - // Drag and drop related - Window XdndSource; - Atom XdndPositionAtom; - Atom XdndDropAtom; - Atom XdndActionCopyAtom; - Atom XdndStatusAtom; - Atom XdndFinishedAtom; - - //@{ - /** - * X-specific internal timer methods. See the superclass for detailed - * documentation. - */ - int InternalCreateTimer(int timerId, int timerType, unsigned long duration) override; - int InternalDestroyTimer(int platformTimerId) override; - //@} - - void FireTimers(); - - /** - * This will start up the X event loop and never return. If you - * call this method it will loop processing X events until the - * application is exited. - */ - void StartEventLoop() override; - -private: - vtkXRenderWindowInteractor2(const vtkXRenderWindowInteractor2&) = delete; - void operator=(const vtkXRenderWindowInteractor2&) = delete; -}; \ No newline at end of file