]> Creatis software - crea.git/blob - src/creawxVTKRenderWindowInteractor.mm
Clean code
[crea.git] / src / creawxVTKRenderWindowInteractor.mm
1 /*
2  # ---------------------------------------------------------------------
3  #
4  # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5  #                        pour la SantÈ)
6  # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7  # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8  # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9  #
10  #  This software is governed by the CeCILL-B license under French law and
11  #  abiding by the rules of distribution of free software. You can  use,
12  #  modify and/ or redistribute the software under the terms of the CeCILL-B
13  #  license as circulated by CEA, CNRS and INRIA at the following URL
14  #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15  #  or in the file LICENSE.txt.
16  #
17  #  As a counterpart to the access to the source code and  rights to copy,
18  #  modify and redistribute granted by the license, users are provided only
19  #  with a limited warranty  and the software's author,  the holder of the
20  #  economic rights,  and the successive licensors  have only  limited
21  #  liability.
22  #
23  #  The fact that you are presently reading this means that you have had
24  #  knowledge of the CeCILL-B license and that you accept its terms.
25  # ------------------------------------------------------------------------ */
26
27
28 /*=========================================================================
29
30   Program:   Visualization Toolkit
31   Module:    $RCSfile$
32   Language:  C++
33   Date:      $Date$
34   Version:   $Revision$
35
36   Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen 
37   All rights reserved.
38   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
39
40      This software is distributed WITHOUT ANY WARRANTY; without even 
41      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
42      PURPOSE.  See the above copyright notice for more information.
43
44 =========================================================================*/
45
46
47 #include <assert.h>
48
49 #include "creawxVTKRenderWindowInteractor.h"
50
51 //This is needed for vtk 3.1 :
52 #ifndef VTK_MAJOR_VERSION
53 #  include "vtkVersion.h"
54 #endif
55
56
57 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
58 #  include "vtkCommand.h"
59 #else
60 #  include "vtkInteractorStyle.h"
61 #endif
62 #include "vtkDebugLeaks.h"
63
64 // AKT: wxOSX 2.9.x defines __WXOSX_COCOA__ rather than __WXCOCOA__
65 #ifdef __WXOSX_COCOA__
66    #import <Cocoa/Cocoa.h>
67    #define __WXCOCOA__
68 #endif
69
70 #if defined(__WXMAC__) && wxCHECK_VERSION(2,9,0)
71     // ControlDown has been changed to mean Command key down
72     #define ControlDown RawControlDown
73 #endif
74
75 #ifdef __WXMAC__
76 #ifdef __WXCOCOA__
77 #include "vtkCocoaRenderWindow.h"
78 #else
79 #include "vtkCarbonRenderWindow.h"
80 #endif
81 #endif
82
83
84 #ifdef VTK_USE_TDX
85 #import "vtkTDxMacDevice.h"
86 #endif
87
88
89 //=======================================================================
90 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
91 namespace crea
92 {
93
94
95 //Keep this for compatibilty reason, this was introduced in wxGTK 2.4.0
96 #if (!wxCHECK_VERSION(2, 4, 0))
97 wxWindow* wxGetTopLevelParent(wxWindow *win)
98 {
99     while ( win && !win->IsTopLevel() )
100          win = win->GetParent();
101     return win;
102 }
103 #endif
104 }
105 // LG : EO namespace bbwxvtk
106 //=======================================================================
107
108 // To access objc calls on cocoa
109 #ifdef __WXCOCOA__
110
111 #define id Id
112
113 // #ifdef VTK_USE_COCOA
114 // // This trick is no longer need in VTK CVS, should get rid of that:
115 // #define id Id
116 // #else
117 // #error Build mismatch you need both wxWidgets and VTK to be configure against Cocoa to work
118 // #endif //VTK_USE_COCOA
119
120 #endif //__WXCOCOA__
121
122 #if wxMAJOR_VERSION <= 2
123         #ifdef __WXGTK__
124          #include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW is found here in wxWidgets 2.8.0
125          #include "gdk/gdkprivate.h"
126          #if wxCHECK_VERSION(2, 9, 0)
127           // thanks to: http://thomasfischer.biz/?p=382
128           #include <gtk/gtkfixed.h>
129           #include <gtk/gtkwidget.h>
130           #include <wx/gtk/private/win_gtk.h>
131           #define piz(wxwin) WX_PIZZA((wxwin)->m_wxwindow)
132           #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
133                 GDK_WINDOW_XWINDOW(((GtkWidget*)piz(wxwin))->window) : \
134                 GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
135          #else
136           #if wxCHECK_VERSION(2, 8, 0)
137            #ifdef __WXGTK20__
138             #include <wx/gtk/win_gtk.h>
139            #else
140             #include <wx/gtk1/win_gtk.h>
141            #endif
142           #else
143            #include <wx/gtk/win_gtk.h>
144           #endif
145          
146           #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
147                                   GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
148                                   GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
149          #endif
150         #endif
151
152 #else
153         #ifdef __WXGTK__
154             #include <gdk/gdkx.h>
155             #include <gtk/gtk.h>
156 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
157                           GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_wxwindow)) :  \
158                          GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_widget))
159         #endif
160 #endif
161
162 #ifdef __WXX11__
163 #include "wx/x11/privx.h"
164 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle())
165 #endif
166
167 //For more info on this class please go to:
168 //http://wxvtk.sf.net
169 //This hack is for some buggy wxGTK version:
170 #if wxCHECK_VERSION(2, 3, 2) && !wxCHECK_VERSION(2, 4, 1) && defined(__WXGTK__)
171 #  define WX_USE_X_CAPTURE 0
172 #else
173 #  define WX_USE_X_CAPTURE 1
174 #endif
175
176 #define ID_wxVTKRenderWindowInteractor_TIMER 1001
177
178 //=======================================================================
179 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
180 namespace crea
181 {
182
183 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
184 #else
185 #endif  //__WXGTK__
186
187 //---------------------------------------------------------------------------
188 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
189                 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
190                 #if wxMAJOR_VERSION <= 2
191                         IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas)
192                         BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
193                 #else
194                         wxIMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas);
195                         wxBEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
196                 #endif
197 #else
198                 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
199                 #if wxMAJOR_VERSION <= 2
200                         IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow)
201                         BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
202                 #else
203                         wxIMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow);
204                         wxBEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
205                 #endif
206 #endif //__WXGTK__
207   //refresh window by doing a Render
208   EVT_PAINT       (wxVTKRenderWindowInteractor::OnPaint)
209   EVT_ERASE_BACKGROUND(wxVTKRenderWindowInteractor::OnEraseBackground)
210   EVT_MOTION      (wxVTKRenderWindowInteractor::OnMotion)
211
212   //Bind the events to the event converters
213   EVT_LEFT_DOWN   (wxVTKRenderWindowInteractor::OnButtonDown)
214   EVT_MIDDLE_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
215   EVT_RIGHT_DOWN  (wxVTKRenderWindowInteractor::OnButtonDown)
216   EVT_LEFT_UP     (wxVTKRenderWindowInteractor::OnButtonUp)
217   EVT_MIDDLE_UP   (wxVTKRenderWindowInteractor::OnButtonUp)
218   EVT_RIGHT_UP    (wxVTKRenderWindowInteractor::OnButtonUp)
219 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
220   EVT_ENTER_WINDOW(wxVTKRenderWindowInteractor::OnEnter)
221   EVT_LEAVE_WINDOW(wxVTKRenderWindowInteractor::OnLeave)
222   EVT_MOUSEWHEEL  (wxVTKRenderWindowInteractor::OnMouseWheel)
223 #if wxCHECK_VERSION(2, 8, 0)
224   EVT_MOUSE_CAPTURE_LOST(wxVTKRenderWindowInteractor::OnMouseCaptureLost)
225 #endif
226   EVT_KEY_DOWN    (wxVTKRenderWindowInteractor::OnKeyDown)
227   EVT_KEY_UP      (wxVTKRenderWindowInteractor::OnKeyUp)
228   EVT_CHAR        (wxVTKRenderWindowInteractor::OnChar)
229 #endif
230   EVT_TIMER       (ID_wxVTKRenderWindowInteractor_TIMER, wxVTKRenderWindowInteractor::OnTimer)
231   EVT_SIZE        (wxVTKRenderWindowInteractor::OnSize)
232 END_EVENT_TABLE()
233
234 //EED win Compilation why??:  vtkCxxRevisionMacro(wxVTKRenderWindowInteractor, "$Revision$")
235
236 //EED2020-04-10
237 #if VTK_MAJOR_VERSION < 8 
238     vtkInstantiatorNewMacro(wxVTKRenderWindowInteractor)
239 #endif
240
241 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
242 static int wxvtk_attributes[]={
243   WX_GL_DOUBLEBUFFER,
244   WX_GL_RGBA,
245   WX_GL_DEPTH_SIZE,
246   16,
247   0
248 };
249 #endif
250
251 //---------------------------------------------------------------------------
252 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() 
253
254 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
255     #if wxCHECK_VERSION(2, 9, 0) // the order of the parameters to wxGLCanvas::wxGLCanvas has changed
256                 : wxGLCanvas(0, -1, wxvtk_attributes, wxDefaultPosition, wxDefaultSize, 0, wxT("wxVTKRenderWindowInteractor")), 
257         #else
258                 : wxGLCanvas(0, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("wxVTKRenderWindowInteractor"), wxvtk_attributes), 
259         #endif
260 #else
261                 : wxWindow(), 
262 #endif //__WXGTK__
263
264           vtkRenderWindowInteractor()
265       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
266       , ActiveButton(wxEVT_NULL)
267       , Stereo(0)
268       , Handle(0)
269       , Created(true)
270       , RenderWhenDisabled(1)
271       , UseCaptureMouse(0)
272 {
273     
274 #ifdef VTK_DEBUG_LEAKS
275   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
276 #endif
277 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
278   this->context = new wxGLContext(this);
279 #endif
280   this->RenderWindow = NULL;
281   this->SetRenderWindow(vtkRenderWindow::New());
282   this->RenderWindow->Delete();
283     
284 #ifdef VTK_USE_TDX
285     this->Device=vtkTDxMacDevice::New();
286 #endif
287
288 }
289 //---------------------------------------------------------------------------
290 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor(wxWindow *parent,
291                                                          wxWindowID id,
292                                                          const wxPoint &pos,
293                                                          const wxSize &size,
294                                                          long style,
295                                                          const wxString &name)
296 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
297     #if wxCHECK_VERSION(2, 9, 0) // the order of the parameters to wxGLCanvas::wxGLCanvas has changed
298       : wxGLCanvas(parent, id, wxvtk_attributes, pos, size, style, name)
299     #else
300       : wxGLCanvas(parent, id, pos, size, style, name, wxvtk_attributes)
301     #endif
302 #else
303       : wxWindow(parent, id, pos, size, style, name)
304 #endif //__WXGTK__
305           , vtkRenderWindowInteractor()
306       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
307       , ActiveButton(wxEVT_NULL)
308       , Stereo(0)
309       , Handle(0)
310       , Created(true)
311       , RenderWhenDisabled(1)
312       , UseCaptureMouse(0)
313 {
314         
315 #ifdef VTK_DEBUG_LEAKS
316   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
317 #endif
318 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
319   this->context = new wxGLContext(this);
320 #endif
321   this->RenderWindow = NULL;
322   this->SetRenderWindow(vtkRenderWindow::New());
323   this->RenderWindow->Delete();
324 #ifdef __WXMAC__
325   // On Mac (Carbon) we don't get notified of the initial window size with an EVT_SIZE event,
326   // so we update the size information of the interactor/renderwindow here
327   this->UpdateSize(size.x, size.y);
328 #endif
329     
330
331 #ifdef VTK_USE_TDX
332     this->Device=vtkTDxMacDevice::New();
333 #endif
334
335 }
336
337 //---------------------------------------------------------------------------
338 wxVTKRenderWindowInteractor::~wxVTKRenderWindowInteractor()
339 {
340   SetRenderWindow(NULL);
341   SetInteractorStyle(NULL);
342 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
343   delete this->context;
344 #endif
345     
346 #ifdef VTK_USE_TDX
347   this->Device->Delete();
348 #endif
349 }
350
351 //---------------------------------------------------------------------------
352 wxVTKRenderWindowInteractor * wxVTKRenderWindowInteractor::New()
353 {
354   // we don't make use of the objectfactory, because we're not registered
355   return new wxVTKRenderWindowInteractor;
356 }
357
358 //---------------------------------------------------------------------------
359 void wxVTKRenderWindowInteractor::Initialize()
360 {
361   int *size = RenderWindow->GetSize();
362   // enable everything and start rendering
363   Enable();
364   //RenderWindow->Start();
365   // set the size in the render window interactor
366   Size[0] = size[0];
367   Size[1] = size[1];
368   // this is initialized
369     Initialized = 1;
370 }
371 //---------------------------------------------------------------------------
372 void wxVTKRenderWindowInteractor::Enable()
373 {
374   // if already enabled then done
375   if (Enabled)
376     return;
377
378   // that's it
379   Enabled = 1;
380 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
381   wxGLCanvas::SetCurrent(*this->context);
382 #endif
383
384 //EED 2010-10-14
385 #ifdef VTK_USE_TDX
386   if(this->UseTDx)
387   {
388     this->Device->SetInteractor(this);
389     this->Device->Initialize();
390   }
391 #endif
392
393   Modified();
394     
395 }
396 //---------------------------------------------------------------------------
397 bool wxVTKRenderWindowInteractor::Enable(bool enable)
398 {
399 #ifdef VTK_USE_TDX
400   if(this->UseTDx)
401   {
402     this->Device->SetInteractor(this);
403     this->Device->Initialize();
404   }
405 #endif
406
407 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
408   return wxGLCanvas::Enable(enable);
409 #else
410   return wxWindow::Enable(enable);
411 #endif
412 }
413 //---------------------------------------------------------------------------
414 void wxVTKRenderWindowInteractor::Disable()
415 {
416   // if already disabled then done
417   if (!Enabled)
418   {
419     return;
420   }
421 #ifdef VTK_USE_TDX
422   if(this->Device->GetInitialized())
423   {
424     this->Device->Close();
425   }
426 #endif
427     
428     
429   // that's it (we can't remove the event handler like it should be...)
430   Enabled = 0;
431   Modified();
432 }
433 //---------------------------------------------------------------------------
434 void wxVTKRenderWindowInteractor::Start()
435 {
436   // the interactor cannot control the event loop
437   vtkErrorMacro( << "wxVTKRenderWindowInteractor::Start() "
438     "interactor cannot control event loop.");
439 }
440 //---------------------------------------------------------------------------
441 void wxVTKRenderWindowInteractor::UpdateSize(int x, int y)
442 {
443   if( RenderWindow )
444   {
445     // if the size changed tell render window
446     if ( x != Size[0] || y != Size[1] )
447     {
448       // adjust our (vtkRenderWindowInteractor size)
449       Size[0] = x;
450       Size[1] = y;
451       // and our RenderWindow's size
452
453 #ifdef __WXCOCOA__
454 //  #ifdef VTK_USE_COCOA
455 //  #else
456 //  #endif //VTK_USE_COCOA
457 #else
458       RenderWindow->SetSize(x, y);
459 #endif //__WXCOCOA__
460       
461 #if defined(__WXMSW__)
462       this->Refresh();
463 #endif //__WXMSW__
464     } // if x y
465   } // if RenderWindow
466 }
467 //---------------------------------------------------------------------------
468 int wxVTKRenderWindowInteractor::CreateTimer(int WXUNUSED(timertype))
469 {
470   // it's a one shot timer
471   if (!timer.Start(10, TRUE))
472   {
473     return 0;
474   }
475   return 1;
476 }
477
478 #if VTK_MAJOR_VERSION > 5 || (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION >= 2)
479 //------------------------------------------------------------------
480 int wxVTKRenderWindowInteractor::InternalCreateTimer(int timerId, int timerType,
481                                                      unsigned long duration)
482 {
483   if (!timer.Start(duration, timerType == OneShotTimer))
484   {
485     return 0;
486   }
487   return ID_wxVTKRenderWindowInteractor_TIMER;
488 }
489 //------------------------------------------------------------------
490 int wxVTKRenderWindowInteractor::InternalDestroyTimer(int platformTimerId)
491 {
492   timer.Stop();
493   return 1;
494 }
495 #endif
496
497 //---------------------------------------------------------------------------
498 int wxVTKRenderWindowInteractor::DestroyTimer()
499 {
500   // do nothing
501   return 1;
502 }
503
504 //---------------------------------------------------------------------------
505 void wxVTKRenderWindowInteractor::OnTimer(wxTimerEvent& WXUNUSED(event))
506 {
507   if (!Enabled)
508     return;
509     
510 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
511   // new style
512 #if VTK_MAJOR_VERSION > 5 || (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION >= 2)
513   // pass the right timer id
514   int timerId = this->GetCurrentTimerId();
515   this->InvokeEvent(vtkCommand::TimerEvent, &timerId);
516 #else
517   this->InvokeEvent(vtkCommand::TimerEvent, NULL);
518 #endif
519 #else
520   // old style
521   InteractorStyle->OnTimer();
522 #endif
523 }
524
525 //---------------------------------------------------------------------------
526 // NOTE on implementation:
527 // Bad luck you ended up in the only tricky place of this code.
528 // A few note, wxWidgets still refuse to provide such convenient method
529 // so I have to maintain it myself, eventhough this is completely integrated
530 // in wxPython...
531 // Anyway if this happen to break for you then compare to a recent version of wxPython
532 // and look for the function long wxPyGetWinHandle(wxWindow* win)
533 // in wxPython/src/helpers.cpp
534 long wxVTKRenderWindowInteractor::GetHandleHack()
535 {
536   //helper function to hide the MSW vs GTK stuff
537   long handle_tmp = 0;
538
539 // __WXMSW__ is for Win32
540 // __WXMAC__ is for Carbon or Cocoa builds
541 // __WXGTK__ is for both gtk 1.2.x and gtk 2.x
542 #if defined(__WXMSW__) || defined(__WXMAC__)
543     handle_tmp = (long)this->GetHandle();
544 #endif //__WXMSW__
545
546 // using above GetHandle() works fine with wxOSX 2.9.x
547 #if defined(__WXCOCOA__) && !wxCHECK_VERSION(2, 9, 0)
548    // Here is how to find the NSWindow
549    wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent( this ) );
550    if (toplevel != NULL )
551    {
552       handle_tmp = (long)toplevel->GetNSWindow();
553    }
554    // The NSView will be deducted from 
555    // [(NSWindow*)Handle contentView]
556    // if only I knew how to write that in c++
557 #endif //__WXCOCOA__ && !wxCHECK_VERSION(2, 9, 0)
558
559     // Find and return the actual X-Window.
560 #if defined(__WXGTK__) || defined(__WXX11__)
561     return (long)GetXWindow(this);
562 #endif
563
564 //#ifdef __WXMOTIF__
565 //    handle_tmp = (long)this->GetXWindow();
566 //#endif
567
568   return handle_tmp;
569 }
570 //---------------------------------------------------------------------------
571 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
572 {
573   //must always be here
574 //EED2021-08-26  
575 #ifdef __WXCOCOA__
576 #else
577         wxPaintDC pDC(this);
578 #endif
579
580   //do it here rather than in the cstor: this is safer.
581   if(!Handle)
582   {
583     Handle = GetHandleHack();
584         
585 #ifdef __WXCOCOA__
586         vtkCocoaRenderWindow    *rwin           = vtkCocoaRenderWindow::SafeDownCast(RenderWindow);
587     NSView                                      *nvsview        = (NSView* )Handle;
588         NSWindow                                *nswindow       = nvsview.window;
589     rwin->SetRootWindow( nswindow );
590     rwin->SetWindowId(  reinterpret_cast<void *>(nvsview) );
591 #else   
592     RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
593 #endif
594         
595 // Cocoa
596 // this->GetNSView() <-> DisplayId
597 // this->GetTopLevel()->GetNSWindow() <-> WindowId
598 #ifdef __WXMSW__
599     RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
600 #endif //__WXMSW__
601       
602     // This is another hack to prevent the VTK Render Window from closing the display.
603     // If VTK closes the display, ~wxContext chashes while trying to destroy its
604     // glContext (because the display is closed). The Get -> Set makes this VTK
605     // object think someone else is responsible for the display. 
606     #ifdef __WXCOCOA__
607       // avoid "Method not implemented" messages in Console
608     #else
609       this->RenderWindow->SetDisplayId(this->RenderWindow->GetGenericDisplayId());
610     #endif
611   }
612   // get vtk to render to the wxWindows
613   Render();
614 #ifdef __WXMAC__
615   // This solves a problem with repainting after a window resize
616   // See also: http://sourceforge.net/mailarchive/forum.php?thread_id=31690967&forum_id=41789
617 #ifdef __WXCOCOA__
618   #if !wxCHECK_VERSION(2, 9, 0)
619     // this doesn't seem necessary with wxOSX 2.9.x
620     vtkCocoaRenderWindow * rwin = vtkCocoaRenderWindow::SafeDownCast(RenderWindow);
621     if( rwin )
622     {
623       rwin->UpdateContext();
624     }
625   #endif
626 #else
627   vtkCarbonRenderWindow* rwin = vtkCarbonRenderWindow::SafeDownCast(RenderWindow);
628   if( rwin )
629   {
630 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
631     // Must be somewhere after VTK 4.4
632     rwin->UpdateGLRegion();
633 #endif
634   }
635 #endif
636 #endif
637     
638 }
639 //---------------------------------------------------------------------------
640 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
641 {
642   //turn off background erase to reduce flickering on MSW
643   event.Skip(false);
644 }
645 //---------------------------------------------------------------------------
646 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
647 {
648   int w, h;
649   GetClientSize(&w, &h);
650   UpdateSize(w, h);
651
652   if (!Enabled) 
653     {
654     return;
655     }
656
657 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
658   InvokeEvent(vtkCommand::ConfigureEvent, NULL);
659 #endif
660   //this will check for Handle
661   //Render();
662 }
663 //---------------------------------------------------------------------------
664 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
665 {
666  if (!Enabled) 
667     {
668     return;
669     }
670 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
671   SetEventInformationFlipY(event.GetX(), event.GetY(), 
672     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
673
674   InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
675 #else
676   InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
677     event.GetX(), Size[1] - event.GetY() - 1);
678 #endif
679 }
680 //---------------------------------------------------------------------------
681 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
682 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
683 {
684   if (!Enabled) 
685     {
686     return;
687     }
688
689 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
690     // new style
691   SetEventInformationFlipY(event.GetX(), event.GetY(), 
692       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
693
694   InvokeEvent(vtkCommand::EnterEvent, NULL);
695 #else
696     // old style
697   InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
698       event.GetX(), Size[1] - event.GetY() - 1);  
699 #endif
700 }
701 //---------------------------------------------------------------------------
702 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
703 {
704   if (!Enabled) 
705     {
706     return;
707     }
708
709 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
710     // new style
711   SetEventInformationFlipY(event.GetX(), event.GetY(), 
712       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
713
714   InvokeEvent(vtkCommand::LeaveEvent, NULL);
715 #else
716     // old style
717   InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
718       event.GetX(), Size[1] - event.GetY() - 1);  
719 #endif
720 }
721 //---------------------------------------------------------------------------
722 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
723 {
724   if (!Enabled)
725     {
726     return;
727     }
728
729 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
730     // new style
731   int keycode = event.GetKeyCode();
732   char key = '\0';
733   if (((unsigned int)keycode) < 256)
734   {
735     // TODO: Unicode in non-Unicode mode ??
736     key = (char)keycode;
737   }
738
739   // we don't get a valid mouse position inside the key event on every platform
740   // so we retrieve the mouse position explicitly and pass it along
741   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
742   SetEventInformationFlipY(mousePos.x, mousePos.y, 
743                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
744   InvokeEvent(vtkCommand::KeyPressEvent, NULL);
745 #else
746   InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(), 
747     event.GetKeyCode(), 1);
748 #endif
749   event.Skip();
750 }
751 //---------------------------------------------------------------------------
752 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
753 {
754   if (!Enabled)
755     {
756     return;
757     }
758
759 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
760     // new style
761   int keycode = event.GetKeyCode();
762   char key = '\0';
763   if (((unsigned int)keycode) < 256)
764   {
765     // TODO: Unicode in non-Unicode mode ??
766     key = (char)keycode;
767   }
768
769   // we don't get a valid mouse position inside the key event on every platform
770   // so we retrieve the mouse position explicitly and pass it along
771   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
772   SetEventInformationFlipY(mousePos.x, mousePos.y, 
773                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
774   InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
775 #else
776   InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(), 
777     event.GetKeyCode(), 1);
778 #endif
779   event.Skip();
780 }
781 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
782  //---------------------------------------------------------------------------
783 void wxVTKRenderWindowInteractor::OnChar(wxKeyEvent &event)
784 {
785   if (!Enabled)
786     {
787     return;
788     }
789     
790 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
791   // new style
792   int keycode = event.GetKeyCode();
793   char key = '\0';
794   if (((unsigned int)keycode) < 256)
795     {
796     // TODO: Unicode in non-Unicode mode ??
797     key = (char)keycode;
798     }
799
800   // we don't get a valid mouse position inside the key event on every platform
801   // so we retrieve the mouse position explicitly and pass it along
802   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
803   SetEventInformationFlipY(mousePos.x, mousePos.y, 
804                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
805   InvokeEvent(vtkCommand::CharEvent, NULL);
806 #endif
807   event.Skip();
808 }
809 //---------------------------------------------------------------------------
810 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
811 {
812   if (!Enabled || (ActiveButton != wxEVT_NULL))
813     {
814     return;
815     }
816   ActiveButton = event.GetEventType();
817
818     // On Mac (Carbon) and Windows we don't automatically get the focus when
819     // you click inside the window
820     // we therefore set the focus explicitly
821     // Apparently we need that on linux (GTK) too:
822     this->SetFocus();
823
824 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
825   SetEventInformationFlipY(event.GetX(), event.GetY(), 
826     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
827 #endif
828
829   if(event.RightDown())
830   {
831 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
832     // new style
833     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
834 #else            
835     // old style
836     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
837       event.GetX(), Size[1] - event.GetY() - 1);
838 #endif
839   }
840   else if(event.LeftDown())
841   {
842 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
843     // new style
844     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
845 #else            
846     // old style
847     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
848       event.GetX(), Size[1] - event.GetY() - 1);
849 #endif
850   }
851   else if(event.MiddleDown())
852   {
853 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
854     // new style
855     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
856 #else            
857     // old style
858     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
859       event.GetX(), Size[1] - event.GetY() - 1);
860 #endif
861   }
862   //save the button and capture mouse until the button is released
863   //Only if :
864   //1. it is possible (WX_USE_X_CAPTURE)
865   //2. user decided to.
866   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
867   {
868     CaptureMouse();
869   }
870 }
871 //---------------------------------------------------------------------------
872 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
873 {
874   //EVT_xxx_DOWN == EVT_xxx_UP - 1
875   //This is only needed if two mouse buttons are pressed at the same time.
876   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
877   //wxEVT_COMMAND_RIGHT_CLICK
878   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
879     {
880     return;
881     }
882
883   // See report by Shang Mu / Kerry Loux on wxVTK mailing list
884     this->SetFocus();
885
886 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
887   SetEventInformationFlipY(event.GetX(), event.GetY(), 
888     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
889 #endif
890   
891   if(ActiveButton == wxEVT_RIGHT_DOWN)
892   {
893 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
894     // new style
895     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
896 #else            
897     // old style
898     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
899       event.GetX(), Size[1] - event.GetY() - 1);
900 #endif
901   }
902   else if(ActiveButton == wxEVT_LEFT_DOWN)
903   {
904 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
905     // new style
906     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
907 #else            
908     // old style
909     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
910       event.GetX(), Size[1] - event.GetY() - 1);
911 #endif
912   }
913   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
914   {
915 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
916     // new style
917     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
918 #else            
919     // old style
920     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
921       event.GetX(), Size[1] - event.GetY() - 1);
922 #endif
923   }
924   //if the ActiveButton is realeased, then release mouse capture
925   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
926   {
927     ReleaseMouse();
928   }
929   ActiveButton = wxEVT_NULL;
930 }
931 //---------------------------------------------------------------------------
932 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
933 {
934 // Mouse wheel was only added after VTK 4.4 (I think...)
935 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
936   // new style
937   //Set vtk event information ... The numebr of wheel rotations is stored in
938   //the x varible.  y varible is zero
939   SetEventInformationFlipY(event.GetX() , event.GetY(), 
940                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
941   if(event.GetWheelRotation() > 0)
942     {
943       //Send event to VTK
944       InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
945     }
946   else
947     {
948       //Send event to VTK
949       InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
950     }
951 #endif
952
953 }
954
955 //---------------------------------------------------------------------------
956 #if wxCHECK_VERSION(2, 8, 0)
957 void wxVTKRenderWindowInteractor::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
958 {
959    if (ActiveButton != wxEVT_NULL)
960    {
961        //Maybe also invoke the button release event here
962    }
963    // Reset ActiveButton so that
964    // 1. we do not process mouse button up events any more,
965    // 2. the next button down event will be processed and call CaptureMouse().
966    // Otherwise ReleaseMouse() will be called
967    // without a previous CaptureMouse().
968    ActiveButton = wxEVT_NULL;
969 }
970 #endif
971
972 //---------------------------------------------------------------------------
973 void wxVTKRenderWindowInteractor::Render()
974 {
975 #if wxCHECK_VERSION(2, 8, 0)
976   int renderAllowed = !IsFrozen();
977 #else
978   int renderAllowed = 1;
979 #endif
980   if (renderAllowed && !RenderWhenDisabled)
981     {
982     //the user doesn't want us to render when the toplevel frame
983     //is disabled - first find the top level parent
984     wxWindow *topParent = wxGetTopLevelParent(this);
985     if (topParent)
986       {
987       //if it exists, check whether it's enabled
988       //if it's not enabeld, renderAllowed will be false
989       renderAllowed = topParent->IsEnabled();
990       }
991     } // if renderAllowed && !RenderWhenDisabled
992
993   if (renderAllowed)
994     {
995 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
996     wxGLCanvas::SetCurrent(*(this->context));
997 #endif
998     if(Handle && (Handle == GetHandleHack()) )
999       {
1000       RenderWindow->Render();
1001       }
1002 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
1003     else if(GetHandleHack())
1004       {
1005       //this means the user has reparented us; let's adapt to the
1006       //new situation by doing the WindowRemap dance
1007       //store the new situation
1008       Handle = GetHandleHack();
1009       RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
1010       RenderWindow->WindowRemap();
1011       RenderWindow->Render();
1012       }
1013 #endif
1014     } // if renderAllowed
1015 }
1016 //---------------------------------------------------------------------------
1017 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
1018 {
1019   //Change value of __RenderWhenDisabled ivar.
1020   //If __RenderWhenDisabled is false (the default), this widget will not
1021   //call Render() on the RenderWindow if the top level frame (i.e. the
1022   //containing frame) has been disabled.
1023
1024   //This prevents recursive rendering during wxSafeYield() calls.
1025   //wxSafeYield() can be called during the ProgressMethod() callback of
1026   //a VTK object to have progress bars and other GUI elements updated -
1027   //it does this by disabling all windows (disallowing user-input to
1028   //prevent re-entrancy of code) and then handling all outstanding
1029   //GUI events.
1030         
1031   //However, this often triggers an OnPaint() method for wxVTKRWIs,
1032   //resulting in a Render(), resulting in Update() being called whilst
1033   //still in progress.
1034
1035   RenderWhenDisabled = (bool)newValue;
1036 }
1037 //---------------------------------------------------------------------------
1038 //
1039 // Set the variable that indicates that we want a stereo capable window
1040 // be created. This method can only be called before a window is realized.
1041 //
1042 void wxVTKRenderWindowInteractor::SetStereo(int capable)
1043 {
1044   if (Stereo != capable)
1045     {
1046     Stereo = capable;
1047     RenderWindow->StereoCapableWindowOn();
1048     RenderWindow->SetStereoTypeToCrystalEyes();
1049     Modified();
1050     }
1051 }
1052
1053 //---------------------------------------------------------------------------
1054 //
1055 //
1056 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
1057 {
1058   this->Superclass::PrintSelf(os, indent);
1059 }
1060
1061
1062 }
1063 // LG : EO namespace bbwxvtk
1064 //=======================================================================
1065
1066