1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup GHOST
22  * Declaration of GHOST_Window class.
23  */
24 
25 #pragma once
26 
27 #include "GHOST_IWindow.h"
28 
29 class GHOST_Context;
30 
31 /**
32  * Platform independent implementation of GHOST_IWindow.
33  * Dimensions are given in screen coordinates that are relative to the
34  * upper-left corner of the screen.
35  * Implements part of the GHOST_IWindow interface and adds some methods to
36  * be implemented by sub-classes of this class.
37  */
38 class GHOST_Window : public GHOST_IWindow {
39  public:
40   /**
41    * Constructor.
42    * Creates a new window and opens it.
43    * To check if the window was created properly, use the getValid() method.
44    * \param width             The width the window.
45    * \param heigh             The height the window.
46    * \param state             The state the window is initially opened with.
47    * \param type              The type of drawing context installed in this window.
48    * \param stereoVisual      Stereo visual for quad buffered stereo.
49    * \param exclusive         Use to show the window ontop and ignore others
50    *                          (used fullscreen).
51    */
52   GHOST_Window(GHOST_TUns32 width,
53                GHOST_TUns32 height,
54                GHOST_TWindowState state,
55                const bool wantStereoVisual = false,
56                const bool exclusive = false);
57 
58   /**
59    * \section Interface inherited from GHOST_IWindow left for derived class
60    * implementation.
61    * virtual  bool getValid() const = 0;
62    * virtual void setTitle(const char * title) = 0;
63    * virtual std::string getTitle() const = 0;
64    * virtual  void getWindowBounds(GHOST_Rect& bounds) const = 0;
65    * virtual  void getClientBounds(GHOST_Rect& bounds) const = 0;
66    * virtual  GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
67    * virtual  GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
68    * virtual  GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
69    * virtual void screenToClient(
70    *     GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
71    * virtual void clientToScreen(
72    *     GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
73    * virtual GHOST_TWindowState getState() const = 0;
74    * virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
75    * virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
76    * virtual GHOST_TSuccess swapBuffers() = 0;
77    * virtual GHOST_TSuccess setSwapInterval() = 0;
78    * virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
79    * virtual GHOST_TSuccess activateDrawingContext() = 0;
80    * virtual GHOST_TSuccess invalidate() = 0;
81    */
82 
83   /**
84    * Destructor.
85    * Closes the window and disposes resources allocated.
86    */
87   virtual ~GHOST_Window();
88 
89   /**
90    * Returns indication as to whether the window is valid.
91    * \return The validity of the window.
92    */
getValid()93   virtual bool getValid() const
94   {
95     return m_context != NULL;
96   }
97 
98   /**
99    * Returns the associated OS object/handle
100    * \return The associated OS object/handle
101    */
102   virtual void *getOSWindow() const;
103 
104   /**
105    * Returns the current cursor shape.
106    * \return  The current cursor shape.
107    */
108   inline GHOST_TStandardCursor getCursorShape() const;
109 
isDialog()110   inline bool isDialog() const
111   {
112     return false;
113   }
114 
115   /**
116    * Set the shape of the cursor.
117    * \param   cursorShape: The new cursor shape type id.
118    * \return  Indication of success.
119    */
120   GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
121 
122   /**
123    * Set the shape of the cursor to a custom cursor.
124    * \param   bitmap  The bitmap data for the cursor.
125    * \param   mask    The mask data for the cursor.
126    * \param   hotX    The X coordinate of the cursor hot-spot.
127    * \param   hotY    The Y coordinate of the cursor hot-spot.
128    * \return  Indication of success.
129    */
130   GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
131                                       GHOST_TUns8 *mask,
132                                       int sizex,
133                                       int sizey,
134                                       int hotX,
135                                       int hotY,
136                                       bool canInvertColor);
137 
138   /**
139    * Returns the visibility state of the cursor.
140    * \return  The visibility state of the cursor.
141    */
142   inline bool getCursorVisibility() const;
143   inline GHOST_TGrabCursorMode getCursorGrabMode() const;
144   inline bool getCursorGrabModeIsWarp() const;
145   inline GHOST_TAxisFlag getCursorGrabAxis() const;
146   inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
147   inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
148   inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
149 
150   /**
151    * Shows or hides the cursor.
152    * \param   visible The new visibility state of the cursor.
153    * \return  Indication of success.
154    */
155   GHOST_TSuccess setCursorVisibility(bool visible);
156 
157   /**
158    * Sets the cursor grab.
159    * \param   mode The new grab state of the cursor.
160    * \return  Indication of success.
161    */
162   GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode,
163                                GHOST_TAxisFlag wrap_axis,
164                                GHOST_Rect *bounds,
165                                GHOST_TInt32 mouse_ungrab_xy[2]);
166 
167   /**
168    * Gets the cursor grab region, if unset the window is used.
169    * reset when grab is disabled.
170    */
171   GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds);
172 
173   /**
174    * Sets the progress bar value displayed in the window/application icon
175    * \param progress The progress % (0.0 to 1.0)
176    */
setProgressBar(float)177   virtual GHOST_TSuccess setProgressBar(float /*progress*/)
178   {
179     return GHOST_kFailure;
180   }
181 
182   /**
183    * Hides the progress bar in the icon
184    */
endProgressBar()185   virtual GHOST_TSuccess endProgressBar()
186   {
187     return GHOST_kFailure;
188   }
189 
190   /**
191    * Sets the swap interval for swapBuffers.
192    * \param interval The swap interval to use.
193    * \return A boolean success indicator.
194    */
195   GHOST_TSuccess setSwapInterval(int interval);
196 
197   /**
198    * Gets the current swap interval for swapBuffers.
199    * \return An integer.
200    */
201   GHOST_TSuccess getSwapInterval(int &intervalOut);
202 
203   /**
204    * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
205    */
206   void setAcceptDragOperation(bool canAccept);
207 
208   /**
209    * Returns acceptance of the dropped object
210    * Usually called by the "object dropped" event handling function
211    */
212   bool canAcceptDragOperation() const;
213 
214   /**
215    * Sets the window "modified" status, indicating unsaved changes
216    * \param isUnsavedChanges Unsaved changes or not
217    * \return Indication of success.
218    */
219   virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
220 
221   /**
222    * Gets the window "modified" status, indicating unsaved changes
223    * \return True if there are unsaved changes
224    */
225   virtual bool getModifiedState();
226 
227   /**
228    * Returns the type of drawing context used in this window.
229    * \return The current type of drawing context.
230    */
231   inline GHOST_TDrawingContextType getDrawingContextType();
232 
233   /**
234    * Tries to install a rendering context in this window.
235    * Child classes do not need to overload this method,
236    * They should overload newDrawingContext instead.
237    * \param type  The type of rendering context installed.
238    * \return Indication as to whether installation has succeeded.
239    */
240   GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
241 
242   /**
243    * Swaps front and back buffers of a window.
244    * \return  A boolean success indicator.
245    */
246   virtual GHOST_TSuccess swapBuffers();
247 
248   /**
249    * Activates the drawing context of this window.
250    * \return  A boolean success indicator.
251    */
252   virtual GHOST_TSuccess activateDrawingContext();
253 
254   /**
255    * Updates the drawing context of this window. Needed
256    * whenever the window is changed.
257    * \return Indication of success.
258    */
259   GHOST_TSuccess updateDrawingContext();
260 
261   /**
262    * Gets the OpenGL framebuffer associated with the window's contents.
263    * \return The ID of an OpenGL framebuffer object.
264    */
265   virtual unsigned int getDefaultFramebuffer();
266 
267   /**
268    * Returns the window user data.
269    * \return The window user data.
270    */
getUserData()271   inline GHOST_TUserDataPtr getUserData() const
272   {
273     return m_userData;
274   }
275 
276   /**
277    * Changes the window user data.
278    * \param userData: The window user data.
279    */
setUserData(const GHOST_TUserDataPtr userData)280   void setUserData(const GHOST_TUserDataPtr userData)
281   {
282     m_userData = userData;
283   }
284 
getNativePixelSize(void)285   float getNativePixelSize(void)
286   {
287     if (m_nativePixelSize > 0.0f)
288       return m_nativePixelSize;
289     return 1.0f;
290   }
291 
292   /**
293    * Returns the recommended DPI for this window.
294    * \return The recommended DPI for this window.
295    */
getDPIHint()296   virtual inline GHOST_TUns16 getDPIHint()
297   {
298     return 96;
299   }
300 
301 #ifdef WITH_INPUT_IME
beginIME(GHOST_TInt32 x,GHOST_TInt32 y,GHOST_TInt32 w,GHOST_TInt32 h,int completed)302   virtual void beginIME(
303       GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
304   {
305     /* do nothing temporarily if not in windows */
306   }
307 
endIME()308   virtual void endIME()
309   {
310     /* do nothing temporarily if not in windows */
311   }
312 #endif /* WITH_INPUT_IME */
313 
314  protected:
315   /**
316    * Tries to install a rendering context in this window.
317    * \param type  The type of rendering context installed.
318    * \return Indication as to whether installation has succeeded.
319    */
320   virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0;
321 
322   /**
323    * Sets the cursor visibility on the window using
324    * native window system calls.
325    */
326   virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
327 
328   /**
329    * Sets the cursor grab on the window using
330    * native window system calls.
331    */
setWindowCursorGrab(GHOST_TGrabCursorMode)332   virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/)
333   {
334     return GHOST_kSuccess;
335   }
336 
337   /**
338    * Sets the cursor shape on the window using
339    * native window system calls.
340    */
341   virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) = 0;
342 
343   /**
344    * Sets the cursor shape on the window using
345    * native window system calls.
346    */
347   virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
348                                                     GHOST_TUns8 *mask,
349                                                     int szx,
350                                                     int szy,
351                                                     int hotX,
352                                                     int hotY,
353                                                     bool canInvertColor) = 0;
354 
355   GHOST_TSuccess releaseNativeHandles();
356 
357   /** The drawing context installed in this window. */
358   GHOST_TDrawingContextType m_drawingContextType;
359 
360   /** The window user data */
361   GHOST_TUserDataPtr m_userData;
362 
363   /** The current visibility of the cursor */
364   bool m_cursorVisible;
365 
366   /** The current grabbed state of the cursor */
367   GHOST_TGrabCursorMode m_cursorGrab;
368 
369   /** Grab cursor axis.*/
370   GHOST_TAxisFlag m_cursorGrabAxis;
371 
372   /** Initial grab location. */
373   GHOST_TInt32 m_cursorGrabInitPos[2];
374 
375   /** Accumulated offset from m_cursorGrabInitPos. */
376   GHOST_TInt32 m_cursorGrabAccumPos[2];
377 
378   /** Wrap the cursor within this region. */
379   GHOST_Rect m_cursorGrabBounds;
380 
381   /** The current shape of the cursor */
382   GHOST_TStandardCursor m_cursorShape;
383 
384   /** The presence of progress indicator with the application icon */
385   bool m_progressBarVisible;
386 
387   /** The acceptance of the "drop candidate" of the current drag'n'drop operation */
388   bool m_canAcceptDragOperation;
389 
390   /** Modified state : are there unsaved changes */
391   bool m_isUnsavedChanges;
392 
393   /** Stores whether this is a full screen window. */
394   bool m_fullScreen;
395 
396   /** Whether to attempt to initialize a context with a stereo framebuffer. */
397   bool m_wantStereoVisual;
398 
399   /** Full-screen width */
400   GHOST_TUns32 m_fullScreenWidth;
401   /** Full-screen height */
402   GHOST_TUns32 m_fullScreenHeight;
403 
404   /* OSX only, retina screens */
405   float m_nativePixelSize;
406 
407  private:
408   GHOST_Context *m_context;
409 };
410 
getDrawingContextType()411 inline GHOST_TDrawingContextType GHOST_Window::getDrawingContextType()
412 {
413   return m_drawingContextType;
414 }
415 
getCursorVisibility()416 inline bool GHOST_Window::getCursorVisibility() const
417 {
418   return m_cursorVisible;
419 }
420 
getCursorGrabMode()421 inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const
422 {
423   return m_cursorGrab;
424 }
425 
getCursorGrabModeIsWarp()426 inline bool GHOST_Window::getCursorGrabModeIsWarp() const
427 {
428   return (m_cursorGrab == GHOST_kGrabWrap) || (m_cursorGrab == GHOST_kGrabHide);
429 }
430 
getCursorGrabAxis()431 inline GHOST_TAxisFlag GHOST_Window::getCursorGrabAxis() const
432 {
433   return m_cursorGrabAxis;
434 }
435 
getCursorGrabInitPos(GHOST_TInt32 & x,GHOST_TInt32 & y)436 inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
437 {
438   x = m_cursorGrabInitPos[0];
439   y = m_cursorGrabInitPos[1];
440 }
441 
getCursorGrabAccum(GHOST_TInt32 & x,GHOST_TInt32 & y)442 inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
443 {
444   x = m_cursorGrabAccumPos[0];
445   y = m_cursorGrabAccumPos[1];
446 }
447 
setCursorGrabAccum(GHOST_TInt32 x,GHOST_TInt32 y)448 inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
449 {
450   m_cursorGrabAccumPos[0] = x;
451   m_cursorGrabAccumPos[1] = y;
452 }
453 
getCursorShape()454 inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
455 {
456   return m_cursorShape;
457 }
458