1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14/* Note, elements of GraphicsWindowX11 have used Prodcer/RenderSurface_X11.cpp as both
15 * a guide to use of X11/GLX and copiying directly in the case of setBorder().
16 * These elements are license under OSGPL as above, with Copyright (C) 2001-2004  Don Burns.
17 */
18
19#ifndef OSGVIEWER_GRAPHICSWINDOWCOCOA
20#define OSGVIEWER_GRAPHICSWINDOWCOCOA 1
21
22#ifdef __APPLE__
23
24#ifdef __OBJC__
25@class GraphicsWindowIOSWindow;
26@class GraphicsWindowIOSGLView;
27@class GraphicsWindowIOSGLViewController;
28@class EAGLContext;
29@class UIWindow;
30@class UIView;
31@class UIViewController;
32#else
33class GraphicsWindowIOSGLView;
34class GraphicsWindowIOSWindow;
35class GraphicsWindowIOSGLViewController;
36class EAGLContext;
37class UIWindow;
38class UIView;
39class UIViewController;
40#endif
41
42#include <osgViewer/GraphicsWindow>
43
44// Do not include any cocoa-header here, because this will pollute the name-space and causes compile errors
45
46namespace osgViewer
47{
48/**
49 * Implementation of a GraphicsWindow for the iOS platform.
50 */
51class GraphicsWindowIOS : public osgViewer::GraphicsWindow
52{
53    public:
54        class Implementation;
55
56        GraphicsWindowIOS(osg::GraphicsContext::Traits* traits) : GraphicsWindow(),
57            _valid(false),
58            _initialized(false),
59            _realized(false),
60            _window(NULL),
61            _view(NULL),
62            _viewController(NULL),
63            _context(NULL),
64            _ownsWindow(true),
65            _deviceOrientationFlags(WindowData::ALL_ORIENTATIONS),
66            _viewContentScaleFactor(-1.0f)
67        {
68            _traits = traits;
69
70            init();
71
72            if (valid())
73            {
74                setState( new osg::State );
75                getState()->setGraphicsContext(this);
76
77                if (_traits.valid() && _traits->sharedContext.valid())
78                {
79                    getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
80                    incrementContextIDUsageCount( getState()->getContextID() );
81                }
82                else
83                {
84                    getState()->setContextID( osg::GraphicsContext::createNewContextID() );
85                }
86            }
87        }
88
89        virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindowIOS*>(object)!=0; }
90        virtual const char* libraryName() const { return "osgViewer"; }
91        virtual const char* className() const { return "GraphicsWindowIOS"; }
92
93        virtual void runOperations();
94
95        virtual bool valid() const { return _valid; }
96
97        /** Realise the GraphicsContext.*/
98        virtual bool realizeImplementation();
99
100        /** Return true if the graphics context has been realised and is ready to use.*/
101        virtual bool isRealizedImplementation() const { return _realized; }
102
103        /** Close the graphics context.*/
104        virtual void closeImplementation();
105
106        /** Make this graphics context current.*/
107        virtual bool makeCurrentImplementation();
108
109        /** Release the graphics context.*/
110        virtual bool releaseContextImplementation();
111
112        /** Swap the front and back buffers.*/
113        virtual void swapBuffersImplementation();
114
115        /** Check to see if any events have been generated.*/
116        virtual bool checkEvents();
117
118        /** Set Window decoration.*/
119        virtual bool setWindowDecorationImplementation(bool flag);
120
121        /** Get focus.*/
122        virtual void grabFocus();
123
124        /** Get focus on if the pointer is in this window.*/
125        virtual void grabFocusIfPointerInWindow();
126
127        /** Raise the window to the top.*/
128        virtual void raiseWindow();
129
130        virtual void resizedImplementation(int x, int y, int width, int height);
131
132        virtual bool setWindowRectangleImplementation(int x, int y, int width, int height);
133
134        virtual void setWindowName (const std::string & name);
135        virtual void useCursor(bool cursorOn);
136        virtual void setCursor(MouseCursor mouseCursor);
137
138        // WindowData is used to pass in the an existing UIWindow to be used to display our glView
139        class WindowData : public osg::Referenced
140        {
141            public:
142                enum DeviceOrientation{
143                    IGNORE_ORIENTATION = 0,
144                    PORTRAIT_ORIENTATION = 1<<0,
145                    PORTRAIT_UPSIDEDOWN_ORIENTATION  = 1<<1,
146                    LANDSCAPE_LEFT_ORIENTATION  = 1<<2,
147                    LANDSCAPE_RIGHT_ORIENTATION  = 1<<3,
148                    ALL_ORIENTATIONS = PORTRAIT_ORIENTATION  | PORTRAIT_UPSIDEDOWN_ORIENTATION  | LANDSCAPE_LEFT_ORIENTATION  | LANDSCAPE_RIGHT_ORIENTATION
149                };
150                typedef unsigned int DeviceOrientationFlags;
151
152                WindowData(UIView* window_or_view = NULL, UIViewController* parentController = NULL, DeviceOrientationFlags orientationFlags = ALL_ORIENTATIONS, float scaleFactor = -1.0f)
153                :   _windowOrView(window_or_view),
154                    _parentController(parentController),
155                    _deviceOrientationFlags(orientationFlags),
156                    _viewContentScaleFactor(scaleFactor),
157                    _createTransparentView(false),
158                    _useRetainedBacking(false)
159                {
160                }
161
162                void setAdaptToDeviceOrientation(DeviceOrientationFlags flags) { _deviceOrientationFlags = flags; }
163
164                void setViewContentScaleFactor(float scaleFactor) { _viewContentScaleFactor = scaleFactor; }
165
166                UIView* getWindowOrParentView() const { return _windowOrView; }
167                UIViewController* getController() const;
168
169                bool getCreateTransparentView() { return _createTransparentView; }
170                void setCreateTransparentView(bool b) { _createTransparentView = b; }
171
172                bool getUseRetainedBacking() { return _useRetainedBacking; }
173                void setUseRetainedBacking(bool b) { _useRetainedBacking = b; }
174
175            private:
176
177                UIView*                _windowOrView;
178                UIViewController*       _parentController;
179                DeviceOrientationFlags _deviceOrientationFlags;
180                float                  _viewContentScaleFactor;
181                bool                   _createTransparentView;
182                bool                   _useRetainedBacking;
183
184            friend class GraphicsWindowIOS;
185
186        };
187
188        EAGLContext* getContext() { return _context; }
189        GraphicsWindowIOSWindow* getWindow() { return _window; }
190        GraphicsWindowIOSGLView* getView() { return _view; }
191        void setVSync(bool f);
192
193        /** adapts a resize / move of the window, coords in global screen space */
194        void adaptResize(int x, int y, int w, int h);
195
196
197        WindowData::DeviceOrientationFlags getDeviceOrientationFlags() const { return _deviceOrientationFlags; }
198
199        void setDeviceOrientationFlags(WindowData::DeviceOrientationFlags flags) { _deviceOrientationFlags = flags; }
200
201
202        //
203        //helper funs for converting points to pixels
204        osg::Vec2 pointToPixel(const osg::Vec2& point);
205        osg::Vec2 pixelToPoint(const osg::Vec2& pixel);
206
207    protected:
208
209        void init();
210
211        void transformMouseXY(float& x, float& y);
212
213        virtual ~GraphicsWindowIOS();
214
215
216        bool            _valid;
217        bool            _initialized;
218        bool            _realized;
219        bool            _useWindowDecoration;
220
221
222    private:
223
224        GraphicsWindowIOSWindow*           _window;
225        GraphicsWindowIOSGLView*           _view;
226        GraphicsWindowIOSGLViewController* _viewController;
227        EAGLContext*                       _context;
228        bool                               _updateContext;
229
230        bool                               _ownsWindow;
231
232        WindowData::DeviceOrientationFlags _deviceOrientationFlags;
233
234        float                              _viewContentScaleFactor;
235
236};
237
238}
239
240#endif
241#endif
242