dd6154a42bb5a10ae51fcf4f7795f8be1145a0f5
[blender.git] / intern / ghost / intern / GHOST_Window.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file ghost/intern/GHOST_Window.cpp
29  *  \ingroup GHOST
30  */
31
32
33 /**
34  * Copyright (C) 2001 NaN Technologies B.V.
35  * \author      Maarten Gribnau
36  * \date        May 10, 2001
37  */
38
39 #include "GHOST_Window.h"
40
41 #include "GHOST_ContextNone.h"
42
43 #include <assert.h>
44
45 GHOST_Window::GHOST_Window(
46         GHOST_TUns32 width, GHOST_TUns32 height,
47         GHOST_TWindowState state,
48         const bool wantStereoVisual,
49         const bool exclusive,
50         const GHOST_TUns16 wantNumOfAASamples)
51     : m_drawingContextType(GHOST_kDrawingContextTypeNone),
52       m_cursorVisible(true),
53       m_cursorGrab(GHOST_kGrabDisable),
54       m_cursorShape(GHOST_kStandardCursorDefault),
55       m_wantStereoVisual(wantStereoVisual),
56       m_wantNumOfAASamples(wantNumOfAASamples),
57       m_context(new GHOST_ContextNone(false, 0))
58 {
59         m_isUnsavedChanges = false;
60         m_canAcceptDragOperation = false;
61         
62         m_progressBarVisible = false;
63         
64         m_cursorGrabAccumPos[0] = 0;
65         m_cursorGrabAccumPos[1] = 0;
66         
67         m_nativePixelSize = 1.0f;
68
69         m_fullScreen = state == GHOST_kWindowStateFullScreen;
70         if (m_fullScreen) {
71                 m_fullScreenWidth = width;
72                 m_fullScreenHeight = height;
73         }
74 }
75
76
77 GHOST_Window::~GHOST_Window()
78 {
79         delete m_context;
80 }
81
82 void *GHOST_Window::getOSWindow() const
83 {
84         return NULL;
85 }
86
87 GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type)
88 {
89         if (type != m_drawingContextType) {
90                 delete m_context;
91                 m_context = NULL;
92
93                 if (type != GHOST_kDrawingContextTypeNone)
94                         m_context = newDrawingContext(type);
95
96                 if (m_context != NULL) {
97                         m_drawingContextType = type;
98                 }
99                 else {
100                         m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples);
101                         m_drawingContextType = GHOST_kDrawingContextTypeNone;
102                 }
103
104                 return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure;
105         }
106         else {
107                 return GHOST_kSuccess;
108         }
109 }
110
111 GHOST_TSuccess GHOST_Window::swapBuffers()
112 {
113         return m_context->swapBuffers();
114 }
115
116 GHOST_TSuccess GHOST_Window::setSwapInterval(int interval)
117 {
118         return m_context->setSwapInterval(interval);
119 }
120
121 GHOST_TSuccess GHOST_Window::getSwapInterval(int& intervalOut)
122 {
123         return m_context->getSwapInterval(intervalOut);
124 }
125
126 GHOST_TUns16 GHOST_Window::getNumOfAASamples()
127 {
128         return m_context->getNumOfAASamples();
129 }
130
131 GHOST_TSuccess GHOST_Window::activateDrawingContext()
132 {
133         return m_context->activateDrawingContext();
134 }
135
136 GHOST_TSuccess GHOST_Window::updateDrawingContext()
137 {
138         return m_context->updateDrawingContext();
139 }
140
141 GHOST_TSuccess GHOST_Window::releaseNativeHandles()
142 {
143         return m_context->releaseNativeHandles();
144 }
145
146 GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
147 {
148         if (setWindowCursorVisibility(visible)) {
149                 m_cursorVisible = visible;
150                 return GHOST_kSuccess;
151         }
152         else {
153                 return GHOST_kFailure;
154         }
155 }
156
157 GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2])
158 {
159         if (m_cursorGrab == mode)
160                 return GHOST_kSuccess;
161
162         /* override with new location */
163         if (mouse_ungrab_xy) {
164                 assert(mode == GHOST_kGrabDisable);
165                 m_cursorGrabInitPos[0] = mouse_ungrab_xy[0];
166                 m_cursorGrabInitPos[1] = mouse_ungrab_xy[1];
167         }
168
169         if (setWindowCursorGrab(mode)) {
170
171                 if (mode == GHOST_kGrabDisable)
172                         m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1;
173                 else if (bounds) {
174                         m_cursorGrabBounds = *bounds;
175                 }
176                 else {  /* if bounds not defined, use window */
177                         getClientBounds(m_cursorGrabBounds);
178                 }
179                 m_cursorGrab = mode;
180                 return GHOST_kSuccess;
181         }
182         else {
183                 return GHOST_kFailure;
184         }
185 }
186
187 GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds)
188 {
189         bounds = m_cursorGrabBounds;
190         return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess;
191 }
192
193 GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
194 {
195         if (setWindowCursorShape(cursorShape)) {
196                 m_cursorShape = cursorShape;
197                 return GHOST_kSuccess;
198         }
199         else {
200                 return GHOST_kFailure;
201         }
202 }
203
204 GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2],
205                                                   int hotX, int hotY)
206 {
207         return setCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
208                                     16, 16, hotX, hotY, 0, 1);
209 }
210
211 GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, 
212                                                   int sizex, int sizey, int hotX, int hotY,
213                                                   int fg_color, int bg_color)
214 {
215         if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color)) {
216                 m_cursorShape = GHOST_kStandardCursorCustom;
217                 return GHOST_kSuccess;
218         }
219         else {
220                 return GHOST_kFailure;
221         }
222 }
223
224 void GHOST_Window::setAcceptDragOperation(bool canAccept)
225 {
226         m_canAcceptDragOperation = canAccept;
227 }
228
229 bool GHOST_Window::canAcceptDragOperation() const
230 {
231         return m_canAcceptDragOperation;
232 }
233
234 GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges)
235 {
236         m_isUnsavedChanges = isUnsavedChanges;
237         
238         return GHOST_kSuccess;
239 }
240
241 bool GHOST_Window::getModifiedState()
242 {
243         return m_isUnsavedChanges;
244 }
245