1/*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of the copyright holders may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // Authors:
41 //  * Anatoly Baksheev, Itseez Inc.  myname.mysurname <> mycompany.com
42 //
43 //  This workaround code was taken from PCL library(www.pointclouds.org)
44 //
45 //  Modified by Jasper Shemilt to work with VTK 6.2
46 //  The fix was needed because GetCocoaServer has been moved from
47 //  vtkCocoaRenderWindowInteractor to vtkCocoaRenderWindow in VTK 6.2.
48 //  This alteration to VTK happened almost a year ago according to the gitHub
49 //  commit a3e9fc9.
50 //
51 //M*/
52
53#import <Cocoa/Cocoa.h>
54#include <vtkCocoaRenderWindow.h>
55#include <vtkCocoaRenderWindowInteractor.h>
56#include <vtkObjectFactory.h>
57#include <vtkSmartPointer.h>
58
59//----------------------------------------------------------------------------
60@interface vtkCocoaServerFix : NSObject
61{
62    vtkCocoaRenderWindow* renWin;
63}
64
65+ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow*)inRenderWindow;
66
67- (void)start;
68- (void)stop;
69- (void)breakEventLoop;
70
71@end
72
73//----------------------------------------------------------------------------
74@implementation vtkCocoaServerFix
75
76//----------------------------------------------------------------------------
77- (id)initWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow
78{
79    self = [super init];
80    if (self)
81        renWin = inRenderWindow;
82    return self;
83}
84
85//----------------------------------------------------------------------------
86+ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow
87{
88    vtkCocoaServerFix *server = [[[vtkCocoaServerFix alloc] initWithRenderWindow:inRenderWindow] autorelease];
89    return server;
90}
91
92//----------------------------------------------------------------------------
93- (void)start
94{
95    // Retrieve the NSWindow.
96    NSWindow *win = nil;
97    if (renWin)
98    {
99        win = reinterpret_cast<NSWindow*> (renWin->GetRootWindow ());
100
101        // We don't want to be informed of every window closing, so check for nil.
102        if (win != nil)
103        {
104            // Register for the windowWillClose notification in order to stop the run loop if the window closes.
105            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
106            [nc addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:win];
107        }
108    }
109    // Start the NSApplication's run loop
110    NSApplication* application = [NSApplication sharedApplication];
111    [application run];
112}
113
114//----------------------------------------------------------------------------
115- (void)stop
116{
117    [self breakEventLoop];
118}
119
120//----------------------------------------------------------------------------
121- (void)breakEventLoop
122{
123    NSApplication* application = [NSApplication sharedApplication];
124    [application stop:application];
125
126    NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
127                                        location:NSMakePoint(0.0,0.0)
128                                   modifierFlags:0
129                                       timestamp:0
130                                    windowNumber:-1
131                                         context:nil
132                                         subtype:0
133                                           data1:0
134                                           data2:0];
135    [application postEvent:event atStart:YES];
136}
137
138//----------------------------------------------------------------------------
139- (void)windowWillClose:(NSNotification*)aNotification
140{
141    (void)aNotification;
142
143    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
144    [nc removeObserver:self name:NSWindowWillCloseNotification object:nil];
145
146    if (renWin)
147    {
148        int windowCreated = renWin->GetWindowCreated ();
149        if (windowCreated)
150        {
151            [self breakEventLoop];
152
153            // The NSWindow is closing, so prevent anyone from accidently using it
154            renWin->SetRootWindow(NULL);
155        }
156    }
157}
158
159@end
160
161//----------------------------------------------------------------------------
162
163#if VTK_MAJOR_VERSION >= 6 && VTK_MINOR_VERSION  >=2
164
165namespace cv { namespace viz
166    {
167        class vtkCocoaRenderWindowInteractorFix : public vtkCocoaRenderWindowInteractor
168        {
169        public:
170            static vtkCocoaRenderWindowInteractorFix *New ();
171            vtkTypeMacro (vtkCocoaRenderWindowInteractorFix, vtkCocoaRenderWindowInteractor)
172
173            virtual void Start ();
174            virtual void TerminateApp ();
175
176        protected:
177            vtkCocoaRenderWindowInteractorFix () {}
178            ~vtkCocoaRenderWindowInteractorFix () {}
179
180        private:
181            vtkCocoaRenderWindowInteractorFix (const vtkCocoaRenderWindowInteractorFix&);  // Not implemented.
182            void operator = (const vtkCocoaRenderWindowInteractorFix&);  // Not implemented.
183        };
184
185        vtkStandardNewMacro (vtkCocoaRenderWindowInteractorFix)
186
187        vtkSmartPointer<vtkRenderWindowInteractor> vtkCocoaRenderWindowInteractorNew();
188
189        class vtkCocoaRenderWindowFix : public vtkCocoaRenderWindow
190        {
191        public:
192            static vtkCocoaRenderWindowFix *New ();
193            vtkTypeMacro ( vtkCocoaRenderWindowFix, vtkCocoaRenderWindow)
194
195            virtual vtkCocoaServerFix * GetCocoaServer ();
196            virtual void SetCocoaServer (void* );
197
198        protected:
199            vtkCocoaRenderWindowFix () {}
200            ~vtkCocoaRenderWindowFix () {}
201
202        private:
203            vtkCocoaRenderWindowFix (const vtkCocoaRenderWindowInteractorFix&);  // Not implemented.
204            void operator = (const vtkCocoaRenderWindowFix&);  // Not implemented.
205        };
206
207        vtkStandardNewMacro (vtkCocoaRenderWindowFix)
208
209        vtkSmartPointer<vtkRenderWindow> vtkCocoaRenderWindowNew();
210    }}
211
212vtkCocoaServerFix * cv::viz::vtkCocoaRenderWindowFix::GetCocoaServer ()
213{
214    return reinterpret_cast<vtkCocoaServerFix*> (this->GetCocoaServer ());
215}
216
217void cv::viz::vtkCocoaRenderWindowFix::SetCocoaServer (void* server)
218{
219    this->SetCocoaServer (server);
220}
221
222void cv::viz::vtkCocoaRenderWindowInteractorFix::Start ()
223{
224    vtkCocoaRenderWindowFix* renWin = vtkCocoaRenderWindowFix::SafeDownCast(this->GetRenderWindow ());
225    if (renWin != NULL)
226    {
227        vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (renWin->GetCocoaServer ());
228        if (!renWin->GetCocoaServer ())
229        {
230            server = [vtkCocoaServerFix cocoaServerWithRenderWindow:renWin];
231            renWin->SetCocoaServer (reinterpret_cast<void*> (server));
232        }
233
234        [server start];
235    }
236}
237
238void cv::viz::vtkCocoaRenderWindowInteractorFix::TerminateApp ()
239{
240    vtkCocoaRenderWindowFix *renWin = vtkCocoaRenderWindowFix::SafeDownCast (this->RenderWindow);
241    if (renWin)
242    {
243        vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (renWin->GetCocoaServer ());
244        [server stop];
245    }
246}
247
248vtkSmartPointer<vtkRenderWindowInteractor> cv::viz::vtkCocoaRenderWindowInteractorNew()
249{
250    return vtkSmartPointer<vtkCocoaRenderWindowInteractorFix>::New();
251}
252
253#else
254namespace cv { namespace viz
255    {
256        class vtkCocoaRenderWindowInteractorFix : public vtkCocoaRenderWindowInteractor
257        {
258        public:
259            static vtkCocoaRenderWindowInteractorFix *New ();
260            vtkTypeMacro (vtkCocoaRenderWindowInteractorFix, vtkCocoaRenderWindowInteractor)
261
262            virtual void Start ();
263            virtual void TerminateApp ();
264
265        protected:
266            vtkCocoaRenderWindowInteractorFix () {}
267            ~vtkCocoaRenderWindowInteractorFix () {}
268
269        private:
270            vtkCocoaRenderWindowInteractorFix (const vtkCocoaRenderWindowInteractorFix&);  // Not implemented.
271            void operator = (const vtkCocoaRenderWindowInteractorFix&);  // Not implemented.
272        };
273
274        vtkStandardNewMacro (vtkCocoaRenderWindowInteractorFix)
275
276        vtkSmartPointer<vtkRenderWindowInteractor> vtkCocoaRenderWindowInteractorNew();
277    }}
278
279void cv::viz::vtkCocoaRenderWindowInteractorFix::Start ()
280{
281    vtkCocoaRenderWindow* renWin = vtkCocoaRenderWindow::SafeDownCast(this->GetRenderWindow ());
282    if (renWin != NULL)
283    {
284        vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (this->GetCocoaServer ());
285        if (!this->GetCocoaServer ())
286        {
287            server = [vtkCocoaServerFix cocoaServerWithRenderWindow:renWin];
288            this->SetCocoaServer (reinterpret_cast<void*> (server));
289        }
290
291        [server start];
292    }
293}
294
295void cv::viz::vtkCocoaRenderWindowInteractorFix::TerminateApp ()
296{
297    vtkCocoaRenderWindow *renWin = vtkCocoaRenderWindow::SafeDownCast (this->RenderWindow);
298    if (renWin)
299    {
300        vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (this->GetCocoaServer ());
301        [server stop];
302    }
303}
304
305vtkSmartPointer<vtkRenderWindowInteractor> cv::viz::vtkCocoaRenderWindowInteractorNew()
306{
307    return vtkSmartPointer<vtkCocoaRenderWindowInteractorFix>::New();
308}
309
310#endif
311