1 // Created on: 2012-05-28
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
18 #include <vtkWin32RenderWindowInteractor.h>
19 #include <vtkWin32OpenGLRenderWindow.h>
22 #include <IVtkTools_ShapePicker.hxx>
23 #include <IVtkTools_SubPolyDataFilter.hxx>
24 #include <IVtkTools_DisplayModeFilter.hxx>
25 #include <IVtkTools_ShapeObject.hxx>
26 #include <IVtkTools_ShapeDataSource.hxx>
27 #include <IVtkDraw_Interactor.hxx>
29 #include <Message.hxx>
30 #include <Message_Messenger.hxx>
33 #include <vtkActorCollection.h>
34 #include <vtkCommand.h>
35 #include <vtkObjectFactory.h>
36 #include <vtkSmartPointer.h>
40 #include <X11/Shell.h>
43 #include <vtkXRenderWindowInteractor.h>
44 #include <vtkXOpenGLRenderWindow.h>
45 #include <X11/Xutil.h>
49 //===========================================================
50 // Function : ClearHighlightAndSelection
52 //===========================================================
53 static void ClearHighlightAndSelection (const Handle(ShapePipelineMap)& theMap,
54 const Standard_Boolean doHighlighting,
55 const Standard_Boolean doSelection)
57 if (!doHighlighting && !doSelection)
62 for (ShapePipelineMap::Iterator anIt (*theMap); anIt.More(); anIt.Next())
64 const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = anIt.Value();
68 aPL->ClearHighlightFilters();
73 aPL->ClearSelectionFilters();
78 vtkStandardNewMacro(IVtkDraw_Interactor)
80 //===========================================================
81 // Function : Constructor
83 //===========================================================
84 IVtkDraw_Interactor::IVtkDraw_Interactor()
90 myIsLeftButtonPressed (Standard_False)
94 //===========================================================
95 // Function : Destructor
97 //===========================================================
98 IVtkDraw_Interactor::~IVtkDraw_Interactor()
102 //===========================================================
103 // Function : SetShapePicker
105 //===========================================================
106 void IVtkDraw_Interactor::SetShapePicker (const PSelector& theSelector)
108 mySelector = theSelector;
111 //===========================================================
112 // Function : SetPipelines
114 //===========================================================
115 void IVtkDraw_Interactor::SetPipelines (const Handle(ShapePipelineMap)& thePipelines)
117 myPipelines = thePipelines;
120 //===========================================================
121 // Function : SetOCCWindow
123 //===========================================================
124 void IVtkDraw_Interactor::SetOCCWindow (const Handle(Aspect_Window)& theWindow)
126 myWindow = theWindow;
129 //===========================================================
130 // Function : GetOCCWindow
132 //===========================================================
133 const Handle(Aspect_Window)& IVtkDraw_Interactor::GetOCCWindow() const
138 //===========================================================
139 // Function : IsEnabled
141 //===========================================================
142 Standard_Boolean IVtkDraw_Interactor::IsEnabled() const
144 return (Enabled != 0);
147 //===========================================================
148 // Function : Initialize
150 //===========================================================
151 void IVtkDraw_Interactor::Initialize()
153 // Make sure we have a RenderWindow and camera
154 if (!this->RenderWindow)
156 vtkErrorMacro(<<"No renderer defined!");
160 if (this->Initialized)
165 this->Initialized = 1;
167 // Get the info we need from the RenderingWindow
168 Standard_Integer *aSize;
170 vtkWin32OpenGLRenderWindow *aRenWin;
171 aRenWin = (vtkWin32OpenGLRenderWindow *)(this->RenderWindow);
173 aSize = aRenWin->GetSize();
174 aRenWin->GetPosition();
175 this->myWindowId = aRenWin->GetWindowId();
177 vtkXOpenGLRenderWindow *aRenWin;
178 aRenWin = static_cast<vtkXOpenGLRenderWindow *>(this->RenderWindow);
179 this->myDisplayId = aRenWin->GetDisplayId();
180 this->myWindowId = aRenWin->GetWindowId();
181 aSize = aRenWin->GetSize();
186 this->Size[0] = aSize[0];
187 this->Size[1] = aSize[1];
190 //===========================================================
193 //===========================================================
194 void IVtkDraw_Interactor::Enable()
201 // Add event handlers
203 SetWindowLongPtr(this->myWindowId, GWLP_USERDATA, (LONG_PTR)this);
204 SetWindowLongPtr(this->myWindowId, GWLP_WNDPROC, (LONG_PTR)WndProc);
206 #if TCL_MAJOR_VERSION < 8
207 Tk_CreateFileHandler((void*)ConnectionNumber(this->myDisplayId),
208 TK_READABLE, ProcessEvents, (ClientData) this);
210 Tk_CreateFileHandler(ConnectionNumber(this->myDisplayId),
211 TK_READABLE, ProcessEvents, (ClientData) this);
219 //===========================================================
222 //===========================================================
223 void IVtkDraw_Interactor::MoveTo (Standard_Integer theX, Standard_Integer theY)
225 // Processing highlighting
226 mySelector->Pick (theX, theY, 0.0);
227 vtkSmartPointer<vtkActorCollection> anActorCollection = mySelector->GetPickedActors();
229 if (anActorCollection)
231 // Highlight picked subshapes
232 ClearHighlightAndSelection (myPipelines, Standard_True, Standard_False);
233 anActorCollection->InitTraversal();
234 while (vtkActor* anActor = anActorCollection->GetNextActor())
236 IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource (anActor);
242 IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
243 if (anOccShape.IsNull())
248 IVtk_IdType aShapeID = anOccShape->GetId();
249 Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
250 if (!myPipelines->IsBound(aShapeID))
252 anOutput << "Warning: there is no VTK pipeline registered for highlighted shape" << endl;
256 const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = myPipelines->Find (aShapeID);
258 // Add a subpolydata filter to the highlight pipeline for the shape data source.
259 IVtkTools_SubPolyDataFilter* aFilter = aPL->GetHighlightFilter();
261 // Set the selected sub-shapes ids to subpolydata filter.
262 IVtk_ShapeIdList aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
264 // Get ids of cells for picked subshapes.
265 IVtk_ShapeIdList aSubIds;
266 IVtk_ShapeIdList::Iterator aMetaIds (aSubShapeIds);
267 for (; aMetaIds.More(); aMetaIds.Next())
269 IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds (aMetaIds.Value());
270 aSubIds.Append (aSubSubIds);
273 aFilter->SetDoFiltering (!aSubIds.IsEmpty());
274 aFilter->SetData (aSubIds);
275 if (!aFilter->GetInput())
277 aFilter->SetInputConnection (aDataSource->GetOutputPort());
285 //===========================================================
286 // Function : OnSelection
288 //===========================================================
289 void IVtkDraw_Interactor::OnSelection()
291 // Processing selection
292 vtkSmartPointer<vtkActorCollection> anActorCollection = mySelector->GetPickedActors();
294 if (anActorCollection)
296 // Highlight picked subshapes.
297 ClearHighlightAndSelection (myPipelines, Standard_False, Standard_True);
298 anActorCollection->InitTraversal();
299 while (vtkActor* anActor = anActorCollection->GetNextActor())
301 IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource (anActor);
307 IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
308 if (anOccShape.IsNull())
313 IVtk_IdType aShapeID = anOccShape->GetId();
314 Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
315 if (!myPipelines->IsBound (aShapeID))
317 anOutput << "Warning: there is no VTK pipeline registered for picked shape" << endl;
321 const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = myPipelines->Find (aShapeID);
323 // Add a subpolydata filter to the selection pipeline for the shape data source.
324 IVtkTools_SubPolyDataFilter* aFilter = aPL->GetSelectionFilter();
326 // Set the selected sub-shapes ids to subpolydata filter.
327 IVtk_ShapeIdList aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
329 // Get ids of cells for picked subshapes.
330 IVtk_ShapeIdList aSubIds;
331 IVtk_ShapeIdList::Iterator aMetaIds (aSubShapeIds);
332 for (; aMetaIds.More(); aMetaIds.Next())
334 IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds (aMetaIds.Value());
335 aSubIds.Append (aSubSubIds);
338 aFilter->SetDoFiltering (!aSubIds.IsEmpty());
339 aFilter->SetData (aSubIds);
340 if (!aFilter->GetInput())
342 aFilter->SetInputConnection (aDataSource->GetOutputPort());
352 //===========================================================
353 // Function : OnMouseMove
355 //===========================================================
356 void IVtkDraw_Interactor::OnMouseMove (HWND theHWnd, UINT theNFlags,
357 Standard_Integer theX,
358 Standard_Integer theY)
365 this->SetEventInformationFlipY (theX,
367 theNFlags & MK_CONTROL,
368 theNFlags & MK_SHIFT);
369 this->SetAltKey(GetKeyState(VK_MENU) & (~1));
370 if (!this->myMouseInWindow &&
371 (theX >= 0 && theX < this->Size[0] && theY >= 0 && theY < this->Size[1]))
373 this->InvokeEvent (vtkCommand::EnterEvent, NULL);
374 this->myMouseInWindow = 1;
375 // request WM_MOUSELEAVE generation
376 TRACKMOUSEEVENT aTme;
377 aTme.cbSize = sizeof (TRACKMOUSEEVENT);
378 aTme.dwFlags = TME_LEAVE;
379 aTme.hwndTrack = theHWnd;
380 TrackMouseEvent (&aTme);
383 if (!(theNFlags & MK_LBUTTON))
384 this->MoveTo (theX, this->Size[1] - theY - 1);
386 this->InvokeEvent (vtkCommand::MouseMoveEvent, NULL);
389 //===========================================================
390 // Function : OnMouseWheelForward
392 //===========================================================
393 void IVtkDraw_Interactor::OnMouseWheelForward (HWND, UINT theNFlags,
394 Standard_Integer theX,
395 Standard_Integer theY)
402 this->SetEventInformationFlipY (theX,
404 theNFlags & MK_CONTROL,
405 theNFlags & MK_SHIFT);
407 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
408 this->InvokeEvent (vtkCommand::MouseWheelForwardEvent, NULL);
411 //===========================================================
412 // Function : OnMouseWheelBackward
414 //===========================================================
415 void IVtkDraw_Interactor::OnMouseWheelBackward (HWND, UINT theNFlags,
416 Standard_Integer theX,
417 Standard_Integer theY)
424 this->SetEventInformationFlipY (theX,
426 theNFlags & MK_CONTROL,
427 theNFlags & MK_SHIFT);
429 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
430 this->InvokeEvent (vtkCommand::MouseWheelBackwardEvent, NULL);
433 //===========================================================
434 // Function : OnLButtonDown
436 //===========================================================
437 void IVtkDraw_Interactor::OnLButtonDown (HWND theHWnd, UINT theNFlags,
438 Standard_Integer theX,
439 Standard_Integer theY,
440 Standard_Integer theRepeat)
447 SetCapture (theHWnd);
448 this->SetEventInformationFlipY (theX,
450 theNFlags & MK_CONTROL,
451 theNFlags & MK_SHIFT,
453 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
457 this->InvokeEvent (vtkCommand::LeftButtonPressEvent, NULL);
460 //===========================================================
461 // Function : OnLButtonUp
463 //===========================================================
464 void IVtkDraw_Interactor::OnLButtonUp (HWND, UINT theNFlags,
465 Standard_Integer theX,
466 Standard_Integer theY)
473 this->SetEventInformationFlipY (theX,
475 theNFlags & MK_CONTROL,
476 theNFlags & MK_SHIFT);
478 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
479 this->InvokeEvent (vtkCommand::LeftButtonReleaseEvent, NULL);
483 //===========================================================
484 // Function : OnMButtonDown
486 //===========================================================
487 void IVtkDraw_Interactor::OnMButtonDown (HWND theHWnd, UINT theNFlags,
488 Standard_Integer theX,
489 Standard_Integer theY,
490 Standard_Integer theRepeat)
498 SetCapture (theHWnd);
499 this->SetEventInformationFlipY (theX,
501 theNFlags & MK_CONTROL,
502 theNFlags & MK_SHIFT,
504 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
505 this->InvokeEvent (vtkCommand::MiddleButtonPressEvent, NULL);
508 //===========================================================
509 // Function : OnMButtonUp
511 //===========================================================
512 void IVtkDraw_Interactor::OnMButtonUp (HWND, UINT theNFlags,
513 Standard_Integer theX,
514 Standard_Integer theY)
520 this->SetEventInformationFlipY (theX,
522 theNFlags & MK_CONTROL,
523 theNFlags & MK_SHIFT);
525 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
526 this->InvokeEvent (vtkCommand::MiddleButtonReleaseEvent, NULL);
530 //===========================================================
531 // Function : OnRButtonDown
533 //===========================================================
534 void IVtkDraw_Interactor::OnRButtonDown (HWND theHWnd, UINT theNFlags,
535 Standard_Integer theX,
536 Standard_Integer theY,
537 Standard_Integer theRepeat)
546 this->SetEventInformationFlipY (theX,
548 theNFlags & MK_CONTROL,
549 theNFlags & MK_SHIFT,
552 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
553 this->InvokeEvent (vtkCommand::RightButtonPressEvent, NULL);
556 //===========================================================
557 // Function : OnRButtonUp
559 //===========================================================
560 void IVtkDraw_Interactor::OnRButtonUp (HWND, UINT theNFlags,
561 Standard_Integer theX,
562 Standard_Integer theY)
568 this->SetEventInformationFlipY (theX,
570 theNFlags & MK_CONTROL,
571 theNFlags & MK_SHIFT);
573 this->SetAltKey (GetKeyState(VK_MENU) & (~1));
574 this->InvokeEvent (vtkCommand::RightButtonReleaseEvent, NULL);
578 //===========================================================
581 //===========================================================
582 void IVtkDraw_Interactor::OnSize (HWND, UINT,
583 Standard_Integer theX,
584 Standard_Integer theY)
586 this->UpdateSize (theX, theY);
589 this->InvokeEvent (vtkCommand::ConfigureEvent, NULL);
593 //===========================================================
594 // Function : OnTimer
596 //===========================================================
597 void IVtkDraw_Interactor::OnTimer (HWND, UINT theTimerId)
604 Standard_Integer aTid = static_cast<Standard_Integer>(theTimerId);
605 this->InvokeEvent (vtkCommand::TimerEvent, (void*)&aTid);
607 // Here we deal with one-shot versus repeating timers
608 if (this->IsOneShotTimer(aTid))
610 KillTimer (this->myWindowId, aTid); //'cause windows timers are always repeating
614 //===========================================================
615 // Function : WndProc
617 //===========================================================
618 LRESULT CALLBACK WndProc (HWND theHWnd,UINT theUMsg,
623 IVtkDraw_Interactor *anInteractor = 0;
625 anInteractor = (IVtkDraw_Interactor *)GetWindowLongPtr (theHWnd, GWLP_USERDATA);
627 if (anInteractor && anInteractor->GetReferenceCount() > 0)
629 anInteractor->Register (anInteractor);
630 aRes = ViewerWindowProc (theHWnd, theUMsg, theWParam, theLParam, anInteractor);
631 anInteractor->UnRegister (anInteractor);
637 //===========================================================
638 // Function : ViewerWindowProc
640 //===========================================================
641 LRESULT CALLBACK ViewerWindowProc (HWND theHWnd,
645 IVtkDraw_Interactor *theInteractor)
650 theInteractor->GetOCCWindow ()->Unmap ();
653 theInteractor->Render();
656 theInteractor->OnSize (theHWnd, theWParam, LOWORD(theLParam), HIWORD(theLParam));
658 case WM_LBUTTONDBLCLK:
659 theInteractor->OnLButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
662 theInteractor->OnLButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
665 theInteractor->OnLButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
667 case WM_MBUTTONDBLCLK:
668 theInteractor->OnMButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
671 theInteractor->OnMButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
674 theInteractor->OnMButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
676 case WM_RBUTTONDBLCLK:
677 theInteractor->OnRButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
680 theInteractor->OnRButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
683 theInteractor->OnRButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
687 theInteractor->InvokeEvent (vtkCommand::LeaveEvent, NULL);
688 theInteractor->myMouseInWindow = 0;
692 theInteractor->OnMouseMove (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
697 pt.x = MAKEPOINTS(theLParam).x;
698 pt.y = MAKEPOINTS(theLParam).y;
699 ::ScreenToClient(theHWnd, &pt);
700 if( GET_WHEEL_DELTA_WPARAM(theWParam) > 0)
702 theInteractor->OnMouseWheelForward (theHWnd, theWParam, pt.x, pt.y);
706 theInteractor->OnMouseWheelBackward (theHWnd, theWParam, pt.x, pt.y);
711 theInteractor->OnTimer (theHWnd, theWParam);
714 return DefWindowProc(theHWnd, theMsg, theWParam, theLParam);
719 //===========================================================
720 // Function : GetDisplayId
722 //===========================================================
723 Display* IVtkDraw_Interactor::GetDisplayId() const
728 //===========================================================
729 // Function : GetMousePosition
731 //===========================================================
732 void IVtkDraw_Interactor::GetMousePosition (Standard_Integer *theX,
733 Standard_Integer *theY)
735 Window aRoot, aChild;
736 Standard_Integer aRoot_x, aRoot_y;
739 XQueryPointer (this->myDisplayId, this->myWindowId,
740 &aRoot, &aChild, &aRoot_x, &aRoot_y, theX, theY, &aKeys);
744 //===========================================================
745 // Function : ViewerMainLoop
747 //===========================================================
748 Standard_Integer IVtkDraw_Interactor::ViewerMainLoop (Standard_Integer theArgNum, const char** /*theArgs*/)
750 Standard_Integer aXp, aYp;
751 Standard_Boolean aPick = theArgNum > 0;
753 static XEvent anEvent;
754 XNextEvent (myDisplayId, &anEvent);
756 switch (anEvent.type)
765 while (XCheckTypedWindowEvent (this->myDisplayId,
770 // just getting the expose configure event
774 this->SetEventSize (anEvent.xexpose.width, anEvent.xexpose.height);
777 aXp = anEvent.xexpose.x;
778 aYp = this->Size[1] - anEvent.xexpose.y - 1;
779 this->SetEventPosition (aXp, aYp);
781 // only render if we are currently accepting events
784 this->InvokeEvent(vtkCommand::ExposeEvent,NULL);
792 // only render if we are currently accepting events
793 if (this->Enabled && this->GetRenderWindow()->GetNeverRendered())
800 case ConfigureNotify:
803 while (XCheckTypedWindowEvent(this->myDisplayId,
808 // just getting the last configure event
811 Standard_Integer aWidth = anEvent.xconfigure.width;
812 Standard_Integer aHeight = anEvent.xconfigure.height;
813 if (aWidth != this->Size[0] || aHeight != this->Size[1])
815 Standard_Boolean toResizeSmaller = aWidth <= this->Size[0] && aHeight <= this->Size[1];
816 this->UpdateSize (aWidth, aHeight);
817 aXp = anEvent.xbutton.x;
818 aYp = anEvent.xbutton.y;
820 SetEventPosition (aXp, this->Size[1] - aYp - 1);
822 // only render if we are currently accepting events
825 this->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
828 // Don't call Render when the window is resized to be larger:
830 // - if the window is resized to be larger, an Expose event will
831 // be trigged by the X server which will trigger a call to
833 // - if the window is resized to be smaller, no Expose event will
834 // be trigged by the X server, as no new area become visible.
835 // only in this case, we need to explicitly call Render()
836 // in ConfigureNotify.
851 Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
852 Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
853 Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
854 aXp = anEvent.xbutton.x;
855 aYp = anEvent.xbutton.y;
857 // check for double click
858 static Standard_Integer aMousePressTime = 0;
859 Standard_Integer aRepeat = 0;
860 // 400 ms threshold by default is probably good to start
861 Standard_Integer anEventTime = static_cast<int>(anEvent.xbutton.time);
862 if ((anEventTime - aMousePressTime) < 400)
864 aMousePressTime -= 2000; // no double click next time
869 aMousePressTime = anEventTime;
872 this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift, 0, aRepeat);
873 this->SetAltKey (anAlt);
875 switch (anEvent.xbutton.button)
878 this->OnSelection ();
879 this->myIsLeftButtonPressed = 1;
880 this->InvokeEvent (vtkCommand::LeftButtonPressEvent,NULL);
883 this->InvokeEvent (vtkCommand::MiddleButtonPressEvent,NULL);
886 this->InvokeEvent (vtkCommand::RightButtonPressEvent,NULL);
889 this->InvokeEvent (vtkCommand::MouseWheelForwardEvent,NULL);
892 this->InvokeEvent (vtkCommand::MouseWheelBackwardEvent,NULL);
905 Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
906 Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
907 Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
908 aXp = anEvent.xbutton.x;
909 aYp = anEvent.xbutton.y;
911 this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift);
912 this->SetAltKey (anAlt);
913 switch (anEvent.xbutton.button)
916 this->InvokeEvent (vtkCommand::LeftButtonReleaseEvent,NULL);
917 this->myIsLeftButtonPressed = False;
920 this->InvokeEvent (vtkCommand::MiddleButtonReleaseEvent,NULL);
923 this->InvokeEvent (vtkCommand::RightButtonReleaseEvent,NULL);
934 XEnterWindowEvent *anEnterEvent = reinterpret_cast<XEnterWindowEvent *>(&anEvent);
935 this->SetEventInformationFlipY (anEnterEvent->x,
937 (anEnterEvent->state & ControlMask) != 0,
938 (anEnterEvent->state & ShiftMask) != 0);
940 this->SetAltKey (anEvent.xbutton.state & Mod1Mask ? 1 : 0);
941 this->InvokeEvent (vtkCommand::EnterEvent, NULL);
951 XLeaveWindowEvent *aLeaveEvent = reinterpret_cast<XLeaveWindowEvent *>(&anEvent);
952 this->SetEventInformationFlipY (aLeaveEvent->x,
954 (aLeaveEvent->state & ControlMask) != 0,
955 (aLeaveEvent->state & ShiftMask) != 0);
957 this->SetAltKey (anEvent.xbutton.state & Mod1Mask ? 1 : 0);
958 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
971 Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
972 Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
973 Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
975 // Note that even though the (x,y) location of the pointer is event structure,
976 // we must call XQueryPointer for the hints (motion event compression) to
978 this->GetMousePosition (&aXp, &aYp);
979 this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift);
980 this->SetAltKey (anAlt);
981 if (!myIsLeftButtonPressed)
982 MoveTo (aXp, this->Size[1]- aYp - 1);
983 this->InvokeEvent (vtkCommand::MouseMoveEvent, NULL);
991 //===========================================================
992 // Function : ProcessEvents
994 //===========================================================
995 void IVtkDraw_Interactor::ProcessEvents (ClientData theData, int)
997 IVtkDraw_Interactor *anInteractor = (IVtkDraw_Interactor *)theData;
999 while (XPending(anInteractor->GetDisplayId()))
1001 anInteractor->ViewerMainLoop (0, NULL);