Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Lambermont <hans@lambermont.dyndns.org>2002-10-12 15:37:38 +0400
committerHans Lambermont <hans@lambermont.dyndns.org>2002-10-12 15:37:38 +0400
commit12315f4d0e0ae993805f141f64cb8c73c5297311 (patch)
tree59b45827cd8293cfb727758989c7a74b40183974 /intern/ghost
Initial revisionv2.25
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/GHOST_C-api.h733
-rw-r--r--intern/ghost/GHOST_IEvent.h88
-rw-r--r--intern/ghost/GHOST_IEventConsumer.h66
-rw-r--r--intern/ghost/GHOST_ISystem.h282
-rw-r--r--intern/ghost/GHOST_ITimerTask.h88
-rw-r--r--intern/ghost/GHOST_IWindow.h241
-rw-r--r--intern/ghost/GHOST_Rect.h237
-rw-r--r--intern/ghost/GHOST_Types.h354
-rw-r--r--intern/ghost/Makefile52
-rw-r--r--intern/ghost/doc/Doxyfile.win747
-rw-r--r--intern/ghost/intern/GHOST_Buttons.cpp82
-rw-r--r--intern/ghost/intern/GHOST_Buttons.h76
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp778
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.cpp55
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.h77
-rw-r--r--intern/ghost/intern/GHOST_Debug.h74
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp219
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.h142
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp178
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCarbon.h119
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp186
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.h106
-rwxr-xr-xintern/ghost/intern/GHOST_DisplayManagerX11.cpp125
-rwxr-xr-xintern/ghost/intern/GHOST_DisplayManagerX11.h129
-rw-r--r--intern/ghost/intern/GHOST_Event.h114
-rw-r--r--intern/ghost/intern/GHOST_EventButton.h73
-rw-r--r--intern/ghost/intern/GHOST_EventCursor.h74
-rw-r--r--intern/ghost/intern/GHOST_EventKey.h87
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp215
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h157
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.cpp259
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.h70
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp98
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.cpp136
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.h102
-rw-r--r--intern/ghost/intern/GHOST_Rect.cpp140
-rw-r--r--intern/ghost/intern/GHOST_System.cpp320
-rw-r--r--intern/ghost/intern/GHOST_System.h328
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp735
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h251
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h65
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp817
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h278
-rwxr-xr-xintern/ghost/intern/GHOST_SystemX11.cpp803
-rwxr-xr-xintern/ghost/intern/GHOST_SystemX11.h252
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp163
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h133
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h195
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp116
-rw-r--r--intern/ghost/intern/GHOST_Window.h255
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp581
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.h273
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.cpp190
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h165
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp584
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h276
-rwxr-xr-xintern/ghost/intern/GHOST_WindowX11.cpp714
-rwxr-xr-xintern/ghost/intern/GHOST_WindowX11.h292
-rw-r--r--intern/ghost/intern/Makefile65
-rw-r--r--intern/ghost/make/msvc/ghost.dsp576
-rw-r--r--intern/ghost/make/msvc/ghost.dsw58
-rwxr-xr-xintern/ghost/test/Makefile86
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c543
-rwxr-xr-xintern/ghost/test/gears/GHOST_Test.cpp745
-rwxr-xr-xintern/ghost/test/gears/Makefile48
-rw-r--r--intern/ghost/test/make/msvc_6_0/gears.dsp102
-rw-r--r--intern/ghost/test/make/msvc_6_0/gears_C.dsp102
-rw-r--r--intern/ghost/test/make/msvc_6_0/ghost_test.dsw77
-rw-r--r--intern/ghost/test/multitest/Basic.c68
-rw-r--r--intern/ghost/test/multitest/Basic.h44
-rw-r--r--intern/ghost/test/multitest/EventToBuf.c236
-rw-r--r--intern/ghost/test/multitest/EventToBuf.h35
-rw-r--r--intern/ghost/test/multitest/GL.h43
-rw-r--r--intern/ghost/test/multitest/Makefile60
-rwxr-xr-xintern/ghost/test/multitest/MultiTest.c855
-rw-r--r--intern/ghost/test/multitest/ScrollBar.c145
-rw-r--r--intern/ghost/test/multitest/ScrollBar.h56
-rw-r--r--intern/ghost/test/multitest/Util.c73
-rw-r--r--intern/ghost/test/multitest/Util.h35
-rw-r--r--intern/ghost/test/multitest/WindowData.c60
-rw-r--r--intern/ghost/test/multitest/WindowData.h40
81 files changed, 18697 insertions, 0 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
new file mode 100644
index 00000000000..10b986a55b0
--- /dev/null
+++ b/intern/ghost/GHOST_C-api.h
@@ -0,0 +1,733 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef GHOST_C_API_H
+
+#define GHOST_C_API_H
+
+#include "GHOST_Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GHOST_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+GHOST_DECLARE_HANDLE(GHOST_SystemHandle);
+GHOST_DECLARE_HANDLE(GHOST_TimerTaskHandle);
+GHOST_DECLARE_HANDLE(GHOST_WindowHandle);
+GHOST_DECLARE_HANDLE(GHOST_EventHandle);
+GHOST_DECLARE_HANDLE(GHOST_RectangleHandle);
+GHOST_DECLARE_HANDLE(GHOST_EventConsumerHandle);
+
+
+/**
+ * Definition of a callback routine that receives events.
+ * @param event The event received.
+ * @param userdata The callback's user data, supplied to GHOST_CreateSystem.
+ */
+typedef int (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata);
+
+
+/**
+ * Creates the one and only system.
+ * @return a handle to the system.
+ */
+extern GHOST_SystemHandle GHOST_CreateSystem(void);
+
+/**
+ * Disposes the one and only system.
+ * @param systemhandle The handle to the system
+ * @return An indication of success.
+ */
+extern GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle);
+
+
+/**
+ * Creates an event consumer object
+ * @param eventCallback The event callback routine.
+ * @param userdata Pointer to user data returned to the callback routine.
+ */
+extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata);
+
+/**
+ * Disposes an event consumer object
+ * @param consumerhandle Handle to the event consumer.
+ * @return An indication of success.
+ */
+extern GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle);
+
+
+/**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * @param systemhandle The handle to the system
+ * @return The number of milliseconds.
+ */
+extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle);
+
+/**
+ * Installs a timer.
+ * Note that, on most operating systems, messages need to be processed in order
+ * for the timer callbacks to be invoked.
+ * @param systemhandle The handle to the system
+ * @param delay The time to wait for the first call to the timerProc (in milliseconds)
+ * @param interval The interval between calls to the timerProc (in milliseconds)
+ * @param timerProc The callback invoked when the interval expires,
+ * @param userData Placeholder for user data.
+ * @return A timer task (0 if timer task installation failed).
+ */
+extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
+ GHOST_TUns64 delay,
+ GHOST_TUns64 interval,
+ GHOST_TimerProcPtr timerProc,
+ GHOST_TUserDataPtr userData);
+
+/**
+ * Removes a timer.
+ * @param systemhandle The handle to the system
+ * @param timerTask Timer task to be removed.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
+ GHOST_TimerTaskHandle timertaskhandle);
+
+/***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+/**
+ * Returns the number of displays on this system.
+ * @param systemhandle The handle to the system
+ * @return The number of displays.
+ */
+extern GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle);
+
+/**
+ * Returns the dimensions of the main display on this system.
+ * @param systemhandle The handle to the system
+ * @param width A pointer the width gets put in
+ * @param height A pointer the height gets put in
+ * @return void.
+ */
+extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
+ GHOST_TUns32* width,
+ GHOST_TUns32* height);
+
+/**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param systemhandle The handle to the system
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @return A handle to the new window ( == NULL if creation failed).
+ */
+extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
+ char* title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const int stereoVisual);
+
+/**
+ * Returns the window user data.
+ * @param windowhandle The handle to the window
+ * @return The window user data.
+ */
+extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle);
+
+/**
+ * Changes the window user data.
+ * @param windowhandle The handle to the window
+ * @param data The window user data.
+ */
+extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
+ GHOST_TUserDataPtr userdata);
+
+/**
+ * Dispose a window.
+ * @param systemhandle The handle to the system
+ * @param window Handle to the window to be disposed.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle windowhandle);
+
+/**
+ * Returns whether a window is valid.
+ * @param systemhandle The handle to the system
+ * @param window Handle to the window to be checked.
+ * @return Indication of validity.
+ */
+extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle windowhandle);
+
+/**
+ * Begins full screen mode.
+ * @param systemhandle The handle to the system
+ * @param setting The new setting of the display.
+ * @return A handle to the window displayed in full screen.
+ * This window is invalid after full screen has been ended.
+ */
+extern GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
+ GHOST_DisplaySetting* setting,
+ const int stereoVisual);
+
+/**
+ * Ends full screen mode.
+ * @param systemhandle The handle to the system
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle);
+
+/**
+ * Returns current full screen mode status.
+ * @param systemhandle The handle to the system
+ * @return The current status.
+ */
+extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle);
+
+/***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+/**
+ * Retrieves events from the system and stores them in the queue.
+ * @param systemhandle The handle to the system
+ * @param waitForEvent Boolean to indicate that ProcessEvents should
+ * wait (block) until the next event before returning.
+ * @return Indication of the presence of events.
+ */
+extern int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent);
+
+/**
+ * Retrieves events from the queue and send them to the event consumers.
+ * @param systemhandle The handle to the system
+ * @return Indication of the presence of events.
+ */
+extern int GHOST_DispatchEvents(GHOST_SystemHandle systemhandle);
+
+/**
+ * Adds the given event consumer to our list.
+ * @param systemhandle The handle to the system
+ * @param consumerhandle The event consumer to add.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle,
+ GHOST_EventConsumerHandle consumerhandle);
+
+
+
+/***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+/**
+ * Returns the current cursor shape.
+ * @param windowhandle The handle to the window
+ * @return The current cursor shape.
+ */
+extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle);
+
+/**
+ * Set the shape of the cursor.
+ * @param windowhandle The handle to the window
+ * @param cursor The new cursor shape type id.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
+ GHOST_TStandardCursor cursorshape);
+
+/**
+ * Set the shape of the cursor to a custom cursor.
+ * @param windowhandle The handle to the window
+ * @param bitmap The bitmap data for the cursor.
+ * @param mask The mask data for the cursor.
+ * @param hotX The X coordinate of the cursor hotspot.
+ * @param hotY The Y coordinate of the cursor hotspot.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
+ GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+/**
+ * Returns the visibility state of the cursor.
+ * @param windowhandle The handle to the window
+ * @return The visibility state of the cursor.
+ */
+extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
+
+/**
+ * Shows or hides the cursor.
+ * @param windowhandle The handle to the window
+ * @param visible The new visibility state of the cursor.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle,
+ int visible);
+
+/**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * @param systemhandle The handle to the system
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
+ GHOST_TInt32* x,
+ GHOST_TInt32* y);
+
+/**
+ * Updates the location of the cursor (location in screen coordinates).
+ * Not all operating systems allow the cursor to be moved (without the input device being moved).
+ * @param systemhandle The handle to the system
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y);
+
+/***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+/**
+ * Returns the state of a modifier key (ouside the message queue).
+ * @param systemhandle The handle to the system
+ * @param mask The modifier key state to retrieve.
+ * @param isDown Pointer to return modifier state in.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
+ GHOST_TModifierKeyMask mask,
+ int* isDown);
+
+/**
+ * Returns the state of a mouse button (ouside the message queue).
+ * @param systemhandle The handle to the system
+ * @param mask The button state to retrieve.
+ * @param isDown Pointer to return button state in.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
+ GHOST_TButtonMask mask,
+ int* isDown);
+
+/**
+ * Returns the event type.
+ * @param eventhandle The handle to the event
+ * @return The event type.
+ */
+extern GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle);
+
+/**
+ * Returns the time this event was generated.
+ * @param eventhandle The handle to the event
+ * @return The event generation time.
+ */
+extern GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle);
+
+/**
+ * Returns the window this event was generated on,
+ * or NULL if it is a 'system' event.
+ * @param eventhandle The handle to the event
+ * @return The generating window.
+ */
+extern GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle);
+
+/**
+ * Returns the event data.
+ * @param eventhandle The handle to the event
+ * @return The event data.
+ */
+extern GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle);
+
+/**
+ * Returns the timer callback.
+ * @param timertaskhandle The handle to the timertask
+ * @return The timer callback.
+ */
+extern GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle);
+
+/**
+ * Changes the timer callback.
+ * @param timertaskhandle The handle to the timertask
+ * @param timerProc The timer callback.
+ */
+extern void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle,
+ GHOST_TimerProcPtr timerProc);
+
+/**
+ * Returns the timer user data.
+ * @param timertaskhandle The handle to the timertask
+ * @return The timer user data.
+ */
+extern GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle);
+
+/**
+ * Changes the time user data.
+ * @param timertaskhandle The handle to the timertask
+ * @param data The timer user data.
+ */
+extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
+ GHOST_TUserDataPtr userData);
+
+/**
+ * Returns indication as to whether the window is valid.
+ * @param windowhandle The handle to the window
+ * @return The validity of the window.
+ */
+extern int GHOST_GetValid(GHOST_WindowHandle windowhandle) ;
+
+/**
+ * Returns the type of drawing context used in this window.
+ * @param windowhandle The handle to the window
+ * @return The current type of drawing context.
+ */
+extern GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle);
+
+/**
+ * Tries to install a rendering context in this window.
+ * @param windowhandle The handle to the window
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+extern GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,
+ GHOST_TDrawingContextType type);
+
+/**
+ * Sets the title displayed in the title bar.
+ * @param windowhandle The handle to the window
+ * @param title The title to display in the title bar.
+ */
+extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
+ char* title);
+
+/**
+ * Returns the title displayed in the title bar. The title
+ * should be free'd with free().
+ *
+ * @param windowhandle The handle to the window
+ * @return The title, free with free().
+ */
+extern char* GHOST_GetTitle(GHOST_WindowHandle windowhandle);
+
+/**
+ * Returns the window rectangle dimensions.
+ * These are screen coordinates.
+ * @param windowhandle The handle to the window
+ * @return A handle to the bounding rectangle of the window.
+ */
+extern GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle);
+
+/**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * @param windowhandle The handle to the window
+ * @return A handle to the bounding rectangle of the window.
+ */
+extern GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle);
+
+/**
+ * Disposes a rectangle object
+ * @param rectanglehandle Handle to the rectangle.
+ */
+void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle);
+
+/**
+ * Resizes client rectangle width.
+ * @param windowhandle The handle to the window
+ * @param width The new width of the client area of the window.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 width);
+
+/**
+ * Resizes client rectangle height.
+ * @param windowhandle The handle to the window
+ * @param height The new height of the client area of the window.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 height);
+
+/**
+ * Resizes client rectangle.
+ * @param windowhandle The handle to the window
+ * @param width The new width of the client area of the window.
+ * @param height The new height of the client area of the window.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height);
+
+/**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param windowhandle The handle to the window
+ * @param inX The x-coordinate on the screen.
+ * @param inY The y-coordinate on the screen.
+ * @param outX The x-coordinate in the client rectangle.
+ * @param outY The y-coordinate in the client rectangle.
+ */
+extern void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32* outX,
+ GHOST_TInt32* outY) ;
+
+/**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param windowhandle The handle to the window
+ * @param inX The x-coordinate in the client rectangle.
+ * @param inY The y-coordinate in the client rectangle.
+ * @param outX The x-coordinate on the screen.
+ * @param outY The y-coordinate on the screen.
+ */
+extern void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32* outX,
+ GHOST_TInt32* outY);
+
+/**
+ * Returns the state of the window (normal, minimized, maximized).
+ * @param windowhandle The handle to the window
+ * @return The state of the window.
+ */
+extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle);
+
+/**
+ * Sets the state of the window (normal, minimized, maximized).
+ * @param windowhandle The handle to the window
+ * @param state The state of the window.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
+ GHOST_TWindowState state);
+
+/**
+ * Sets the order of the window (bottom, top).
+ * @param windowhandle The handle to the window
+ * @param order The order of the window.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
+ GHOST_TWindowOrder order);
+
+/**
+ * Swaps front and back buffers of a window.
+ * @param windowhandle The handle to the window
+ * @return An intean success indicator.
+ */
+extern GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle);
+
+/**
+ * Activates the drawing context of this window.
+ * @param windowhandle The handle to the window
+ * @return An intean success indicator.
+ */
+extern GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle);
+
+/**
+ * Invalidates the contents of this window.
+ * @param windowhandle The handle to the window
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle);
+
+/**
+ * Access to rectangle width.
+ * @param rectanglehandle The handle to the rectangle
+ * @return width of the rectangle
+ */
+extern GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle);
+
+/**
+ * Access to rectangle height.
+ * @param rectanglehandle The handle to the rectangle
+ * @return height of the rectangle
+ */
+extern GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle);
+
+/**
+ * Gets all members of the rectangle.
+ * @param rectanglehandle The handle to the rectangle
+ * @param l Pointer to return left coordinate in.
+ * @param t Pointer to return top coordinate in.
+ * @param r Pointer to return right coordinate in.
+ * @param b Pointer to return bottom coordinate in.
+ */
+extern void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32* l,
+ GHOST_TInt32* t,
+ GHOST_TInt32* r,
+ GHOST_TInt32* b);
+
+/**
+ * Sets all members of the rectangle.
+ * @param rectanglehandle The handle to the rectangle
+ * @param l requested left coordinate of the rectangle
+ * @param t requested top coordinate of the rectangle
+ * @param r requested right coordinate of the rectangle
+ * @param b requested bottom coordinate of the rectangle
+ */
+extern void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 l,
+ GHOST_TInt32 t,
+ GHOST_TInt32 r,
+ GHOST_TInt32 b);
+
+/**
+ * Returns whether this rectangle is empty.
+ * Empty rectangles are rectangles that have width==0 and/or height==0.
+ * @param rectanglehandle The handle to the rectangle
+ * @return intean value (true == empty rectangle)
+ */
+extern GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle);
+
+/**
+ * Returns whether this rectangle is valid.
+ * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. Thus, emapty rectangles are valid.
+ * @param rectanglehandle The handle to the rectangle
+ * @return intean value (true==valid rectangle)
+ */
+extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle);
+
+/**
+ * Grows (or shrinks the rectangle).
+ * The method avoids negative insets making the rectangle invalid
+ * @param rectanglehandle The handle to the rectangle
+ * @param i The amount of offset given to each extreme (negative values shrink the rectangle).
+ */
+extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 i);
+
+/**
+ * Does a union of the rectangle given and this rectangle.
+ * The result is stored in this rectangle.
+ * @param rectanglehandle The handle to the rectangle
+ * @param r The rectangle that is input for the union operation.
+ */
+extern void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle);
+
+/**
+ * Grows the rectangle to included a point.
+ * @param rectanglehandle The handle to the rectangle
+ * @param x The x-coordinate of the point.
+ * @param y The y-coordinate of the point.
+ */
+extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y);
+
+/**
+ * Returns whether the point is inside this rectangle.
+ * Point on the boundary is considered inside.
+ * @param rectanglehandle The handle to the rectangle
+ * @param x x-coordinate of point to test.
+ * @param y y-coordinate of point to test.
+ * @return intean value (true if point is inside).
+ */
+extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y);
+
+/**
+ * Returns whether the rectangle is inside this rectangle.
+ * @param rectanglehandle The handle to the rectangle
+ * @param r rectangle to test.
+ * @return visibility (not, partially or fully visible).
+ */
+extern GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle);
+
+/**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location.
+ * @param rectanglehandle The handle to the rectangle
+ * @param cx requested center x-coordinate of the rectangle
+ * @param cy requested center y-coordinate of the rectangle
+ */
+extern void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 cx,
+ GHOST_TInt32 cy);
+
+/**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location,
+ * with the width requested.
+ * @param rectanglehandle The handle to the rectangle
+ * @param cx requested center x-coordinate of the rectangle
+ * @param cy requested center y-coordinate of the rectangle
+ * @param w requested width of the rectangle
+ * @param h requested height of the rectangle
+ */
+extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 cx,
+ GHOST_TInt32 cy,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h);
+
+/**
+ * Clips a rectangle.
+ * Updates the rectangle given such that it will fit within this one.
+ * This can result in an empty rectangle.
+ * @param rectanglehandle The handle to the rectangle
+ * @param r the rectangle to clip
+ * @return whether clipping has occurred
+ */
+extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h
new file mode 100644
index 00000000000..ba901708e84
--- /dev/null
+++ b/intern/ghost/GHOST_IEvent.h
@@ -0,0 +1,88 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#ifndef _GHOST_IEVENT_H_
+#define _GHOST_IEVENT_H_
+
+#include "GHOST_Types.h"
+
+class GHOST_IWindow;
+
+/**
+ * Interface class for events received the operating system.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+class GHOST_IEvent
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IEvent()
+ {
+ }
+
+ /**
+ * Returns the event type.
+ * @return The event type.
+ */
+ virtual GHOST_TEventType getType() = 0;
+
+ /**
+ * Returns the time this event was generated.
+ * @return The event generation time.
+ */
+ virtual GHOST_TUns64 getTime() = 0;
+
+ /**
+ * Returns the window this event was generated on,
+ * or NULL if it is a 'system' event.
+ * @return The generating window.
+ */
+ virtual GHOST_IWindow* getWindow() = 0;
+
+ /**
+ * Returns the event data.
+ * @return The event data.
+ */
+ virtual GHOST_TEventDataPtr getData() = 0;
+};
+
+#endif // _GHOST_IEVENT_H_
diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h
new file mode 100644
index 00000000000..7234beff777
--- /dev/null
+++ b/intern/ghost/GHOST_IEventConsumer.h
@@ -0,0 +1,66 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 14, 2001
+ */
+
+#ifndef _GHOST_IEVENT_CONSUMER_H_
+#define _GHOST_IEVENT_CONSUMER_H_
+
+#include "GHOST_IEvent.h"
+
+/**
+ * Interface class for objects interested in receiving events.
+ */
+class GHOST_IEventConsumer
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IEventConsumer()
+ {
+ }
+
+ /**
+ * This method is called by an event producer when an event is available.
+ * @param event The event that can be handled or ignored.
+ * @return Indication as to whether the event was handled.
+ */
+ virtual bool processEvent(GHOST_IEvent* event) = 0;
+};
+
+#endif // _GHOST_EVENT_CONSUMER_H_
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
new file mode 100644
index 00000000000..3c3398408f0
--- /dev/null
+++ b/intern/ghost/GHOST_ISystem.h
@@ -0,0 +1,282 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 30, 2001
+ */
+
+#ifndef _GHOST_ISYSTEM_H_
+#define _GHOST_ISYSTEM_H_
+
+#include "GHOST_Types.h"
+#include "GHOST_ITimerTask.h"
+#include "GHOST_IWindow.h"
+
+class GHOST_IEventConsumer;
+
+/**
+ * Interface for classes that provide access to the operating system.
+ * There should be only one system class in an application.
+ * Therefore, the routines to create and dispose the system are static.
+ * Provides:
+ * 1. Time(r) management.
+ * 2. Display/window management (windows are only created on the main display for now).
+ * 3. Event management.
+ * 4. Access to the state of the mouse buttons and the keyboard.
+ * @author Maarten Gribnau
+ * @date May 30, 2001
+ */
+
+class GHOST_ISystem
+{
+public:
+ /**
+ * Creates the one and only system.
+ * @return An indication of success.
+ */
+ static GHOST_TSuccess createSystem();
+
+ /**
+ * Disposes the one and only system.
+ * @return An indication of success.
+ */
+ static GHOST_TSuccess disposeSystem();
+
+ /**
+ * Returns a pointer to the one and only system (nil if it hasn't been created).
+ * @return A pointer to the system.
+ */
+ static GHOST_ISystem* getSystem();
+
+protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_ISystem() {}
+
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_ISystem() {}
+
+public:
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * @return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const = 0;
+
+ /**
+ * Installs a timer.
+ * Note that, on most operating systems, messages need to be processed in order
+ * for the timer callbacks to be invoked.
+ * @param delay The time to wait for the first call to the timerProc (in milliseconds)
+ * @param interval The interval between calls to the timerProc (in milliseconds)
+ * @param timerProc The callback invoked when the interval expires,
+ * @param userData Placeholder for user data.
+ * @return A timer task (0 if timer task installation failed).
+ */
+ virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0) = 0;
+
+ /**
+ * Removes a timer.
+ * @param timerTask Timer task to be removed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask* timerTask) = 0;
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * @return The number of displays.
+ */
+ virtual GHOST_TUns8 getNumDisplays() const = 0;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Create a stereo visual for quad buffered stereo.
+ * @return The new window (or 0 if creation failed).
+ */
+ virtual GHOST_IWindow* createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
+ GHOST_TWindowState state, GHOST_TDrawingContextType type,
+ const bool stereoVisual) = 0;
+
+ /**
+ * Dispose a window.
+ * @param window Pointer to the window to be disposed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess disposeWindow(GHOST_IWindow* window) = 0;
+
+ /**
+ * Returns whether a window is valid.
+ * @param window Pointer to the window to be checked.
+ * @return Indication of validity.
+ */
+ virtual bool validWindow(GHOST_IWindow* window) = 0;
+
+ /**
+ * Begins full screen mode.
+ * @param setting The new setting of the display.
+ * @param window Window displayed in full screen.
+ * This window is invalid after full screen has been ended.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
+ const bool stereoVisual) = 0;
+
+ /**
+ * Ends full screen mode.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess endFullScreen(void) = 0;
+
+ /**
+ * Returns current full screen mode status.
+ * @return The current status.
+ */
+ virtual bool getFullScreen(void) = 0;
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Retrieves events from the system and stores them in the queue.
+ * @param waitForEvent Flag to wait for an event (or return immediately).
+ * @return Indication of the presence of events.
+ */
+ virtual bool processEvents(bool waitForEvent) = 0;
+
+ /**
+ * Retrieves events from the queue and send them to the event consumers.
+ * @return Indication of the presence of events.
+ */
+ virtual bool dispatchEvents() = 0;
+
+ /**
+ * Adds the given event consumer to our list.
+ * @param consumer The event consumer to add.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer* consumer) = 0;
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * Not all operating systems allow the cursor to be moved (without the input device being moved).
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const = 0;
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of a modifier key (ouside the message queue).
+ * @param mask The modifier key state to retrieve.
+ * @param isDown The state of a modifier key (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const = 0;
+
+ /**
+ * Returns the state of a mouse button (ouside the message queue).
+ * @param mask The button state to retrieve.
+ * @param isDown Button state.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
+
+protected:
+ /**
+ * Initialize the system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess init() = 0;
+
+ /**
+ * Shut the system down.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess exit() = 0;
+
+ /** The one and only system */
+ static GHOST_ISystem* m_system;
+};
+
+#endif // _GHOST_ISYSTEM_H_
diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h
new file mode 100644
index 00000000000..354652017d9
--- /dev/null
+++ b/intern/ghost/GHOST_ITimerTask.h
@@ -0,0 +1,88 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#ifndef _GHOST_ITIMER_TASK_H_
+#define _GHOST_ITIMER_TASK_H_
+
+
+#include "GHOST_Types.h"
+
+
+/**
+ * Interface for a timer task.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+class GHOST_ITimerTask
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_ITimerTask()
+ {
+ }
+
+ /**
+ * Returns the timer callback.
+ * @return The timer callback.
+ */
+ inline virtual GHOST_TimerProcPtr getTimerProc() const = 0;
+
+ /**
+ * Changes the timer callback.
+ * @param timerProc The timer callback.
+ */
+ inline virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0;
+
+ /**
+ * Returns the timer user data.
+ * @return The timer user data.
+ */
+ inline virtual GHOST_TUserDataPtr getUserData() const = 0;
+
+ /**
+ * Changes the time user data.
+ * @param data The timer user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+};
+
+
+#endif // _GHOST_ITIMER_TASK_H_
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
new file mode 100644
index 00000000000..8f41345ec5f
--- /dev/null
+++ b/intern/ghost/GHOST_IWindow.h
@@ -0,0 +1,241 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#ifndef _GHOST_IWINDOW_H_
+#define _GHOST_IWINDOW_H_
+
+#include "STR_String.h"
+#include "GHOST_Rect.h"
+#include "GHOST_Types.h"
+
+
+/**
+ * Interface for GHOST windows.
+ * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+class GHOST_IWindow
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IWindow()
+ {
+ }
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * @return The validity of the window.
+ */
+ virtual bool getValid() const = 0;
+
+ /**
+ * Returns the type of drawing context used in this window.
+ * @return The current type of drawing context.
+ */
+ inline virtual GHOST_TDrawingContextType getDrawingContextType() = 0;
+
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) = 0;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * @param title The title to display in the title bar.
+ */
+ virtual void setTitle(const STR_String& title) = 0;
+
+ /**
+ * Returns the title displayed in the title bar.
+ * @param title The title displayed in the title bar.
+ */
+ virtual void getTitle(STR_String& title) const = 0;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * These are screen coordinates.
+ * @param bounds The bounding rectangle of the window.
+ */
+ virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * @param bounds The bounding rectangle of the client area of the window.
+ */
+ virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
+
+ /**
+ * Resizes client rectangle width.
+ * @param width The new width of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
+
+ /**
+ * Resizes client rectangle height.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
+
+ /**
+ * Resizes client rectangle.
+ * @param width The new width of the client area of the window.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate on the screen.
+ * @param inY The y-coordinate on the screen.
+ * @param outX The x-coordinate in the client rectangle.
+ * @param outY The y-coordinate in the client rectangle.
+ */
+ virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate in the client rectangle.
+ * @param inY The y-coordinate in the client rectangle.
+ * @param outX The x-coordinate on the screen.
+ * @param outY The y-coordinate on the screen.
+ */
+ virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * @return The state of the window.
+ */
+ virtual GHOST_TWindowState getState() const = 0;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * @param state The state of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * @param order The order of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
+
+ /**
+ * Swaps front and back buffers of a window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers() = 0;
+
+ /**
+ * Activates the drawing context of this window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext() = 0;
+
+ /**
+ * Invalidates the contents of this window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess invalidate() = 0;
+
+ /**
+ * Returns the window user data.
+ * @return The window user data.
+ */
+ inline virtual GHOST_TUserDataPtr getUserData() const = 0;
+
+ /**
+ * Changes the window user data.
+ * @param data The window user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current cursor shape.
+ * @return The current cursor shape.
+ */
+ virtual GHOST_TStandardCursor getCursorShape() const = 0;
+
+ /**
+ * Set the shape of the cursor.
+ * @param cursor The new cursor shape type id.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0;
+
+ /**
+ * Set the shape of the cursor to a custom cursor.
+ * @param bitmap The bitmap data for the cursor.
+ * @param mask The mask data for the cursor.
+ * @param hotX The X coordinate of the cursor hotspot.
+ * @param hotY The Y coordinate of the cursor hotspot.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY) = 0;
+
+ /**
+ * Returns the visibility state of the cursor.
+ * @return The visibility state of the cursor.
+ */
+ virtual bool getCursorVisibility() const = 0;
+
+ /**
+ * Shows or hides the cursor.
+ * @param visible The new visibility state of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
+};
+
+#endif // _GHOST_IWINDOW_H_
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
new file mode 100644
index 00000000000..c8cfc79ea9d
--- /dev/null
+++ b/intern/ghost/GHOST_Rect.h
@@ -0,0 +1,237 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _H_GHOST_Rect
+#define _H_GHOST_Rect
+
+#include "GHOST_Types.h"
+
+
+/**
+ * Implements rectangle functionality.
+ * The four extreme coordinates are stored as left, top, right and bottom.
+ * To be valid, a rectangle should have a left coordinate smaller than or equal to right.
+ * To be valid, a rectangle should have a top coordinate smaller than or equal to bottom.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+class GHOST_Rect {
+public:
+
+ /**
+ * Constructs a rectangle with the given values.
+ * @param l requested left coordinate of the rectangle
+ * @param t requested top coordinate of the rectangle
+ * @param r requested right coordinate of the rectangle
+ * @param b requested bottom coordinate of the rectangle
+ */
+ GHOST_Rect(GHOST_TInt32 l=0, GHOST_TInt32 t=0, GHOST_TInt32 r=0, GHOST_TInt32 b=0)
+ : m_l(l), m_t(t), m_r(r), m_b(b) {}
+
+ /**
+ * Copy constructor.
+ * @param r rectangle to copy
+ */
+ GHOST_Rect(const GHOST_Rect& r)
+ : m_l(r.m_l), m_t(r.m_t), m_r(r.m_r), m_b(r.m_b) {}
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_Rect() {};
+
+ /**
+ * Access to rectangle width.
+ * @return width of the rectangle
+ */
+ virtual inline GHOST_TInt32 getWidth() const;
+
+ /**
+ * Access to rectangle height.
+ * @return height of the rectangle
+ */
+ virtual inline GHOST_TInt32 getHeight() const;
+
+ /**
+ * Sets all members of the rectangle.
+ * @param l requested left coordinate of the rectangle
+ * @param t requested top coordinate of the rectangle
+ * @param r requested right coordinate of the rectangle
+ * @param b requested bottom coordinate of the rectangle
+ */
+ virtual inline void set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b);
+
+ /**
+ * Returns whether this rectangle is empty.
+ * Empty rectangles are rectangles that have width==0 and/or height==0.
+ * @return boolean value (true==empty rectangle)
+ */
+ virtual inline bool isEmpty() const;
+
+ /**
+ * Returns whether this rectangle is valid.
+ * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. Thus, emapty rectangles are valid.
+ * @return boolean value (true==valid rectangle)
+ */
+ virtual inline bool isValid() const;
+
+ /**
+ * Grows (or shrinks the rectangle).
+ * The method avoids negative insets making the rectangle invalid
+ * @param i The amount of offset given to each extreme (negative values shrink the rectangle).
+ */
+ virtual void inset(GHOST_TInt32 i);
+
+ /**
+ * Does a union of the rectangle given and this rectangle.
+ * The result is stored in this rectangle.
+ * @param r The rectangle that is input for the union operation.
+ */
+ virtual inline void unionRect(const GHOST_Rect& r);
+
+ /**
+ * Grows the rectangle to included a point.
+ * @param x The x-coordinate of the point.
+ * @param y The y-coordinate of the point.
+ */
+ virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /**
+ * Returns whether the point is inside this rectangle.
+ * Point on the boundary is considered inside.
+ * @param x x-coordinate of point to test.
+ * @param y y-coordinate of point to test.
+ * @return boolean value (true if point is inside).
+ */
+ virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+ /**
+ * Returns whether the rectangle is inside this rectangle.
+ * @param r rectangle to test.
+ * @return visibility (not, partially or fully visible).
+ */
+ virtual GHOST_TVisibility getVisibility(GHOST_Rect& r) const;
+
+ /**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location.
+ * @param cx requested center x-coordinate of the rectangle
+ * @param cy requested center y-coordinate of the rectangle
+ */
+ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy);
+
+ /**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location,
+ * with the width requested.
+ * @param cx requested center x-coordinate of the rectangle
+ * @param cy requested center y-coordinate of the rectangle
+ * @param w requested width of the rectangle
+ * @param h requested height of the rectangle
+ */
+ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h);
+
+ /**
+ * Clips a rectangle.
+ * Updates the rectangle given such that it will fit within this one.
+ * This can result in an empty rectangle.
+ * @param r the rectangle to clip
+ * @return whether clipping has occurred
+ */
+ virtual bool clip(GHOST_Rect& r) const;
+
+ /** Left coordinate of the rectangle */
+ GHOST_TInt32 m_l;
+ /** Top coordinate of the rectangle */
+ GHOST_TInt32 m_t;
+ /** Right coordinate of the rectangle */
+ GHOST_TInt32 m_r;
+ /** Bottom coordinate of the rectangle */
+ GHOST_TInt32 m_b;
+};
+
+
+inline GHOST_TInt32 GHOST_Rect::getWidth() const
+{
+ return m_r - m_l;
+}
+
+inline GHOST_TInt32 GHOST_Rect::getHeight() const
+{
+ return m_b - m_t;
+}
+
+inline void GHOST_Rect::set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b)
+{
+ m_l = l; m_t = t; m_r = r; m_b = b;
+}
+
+inline bool GHOST_Rect::isEmpty() const
+{
+ return (getWidth() == 0) || (getHeight() == 0);
+}
+
+inline bool GHOST_Rect::isValid() const
+{
+ return (m_l <= m_r) && (m_t <= m_b);
+}
+
+inline void GHOST_Rect::unionRect(const GHOST_Rect& r)
+{
+ if (r.m_l < m_l) m_l = r.m_l;
+ if (r.m_r > m_r) m_r = r.m_r;
+ if (r.m_t < m_t) m_t = r.m_t;
+ if (r.m_b > m_b) m_b = r.m_b;
+}
+
+inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y)
+{
+ if (x < m_l) m_l = x;
+ if (x > m_r) m_r = x;
+ if (y < m_t) m_t = y;
+ if (y > m_b) m_b = y;
+}
+
+inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
+{
+ return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
+}
+
+#endif // _H_GHOST_Rect
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
new file mode 100644
index 00000000000..c7b8f3b19e0
--- /dev/null
+++ b/intern/ghost/GHOST_Types.h
@@ -0,0 +1,354 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#ifndef _GHOST_TYPES_H_
+#define _GHOST_TYPES_H_
+
+typedef char GHOST_TInt8;
+typedef unsigned char GHOST_TUns8;
+typedef short GHOST_TInt16;
+typedef unsigned short GHOST_TUns16;
+typedef int GHOST_TInt32;
+typedef unsigned int GHOST_TUns32;
+
+#ifdef WIN32
+typedef __int64 GHOST_TInt64;
+typedef unsigned __int64 GHOST_TUns64;
+#else
+typedef long long GHOST_TInt64;
+typedef unsigned long long GHOST_TUns64;
+#endif
+
+typedef void* GHOST_TUserDataPtr;
+
+typedef enum
+{
+ GHOST_kFailure = 0,
+ GHOST_kSuccess
+} GHOST_TSuccess;
+
+
+typedef enum {
+ GHOST_kNotVisible = 0,
+ GHOST_kPartiallyVisible,
+ GHOST_kFullyVisible
+} GHOST_TVisibility;
+
+
+typedef enum {
+ GHOST_kFireTimeNever = 0xFFFFFFFF
+} GHOST_TFireTimeConstant;
+
+typedef enum {
+ GHOST_kModifierKeyLeftShift = 0,
+ GHOST_kModifierKeyRightShift,
+ GHOST_kModifierKeyLeftAlt,
+ GHOST_kModifierKeyRightAlt,
+ GHOST_kModifierKeyLeftControl,
+ GHOST_kModifierKeyRightControl,
+ GHOST_kModifierKeyCommand, // APPLE only
+ GHOST_kModifierKeyNumMasks
+} GHOST_TModifierKeyMask;
+
+
+typedef enum {
+ GHOST_kWindowStateNormal = 0,
+ GHOST_kWindowStateMaximized,
+ GHOST_kWindowStateMinimized,
+ GHOST_kWindowStateFullScreen
+} GHOST_TWindowState;
+
+
+typedef enum {
+ GHOST_kWindowOrderTop = 0,
+ GHOST_kWindowOrderBottom
+} GHOST_TWindowOrder;
+
+
+typedef enum {
+ GHOST_kDrawingContextTypeNone = 0,
+ GHOST_kDrawingContextTypeOpenGL
+} GHOST_TDrawingContextType;
+
+
+typedef enum {
+ GHOST_kButtonMaskLeft = 0,
+ GHOST_kButtonMaskMiddle,
+ GHOST_kButtonMaskRight,
+ GHOST_kButtonNumMasks
+} GHOST_TButtonMask;
+
+
+typedef enum {
+ GHOST_kEventUnknown = 0,
+
+ GHOST_kEventCursorMove,
+ GHOST_kEventButtonDown,
+ GHOST_kEventButtonUp,
+
+ GHOST_kEventKeyDown,
+ GHOST_kEventKeyUp,
+// GHOST_kEventKeyAuto,
+
+ GHOST_kEventQuit,
+
+ GHOST_kEventWindowClose,
+ GHOST_kEventWindowActivate,
+ GHOST_kEventWindowDeactivate,
+ GHOST_kEventWindowUpdate,
+ GHOST_kEventWindowSize,
+
+ GHOST_kNumEventTypes
+} GHOST_TEventType;
+
+
+typedef enum {
+ GHOST_kStandardCursorFirstCursor = 0,
+ GHOST_kStandardCursorDefault = 0,
+ GHOST_kStandardCursorRightArrow,
+ GHOST_kStandardCursorLeftArrow,
+ GHOST_kStandardCursorInfo,
+ GHOST_kStandardCursorDestroy,
+ GHOST_kStandardCursorHelp,
+ GHOST_kStandardCursorCycle,
+ GHOST_kStandardCursorSpray,
+ GHOST_kStandardCursorWait,
+ GHOST_kStandardCursorText,
+ GHOST_kStandardCursorCrosshair,
+ GHOST_kStandardCursorUpDown,
+ GHOST_kStandardCursorLeftRight,
+ GHOST_kStandardCursorTopSide,
+ GHOST_kStandardCursorBottomSide,
+ GHOST_kStandardCursorLeftSide,
+ GHOST_kStandardCursorRightSide,
+ GHOST_kStandardCursorTopLeftCorner,
+ GHOST_kStandardCursorTopRightCorner,
+ GHOST_kStandardCursorBottomRightCorner,
+ GHOST_kStandardCursorBottomLeftCorner,
+ GHOST_kStandardCursorCustom,
+ GHOST_kStandardCursorNumCursors
+} GHOST_TStandardCursor;
+
+
+typedef enum {
+ GHOST_kKeyUnknown = -1,
+ GHOST_kKeyBackSpace,
+ GHOST_kKeyTab,
+ GHOST_kKeyLinefeed,
+ GHOST_kKeyClear,
+ GHOST_kKeyEnter = 0x0D,
+
+ GHOST_kKeyEsc = 0x1B,
+ GHOST_kKeySpace = ' ',
+ GHOST_kKeyQuote = 0x27,
+ GHOST_kKeyComma = ',',
+ GHOST_kKeyMinus = '-',
+ GHOST_kKeyPeriod = '.',
+ GHOST_kKeySlash = '/',
+
+ // Number keys
+ GHOST_kKey0 = '0',
+ GHOST_kKey1,
+ GHOST_kKey2,
+ GHOST_kKey3,
+ GHOST_kKey4,
+ GHOST_kKey5,
+ GHOST_kKey6,
+ GHOST_kKey7,
+ GHOST_kKey8,
+ GHOST_kKey9,
+
+ GHOST_kKeySemicolon = ';',
+ GHOST_kKeyEqual = '=',
+
+ // Character keys
+ GHOST_kKeyA = 'A',
+ GHOST_kKeyB,
+ GHOST_kKeyC,
+ GHOST_kKeyD,
+ GHOST_kKeyE,
+ GHOST_kKeyF,
+ GHOST_kKeyG,
+ GHOST_kKeyH,
+ GHOST_kKeyI,
+ GHOST_kKeyJ,
+ GHOST_kKeyK,
+ GHOST_kKeyL,
+ GHOST_kKeyM,
+ GHOST_kKeyN,
+ GHOST_kKeyO,
+ GHOST_kKeyP,
+ GHOST_kKeyQ,
+ GHOST_kKeyR,
+ GHOST_kKeyS,
+ GHOST_kKeyT,
+ GHOST_kKeyU,
+ GHOST_kKeyV,
+ GHOST_kKeyW,
+ GHOST_kKeyX,
+ GHOST_kKeyY,
+ GHOST_kKeyZ,
+
+ GHOST_kKeyLeftBracket = '[',
+ GHOST_kKeyRightBracket = ']',
+ GHOST_kKeyBackslash = 0x5C,
+ GHOST_kKeyAccentGrave = '`',
+
+
+ GHOST_kKeyLeftShift = 0x100,
+ GHOST_kKeyRightShift,
+ GHOST_kKeyLeftControl,
+ GHOST_kKeyRightControl,
+ GHOST_kKeyLeftAlt,
+ GHOST_kKeyRightAlt,
+ GHOST_kKeyCommand, // APPLE only!
+
+ GHOST_kKeyCapsLock,
+ GHOST_kKeyNumLock,
+ GHOST_kKeyScrollLock,
+
+ GHOST_kKeyLeftArrow,
+ GHOST_kKeyRightArrow,
+ GHOST_kKeyUpArrow,
+ GHOST_kKeyDownArrow,
+
+ GHOST_kKeyPrintScreen,
+ GHOST_kKeyPause,
+
+ GHOST_kKeyInsert,
+ GHOST_kKeyDelete,
+ GHOST_kKeyHome,
+ GHOST_kKeyEnd,
+ GHOST_kKeyUpPage,
+ GHOST_kKeyDownPage,
+
+ // Numpad keys
+ GHOST_kKeyNumpad0,
+ GHOST_kKeyNumpad1,
+ GHOST_kKeyNumpad2,
+ GHOST_kKeyNumpad3,
+ GHOST_kKeyNumpad4,
+ GHOST_kKeyNumpad5,
+ GHOST_kKeyNumpad6,
+ GHOST_kKeyNumpad7,
+ GHOST_kKeyNumpad8,
+ GHOST_kKeyNumpad9,
+ GHOST_kKeyNumpadPeriod,
+ GHOST_kKeyNumpadEnter,
+ GHOST_kKeyNumpadPlus,
+ GHOST_kKeyNumpadMinus,
+ GHOST_kKeyNumpadAsterisk,
+ GHOST_kKeyNumpadSlash,
+
+ // Function keys
+ GHOST_kKeyF1,
+ GHOST_kKeyF2,
+ GHOST_kKeyF3,
+ GHOST_kKeyF4,
+ GHOST_kKeyF5,
+ GHOST_kKeyF6,
+ GHOST_kKeyF7,
+ GHOST_kKeyF8,
+ GHOST_kKeyF9,
+ GHOST_kKeyF10,
+ GHOST_kKeyF11,
+ GHOST_kKeyF12,
+ GHOST_kKeyF13,
+ GHOST_kKeyF14,
+ GHOST_kKeyF15,
+ GHOST_kKeyF16,
+ GHOST_kKeyF17,
+ GHOST_kKeyF18,
+ GHOST_kKeyF19,
+ GHOST_kKeyF20,
+ GHOST_kKeyF21,
+ GHOST_kKeyF22,
+ GHOST_kKeyF23,
+ GHOST_kKeyF24
+} GHOST_TKey;
+
+
+typedef void* GHOST_TEventDataPtr;
+
+typedef struct {
+ /** The x-coordinate of the cursor position. */
+ GHOST_TInt32 x;
+ /** The y-coordinate of the cursor position. */
+ GHOST_TInt32 y;
+} GHOST_TEventCursorData;
+
+typedef struct {
+ /** The mask of the mouse button. */
+ GHOST_TButtonMask button;
+} GHOST_TEventButtonData;
+
+typedef struct {
+ /** The key code. */
+ GHOST_TKey key;
+ /** The ascii code for the key event ('\0' if none). */
+ char ascii;
+} GHOST_TEventKeyData;
+
+typedef struct {
+ /** Number of pixels on a line. */
+ GHOST_TUns32 xPixels;
+ /** Number of lines. */
+ GHOST_TUns32 yPixels;
+ /** Numberof bits per pixel. */
+ GHOST_TUns32 bpp;
+ /** Refresh rate (in Hertz). */
+ GHOST_TUns32 frequency;
+} GHOST_DisplaySetting;
+
+
+/**
+ * A timer task callback routine.
+ * @param task The timer task object.
+ * @param time The current time.
+ */
+#ifdef __cplusplus
+class GHOST_ITimerTask;
+typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask* task, GHOST_TUns64 time);
+#else
+struct GHOST_TimerTaskHandle__;
+typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__* task, GHOST_TUns64 time);
+#endif
+
+
+#endif // _GHOST_TYPES_H_
diff --git a/intern/ghost/Makefile b/intern/ghost/Makefile
new file mode 100644
index 00000000000..5c78bea192c
--- /dev/null
+++ b/intern/ghost/Makefile
@@ -0,0 +1,52 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# ghost main makefile.
+#
+
+include nan_definitions.mk
+
+LIBNAME = ghost
+SOURCEDIR = intern/$(LIBNAME)
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = intern
+TESTDIRS = test
+
+include nan_subdirs.mk
+
+install: all debug
+ @[ -d $(NAN_GHOST) ] || mkdir $(NAN_GHOST)
+ @[ -d $(NAN_GHOST)/include ] || mkdir $(NAN_GHOST)/include
+ @[ -d $(NAN_GHOST)/lib ] || mkdir $(NAN_GHOST)/lib
+ @[ -d $(NAN_GHOST)/lib/debug ] || mkdir $(NAN_GHOST)/lib/debug
+ cp -f $(DIR)/libghost.a $(NAN_GHOST)/lib/
+ cp -f $(DIR)/debug/libghost.a $(NAN_GHOST)/lib/debug/
+ cp -f *.h $(NAN_GHOST)/include/
+
diff --git a/intern/ghost/doc/Doxyfile.win b/intern/ghost/doc/Doxyfile.win
new file mode 100644
index 00000000000..463da56cc94
--- /dev/null
+++ b/intern/ghost/doc/Doxyfile.win
@@ -0,0 +1,747 @@
+# Doxyfile 1.2.4
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "GHOST (Generic Handy Operating System Toolkit)"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
+# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
+# Polish, Portuguese and Slovene.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+# MAART: changed
+EXTRACT_STATIC = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a class diagram (in Html and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+#MAART: changed
+JAVADOC_AUTOBRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The ENABLE_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+#C:\Documents and Settings\maarten\My Documents\develop\blender\source\blender\img
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Netscape 4.0+
+# or Internet explorer 4.0+).
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+#MAART: changed
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+#MAART: changed
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using a WORD or other.
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+#MAART: changed
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Warning: This feature
+# is still experimental and very incomplete.
+
+GENERATE_XML = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other
+# documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented header file showing
+# the documented files that directly or indirectly include this file
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = c:\program files\doxygen\bin
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
diff --git a/intern/ghost/intern/GHOST_Buttons.cpp b/intern/ghost/intern/GHOST_Buttons.cpp
new file mode 100644
index 00000000000..6e0c46e17a0
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Buttons.cpp
@@ -0,0 +1,82 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#include "GHOST_Buttons.h"
+
+
+GHOST_Buttons::GHOST_Buttons()
+{
+ clear();
+}
+
+
+bool GHOST_Buttons::get(GHOST_TButtonMask mask) const
+{
+ switch (mask) {
+ case GHOST_kButtonMaskLeft:
+ return m_ButtonLeft;
+ case GHOST_kButtonMaskMiddle:
+ return m_ButtonMiddle;
+ case GHOST_kButtonMaskRight:
+ return m_ButtonRight;
+ default:
+ return false;
+ }
+}
+
+void GHOST_Buttons::set(GHOST_TButtonMask mask, bool down)
+{
+ switch (mask) {
+ case GHOST_kButtonMaskLeft:
+ m_ButtonLeft = down; break;
+ case GHOST_kButtonMaskMiddle:
+ m_ButtonMiddle = down; break;
+ case GHOST_kButtonMaskRight:
+ m_ButtonRight = down; break;
+ default:
+ break;
+ }
+}
+
+void GHOST_Buttons::clear()
+{
+ m_ButtonLeft = false;
+ m_ButtonMiddle = false;
+ m_ButtonRight = false;
+}
diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h
new file mode 100644
index 00000000000..fdde52f3e8e
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Buttons.h
@@ -0,0 +1,76 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 15, 2001
+ */
+
+#ifndef _GHOST_BUTTONS_H_
+#define _GHOST_BUTTONS_H_
+
+#include "GHOST_Types.h"
+
+
+struct GHOST_Buttons {
+ /**
+ * Constructor.
+ */
+ GHOST_Buttons();
+
+ /**
+ * Returns the state of a single button.
+ * @param mask. Key button to return.
+ * @return The state of the button (pressed == true).
+ */
+ virtual bool get(GHOST_TButtonMask mask) const;
+
+ /**
+ * Updates the state of a single button.
+ * @param mask. Button state to update.
+ * @param down. The new state of the button.
+ */
+ virtual void set(GHOST_TButtonMask mask, bool down);
+
+ /**
+ * Sets the state of all buttons to up.
+ */
+ virtual void clear();
+
+ GHOST_TUns8 m_ButtonLeft : 1;
+ GHOST_TUns8 m_ButtonMiddle : 1;
+ GHOST_TUns8 m_ButtonRight : 1;
+};
+
+#endif // _GHOST_BUTTONS_H_
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
new file mode 100644
index 00000000000..3ab3ce67fe8
--- /dev/null
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -0,0 +1,778 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+
+ * GHOST_C-Api.cpp
+ *
+ * C Api for GHOST
+ *
+ * Version: $Id$
+ */
+
+#include <stdlib.h>
+
+#include "intern/GHOST_Debug.h"
+#include "GHOST_C-api.h"
+#include "GHOST_ISystem.h"
+#include "GHOST_IEvent.h"
+#include "GHOST_IEventConsumer.h"
+#include "intern/GHOST_CallbackEventConsumer.h"
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+
+GHOST_SystemHandle GHOST_CreateSystem(void)
+{
+ GHOST_ISystem::createSystem();
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+
+ return (GHOST_SystemHandle)system;
+}
+
+
+
+GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->disposeSystem();
+}
+
+
+GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata)
+{
+ return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer (eventCallback, userdata);
+}
+
+
+GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle)
+{
+ delete ((GHOST_CallbackEventConsumer*)consumerhandle);
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->getMilliSeconds();
+}
+
+
+
+GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
+ GHOST_TUns64 delay,
+ GHOST_TUns64 interval,
+ GHOST_TimerProcPtr timerproc,
+ GHOST_TUserDataPtr userdata)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return (GHOST_TimerTaskHandle) system->installTimer(delay, interval, timerproc, userdata);
+}
+
+
+
+GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
+ GHOST_TimerTaskHandle timertaskhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_ITimerTask* timertask = (GHOST_ITimerTask*) timertaskhandle;
+
+ return system->removeTimer(timertask);
+}
+
+
+
+GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->getNumDisplays();
+}
+
+
+
+void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
+ GHOST_TUns32* width,
+ GHOST_TUns32* height)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ system->getMainDisplayDimensions(*width, *height);
+}
+
+
+
+GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
+ char* title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const int stereoVisual)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ bool bstereoVisual;
+
+ if(stereoVisual)
+ bstereoVisual = true;
+ else
+ bstereoVisual = false;
+
+ return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
+ state, type, bstereoVisual);
+}
+
+GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->getUserData();
+}
+void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ window->setUserData(userdata);
+}
+
+GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle windowhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return system->disposeWindow(window);
+}
+
+
+
+int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle windowhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return (int) system->validWindow(window);
+}
+
+
+
+GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
+ GHOST_DisplaySetting* setting,
+ const int stereoVisual)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_IWindow* window = NULL;
+ bool bstereoVisual;
+
+ if(stereoVisual)
+ bstereoVisual = true;
+ else
+ bstereoVisual = false;
+
+ system->beginFullScreen(*setting, &window, bstereoVisual);
+
+ return (GHOST_WindowHandle)window;
+}
+
+
+
+GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->endFullScreen();
+}
+
+
+
+int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return (int) system->getFullScreen();
+}
+
+
+
+int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return (int) system->processEvents(waitForEvent?true:false);
+}
+
+
+
+int GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return (int) system->dispatchEvents();
+}
+
+
+GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->addEventConsumer((GHOST_CallbackEventConsumer*)consumerhandle);
+}
+
+
+
+GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->getCursorShape();
+}
+
+
+
+GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
+ GHOST_TStandardCursor cursorshape)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setCursorShape(cursorshape);
+}
+
+GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
+ GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setCustomCursorShape(bitmap, mask, hotX, hotY);
+}
+
+int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return (int) window->getCursorVisibility();
+}
+
+
+
+GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle,
+ int visible)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setCursorVisibility(visible?true:false);
+}
+
+
+
+GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
+ GHOST_TInt32* x,
+ GHOST_TInt32* y)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->getCursorPosition(*x, *y);
+}
+
+
+
+GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+
+ return system->setCursorPosition(x, y);
+}
+
+
+
+GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
+ GHOST_TModifierKeyMask mask,
+ int* isDown)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_TSuccess result;
+ bool isdown;
+
+ result = system->getModifierKeyState(mask, isdown);
+ *isDown = (int) isdown;
+
+ return result;
+}
+
+
+
+GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
+ GHOST_TButtonMask mask,
+ int* isDown)
+{
+ GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
+ GHOST_TSuccess result;
+ bool isdown;
+
+ result = system->getButtonState(mask, isdown);
+ *isDown = (int) isdown;
+
+ return result;
+}
+
+
+
+GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
+{
+ GHOST_IEvent* event = (GHOST_IEvent*) eventhandle;
+
+ return event->getType();
+}
+
+
+
+GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle)
+{
+ GHOST_IEvent* event = (GHOST_IEvent*) eventhandle;
+
+ return event->getTime();
+}
+
+
+GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle)
+{
+ GHOST_IEvent* event = (GHOST_IEvent*) eventhandle;
+
+ return (GHOST_WindowHandle) event->getWindow();
+}
+
+
+GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
+{
+ GHOST_IEvent* event = (GHOST_IEvent*) eventhandle;
+
+ return event->getData();
+}
+
+
+
+GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)
+{
+ GHOST_ITimerTask* timertask = (GHOST_ITimerTask*) timertaskhandle;
+
+ return timertask->getTimerProc();
+}
+
+
+
+void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle,
+ GHOST_TimerProcPtr timerproc)
+{
+ GHOST_ITimerTask* timertask = (GHOST_ITimerTask*) timertaskhandle;
+
+ timertask->setTimerProc(timerproc);
+}
+
+
+
+GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle)
+{
+ GHOST_ITimerTask* timertask = (GHOST_ITimerTask*) timertaskhandle;
+
+ return timertask->getUserData();
+}
+
+
+
+void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
+ GHOST_TUserDataPtr userdata)
+{
+ GHOST_ITimerTask* timertask = (GHOST_ITimerTask*) timertaskhandle;
+
+ timertask->setUserData(userdata);
+}
+
+
+
+int GHOST_GetValid(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return (int) window->getValid();
+}
+
+
+
+GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->getDrawingContextType();
+}
+
+
+
+GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,
+ GHOST_TDrawingContextType type)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setDrawingContextType(type);
+}
+
+
+
+void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
+ char* title)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ window->setTitle(title);
+}
+
+
+char* GHOST_GetTitle(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+ STR_String title;
+
+ window->getTitle(title);
+
+ char *ctitle = (char*) malloc(title.Length() + 1);
+ strcpy(ctitle, title.Ptr());
+
+ return ctitle;
+}
+
+
+
+GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+ GHOST_Rect* rectangle = NULL;
+
+ rectangle = new GHOST_Rect();
+ window->getWindowBounds(*rectangle);
+
+ return (GHOST_RectangleHandle)rectangle;
+}
+
+
+
+GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+ GHOST_Rect* rectangle = NULL;
+
+ rectangle = new GHOST_Rect();
+ window->getClientBounds(*rectangle);
+
+ return (GHOST_RectangleHandle)rectangle;
+}
+
+
+
+void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle)
+{
+ delete (GHOST_Rect*) rectanglehandle;
+}
+
+
+
+GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 width)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setClientWidth(width);
+}
+
+
+
+GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 height)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setClientHeight(height);
+}
+
+
+
+GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setClientSize(width, height);
+}
+
+
+
+void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32* outX,
+ GHOST_TInt32* outY)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ window->screenToClient(inX, inY, *outX, *outY);
+}
+
+
+
+void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32* outX,
+ GHOST_TInt32* outY)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ window->clientToScreen(inX, inY, *outX, *outY);
+}
+
+
+
+GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->getState();
+}
+
+
+
+GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
+ GHOST_TWindowState state)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setState(state);
+}
+
+
+
+GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
+ GHOST_TWindowOrder order)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setOrder(order);
+}
+
+
+
+GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->swapBuffers();
+}
+
+
+
+GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->activateDrawingContext();
+}
+
+
+
+GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->invalidate();
+}
+
+
+
+GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
+{
+ return ((GHOST_Rect*)rectanglehandle)->getWidth();
+}
+
+
+
+GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle)
+{
+ return ((GHOST_Rect*)rectanglehandle)->getHeight();
+}
+
+
+
+void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32* l,
+ GHOST_TInt32* t,
+ GHOST_TInt32* r,
+ GHOST_TInt32* b)
+{
+ GHOST_Rect *rect= (GHOST_Rect*) rectanglehandle;
+
+ *l= rect->m_l;
+ *t= rect->m_t;
+ *r= rect->m_r;
+ *b= rect->m_b;
+}
+
+
+void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 l,
+ GHOST_TInt32 t,
+ GHOST_TInt32 r,
+ GHOST_TInt32 b)
+{
+ ((GHOST_Rect*)rectanglehandle)->set(l, t, r, b);
+}
+
+
+
+GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle)
+{
+ GHOST_TSuccess result = GHOST_kFailure;
+
+ if (((GHOST_Rect*)rectanglehandle)->isEmpty())
+ result = GHOST_kSuccess;
+
+ return result;
+}
+
+
+
+GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle)
+{
+ GHOST_TSuccess result = GHOST_kFailure;
+
+ if(((GHOST_Rect*)rectanglehandle)->isValid())
+ result = GHOST_kSuccess;
+
+ return result;
+}
+
+
+
+void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 i)
+{
+ ((GHOST_Rect*)rectanglehandle)->inset(i);
+}
+
+
+
+void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle)
+{
+ ((GHOST_Rect*)rectanglehandle)->unionRect(*(GHOST_Rect*)anotherrectanglehandle);
+}
+
+
+
+void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y)
+{
+ ((GHOST_Rect*)rectanglehandle)->unionPoint(x, y);
+}
+
+
+
+GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y)
+{
+ GHOST_TSuccess result = GHOST_kFailure;
+
+ if (((GHOST_Rect*)rectanglehandle)->isInside(x, y))
+ result = GHOST_kSuccess;
+
+ return result;
+}
+
+
+
+GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle)
+{
+ GHOST_TVisibility visible = GHOST_kNotVisible;
+
+ visible = ((GHOST_Rect*)rectanglehandle)->getVisibility(*(GHOST_Rect*)anotherrectanglehandle);
+
+ return visible;
+}
+
+
+
+void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 cx,
+ GHOST_TInt32 cy)
+{
+ ((GHOST_Rect*)rectanglehandle)->setCenter(cx, cy);
+}
+
+
+
+void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
+ GHOST_TInt32 cx,
+ GHOST_TInt32 cy,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h)
+{
+ ((GHOST_Rect*)rectanglehandle)->setCenter(cx, cy, w, h);
+}
+
+
+
+GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
+ GHOST_RectangleHandle anotherrectanglehandle)
+{
+ GHOST_TSuccess result = GHOST_kFailure;
+
+ if (((GHOST_Rect*)rectanglehandle)->clip(*(GHOST_Rect*)anotherrectanglehandle))
+ result = GHOST_kSuccess;
+
+ return result;
+}
+
+
+
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
new file mode 100644
index 00000000000..8099bdbd1d5
--- /dev/null
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
@@ -0,0 +1,55 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date October 25, 2001
+ */
+
+#include "GHOST_Debug.h"
+#include "GHOST_C-api.h"
+#include "GHOST_CallbackEventConsumer.h"
+
+GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
+ GHOST_TUserDataPtr userData)
+{
+ m_eventCallback = eventCallback;
+ m_userData = userData;
+}
+
+
+bool GHOST_CallbackEventConsumer::processEvent(GHOST_IEvent* event)
+{
+ return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0;
+}
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
new file mode 100644
index 00000000000..28326653b31
--- /dev/null
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
@@ -0,0 +1,77 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date October 25, 2001
+ */
+
+#ifndef _GHOST_CALLBACK_EVENT_CONSUMER_H_
+#define _GHOST_CALLBACK_EVENT_CONSUMER_H_
+
+#include "GHOST_IEventConsumer.h"
+#include "GHOST_C-api.h"
+
+/**
+ * Interface class for objects interested in receiving events.
+ */
+class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
+ GHOST_TUserDataPtr userData);
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_CallbackEventConsumer(void)
+ {
+ }
+
+ /**
+ * This method is called by an event producer when an event is available.
+ * @param event The event that can be handled or ignored.
+ * @return Indication as to whether the event was handled.
+ */
+ virtual bool processEvent(GHOST_IEvent* event);
+
+protected:
+ GHOST_EventCallbackProcPtr m_eventCallback;
+ GHOST_TUserDataPtr m_userData;
+};
+
+#endif // _GHOST_CALLBACK_EVENT_CONSUMER_H_
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
new file mode 100644
index 00000000000..18be85e08b4
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -0,0 +1,74 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date June 1, 2001
+ */
+
+#ifndef _GHOST_DEBUG_H_
+#define _GHOST_DEBUG_H_
+
+#ifdef WIN32
+ #ifdef _DEBUG
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+ #define GHOST_DEBUG
+ #endif // _DEBUG
+#else // WIN32
+ #ifndef NDEBUG
+ #define GHOST_DEBUG
+ #endif // DEBUG
+#endif // WIN32
+
+#ifdef GHOST_DEBUG
+ #include <iostream>
+#endif // GHOST_DEBUG
+
+
+#ifdef GHOST_DEBUG
+ #define GHOST_PRINT(x) { std::cout << x; }
+ //#define GHOST_PRINTF(x) { printf(x); }
+#else // GHOST_DEBUG
+ #define GHOST_PRINT(x)
+ //#define GHOST_PRINTF(x)
+#endif // GHOST_DEBUG
+
+
+#ifdef GHOST_DEBUG
+ #define GHOST_ASSERT(x, info) { if (!(x)) {GHOST_PRINT("assertion failed: "); GHOST_PRINT(info); GHOST_PRINT("\n"); } }
+#else // GHOST_DEBUG
+ #define GHOST_ASSERT(x, info)
+#endif // GHOST_DEBUG
+
+#endif // _GHOST_DEBUG_H_
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
new file mode 100644
index 00000000000..dc662634434
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -0,0 +1,219 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#include "GHOST_DisplayManager.h"
+
+#include "GHOST_Debug.h"
+
+
+GHOST_DisplayManager::GHOST_DisplayManager(
+ void)
+: m_settingsInitialized(false)
+{
+}
+
+
+GHOST_DisplayManager::~GHOST_DisplayManager(void)
+{
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::initialize(
+ void)
+{
+ GHOST_TSuccess success;
+ if (!m_settingsInitialized) {
+ success = initializeSettings();
+ m_settingsInitialized = true;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::getNumDisplays(
+ GHOST_TUns8& /*numDisplays*/) const
+{
+ // Don't know if we have a display...
+ return GHOST_kFailure;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::getNumDisplaySettings(
+ GHOST_TUns8 display,
+ GHOST_TInt32& numSettings) const
+{
+ GHOST_TSuccess success;
+
+ GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
+ GHOST_TUns8 numDisplays;
+ success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ if (display < numDisplays) {
+ numSettings = m_settings[display].size();
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::getDisplaySetting(
+ GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting& setting) const
+{
+ GHOST_TSuccess success;
+
+ GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
+ GHOST_TUns8 numDisplays;
+ success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ if (display < numDisplays && index < m_settings[display].size()) {
+ setting = m_settings[display][index];
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::getCurrentDisplaySetting(
+ GHOST_TUns8 /*display*/,
+ GHOST_DisplaySetting& /*setting*/) const
+{
+ return GHOST_kFailure;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::setCurrentDisplaySetting(
+ GHOST_TUns8 /*display*/,
+ const GHOST_DisplaySetting& /*setting*/)
+{
+ return GHOST_kFailure;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::findMatch(
+ GHOST_TUns8 display,
+ const GHOST_DisplaySetting& setting,
+ GHOST_DisplaySetting& match) const
+{
+ GHOST_TSuccess success = GHOST_kSuccess;
+ GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::findMatch(): m_settingsInitialized=false");
+
+ int criteria[4] = { setting.xPixels, setting.yPixels, setting.bpp, setting.frequency };
+ int capabilities[4];
+ double field, score;
+ double best = 1e12; // A big number
+ int found = 0;
+
+ // Look at all the display modes
+ for (int i = 0; (i < (int)m_settings[display].size()); i++) {
+ // Store the capabilities of the display device
+ capabilities[0] = m_settings[display][i].xPixels;
+ capabilities[1] = m_settings[display][i].yPixels;
+ capabilities[2] = m_settings[display][i].bpp;
+ capabilities[3] = m_settings[display][i].frequency;
+
+ // Match against all the fields of the display settings
+ score = 0;
+ for (int j = 0; j < 4; j++) {
+ field = capabilities[j] - criteria[j];
+ score += field * field;
+ }
+
+ if (score < best) {
+ found = i;
+ best = score;
+ }
+ }
+
+ match = m_settings[display][found];
+
+ GHOST_PRINT("GHOST_DisplayManager::findMatch(): settings of match:\n");
+ GHOST_PRINT(" setting.xPixels=" << match.xPixels << "\n");
+ GHOST_PRINT(" setting.yPixels=" << match.yPixels << "\n");
+ GHOST_PRINT(" setting.bpp=" << match.bpp << "\n");
+ GHOST_PRINT(" setting.frequency=" << match.frequency << "\n");
+
+ return success;
+}
+
+
+GHOST_TSuccess
+GHOST_DisplayManager::initializeSettings(
+ void)
+{
+ GHOST_TUns8 numDisplays;
+ GHOST_TSuccess success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ for (GHOST_TUns8 display = 0; (display < numDisplays) && (success == GHOST_kSuccess); display++) {
+ GHOST_DisplaySettings displaySettings;
+ m_settings.push_back(displaySettings);
+ GHOST_TInt32 numSettings;
+ success = getNumDisplaySettings(display, numSettings);
+ if (success == GHOST_kSuccess) {
+ GHOST_TInt32 index;
+ GHOST_DisplaySetting setting;
+ for (index = 0; (index < numSettings) && (success == GHOST_kSuccess); index++) {
+ success = getDisplaySetting(display, index, setting);
+ m_settings[display].push_back(setting);
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ return success;
+}
diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h
new file mode 100644
index 00000000000..efc218a4952
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManager.h
@@ -0,0 +1,142 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_H_
+#define _GHOST_DISPLAY_MANAGER_H_
+
+#include "GHOST_Types.h"
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include <vector>
+
+/**
+ * Manages system displays (platform independent implementation).
+ */
+
+class GHOST_DisplayManager
+{
+public:
+ enum { kMainDisplay = 0 };
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManager(void);
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_DisplayManager(void);
+
+ /**
+ * Initializes the list with devices and settings.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess initialize(void);
+
+ /**
+ * Returns the number of display devices on this system.
+ * @param numDisplays The number of displays on this system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The number of settings of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param index The setting index to be returned.
+ * @param setting The setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * The setting given to this method is matched againts the available diplay settings.
+ * The best match is activated (@see findMatch()).
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The setting of the display device to be matched and activated.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+
+protected:
+ typedef std::vector<GHOST_DisplaySetting> GHOST_DisplaySettings;
+
+ /**
+ * Finds the best display settings match.
+ * @param display The index of the display device.
+ * @param setting The setting to match.
+ * @param match The optimal display setting.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess findMatch(GHOST_TUns8 display, const GHOST_DisplaySetting& setting, GHOST_DisplaySetting& match) const;
+
+ /**
+ * Retrieves settings for each display device and stores them.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess initializeSettings(void);
+
+ /** Tells whether the list of display modes has been stored already. */
+ bool m_settingsInitialized;
+ /** The list with display settings for the main display. */
+ std::vector<GHOST_DisplaySettings> m_settings;
+};
+
+
+#endif // _GHOST_DISPLAY_MANAGER_H_
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp b/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp
new file mode 100644
index 00000000000..3220fa1a330
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp
@@ -0,0 +1,178 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#include "GHOST_DisplayManagerCarbon.h"
+
+#include "GHOST_Debug.h"
+
+// We do not support multiple monitors at the moment
+
+
+GHOST_DisplayManagerCarbon::GHOST_DisplayManagerCarbon(void)
+{
+ if (::CGGetActiveDisplayList(0, NULL, &m_numDisplays) != CGDisplayNoErr)
+ {
+ m_numDisplays = 0;
+ m_displayIDs = NULL;
+ }
+ if (m_numDisplays > 0)
+ {
+ m_displayIDs = new CGDirectDisplayID [m_numDisplays];
+ GHOST_ASSERT((m_displayIDs!=NULL), "GHOST_DisplayManagerCarbon::GHOST_DisplayManagerCarbon(): memory allocation failed");
+ ::CGGetActiveDisplayList(m_numDisplays, m_displayIDs, &m_numDisplays);
+ }
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCarbon::getNumDisplays(GHOST_TUns8& numDisplays) const
+{
+ numDisplays = (GHOST_TUns8) m_numDisplays;
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCarbon::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCarbon::getNumDisplaySettings(): only main display is supported");
+
+ CFArrayRef displayModes;
+ displayModes = ::CGDisplayAvailableModes(m_displayIDs[display]);
+ CFIndex numModes = ::CFArrayGetCount(displayModes);
+ numSettings = (GHOST_TInt32)numModes;
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCarbon::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCarbon::getDisplaySetting(): only main display is supported");
+
+ CFArrayRef displayModes;
+ CGDirectDisplayID d = m_displayIDs[display];
+ displayModes = ::CGDisplayAvailableModes(d);
+ CFIndex numModes = ::CFArrayGetCount(displayModes);
+ GHOST_TInt32 numSettings = (GHOST_TInt32)numModes;
+ CFDictionaryRef displayModeValues = (CFDictionaryRef)::CFArrayGetValueAtIndex(displayModes, index);
+
+ setting.xPixels = getValue(displayModeValues, kCGDisplayWidth);
+ setting.yPixels = getValue(displayModeValues, kCGDisplayHeight);
+ setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+ setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate);
+
+#ifdef GHOST_DEBUG
+ printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCarbon::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCarbon::getCurrentDisplaySetting(): only main display is supported");
+
+ CFDictionaryRef displayModeValues = ::CGDisplayCurrentMode(m_displayIDs[display]);
+
+ setting.xPixels = getValue(displayModeValues, kCGDisplayWidth);
+ setting.yPixels = getValue(displayModeValues, kCGDisplayHeight);
+ setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+ setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate);
+
+#ifdef GHOST_DEBUG
+ printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(): only main display is supported");
+
+#ifdef GHOST_DEBUG
+ printf("GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(): requested settings:\n");
+ printf(" setting.xPixels=%d\n", setting.xPixels);
+ printf(" setting.yPixels=%d\n", setting.yPixels);
+ printf(" setting.bpp=%d\n", setting.bpp);
+ printf(" setting.frequency=%d\n", setting.frequency);
+#endif // GHOST_DEBUG
+
+ CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
+ m_displayIDs[display],
+ (size_t)setting.bpp,
+ (size_t)setting.xPixels,
+ (size_t)setting.yPixels,
+ (CGRefreshRate)setting.frequency,
+ NULL);
+
+#ifdef GHOST_DEBUG
+ printf("GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(): switching to:\n");
+ printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
+ printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
+ printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
+ printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
+#endif // GHOST_DEBUG
+
+ CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
+
+ return err == CGDisplayNoErr ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+long GHOST_DisplayManagerCarbon::getValue(CFDictionaryRef values, CFStringRef key) const
+{
+ CFNumberRef numberValue = (CFNumberRef) CFDictionaryGetValue(values, key);
+
+ if (!numberValue)
+ {
+ return -1;
+ }
+
+ long intValue;
+
+ if (!CFNumberGetValue(numberValue, kCFNumberLongType, &intValue))
+ {
+ return -1;
+ }
+
+ return intValue;
+}
+
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCarbon.h b/intern/ghost/intern/GHOST_DisplayManagerCarbon.h
new file mode 100644
index 00000000000..3374f710f47
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerCarbon.h
@@ -0,0 +1,119 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_CARBON_H_
+#define _GHOST_DISPLAY_MANAGER_CARBON_H_
+
+#ifndef __APPLE__
+#error Apple only!
+#endif // __APPLE__
+
+#include "GHOST_DisplayManager.h"
+
+#include <Carbon/Carbon.h>
+
+/**
+ * Manages system displays (Mac OSX/Carbon implementation).
+ */
+
+class GHOST_DisplayManagerCarbon : public GHOST_DisplayManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerCarbon(void);
+
+ /**
+ * Returns the number of display devices on this system.
+ * @param numDisplays The number of displays on this system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The number of settings of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param index The setting index to be returned.
+ * @param setting The setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+
+protected:
+ /**
+ * Returns a value from a dictionary.
+ * @param values Dictionary to return value from.
+ * @param key Key to return value for.
+ * @return The value for this key.
+ */
+ long getValue(CFDictionaryRef values, CFStringRef key) const;
+
+ /** Cached number of displays. */
+ CGDisplayCount m_numDisplays;
+ /** Cached display id's for each display. */
+ CGDirectDisplayID* m_displayIDs;
+};
+
+
+#endif // _GHOST_DISPLAY_MANAGER_CARBON_H_
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
new file mode 100644
index 00000000000..60892ce094e
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -0,0 +1,186 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#include "GHOST_DisplayManagerWin32.h"
+
+#include "GHOST_Debug.h"
+
+// We do not support multiple monitors at the moment
+#include <windows.h>
+#define COMPILE_MULTIMON_STUBS
+#include <multimon.h>
+
+
+GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void)
+{
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const
+{
+ // We do not support multiple monitors at the moment
+ numDisplays = ::GetSystemMetrics(SM_CMONITORS);
+ return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+/*
+ * When you call EnumDisplaySettings with iModeNum set to zero, the operating system
+ * initializes and caches information about the display device. When you call
+ * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns
+ * the information that was cached the last time the function was called with iModeNum
+ * set to zero.
+ */
+GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getNumDisplaySettings(): only main displlay is supported");
+ numSettings = 0;
+ DEVMODE dm;
+ while (::EnumDisplaySettings(NULL, numSettings, &dm)) {
+ numSettings++;
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getDisplaySetting(): only main display is supported");
+ GHOST_TSuccess success;
+ DEVMODE dm;
+ if (::EnumDisplaySettings(NULL, index, &dm)) {
+#ifdef GHOST_DEBUG
+ printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
+#endif // GHOST_DEBUG
+ setting.xPixels = dm.dmPelsWidth;
+ setting.yPixels = dm.dmPelsHeight;
+ setting.bpp = dm.dmBitsPerPel;
+ /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
+ * may return with the value 0 or 1. These values represent the display hardware's
+ * default refresh rate. This default rate is typically set by switches on a display
+ * card or computer motherboard, or by a configuration program that does not use
+ * Win32 display functions such as ChangeDisplaySettings.
+ */
+ /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
+ * returned 0 or 1 but this doesn't work since later on an exact match will
+ * be searched. And this will never happen if we change it to 60. Now we rely
+ * on the default h/w setting.
+ */
+ setting.frequency = dm.dmDisplayFrequency;
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getCurrentDisplaySetting(): only main display is supported");
+ return getDisplaySetting(kMainDisplay, ENUM_CURRENT_SETTINGS, setting);
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::setCurrentDisplaySetting(): only main display is supported");
+
+ GHOST_DisplaySetting match;
+ GHOST_TSuccess success = findMatch(display, setting, match);
+ DEVMODE dm;
+ int i = 0;
+ while (::EnumDisplaySettings(NULL, i++, &dm)) {
+ if ((dm.dmBitsPerPel == match.bpp) &&
+ (dm.dmPelsWidth == match.xPixels) &&
+ (dm.dmPelsHeight == match.yPixels) &&
+ (dm.dmDisplayFrequency == match.frequency)) {
+ break;
+ }
+ }
+ /*
+ dm.dmBitsPerPel = match.bpp;
+ dm.dmPelsWidth = match.xPixels;
+ dm.dmPelsHeight = match.yPixels;
+ dm.dmDisplayFrequency = match.frequency;
+ dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
+ dm.dmSize = sizeof(DEVMODE);
+ dm.dmDriverExtra = 0;
+ */
+#ifdef GHOST_DEBUG
+ printf("display change: Requested settings:\n");
+ printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
+ printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
+ printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
+ printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
+#endif // GHOST_DEBUG
+
+ LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+#ifdef GHOST_DEBUG
+ switch (status)
+ {
+ case DISP_CHANGE_SUCCESSFUL:
+ printf("display change: The settings change was successful.\n");
+ break;
+ case DISP_CHANGE_RESTART:
+ printf("display change: The computer must be restarted in order for the graphics mode to work.\n");
+ break;
+ case DISP_CHANGE_BADFLAGS:
+ printf("display change: An invalid set of flags was passed in.\n");
+ break;
+ case DISP_CHANGE_BADPARAM:
+ printf("display change: An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
+ break;
+ case DISP_CHANGE_FAILED:
+ printf("display change: The display driver failed the specified graphics mode.\n");
+ break;
+ case DISP_CHANGE_BADMODE:
+ printf("display change: The graphics mode is not supported.\n");
+ break;
+ case DISP_CHANGE_NOTUPDATED:
+ printf("display change: Windows NT: Unable to write settings to the registry.\n");
+ break;
+ default:
+ printf("display change: Return value invalid\n");
+ break;
+ }
+#endif // GHOST_DEBUG
+ return status == DISP_CHANGE_SUCCESSFUL? GHOST_kSuccess : GHOST_kFailure;
+}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
new file mode 100644
index 00000000000..f44ba07ee33
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
@@ -0,0 +1,106 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_WIN32_H_
+#define _GHOST_DISPLAY_MANAGER_WIN32_H_
+
+#ifndef WIN32
+#error WIN32 only!
+#endif // WIN32
+
+#include "GHOST_DisplayManager.h"
+
+
+/**
+ * Manages system displays (WIN32 implementation).
+ */
+
+class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerWin32(void);
+
+ /**
+ * Returns the number of display devices on this system.
+ * @param numDisplays The number of displays on this system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The number of settings of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param index The setting index to be returned.
+ * @param setting The setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+
+protected:
+};
+
+
+#endif // _GHOST_DISPLAY_MANAGER_WIN32_H_
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
new file mode 100755
index 00000000000..1eb0e0a10ca
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -0,0 +1,125 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "GHOST_DisplayManagerX11.h"
+
+#include "GHOST_SystemX11.h"
+
+
+
+GHOST_DisplayManagerX11::
+GHOST_DisplayManagerX11(
+ GHOST_SystemX11 *system
+) :
+ GHOST_DisplayManager(),
+ m_system(system)
+{
+ //nothing to do.
+}
+
+ GHOST_TSuccess
+GHOST_DisplayManagerX11::
+getNumDisplays(
+ GHOST_TUns8& numDisplays
+) const{
+ numDisplays = m_system->getNumDisplays();
+ return GHOST_kSuccess;
+}
+
+
+ GHOST_TSuccess
+GHOST_DisplayManagerX11::
+getNumDisplaySettings(
+ GHOST_TUns8 display,
+ GHOST_TInt32& numSettings
+) const{
+
+ // We only have one X11 setting at the moment.
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ numSettings = GHOST_TInt32(1);
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_DisplayManagerX11::
+getDisplaySetting(
+ GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting& setting
+) const {
+
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
+
+ Display * x_display = m_system->getXDisplay();
+
+ if (x_display == NULL) {
+ return GHOST_kFailure;
+ }
+
+ setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display));
+ setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display));
+ setting.bpp = DefaultDepth(x_display,DefaultScreen(x_display));
+
+ // Don't think it's possible to get this value from X!
+ // So let's guess!!
+ setting.frequency = 60;
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_DisplayManagerX11::
+getCurrentDisplaySetting(
+ GHOST_TUns8 display,
+ GHOST_DisplaySetting& setting
+) const {
+ return getDisplaySetting(display,GHOST_TInt32(0),setting);
+}
+
+
+ GHOST_TSuccess
+GHOST_DisplayManagerX11::
+setCurrentDisplaySetting(
+ GHOST_TUns8 display,
+ const GHOST_DisplaySetting& setting
+){
+ // This is never going to work robustly in X
+ // but it's currently part of the full screen interface
+
+ // we fudge it for now.
+
+ return GHOST_kSuccess;
+}
+
+
+
+
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h
new file mode 100755
index 00000000000..7f4e772ce95
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h
@@ -0,0 +1,129 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_X11_H_
+#define _GHOST_DISPLAY_MANAGER_X11_H_
+
+
+#include "GHOST_DisplayManager.h"
+
+
+class GHOST_SystemX11;
+
+/**
+ * Manages system displays (X11 implementation).
+ */
+
+class GHOST_DisplayManagerX11 : public GHOST_DisplayManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerX11(
+ GHOST_SystemX11 *system
+ );
+
+ /**
+ * Returns the number of display devices on this system.
+ * @param numDisplays The number of displays on this system.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getNumDisplays(
+ GHOST_TUns8& numDisplays
+ ) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The number of settings of the display device with this index.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getNumDisplaySettings(
+ GHOST_TUns8 display,
+ GHOST_TInt32& numSettings
+ ) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param index The setting index to be returned.
+ * @param setting The setting of the display device with this index.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getDisplaySetting(
+ GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting& setting
+ ) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getCurrentDisplaySetting(
+ GHOST_TUns8 display,
+ GHOST_DisplaySetting& setting
+ ) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ setCurrentDisplaySetting(
+ GHOST_TUns8 display,
+ const GHOST_DisplaySetting& setting
+ );
+
+private :
+
+ GHOST_SystemX11 * m_system;
+};
+
+
+#endif //
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
new file mode 100644
index 00000000000..90b411febf9
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -0,0 +1,114 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#ifndef _GHOST_EVENT_H_
+#define _GHOST_EVENT_H_
+
+#include "GHOST_IEvent.h"
+
+
+/**
+ * Base class for events received the operating system.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+class GHOST_Event : public GHOST_IEvent
+{
+public:
+ /**
+ * Constructor.
+ * @param msec The time this event was generated.
+ * @param type The type of this event.
+ * @param window The generating window (or NULL if system event).
+ */
+ GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window)
+ : m_type(type), m_time(msec), m_window(window), m_data(0)
+ {
+ }
+
+ /**
+ * Returns the event type.
+ * @return The event type.
+ */
+ virtual GHOST_TEventType getType()
+ {
+ return m_type;
+ }
+
+ /**
+ * Returns the time this event was generated.
+ * @return The event generation time.
+ */
+ virtual GHOST_TUns64 getTime()
+ {
+ return m_time;
+ }
+
+ /**
+ * Returns the window this event was generated on,
+ * or NULL if it is a 'system' event.
+ * @return The generating window.
+ */
+ virtual GHOST_IWindow* getWindow()
+ {
+ return m_window;
+ }
+
+ /**
+ * Returns the event data.
+ * @return The event data.
+ */
+ virtual GHOST_TEventDataPtr getData()
+ {
+ return m_data;
+ }
+
+protected:
+ /** Type of this event. */
+ GHOST_TEventType m_type;
+ /** The time this event was generated. */
+ GHOST_TUns64 m_time;
+ /** Pointer to the generating window. */
+ GHOST_IWindow* m_window;
+ /** Pointer to the event data. */
+ GHOST_TEventDataPtr m_data;
+};
+
+#endif // _GHOST_EVENT_H_
diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h
new file mode 100644
index 00000000000..f0718414ced
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventButton.h
@@ -0,0 +1,73 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#ifndef _GHOST_EVENT_BUTTON_H_
+#define _GHOST_EVENT_BUTTON_H_
+
+#include "GHOST_Event.h"
+
+/**
+ * Mouse button event.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+class GHOST_EventButton : public GHOST_Event
+{
+public:
+ /**
+ * Constructor.
+ * @param time The time this event was generated.
+ * @param type The type of this event.
+ * @param x The x-coordinate of the location the cursor was at at the time of the event.
+ * @param y The y-coordinate of the location the cursor was at at the time of the event.
+ * @param buttons The state of the buttons was at at the time of the event.
+ */
+ GHOST_EventButton(GHOST_TUns64 time, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TButtonMask button)
+ : GHOST_Event(time, type, window)
+ {
+ m_buttonEventData.button = button;
+ m_data = &m_buttonEventData;
+ }
+
+protected:
+ /** The button event data. */
+ GHOST_TEventButtonData m_buttonEventData;
+};
+
+#endif // _GHOST_EVENT_BUTTON_H_
diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h
new file mode 100644
index 00000000000..9b7d3d3acc7
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventCursor.h
@@ -0,0 +1,74 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#ifndef _GHOST_EVENT_CURSOR_H_
+#define _GHOST_EVENT_CURSOR_H_
+
+#include "GHOST_Event.h"
+
+/**
+ * Cursor event.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+class GHOST_EventCursor : public GHOST_Event
+{
+public:
+ /**
+ * Constructor.
+ * @param msec The time this event was generated.
+ * @param type The type of this event.
+ * @param x The x-coordinate of the location the cursor was at at the time of the event.
+ * @param y The y-coordinate of the location the cursor was at at the time of the event.
+ */
+ GHOST_EventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y)
+ : GHOST_Event(msec, type, window)
+ {
+ m_cursorEventData.x = x;
+ m_cursorEventData.y = y;
+ m_data = &m_cursorEventData;
+ }
+
+protected:
+ /** The x,y-coordinates of the cursor position. */
+ GHOST_TEventCursorData m_cursorEventData;
+};
+
+
+#endif // _GHOST_EVENT_CURSOR_H_
diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h
new file mode 100644
index 00000000000..19602736d99
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventKey.h
@@ -0,0 +1,87 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#ifndef _GHOST_EVENT_KEY_H_
+#define _GHOST_EVENT_KEY_H_
+
+#include "GHOST_Event.h"
+
+/**
+ * Key event.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+class GHOST_EventKey : public GHOST_Event
+{
+public:
+ /**
+ * Constructor.
+ * @param msec The time this event was generated.
+ * @param type The type of key event.
+ * @param key The key code of the key.
+ */
+ GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key)
+ : GHOST_Event(msec, type, window)
+ {
+ m_keyEventData.key = key;
+ m_keyEventData.ascii = '\0';
+ m_data = &m_keyEventData;
+ }
+
+ /**
+ * Constructor.
+ * @param msec The time this event was generated.
+ * @param type The type of key event.
+ * @param key The key code of the key.
+ * @param ascii The ascii code for the key event.
+ */
+ GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key, char ascii)
+ : GHOST_Event(msec, type, window)
+ {
+ m_keyEventData.key = key;
+ m_keyEventData.ascii = ascii;
+ m_data = &m_keyEventData;
+ }
+
+protected:
+ /** The key event data. */
+ GHOST_TEventKeyData m_keyEventData;
+};
+
+#endif // _GHOST_EVENT_KEY_H_
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
new file mode 100644
index 00000000000..f4a8b72db25
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -0,0 +1,215 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 14, 2001
+ */
+
+#include "GHOST_EventManager.h"
+
+#include <algorithm>
+
+#include "GHOST_Debug.h"
+
+
+GHOST_EventManager::GHOST_EventManager()
+{
+}
+
+
+GHOST_EventManager::~GHOST_EventManager()
+{
+ disposeEvents();
+}
+
+
+GHOST_TUns32 GHOST_EventManager::getNumEvents()
+{
+ return (GHOST_TUns32) m_events.size();
+}
+
+
+GHOST_TUns32 GHOST_EventManager::getNumEvents(GHOST_TEventType type)
+{
+ GHOST_TUns32 numEvents = 0;
+ std::deque<GHOST_IEvent*>::iterator p;
+ for (p = m_events.begin(); p != m_events.end(); p++) {
+ if ((*p)->getType() == type) {
+ numEvents++;
+ }
+ }
+ return numEvents;
+}
+
+
+GHOST_IEvent* GHOST_EventManager::peekEvent()
+{
+ GHOST_IEvent* event = 0;
+ if (m_events.size() > 0) {
+ event = m_events.back();
+ }
+ return event;
+}
+
+
+GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event)
+{
+ GHOST_TSuccess success;
+ GHOST_ASSERT(event, "invalid event");
+ if (m_events.size() < m_events.max_size()) {
+ m_events.push_front(event);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+bool GHOST_EventManager::dispatchEvent(GHOST_IEvent* event)
+{
+ bool handled;
+ if (event) {
+ handled = true;
+ /*
+ for (unsigned int i = 0; i < m_consumers.size(); i++) {
+ if (m_consumers[i]->processEvent(event)) {
+ handled = false;
+ }
+ }
+ */
+ TConsumerVector::iterator iter;
+ for (iter = m_consumers.begin(); iter != m_consumers.end(); iter++) {
+ if ((*iter)->processEvent(event)) {
+ handled = false;
+ }
+ }
+ }
+ else {
+ handled = false;
+ }
+ return handled;
+}
+
+
+bool GHOST_EventManager::dispatchEvent()
+{
+ GHOST_IEvent* event = popEvent();
+ bool handled = false;
+ if (event) {
+ handled = dispatchEvent(event);
+ delete event;
+ }
+ return handled;
+}
+
+
+bool GHOST_EventManager::dispatchEvents()
+{
+ bool handled;
+ if (getNumEvents()) {
+ handled = true;
+ while (getNumEvents()) {
+ if (!dispatchEvent()) {
+ handled = false;
+ }
+ }
+ }
+ else {
+ handled = false;
+ }
+ return handled;
+}
+
+
+GHOST_TSuccess GHOST_EventManager::addConsumer(GHOST_IEventConsumer* consumer)
+{
+ GHOST_TSuccess success;
+ GHOST_ASSERT(consumer, "invalid consumer");
+
+ // Check to see whether the consumer is already in our list
+ TConsumerVector::const_iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
+
+ if (iter == m_consumers.end()) {
+ // Add the consumer
+ m_consumers.push_back(consumer);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_EventManager::removeConsumer(GHOST_IEventConsumer* consumer)
+{
+ GHOST_TSuccess success;
+ GHOST_ASSERT(consumer, "invalid consumer");
+
+ // Check to see whether the consumer is in our list
+ TConsumerVector::iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
+
+ if (iter != m_consumers.end()) {
+ // Remove the consumer
+ m_consumers.erase(iter);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_IEvent* GHOST_EventManager::popEvent()
+{
+ GHOST_IEvent* event = peekEvent();
+ if (event) {
+ m_events.pop_back();
+ }
+ return event;
+}
+
+
+void GHOST_EventManager::disposeEvents()
+{
+ while (m_events.size() > 0) {
+ GHOST_ASSERT(m_events[0], "invalid event");
+ delete m_events[0];
+ m_events.pop_front();
+ }
+}
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
new file mode 100644
index 00000000000..93c009b892d
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -0,0 +1,157 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 14, 2001
+ */
+
+#ifndef _GHOST_EVENT_MANAGER_H_
+#define _GHOST_EVENT_MANAGER_H_
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include <deque>
+#include <vector>
+
+#include "GHOST_IEventConsumer.h"
+
+
+/**
+ * Manages an event stack and a list of event consumers.
+ * The stack works on a FIFO (First In First Out) basis.
+ * Events are pushed on the front of the stack and retrieved from the back.
+ * Ownership of the event is transferred to the event manager as soon as an event is pushed.
+ * Ownership of the event is transferred from the event manager as soon as an event is popped.
+ * Events can be dispatched to the event consumers.
+ */
+class GHOST_EventManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_EventManager();
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_EventManager();
+
+ /**
+ * Returns the number of events currently on the stack.
+ * @return The number of events on the stack.
+ */
+ virtual GHOST_TUns32 getNumEvents();
+
+ /**
+ * Returns the number of events of a certain type currently on the stack.
+ * @param type The type of events to be counted.
+ * @return The number of events on the stack of this type.
+ */
+ virtual GHOST_TUns32 getNumEvents(GHOST_TEventType type);
+
+ /**
+ * Return the event at the top of the stack without removal.
+ * Do not delete the event!
+ * @return The event at the top of the stack.
+ */
+ virtual GHOST_IEvent* peekEvent();
+
+ /**
+ * Pushes an event on the stack.
+ * To dispatch it, call dispatchEvent() or dispatchEvents().
+ * Do not delete the event!
+ * @param event The event to push on the stack.
+ */
+ virtual GHOST_TSuccess pushEvent(GHOST_IEvent* event);
+
+ /**
+ * Dispatches the given event directly, bypassing the event stack.
+ * @return Indication as to whether any of the consumers handled the event.
+ */
+ virtual bool dispatchEvent(GHOST_IEvent* event);
+
+ /**
+ * Dispatches the event at the back of the stack.
+ * The event will be removed from the stack.
+ * @return Indication as to whether any of the consumers handled the event.
+ */
+ virtual bool dispatchEvent();
+
+ /**
+ * Dispatches all the events on the stack.
+ * The event stack will be empty afterwards.
+ * @return Indication as to whether any of the consumers handled the events.
+ */
+ virtual bool dispatchEvents();
+
+ /**
+ * Adds a consumer to the list of event consumers.
+ * @param consumer The consumer added to the list.
+ * @return Indication as to whether addition has succeeded.
+ */
+ virtual GHOST_TSuccess addConsumer(GHOST_IEventConsumer* consumer);
+
+ /**
+ * Removes a consumer from the list of event consumers.
+ * @param consumer The consumer removed from the list.
+ * @return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess removeConsumer(GHOST_IEventConsumer* consumer);
+
+protected:
+ /**
+ * Returns the event at the top of the stack and removes it.
+ * Delete the event after use!
+ * @return The event at the top of the stack.
+ */
+ virtual GHOST_IEvent* popEvent();
+
+ /**
+ * Removes all events from the stack.
+ */
+ virtual void disposeEvents();
+
+ /** The event stack. */
+ std::deque<GHOST_IEvent*> m_events;
+
+ typedef std::vector<GHOST_IEventConsumer*> TConsumerVector;
+ /** The list with event consumers. */
+ TConsumerVector m_consumers;
+};
+
+#endif // _GHOST_EVENT_MANAGER_H_
diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp
new file mode 100644
index 00000000000..16576357fbc
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventPrinter.cpp
@@ -0,0 +1,259 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 15, 2001
+ */
+
+#include "GHOST_EventPrinter.h"
+
+#include <iostream>
+
+#include "GHOST_EventKey.h"
+#include "GHOST_Debug.h"
+
+bool GHOST_EventPrinter::processEvent(GHOST_IEvent* event)
+{
+ bool handled = true;
+
+ GHOST_ASSERT(event, "event==0");
+
+ if (event->getType() == GHOST_kEventWindowUpdate) return false;
+
+ std::cout << "GHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime() << ", type: ";
+ switch (event->getType()) {
+ case GHOST_kEventUnknown:
+ std::cout << "GHOST_kEventUnknown"; handled = false; break;
+
+ case GHOST_kEventButtonUp:
+ {
+ GHOST_TEventButtonData* buttonData = (GHOST_TEventButtonData*)((GHOST_IEvent*)event)->getData();
+ std::cout << "GHOST_kEventCursorButtonUp, button: " << buttonData->button;
+ }
+ break;
+ case GHOST_kEventButtonDown:
+ {
+ GHOST_TEventButtonData* buttonData = (GHOST_TEventButtonData*)((GHOST_IEvent*)event)->getData();
+ std::cout << "GHOST_kEventButtonDown, button: " << buttonData->button;
+ }
+ break;
+
+ case GHOST_kEventCursorMove:
+ {
+ GHOST_TEventCursorData* cursorData = (GHOST_TEventCursorData*)((GHOST_IEvent*)event)->getData();
+ std::cout << "GHOST_kEventCursorMove, (x,y): (" << cursorData->x << "," << cursorData->y << ")";
+ }
+ break;
+
+ case GHOST_kEventKeyUp:
+ {
+ GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*)((GHOST_IEvent*)event)->getData();
+ STR_String str;
+ getKeyString(keyData->key, str);
+ std::cout << "GHOST_kEventKeyUp, key: " << str.Ptr();
+ }
+ break;
+ case GHOST_kEventKeyDown:
+ {
+ GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*)((GHOST_IEvent*)event)->getData();
+ STR_String str;
+ getKeyString(keyData->key, str);
+ std::cout << "GHOST_kEventKeyDown, key: " << str.Ptr();
+ }
+ break;
+
+ case GHOST_kEventQuit:
+ std::cout << "GHOST_kEventQuit"; break;
+ case GHOST_kEventWindowClose:
+ std::cout << "GHOST_kEventWindowClose"; break;
+ case GHOST_kEventWindowActivate:
+ std::cout << "GHOST_kEventWindowActivate"; break;
+ case GHOST_kEventWindowDeactivate:
+ std::cout << "GHOST_kEventWindowDeactivate"; break;
+ case GHOST_kEventWindowUpdate:
+ std::cout << "GHOST_kEventWindowUpdate"; break;
+ case GHOST_kEventWindowSize:
+ std::cout << "GHOST_kEventWindowSize"; break;
+
+ default:
+ std::cout << "not found"; handled = false; break;
+ }
+ std::cout << "\n";
+ return handled;
+}
+
+
+void GHOST_EventPrinter::getKeyString(GHOST_TKey key, STR_String& str) const
+{
+ if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
+ str = ((char)key);
+ }
+ else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
+ int number = key - GHOST_kKeyNumpad0;
+ STR_String numberStr (number);
+ str = "Numpad";
+ str += numberStr;
+ }
+ else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
+ int number = key - GHOST_kKeyF1 + 1;
+ STR_String numberStr (number);
+ str = "F";
+ str += numberStr;
+ }
+ else {
+ switch (key)
+ {
+ case GHOST_kKeyBackSpace:
+ str = "BackSpace";
+ break;
+ case GHOST_kKeyTab:
+ str = "Tab";
+ break;
+ case GHOST_kKeyLinefeed:
+ str = "Linefeed";
+ break;
+ case GHOST_kKeyClear:
+ str = "Clear";
+ break;
+ case GHOST_kKeyEnter:
+ str = "Enter";
+ break;
+ case GHOST_kKeyEsc:
+ str = "Esc";
+ break;
+ case GHOST_kKeySpace:
+ str = "Space";
+ break;
+ case GHOST_kKeyQuote:
+ str = "Quote";
+ break;
+ case GHOST_kKeyBackslash:
+ str = "\\";
+ break;
+ case GHOST_kKeyAccentGrave:
+ str = "`";
+ break;
+ case GHOST_kKeyLeftShift:
+ str = "LeftShift";
+ break;
+ case GHOST_kKeyRightShift:
+ str = "RightShift";
+ break;
+ case GHOST_kKeyLeftControl:
+ str = "LeftControl";
+ break;
+ case GHOST_kKeyRightControl:
+ str = "RightControl";
+ break;
+ case GHOST_kKeyLeftAlt:
+ str = "LeftAlt";
+ break;
+ case GHOST_kKeyRightAlt:
+ str = "RightAlt";
+ break;
+ case GHOST_kKeyCommand:
+ // APPLE only!
+ str = "Command";
+ break;
+ case GHOST_kKeyCapsLock:
+ str = "CapsLock";
+ break;
+ case GHOST_kKeyNumLock:
+ str = "NumLock";
+ break;
+ case GHOST_kKeyScrollLock:
+ str = "ScrollLock";
+ break;
+ case GHOST_kKeyLeftArrow:
+ str = "LeftArrow";
+ break;
+ case GHOST_kKeyRightArrow:
+ str = "RightArrow";
+ break;
+ case GHOST_kKeyUpArrow:
+ str = "UpArrow";
+ break;
+ case GHOST_kKeyDownArrow:
+ str = "DownArrow";
+ break;
+ case GHOST_kKeyPrintScreen:
+ str = "PrintScreen";
+ break;
+ case GHOST_kKeyPause:
+ str = "Pause";
+ break;
+ case GHOST_kKeyInsert:
+ str = "Insert";
+ break;
+ case GHOST_kKeyDelete:
+ str = "Delete";
+ break;
+ case GHOST_kKeyHome:
+ str = "Home";
+ break;
+ case GHOST_kKeyEnd:
+ str = "End";
+ break;
+ case GHOST_kKeyUpPage:
+ str = "UpPage";
+ break;
+ case GHOST_kKeyDownPage:
+ str = "DownPage";
+ break;
+ case GHOST_kKeyNumpadPeriod:
+ str = "NumpadPeriod";
+ break;
+ case GHOST_kKeyNumpadEnter:
+ str = "NumpadEnter";
+ break;
+ case GHOST_kKeyNumpadPlus:
+ str = "NumpadPlus";
+ break;
+ case GHOST_kKeyNumpadMinus:
+ str = "NumpadMinus";
+ break;
+ case GHOST_kKeyNumpadAsterisk:
+ str = "NumpadAsterisk";
+ break;
+ case GHOST_kKeyNumpadSlash:
+ str = "NumpadSlash";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+ }
+}
+
diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h
new file mode 100644
index 00000000000..6214e94393d
--- /dev/null
+++ b/intern/ghost/intern/GHOST_EventPrinter.h
@@ -0,0 +1,70 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 14, 2001
+ */
+
+#ifndef _GHOST_EVENT_PRINTER_H_
+#define _GHOST_EVENT_PRINTER_H_
+
+#include "GHOST_IEventConsumer.h"
+
+#include "STR_String.h"
+
+/**
+ * An Event consumer that prints all the events to standard out.
+ * Really useful when debugging.
+ */
+class GHOST_EventPrinter : public GHOST_IEventConsumer
+{
+public:
+ /**
+ * Prints all the events received to std out.
+ * @param event The event that can be handled or not.
+ * @return Indication as to whether the event was handled.
+ */
+ virtual bool processEvent(GHOST_IEvent* event);
+
+protected:
+ /**
+ * Converts GHOST key code to a readable string.
+ * @param key The GHOST key code to convert.
+ * @param str The GHOST key code converted to a readable string.
+ */
+ void getKeyString(GHOST_TKey key, STR_String& str) const;
+};
+
+#endif // _GHOST_EVENT_PRINTER_H_
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
new file mode 100644
index 00000000000..6505194645a
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -0,0 +1,98 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#include "GHOST_ISystem.h"
+
+#ifdef WIN32
+# include "GHOST_SystemWin32.h"
+#else
+# ifdef __APPLE__
+# include "GHOST_SystemCarbon.h"
+# else
+# include "GHOST_SystemX11.h"
+# endif
+#endif
+
+
+GHOST_ISystem* GHOST_ISystem::m_system = 0;
+
+
+GHOST_TSuccess GHOST_ISystem::createSystem()
+{
+ GHOST_TSuccess success;
+ if (!m_system) {
+#ifdef WIN32
+ m_system = new GHOST_SystemWin32 ();
+#else
+# ifdef __APPLE__
+ m_system = new GHOST_SystemCarbon ();
+# else
+ m_system = new GHOST_SystemX11 ();
+# endif
+#endif
+ success = m_system != 0 ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ if (success) {
+ success = m_system->init();
+ }
+ return success;
+}
+
+GHOST_TSuccess GHOST_ISystem::disposeSystem()
+{
+ GHOST_TSuccess success;
+ if (m_system) {
+ delete m_system;
+ m_system = 0;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_ISystem* GHOST_ISystem::getSystem()
+{
+ return m_system;
+}
+
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.cpp b/intern/ghost/intern/GHOST_ModifierKeys.cpp
new file mode 100644
index 00000000000..930ddf97f9a
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ModifierKeys.cpp
@@ -0,0 +1,136 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#include "GHOST_ModifierKeys.h"
+
+
+GHOST_ModifierKeys::GHOST_ModifierKeys()
+{
+ clear();
+}
+
+
+GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKeyMask mask)
+{
+ GHOST_TKey key;
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift: key = GHOST_kKeyLeftShift; break;
+ case GHOST_kModifierKeyRightShift: key = GHOST_kKeyRightShift; break;
+ case GHOST_kModifierKeyLeftAlt: key = GHOST_kKeyLeftAlt; break;
+ case GHOST_kModifierKeyRightAlt: key = GHOST_kKeyRightAlt; break;
+ case GHOST_kModifierKeyLeftControl: key = GHOST_kKeyLeftControl; break;
+ case GHOST_kModifierKeyRightControl: key = GHOST_kKeyRightControl; break;
+ case GHOST_kModifierKeyCommand: key = GHOST_kKeyCommand; break;
+ default:
+ // Should not happen
+ key = GHOST_kKeyUnknown;
+ break;
+ }
+ return key;
+}
+
+
+bool GHOST_ModifierKeys::get(GHOST_TModifierKeyMask mask) const
+{
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift:
+ return m_LeftShift;
+ case GHOST_kModifierKeyRightShift:
+ return m_RightShift;
+ case GHOST_kModifierKeyLeftAlt:
+ return m_LeftAlt;
+ case GHOST_kModifierKeyRightAlt:
+ return m_RightAlt;
+ case GHOST_kModifierKeyLeftControl:
+ return m_LeftControl;
+ case GHOST_kModifierKeyRightControl:
+ return m_RightControl;
+ case GHOST_kModifierKeyCommand:
+ return m_Command;
+ default:
+ return false;
+ }
+}
+
+
+void GHOST_ModifierKeys::set(GHOST_TModifierKeyMask mask, bool down)
+{
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift:
+ m_LeftShift = down; break;
+ case GHOST_kModifierKeyRightShift:
+ m_RightShift = down; break;
+ case GHOST_kModifierKeyLeftAlt:
+ m_LeftAlt = down; break;
+ case GHOST_kModifierKeyRightAlt:
+ m_RightAlt = down; break;
+ case GHOST_kModifierKeyLeftControl:
+ m_LeftControl = down; break;
+ case GHOST_kModifierKeyRightControl:
+ m_RightControl = down; break;
+ case GHOST_kModifierKeyCommand:
+ m_Command = down; break;
+ default:
+ break;
+ }
+}
+
+
+void GHOST_ModifierKeys::clear()
+{
+ m_LeftShift = false;
+ m_RightShift = false;
+ m_LeftAlt = false;
+ m_RightAlt = false;
+ m_LeftControl = false;
+ m_RightControl = false;
+ m_Command = false;
+}
+
+
+bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys& keys) const
+{
+ return (m_LeftShift == keys.m_LeftShift) &&
+ (m_RightShift == keys.m_RightShift) &&
+ (m_LeftAlt == keys.m_LeftAlt) &&
+ (m_RightAlt == keys.m_RightAlt) &&
+ (m_LeftControl == keys.m_LeftControl) &&
+ (m_RightControl == keys.m_RightControl) &&
+ (m_Command == keys.m_Command);
+}
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h
new file mode 100644
index 00000000000..fc590b9597f
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ModifierKeys.h
@@ -0,0 +1,102 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 17, 2001
+ */
+
+#ifndef _GHOST_MODIFIER_KEYS_H_
+#define _GHOST_MODIFIER_KEYS_H_
+
+#include "GHOST_Types.h"
+
+struct GHOST_ModifierKeys
+{
+ /**
+ * Constructor.
+ */
+ GHOST_ModifierKeys();
+
+ /**
+ * Returns the modifier key's key code from a modifier key mask.
+ * @param mask The mask of the modifier key.
+ * @return The modifier key's key code.
+ */
+ static GHOST_TKey getModifierKeyCode(GHOST_TModifierKeyMask mask);
+
+
+ /**
+ * Returns the state of a single modifier key.
+ * @param mask. Key state to return.
+ * @return The state of the key (pressed == true).
+ */
+ virtual bool get(GHOST_TModifierKeyMask mask) const;
+
+ /**
+ * Updates the state of a single modifier key.
+ * @param mask. Key state to update.
+ * @param down. The new state of the key.
+ */
+ virtual void set(GHOST_TModifierKeyMask mask, bool down);
+
+ /**
+ * Sets the state of all modifier keys to up.
+ */
+ virtual void clear();
+
+ /**
+ * Determines whether to modifier key states are equal.
+ * @param keys. The modifier key state to compare to.
+ * @return Indication of equality.
+ */
+ virtual bool equals(const GHOST_ModifierKeys& keys) const;
+
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftShift : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightShift : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftAlt : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightAlt : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftControl : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightControl : 1;
+ /** Bitfield that stores the appropriate key state. APPLE only! */
+ GHOST_TUns8 m_Command : 1;
+};
+
+#endif // _GHOST_MODIFIER_KEYS_H_
diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp
new file mode 100644
index 00000000000..cb600815f69
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Rect.cpp
@@ -0,0 +1,140 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "GHOST_Rect.h"
+
+
+
+void GHOST_Rect::inset(GHOST_TInt32 i)
+{
+ if (i > 0) {
+ // Grow the rectangle
+ m_l -= i;
+ m_r += i;
+ m_t -= i;
+ m_b += i;
+ }
+ else if (i < 0) {
+ // Shrink the rectangle, check for insets larger than half the size
+ GHOST_TInt32 i2 = i * 2;
+ if (getWidth() > i2) {
+ m_l += i;
+ m_r -= i;
+ }
+ else {
+ m_l = m_l + ((m_r - m_l) / 2);
+ m_r = m_l;
+ }
+ if (getHeight() > i2) {
+ m_t += i;
+ m_b -= i;
+ }
+ else {
+ m_t = m_t + ((m_b - m_t) / 2);
+ m_b = m_t;
+ }
+ }
+}
+
+
+GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect& r) const
+{
+ bool lt = isInside(r.m_l, r.m_t);
+ bool rt = isInside(r.m_r, r.m_t);
+ bool lb = isInside(r.m_l, r.m_b);
+ bool rb = isInside(r.m_r, r.m_b);
+ GHOST_TVisibility v;
+ if (lt && rt && lb && rb) {
+ // All points inside, rectangle is inside this
+ v = GHOST_kFullyVisible;
+ }
+ else if (!(lt || rt || lb || rb)) {
+ // None of the points inside
+ // Check to see whether the rectangle is larger than this one
+ if ((r.m_l < m_l) && (r.m_t < m_t) && (r.m_r > m_r) && (r.m_b > m_b)) {
+ v = GHOST_kPartiallyVisible;
+ }
+ else {
+ v = GHOST_kNotVisible;
+ }
+ }
+ else {
+ // Some of the points inside, rectangle is partially inside
+ v = GHOST_kPartiallyVisible;
+ }
+ return v;
+}
+
+
+void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy)
+{
+ GHOST_TInt32 offset = cx - (m_l + (m_r - m_l)/2);
+ m_l += offset;
+ m_r += offset;
+ offset = cy - (m_t + (m_b - m_t)/2);
+ m_t += offset;
+ m_b += offset;
+}
+
+void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h)
+{
+ long w_2, h_2;
+
+ w_2 = w >> 1;
+ h_2 = h >> 1;
+ m_l = cx - w_2;
+ m_t = cy - h_2;
+ m_r = m_l + w;
+ m_b = m_t + h;
+}
+
+bool GHOST_Rect::clip(GHOST_Rect& r) const
+{
+ bool clipped = false;
+ if (r.m_l < m_l) {
+ r.m_l = m_l;
+ clipped = true;
+ }
+ if (r.m_t < m_t) {
+ r.m_t = m_t;
+ clipped = true;
+ }
+ if (r.m_r > m_r) {
+ r.m_r = m_r;
+ clipped = true;
+ }
+ if (r.m_b > m_b) {
+ r.m_b = m_b;
+ clipped = true;
+ }
+ return clipped;
+}
+
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
new file mode 100644
index 00000000000..5585be62f5a
--- /dev/null
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -0,0 +1,320 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#include "GHOST_System.h"
+
+#include <time.h>
+
+#include "GHOST_DisplayManager.h"
+#include "GHOST_EventManager.h"
+#include "GHOST_TimerTask.h"
+#include "GHOST_TimerManager.h"
+#include "GHOST_WindowManager.h"
+
+
+GHOST_System::GHOST_System()
+: m_displayManager(0), m_timerManager(0), m_windowManager(0), m_eventManager(0)
+{
+}
+
+
+GHOST_System::~GHOST_System()
+{
+ exit();
+}
+
+
+GHOST_TUns64 GHOST_System::getMilliSeconds() const
+{
+ GHOST_TUns64 millis = ::clock();
+ if (CLOCKS_PER_SEC != 1000) {
+ millis *= 1000;
+ millis /= CLOCKS_PER_SEC;
+ }
+ return millis;
+}
+
+
+GHOST_ITimerTask* GHOST_System::installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData)
+{
+ GHOST_TUns64 millis = getMilliSeconds();
+ GHOST_TimerTask* timer = new GHOST_TimerTask(millis+delay, interval, timerProc, userData);
+ if (timer) {
+ if (m_timerManager->addTimer(timer) == GHOST_kSuccess) {
+ // Check to see whether we need to fire the timer right away
+ m_timerManager->fireTimers(millis);
+ }
+ else {
+ delete timer;
+ timer = 0;
+ }
+ }
+ return timer;
+}
+
+
+GHOST_TSuccess GHOST_System::removeTimer(GHOST_ITimerTask* timerTask)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (timerTask) {
+ success = m_timerManager->removeTimer((GHOST_TimerTask*)timerTask);
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::disposeWindow(GHOST_IWindow* window)
+{
+ GHOST_TSuccess success;
+ if (window == m_windowManager->getFullScreenWindow()) {
+ success = endFullScreen();
+ }
+ else {
+ if (m_windowManager->getWindowFound(window)) {
+ success = m_windowManager->removeWindow(window);
+ if (success) {
+ delete window;
+ }
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
+}
+
+
+bool GHOST_System::validWindow(GHOST_IWindow* window)
+{
+ return m_windowManager->getWindowFound(window);
+}
+
+
+GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
+ bool stereoVisual)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager")
+ if (m_displayManager) {
+ if (!m_windowManager->getFullScreen()) {
+ m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
+
+ //GHOST_PRINT("GHOST_System::beginFullScreen(): activating new display settings\n");
+ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
+ if (success == GHOST_kSuccess) {
+ //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
+ success = createFullScreenWindow((GHOST_Window**)window, stereoVisual);
+ if (success == GHOST_kSuccess) {
+ m_windowManager->beginFullScreen(*window, stereoVisual);
+ }
+ else {
+ m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
+ }
+ }
+ }
+ }
+ if (success == GHOST_kFailure) {
+ GHOST_PRINT("GHOST_System::beginFullScreen(): could not enter full-screen mode\n");
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::endFullScreen(void)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(m_windowManager, "GHOST_System::endFullScreen(): invalid window manager")
+ if (m_windowManager->getFullScreen()) {
+ GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
+ //GHOST_PRINT("GHOST_System::endFullScreen(): leaving window manager full-screen mode\n");
+ success = m_windowManager->endFullScreen();
+ GHOST_ASSERT(m_displayManager, "GHOST_System::endFullScreen(): invalid display manager")
+ //GHOST_PRINT("GHOST_System::endFullScreen(): leaving full-screen mode\n");
+ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+bool GHOST_System::getFullScreen(void)
+{
+ bool fullScreen;
+ if (m_windowManager) {
+ fullScreen = m_windowManager->getFullScreen();
+ }
+ else {
+ fullScreen = false;
+ }
+ return fullScreen;
+}
+
+
+bool GHOST_System::dispatchEvents()
+{
+ bool handled;
+ if (m_eventManager) {
+ handled = m_eventManager->dispatchEvents();
+ }
+ else {
+ handled = false;
+ }
+
+ m_timerManager->fireTimers(getMilliSeconds());
+ return handled;
+}
+
+
+GHOST_TSuccess GHOST_System::addEventConsumer(GHOST_IEventConsumer* consumer)
+{
+ GHOST_TSuccess success;
+ if (m_eventManager) {
+ success = m_eventManager->addConsumer(consumer);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event)
+{
+ GHOST_TSuccess success;
+ if (m_eventManager) {
+ success = m_eventManager->pushEvent(event);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
+{
+ GHOST_ModifierKeys keys;
+ // Get the state of all modifier keys
+ GHOST_TSuccess success = getModifierKeys(keys);
+ if (success) {
+ // Isolate the state of the key requested
+ isDown = keys.get(mask);
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown) const
+{
+ GHOST_Buttons buttons;
+ // Get the state of all mouse buttons
+ GHOST_TSuccess success = getButtons(buttons);
+ if (success) {
+ // Isolate the state of the mouse button requested
+ isDown = buttons.get(mask);
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_System::init()
+{
+ m_timerManager = new GHOST_TimerManager ();
+ m_windowManager = new GHOST_WindowManager ();
+ m_eventManager = new GHOST_EventManager ();
+#ifdef GHOST_DEBUG
+ if (m_eventManager) {
+ //m_eventManager->addConsumer(&m_eventPrinter);
+ }
+#endif // GHOST_DEBUG
+
+ if (m_timerManager && m_windowManager && m_eventManager) {
+ return GHOST_kSuccess;
+ } else {
+ return GHOST_kFailure;
+ }
+}
+
+
+GHOST_TSuccess GHOST_System::exit()
+{
+ if (getFullScreen()) {
+ endFullScreen();
+ }
+ if (m_displayManager) {
+ delete m_displayManager;
+ m_displayManager = 0;
+ }
+ if (m_windowManager) {
+ delete m_windowManager;
+ m_windowManager = 0;
+ }
+ if (m_timerManager) {
+ delete m_timerManager;
+ m_timerManager = 0;
+ }
+ if (m_eventManager) {
+ delete m_eventManager;
+ m_eventManager = 0;
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, bool stereoVisual)
+{
+ GHOST_TSuccess success;
+ GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager")
+ GHOST_DisplaySetting settings;
+
+ success = m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, settings);
+ if (success) {
+ //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
+ *window = (GHOST_Window*)createWindow(
+ STR_String (""),
+ 0, 0, settings.xPixels, settings.yPixels,
+ GHOST_kWindowStateFullScreen,
+ GHOST_kDrawingContextTypeOpenGL,
+ stereoVisual);
+ success = *window == 0 ? GHOST_kFailure : GHOST_kSuccess;
+ }
+ return success;
+}
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
new file mode 100644
index 00000000000..52d90cab7a7
--- /dev/null
+++ b/intern/ghost/intern/GHOST_System.h
@@ -0,0 +1,328 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#ifndef _GHOST_SYSTEM_H_
+#define _GHOST_SYSTEM_H_
+
+#include "GHOST_ISystem.h"
+
+#include "GHOST_Debug.h"
+#include "GHOST_Buttons.h"
+#include "GHOST_ModifierKeys.h"
+#include "GHOST_EventManager.h"
+#ifdef GHOST_DEBUG
+#include "GHOST_EventPrinter.h"
+#endif // GHOST_DEBUG
+
+class GHOST_DisplayManager;
+class GHOST_Event;
+class GHOST_TimerManager;
+class GHOST_Window;
+class GHOST_WindowManager;
+
+/**
+ * Implementation of platform independent functionality of the GHOST_ISystem interface.
+ * GHOST_System is an abstract base class because not all methods of GHOST_ISystem are implemented.
+ * There should be only one system class in an application.
+ * Therefore, the routines to create and dispose the system are static.
+ * Provides:
+ * 1. Time(r) management.
+ * 2. Display/window management (windows are only created on the main display for now).
+ * 3. Event management.
+ * 4. Cursor shape management (no custom cursors for now).
+ * 5. Access to the state of the mouse buttons and the keyboard.
+ * @see GHOST_ISystem.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+class GHOST_System : public GHOST_ISystem
+{
+protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_System();
+
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_System();
+
+public:
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * @return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const;
+
+ /**
+ * Installs a timer.
+ * Note that, on most operating systems, messages need to be processed in order
+ * for the timer callbacks to be invoked.
+ * @param delay The time to wait for the first call to the timerProc (in milliseconds)
+ * @param interval The interval between calls to the timerProc
+ * @param timerProc The callback invoked when the interval expires,
+ * @param userData Placeholder for user data.
+ * @return A timer task (0 if timer task installation failed).
+ */
+ virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0);
+
+ /**
+ * Removes a timer.
+ * @param timerTask Timer task to be removed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask* timerTask);
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Inherited from GHOST_ISystem but left pure virtual
+ *
+ * virtual GHOST_TUns8 getNumDisplays() const = 0;
+ * virtual void getMainDisplayDimensions(...) const = 0;
+ * virtual GHOST_IWindow* createWindow(..)
+ */
+
+ /**
+ * Dispose a window.
+ * @param window Pointer to the window to be disposed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess disposeWindow(GHOST_IWindow* window);
+
+ /**
+ * Returns whether a window is valid.
+ * @param window Pointer to the window to be checked.
+ * @return Indication of validity.
+ */
+ virtual bool validWindow(GHOST_IWindow* window);
+
+ /**
+ * Begins full screen mode.
+ * @param setting The new setting of the display.
+ * @param window Window displayed in full screen.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * This window is invalid after full screen has been ended.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
+ const bool stereoVisual);
+
+ /**
+ * Ends full screen mode.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess endFullScreen(void);
+
+ /**
+ * Returns current full screen mode status.
+ * @return The current status.
+ */
+ virtual bool getFullScreen(void);
+
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Inherited from GHOST_ISystem but left pure virtual
+ *
+ * virtual bool processEvents(bool waitForEvent) = 0;
+ */
+
+
+
+ /**
+ * Dispatches all the events on the stack.
+ * The event stack will be empty afterwards.
+ * @return Indication as to whether any of the consumers handled the events.
+ */
+ virtual bool dispatchEvents();
+
+ /**
+ * Adds the given event consumer to our list.
+ * @param consumer The event consumer to add.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer* consumer);
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /** Inherited from GHOST_ISystem but left pure virtual
+ * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
+ * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
+ */
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of a modifier key (ouside the message queue).
+ * @param mask The modifier key state to retrieve.
+ * @param isDown The state of a modifier key (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const;
+
+ /**
+ * Returns the state of a mouse button (ouside the message queue).
+ * @param mask The button state to retrieve.
+ * @param isDown Button state.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
+
+ /***************************************************************************************
+ ** Other (internal) functionality.
+ ***************************************************************************************/
+
+ /**
+ * Pushes an event on the stack.
+ * To dispatch it, call dispatchEvent() or dispatchEvents().
+ * Do not delete the event!
+ * @param event The event to push on the stack.
+ */
+ virtual GHOST_TSuccess pushEvent(GHOST_IEvent* event);
+
+ /**
+ * Returns the timer manager.
+ * @return The timer manager.
+ */
+ inline virtual GHOST_TimerManager* getTimerManager() const;
+
+ /**
+ * Returns a pointer to our event manager.
+ * @return A pointer to our event manager.
+ */
+ virtual inline GHOST_EventManager* getEventManager() const;
+
+ /**
+ * Returns a pointer to our window manager.
+ * @return A pointer to our window manager.
+ */
+ virtual inline GHOST_WindowManager* getWindowManager() const;
+
+ /**
+ * Returns the state of all modifier keys.
+ * @param keys The state of all modifier keys (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const = 0;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * @param buttons The state of the buttons.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const = 0;
+
+protected:
+ /**
+ * Initialize the system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess init();
+
+ /**
+ * Shut the system down.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess exit();
+
+ /**
+ * Creates a fullscreen window.
+ * @param window The window created.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window** window,
+ const bool stereoVisual);
+
+ /** The display manager (platform dependant). */
+ GHOST_DisplayManager* m_displayManager;
+
+ /** The timer manager. */
+ GHOST_TimerManager* m_timerManager;
+
+ /** The window manager. */
+ GHOST_WindowManager* m_windowManager;
+
+ /** The event manager. */
+ GHOST_EventManager* m_eventManager;
+
+ /** Prints all the events. */
+#ifdef GHOST_DEBUG
+ GHOST_EventPrinter m_eventPrinter;
+#endif // GHOST_DEBUG
+
+ /** Settings of the display before the display went fullscreen. */
+ GHOST_DisplaySetting m_preFullScreenSetting;
+};
+
+inline GHOST_TimerManager* GHOST_System::getTimerManager() const
+{
+ return m_timerManager;
+}
+
+inline GHOST_EventManager* GHOST_System::getEventManager() const
+{
+ return m_eventManager;
+}
+
+inline GHOST_WindowManager* GHOST_System::getWindowManager() const
+{
+ return m_windowManager;
+}
+
+#endif // _GHOST_SYSTEM_H_
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
new file mode 100644
index 00000000000..baba1bb4e6c
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -0,0 +1,735 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#include "GHOST_SystemCarbon.h"
+
+#include "GHOST_DisplayManagerCarbon.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_TimerManager.h"
+#include "GHOST_TimerTask.h"
+#include "GHOST_WindowManager.h"
+#include "GHOST_WindowCarbon.h"
+
+#define GHOST_KEY_SWITCH(mac, ghost) { case (mac): ghostKey = (ghost); break; }
+
+const EventTypeSpec kEvents[] =
+{
+ { kEventClassAppleEvent, kEventAppleEvent },
+
+/*
+ { kEventClassApplication, kEventAppActivated },
+ { kEventClassApplication, kEventAppDeactivated },
+*/
+
+ { kEventClassKeyboard, kEventRawKeyDown },
+ { kEventClassKeyboard, kEventRawKeyRepeat },
+ { kEventClassKeyboard, kEventRawKeyUp },
+ { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseUp },
+ { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseDragged },
+
+ { kEventClassWindow, kEventWindowClose },
+ { kEventClassWindow, kEventWindowActivated },
+ { kEventClassWindow, kEventWindowDeactivated },
+ { kEventClassWindow, kEventWindowUpdate },
+ { kEventClassWindow, kEventWindowBoundsChanged }
+};
+
+static GHOST_TButtonMask convertButton(EventMouseButton button)
+{
+ switch (button) {
+ case kEventMouseButtonPrimary:
+ return GHOST_kButtonMaskLeft;
+ case kEventMouseButtonSecondary:
+ return GHOST_kButtonMaskRight;
+ case kEventMouseButtonTertiary:
+ default:
+ return GHOST_kButtonMaskMiddle;
+ }
+}
+
+static GHOST_TKey convertKey(int rawCode)
+{
+ /* This bit of magic converts the rawCode into a virtual
+ * Mac key based on the current keyboard mapping, but
+ * without regard to the modifiers (so we don't get 'a'
+ * and 'A' for example.
+ */
+ UInt32 dummy= 0;
+ Handle transData = (Handle) GetScriptManagerVariable(smKCHRCache);
+ char vk = KeyTranslate(transData, rawCode, &dummy);
+
+ /* Map numpad based on rawcodes first, otherwise they
+ * look like non-numpad events.
+ */
+ switch (rawCode) {
+ case 82: return GHOST_kKeyNumpad0;
+ case 83: return GHOST_kKeyNumpad1;
+ case 84: return GHOST_kKeyNumpad2;
+ case 85: return GHOST_kKeyNumpad3;
+ case 86: return GHOST_kKeyNumpad4;
+ case 87: return GHOST_kKeyNumpad5;
+ case 88: return GHOST_kKeyNumpad6;
+ case 89: return GHOST_kKeyNumpad7;
+ case 91: return GHOST_kKeyNumpad8;
+ case 92: return GHOST_kKeyNumpad9;
+ case 65: return GHOST_kKeyNumpadPeriod;
+ case 76: return GHOST_kKeyNumpadEnter;
+ case 69: return GHOST_kKeyNumpadPlus;
+ case 78: return GHOST_kKeyNumpadMinus;
+ case 67: return GHOST_kKeyNumpadAsterisk;
+ case 75: return GHOST_kKeyNumpadSlash;
+ }
+
+ if ((vk >= 'a') && (vk <= 'z')) {
+ return (GHOST_TKey) (vk - 'a' + GHOST_kKeyA);
+ } else if ((vk >= '0') && (vk <= '9')) {
+ return (GHOST_TKey) (vk - '0' + GHOST_kKey0);
+ } else if (vk==16) {
+ switch (rawCode) {
+ case 122: return GHOST_kKeyF1;
+ case 120: return GHOST_kKeyF2;
+ case 99: return GHOST_kKeyF3;
+ case 118: return GHOST_kKeyF4;
+ case 96: return GHOST_kKeyF5;
+ case 97: return GHOST_kKeyF6;
+ case 98: return GHOST_kKeyF7;
+ case 100: return GHOST_kKeyF8;
+ case 101: return GHOST_kKeyF9;
+ case 109: return GHOST_kKeyF10;
+ case 103: return GHOST_kKeyF11;
+ case 111: return GHOST_kKeyF12; // Never get, is used for ejecting the CD!
+ }
+ } else {
+ switch (vk) {
+ case kUpArrowCharCode: return GHOST_kKeyUpArrow;
+ case kDownArrowCharCode: return GHOST_kKeyDownArrow;
+ case kLeftArrowCharCode: return GHOST_kKeyLeftArrow;
+ case kRightArrowCharCode: return GHOST_kKeyRightArrow;
+
+ case kReturnCharCode: return GHOST_kKeyEnter;
+ case kBackspaceCharCode: return GHOST_kKeyBackSpace;
+ case kDeleteCharCode: return GHOST_kKeyDelete;
+ case kEscapeCharCode: return GHOST_kKeyEsc;
+ case kTabCharCode: return GHOST_kKeyTab;
+ case kSpaceCharCode: return GHOST_kKeySpace;
+
+ case kHomeCharCode: return GHOST_kKeyHome;
+ case kEndCharCode: return GHOST_kKeyEnd;
+ case kPageUpCharCode: return GHOST_kKeyUpPage;
+ case kPageDownCharCode: return GHOST_kKeyDownPage;
+
+ case '-': return GHOST_kKeyMinus;
+ case '=': return GHOST_kKeyEqual;
+ case ',': return GHOST_kKeyComma;
+ case '.': return GHOST_kKeyPeriod;
+ case '/': return GHOST_kKeySlash;
+ case ';': return GHOST_kKeySemicolon;
+ case '\'': return GHOST_kKeyQuote;
+ case '\\': return GHOST_kKeyBackslash;
+ case '[': return GHOST_kKeyLeftBracket;
+ case ']': return GHOST_kKeyRightBracket;
+ case '`': return GHOST_kKeyAccentGrave;
+ }
+ }
+
+ printf("GHOST: unknown key: %d %d\n", vk, rawCode);
+
+ return GHOST_kKeyUnknown;
+}
+
+/***/
+
+GHOST_SystemCarbon::GHOST_SystemCarbon() :
+ m_modifierMask(0)
+{
+ m_displayManager = new GHOST_DisplayManagerCarbon ();
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemCarbon::GHOST_SystemCarbon(): m_displayManager==0\n");
+ m_displayManager->initialize();
+
+ UnsignedWide micros;
+ ::Microseconds(&micros);
+ UInt64 millis;
+ m_start_time = UnsignedWideToUInt64(micros)/1000;
+}
+
+GHOST_SystemCarbon::~GHOST_SystemCarbon()
+{
+}
+
+
+GHOST_TUns64 GHOST_SystemCarbon::getMilliSeconds() const
+{
+ UnsignedWide micros;
+ ::Microseconds(&micros);
+ UInt64 millis;
+ millis = UnsignedWideToUInt64(micros);
+ return (millis / 1000) - m_start_time;
+}
+
+
+GHOST_TUns8 GHOST_SystemCarbon::getNumDisplays() const
+{
+ // We do not support multiple monitors at the moment
+ return 1;
+}
+
+
+void GHOST_SystemCarbon::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ BitMap screenBits;
+ Rect bnds = GetQDGlobalsScreenBits(&screenBits)->bounds;
+ width = bnds.right - bnds.left;
+ height = bnds.bottom - bnds.top;
+}
+
+
+GHOST_IWindow* GHOST_SystemCarbon::createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool stereoVisual
+)
+{
+ GHOST_IWindow* window = 0;
+ window = new GHOST_WindowCarbon (title, left, top, width, height, state, type);
+ if (window) {
+ if (window->getValid()) {
+ // Store the pointer to the window
+ GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCarbon::createWindow(): window invalid\n");
+ delete window;
+ window = 0;
+ }
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCarbon::createWindow(): could not create window\n");
+ }
+ return window;
+}
+
+
+bool GHOST_SystemCarbon::processEvents(bool waitForEvent)
+{
+ bool anyProcessed = false;
+ EventRef event;
+
+ do {
+ GHOST_TimerManager* timerMgr = getTimerManager();
+
+ if (waitForEvent) {
+ GHOST_TUns64 curtime = getMilliSeconds();
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+ double timeOut;
+
+ if (next == GHOST_kFireTimeNever) {
+ timeOut = kEventDurationForever;
+ } else {
+ if (next<=curtime)
+ timeOut = 0.0;
+ else
+ timeOut = (double) (next - getMilliSeconds())/1000.0;
+ }
+
+ ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
+
+ if (getFullScreen()) {
+ // Check if the full-screen window is dirty
+ GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
+ if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+ anyProcessed = true;
+ }
+ }
+
+ while (::ReceiveNextEvent(0, NULL, 0, true, &event)==noErr) {
+ OSStatus status= ::SendEventToEventTarget(event, ::GetEventDispatcherTarget());
+ if (status==noErr) {
+ anyProcessed = true;
+ } else {
+ UInt32 i= ::GetEventClass(event);
+
+ /* Ignore 'cgs ' class, no documentation on what they
+ * are, but we get a lot of them
+ */
+ if (i!='cgs ') {
+ //printf("Missed - Class: '%.4s', Kind: %d\n", &i, ::GetEventKind(event));
+ }
+ }
+ ::ReleaseEvent(event);
+ }
+ } while (waitForEvent && !anyProcessed);
+
+ return anyProcessed;
+}
+
+
+GHOST_TSuccess GHOST_SystemCarbon::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
+{
+ Point mouseLoc;
+ // Get the position of the mouse in the active port
+ ::GetGlobalMouse(&mouseLoc);
+ // Convert the coordinates to screen coordinates
+ x = (GHOST_TInt32)mouseLoc.h;
+ y = (GHOST_TInt32)mouseLoc.v;
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemCarbon::setCursorPosition(GHOST_TInt32 /*x*/, GHOST_TInt32 /*y*/) const
+{
+ // Not supported in Carbon!
+ return GHOST_kFailure;
+}
+
+
+GHOST_TSuccess GHOST_SystemCarbon::getModifierKeys(GHOST_ModifierKeys& keys) const
+{
+ UInt32 modifiers = ::GetCurrentKeyModifiers();
+
+ keys.set(GHOST_kModifierKeyCommand, (modifiers & cmdKey) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & optionKey) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftShift, (modifiers & shiftKey) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftControl, (modifiers & controlKey) ? true : false);
+
+ return GHOST_kSuccess;
+}
+
+ /* XXX, incorrect for multibutton mice */
+GHOST_TSuccess GHOST_SystemCarbon::getButtons(GHOST_Buttons& buttons) const
+{
+ Boolean theOnlyButtonIsDown = ::Button();
+ buttons.clear();
+ buttons.set(GHOST_kButtonMaskLeft, theOnlyButtonIsDown);
+ return GHOST_kSuccess;
+}
+
+static bool g_hasFirstFile = false;
+static char g_firstFileBuf[512];
+
+extern "C" int GHOST_HACK_getFirstFile(char buf[512]) {
+ if (g_hasFirstFile) {
+ strcpy(buf, g_firstFileBuf);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+ AEDescList docs;
+ SInt32 ndocs;
+ OSErr err;
+
+ err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);
+ if (err != noErr) return err;
+
+ err = AECountItems(&docs, &ndocs);
+ if (err==noErr) {
+ int i;
+
+ for (i=0; i<ndocs; i++) {
+ FSSpec fss;
+ AEKeyword kwd;
+ DescType actType;
+ Size actSize;
+
+ err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);
+ if (err!=noErr)
+ break;
+
+ if (i==0) {
+ FSRef fsref;
+
+ if (FSpMakeFSRef(&fss, &fsref)!=noErr)
+ break;
+ if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)
+ break;
+
+ g_hasFirstFile = true;
+ }
+ }
+ }
+
+ AEDisposeDesc(&docs);
+
+ return err;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
+
+ return noErr;
+}
+
+
+GHOST_TSuccess GHOST_SystemCarbon::init()
+{
+ GHOST_TSuccess success = GHOST_System::init();
+ if (success) {
+ /*
+ * Initialize the cursor to the standard arrow shape (so that we can change it later on).
+ * This initializes the cursor's visibility counter to 0.
+ */
+ ::InitCursor();
+
+ MenuRef windMenu;
+ ::CreateStandardWindowMenu(0, &windMenu);
+ ::InsertMenu(windMenu, 0);
+ ::DrawMenuBar();
+
+ ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
+
+ ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false);
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_SystemCarbon::exit()
+{
+ return GHOST_System::exit();
+}
+
+
+OSStatus GHOST_SystemCarbon::handleWindowEvent(EventRef event)
+{
+ GHOST_WindowCarbon *window;
+
+ if (!getFullScreen()) {
+ WindowRef windowref;
+ ::GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &windowref);
+ window = (GHOST_WindowCarbon*) ::GetWRefCon(windowref);
+
+ if (validWindow(window)) {
+ switch(::GetEventKind(event))
+ {
+ case kEventWindowClose:
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
+ break;
+ case kEventWindowActivated:
+ m_windowManager->setActiveWindow(window);
+ window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
+ break;
+ case kEventWindowDeactivated:
+ m_windowManager->setWindowInactive(window);
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
+ break;
+ case kEventWindowUpdate:
+ //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n");
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+ break;
+ case kEventWindowBoundsChanged:
+ window->updateDrawingContext();
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
+ break;
+ }
+ }
+ }
+ //else {
+ //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow();
+ //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n");
+ //::RemoveEventFromQueue(::GetMainEventQueue(), event);
+ //}
+
+ return noErr;
+}
+
+OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
+{
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ UInt32 kind = ::GetEventKind(event);
+
+ switch (kind)
+ {
+ case kEventMouseDown:
+ case kEventMouseUp:
+ // Handle Mac application responsibilities
+ if ((kind == kEventMouseDown) && handleMouseDown(event)) {
+ ;
+ } else {
+ GHOST_TEventType type = (kind == kEventMouseDown) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp;
+ EventMouseButton button;
+
+ /* Window still gets mouse up after command-H */
+ if (window) {
+ ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
+ pushEvent(new GHOST_EventButton(getMilliSeconds(), type, window, convertButton(button)));
+ }
+ }
+ break;
+
+ case kEventMouseMoved:
+ case kEventMouseDragged:
+ Point mousePos;
+ if (window) {
+ ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
+ pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, mousePos.h, mousePos.v));
+ }
+ break;
+ }
+
+ return noErr;
+}
+
+
+OSStatus GHOST_SystemCarbon::handleKeyEvent(EventRef event)
+{
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ UInt32 kind = ::GetEventKind(event);
+ UInt32 modifiers;
+ UInt32 rawCode;
+ GHOST_TKey key;
+ char ascii;
+
+ /* Can happen, very rarely - seems to only be when command-H makes
+ * the window go away and we still get an HKey up.
+ */
+ if (!window) {
+ ::GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &rawCode);
+ key = convertKey(rawCode);
+ return noErr;
+ }
+
+ switch (kind) {
+ case kEventRawKeyDown:
+ case kEventRawKeyRepeat:
+ case kEventRawKeyUp:
+ ::GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &rawCode);
+ ::GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &ascii);
+ key = convertKey(rawCode);
+ if (key!=GHOST_kKeyUnknown) {
+ GHOST_TEventType type;
+ if (kind == kEventRawKeyDown) {
+ type = GHOST_kEventKeyDown;
+ } else if (kind == kEventRawKeyRepeat) {
+ type = GHOST_kEventKeyDown; /* XXX, fixme */
+ } else {
+ type = GHOST_kEventKeyUp;
+ }
+ pushEvent( new GHOST_EventKey( getMilliSeconds(), type, window, key, ascii) );
+ }
+ break;
+
+ case kEventRawKeyModifiersChanged:
+ /* ugh */
+ ::GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+ if ((modifiers & shiftKey) != (m_modifierMask & shiftKey)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & shiftKey)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
+ }
+ if ((modifiers & controlKey) != (m_modifierMask & controlKey)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & controlKey)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
+ }
+ if ((modifiers & optionKey) != (m_modifierMask & optionKey)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & optionKey)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
+ }
+ if ((modifiers & cmdKey) != (m_modifierMask & cmdKey)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & cmdKey)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
+ }
+
+ m_modifierMask = modifiers;
+ break;
+ }
+
+ return noErr;
+}
+
+
+bool GHOST_SystemCarbon::handleMouseDown(EventRef event)
+{
+ WindowPtr window;
+ short part;
+ BitMap screenBits;
+ bool handled = true;
+ GHOST_IWindow* ghostWindow;
+ Point mousePos = {0 , 0};
+
+ ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
+
+ part = ::FindWindow(mousePos, &window);
+ ghostWindow = (GHOST_IWindow*) ::GetWRefCon(window);
+ GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseEvent: invalid window");
+
+ switch (part) {
+ case inMenuBar:
+ handleMenuCommand(::MenuSelect(mousePos));
+ break;
+
+ case inDrag:
+ ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds);
+ break;
+
+ case inContent:
+ if (window != ::FrontWindow()) {
+ ::SelectWindow(window);
+ } else {
+ handled = false;
+ }
+ break;
+
+ case inGoAway:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ if (::TrackGoAway(window, mousePos))
+ {
+ // todo: add option-close, because itÕs in the HIG
+ // if (event.modifiers & optionKey) {
+ // Close the clean documents, others will be confirmed one by one.
+ //}
+ // else {
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow));
+ //}
+ }
+ break;
+
+ case inGrow:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ ::ResizeWindow(window, mousePos, NULL, NULL);
+ break;
+
+ case inZoomIn:
+ case inZoomOut:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ if (::TrackBox(window, mousePos, part)) {
+ ::ZoomWindow(window, part, true);
+ }
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+
+ return handled;
+}
+
+
+bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult)
+{
+ short menuID;
+ short menuItem;
+ UInt32 command;
+ bool handled;
+ OSErr err;
+
+ menuID = HiWord(menuResult);
+ menuItem = LoWord(menuResult);
+
+ err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command);
+
+ handled = false;
+
+ if (err || command == 0) {
+ }
+ else {
+ switch(command) {
+ }
+ }
+
+ ::HiliteMenu(0);
+ return handled;
+}
+
+OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) userData;
+ OSStatus err = eventNotHandledErr;
+
+ switch (::GetEventClass(event))
+ {
+ case kEventClassAppleEvent:
+ EventRecord eventrec;
+ if (ConvertEventRefToEventRecord(event, &eventrec)) {
+ err = AEProcessAppleEvent(&eventrec);
+ }
+ break;
+ case kEventClassMouse:
+ err = sys->handleMouseEvent(event);
+ break;
+ case kEventClassWindow:
+ err = sys->handleWindowEvent(event);
+ break;
+ case kEventClassKeyboard:
+ err = sys->handleKeyEvent(event);
+ break;
+ }
+
+ return err;
+}
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
new file mode 100644
index 00000000000..17c09e8e91f
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -0,0 +1,251 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _GHOST_SYSTEM_CARBON_H_
+#define _GHOST_SYSTEM_CARBON_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+#include <Carbon/Carbon.h>
+
+#include "GHOST_System.h"
+
+
+class GHOST_EventCursor;
+class GHOST_EventKey;
+class GHOST_EventWindow;
+
+/**
+ * OSX/Carbon Implementation of GHOST_System class.
+ * @see GHOST_System.
+ * @author Maarten Gribnau
+ * @date May 21, 2001
+ */
+class GHOST_SystemCarbon : public GHOST_System {
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemCarbon::GHOST_SystemCarbon();
+
+ /**
+ * Destructor.
+ */
+ GHOST_SystemCarbon::~GHOST_SystemCarbon();
+
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * @return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const;
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * @return The number of displays.
+ */
+ virtual GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @return The new window (or 0 if creation failed).
+ */
+ virtual GHOST_IWindow* createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual
+ );
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Gets events from the system and stores them in the queue.
+ * @param waitForEvent Flag to wait for an event (or return immediately).
+ * @return Indication of the presence of events.
+ */
+ virtual bool processEvents(bool waitForEvent);
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of all modifier keys.
+ * @param keys The state of all modifier keys (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * @param buttons The state of the buttons.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+
+protected:
+ /**
+ * Initializes the system.
+ * For now, it justs registers the window class (WNDCLASS).
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess init();
+
+ /**
+ * Closes the system down.
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess exit();
+
+ /**
+ * Handles a mouse event.
+ * @param event A Mac event.
+ * @return Indication whether the event was handled.
+ */
+ OSStatus handleMouseEvent(EventRef event);
+
+ /**
+ * Handles a key event.
+ * @param event A Mac event.
+ * @return Indication whether the event was handled.
+ */
+ OSStatus handleKeyEvent(EventRef event);
+
+ /**
+ * Handles a window event.
+ * @param event A Mac event.
+ * @return Indication whether the event was handled.
+ */
+ OSStatus handleWindowEvent(EventRef event);
+
+ /**
+ * Handles all basic Mac application stuff for a mouse down event.
+ * @param event A Mac event.
+ * @return Indication whether the event was handled.
+ */
+ bool handleMouseDown(EventRef event);
+
+ /**
+ * Handles a Mac menu command.
+ * @param menuResult A Mac menu/item identifier.
+ * @return Indication whether the event was handled.
+ */
+ bool handleMenuCommand(GHOST_TInt32 menuResult);
+
+ /**
+ * Callback for Carbon when it has events.
+ */
+ static OSStatus sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
+
+ /** Apple Event Handlers */
+ static OSErr sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
+ static OSErr sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
+ static OSErr sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
+ static OSErr sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
+
+ /**
+ * Callback for Mac Timer tasks that expire.
+ * @param tmTask Pointer to the timer task that expired.
+ */
+ //static void s_timerCallback(TMTaskPtr tmTask);
+
+ /** Event handler reference. */
+ EventHandlerRef m_handler;
+
+ /** Start time at initialization. */
+ GHOST_TUns64 m_start_time;
+
+ /** State of the modifiers. */
+ UInt32 m_modifierMask;
+};
+
+#endif // _GHOST_SYSTEM_CARBON_H_
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
new file mode 100644
index 00000000000..099706b7e82
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -0,0 +1,65 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 22, 2001
+ */
+
+#ifndef _GHOST_SYSTEM_CARBON_H_
+#define _GHOST_SYSTEM_CARBON_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+#include "GHOST_System.h"
+#include "GHOST_Keys.h"
+
+#include <Carbon/Carbon.h>
+
+class GHOST_EventCursor;
+class GHOST_EventKey;
+class GHOST_EventWindow;
+
+/**
+ * OSX/Cocoa Implementation of GHOST_System class.
+ * @see GHOST_System.
+ * @author Maarten Gribnau
+ * @date May 21, 2001
+ */
+class GHOST_SystemCarbon : public GHOST_System {
+};
+
+#endif // _GHOST_SYSTEM_CARBON_H_
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
new file mode 100644
index 00000000000..6dc00bd1847
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -0,0 +1,817 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#include "GHOST_SystemWin32.h"
+
+
+#include "GHOST_Debug.h"
+#include "GHOST_DisplayManagerWin32.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_TimerTask.h"
+#include "GHOST_TimerManager.h"
+#include "GHOST_WindowManager.h"
+#include "GHOST_WindowWin32.h"
+
+// Key code values not found in winuser.h
+#ifndef VK_MINUS
+#define VK_MINUS 0xBD
+#endif // VK_MINUS
+#ifndef VK_SEMICOLON
+#define VK_SEMICOLON 0xBA
+#endif // VK_SEMICOLON
+#ifndef VK_PERIOD
+#define VK_PERIOD 0xBE
+#endif // VK_PERIOD
+#ifndef VK_COMMA
+#define VK_COMMA 0xBC
+#endif // VK_COMMA
+#ifndef VK_QUOTE
+#define VK_QUOTE 0xDE
+#endif // VK_QUOTE
+#ifndef VK_BACK_QUOTE
+#define VK_BACK_QUOTE 0xC0
+#endif // VK_BACK_QUOTE
+#ifndef VK_SLASH
+#define VK_SLASH 0xBF
+#endif // VK_SLASH
+#ifndef VK_BACK_SLASH
+#define VK_BACK_SLASH 0xDC
+#endif // VK_BACK_SLASH
+#ifndef VK_EQUALS
+#define VK_EQUALS 0xBB
+#endif // VK_EQUALS
+#ifndef VK_OPEN_BRACKET
+#define VK_OPEN_BRACKET 0xDB
+#endif // VK_OPEN_BRACKET
+#ifndef VK_CLOSE_BRACKET
+#define VK_CLOSE_BRACKET 0xDD
+#endif // VK_CLOSE_BRACKET
+
+
+GHOST_SystemWin32::GHOST_SystemWin32()
+: m_hasPerformanceCounter(false), m_freq(0), m_start(0),
+ m_seperateLeftRight(false),
+ m_seperateLeftRightInitialized(false)
+{
+ m_displayManager = new GHOST_DisplayManagerWin32 ();
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
+ m_displayManager->initialize();
+}
+
+GHOST_SystemWin32::~GHOST_SystemWin32()
+{
+}
+
+
+GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const
+{
+ // Hardware does not support high resolution timers. We will use GetTickCount instead then.
+ if (!m_hasPerformanceCounter) {
+ return ::GetTickCount();
+ }
+
+ // Retrieve current count
+ __int64 count = 0;
+ ::QueryPerformanceCounter((LARGE_INTEGER*)&count);
+
+ // Calculate the time passed since system initialization.
+ __int64 delta = 1000*(count-m_start);
+
+ GHOST_TUns64 t = (GHOST_TUns64)(delta/m_freq);
+ return t;
+}
+
+
+GHOST_TUns8 GHOST_SystemWin32::getNumDisplays() const
+{
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::getNumDisplays(): m_displayManager==0\n");
+ GHOST_TUns8 numDisplays;
+ m_displayManager->getNumDisplays(numDisplays);
+ return numDisplays;
+}
+
+
+void GHOST_SystemWin32::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ width = ::GetSystemMetrics(SM_CXSCREEN);
+ height= ::GetSystemMetrics(SM_CYSCREEN);
+}
+
+
+GHOST_IWindow* GHOST_SystemWin32::createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
+ GHOST_TWindowState state, GHOST_TDrawingContextType type,
+ bool stereoVisual)
+{
+ GHOST_Window* window = 0;
+ window = new GHOST_WindowWin32 (title, left, top, width, height, state, type, stereoVisual);
+ if (window) {
+ if (window->getValid()) {
+ // Store the pointer to the window
+ if (state != GHOST_kWindowStateFullScreen) {
+ m_windowManager->addWindow(window);
+ }
+ }
+ else {
+ delete window;
+ window = 0;
+ }
+ }
+ return window;
+}
+
+
+bool GHOST_SystemWin32::processEvents(bool waitForEvent)
+{
+ MSG msg;
+ bool anyProcessed = false;
+
+ do {
+ GHOST_TimerManager* timerMgr = getTimerManager();
+
+ if (waitForEvent && !::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) {
+#if 1
+ ::Sleep(1);
+#else
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+
+ if (next == GHOST_kFireTimeNever) {
+ ::WaitMessage();
+ } else {
+ ::SetTimer(NULL, 0, next - getMilliSeconds(), NULL);
+ ::WaitMessage();
+ ::KillTimer(NULL, 0);
+ }
+#endif
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
+
+ // Process all the events waiting for us
+ while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ anyProcessed = true;
+ }
+ } while (waitForEvent && !anyProcessed);
+
+ return anyProcessed;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
+{
+ POINT point;
+ bool success = ::GetCursorPos(&point) == TRUE;
+ x = point.x;
+ y = point.y;
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const
+{
+ return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) const
+{
+ /*
+ GetKeyState and GetAsyncKeyState only work with Win95, Win98, NT4,
+ Terminal Server and Windows 2000.
+ But on WinME it always returns zero. These two functions are simply
+ skipped by Millenium Edition!
+
+ Official explanation from Microsoft:
+ Intentionally disabled.
+ It didn't work all that well on some newer hardware, and worked less
+ well with the passage of time, so it was fully disabled in ME.
+ */
+ if (m_seperateLeftRight && m_seperateLeftRightInitialized) {
+ bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
+ keys.set(GHOST_kModifierKeyLeftShift, down);
+ down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
+ keys.set(GHOST_kModifierKeyRightShift, down);
+ down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
+ keys.set(GHOST_kModifierKeyLeftAlt, down);
+ down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
+ keys.set(GHOST_kModifierKeyRightAlt, down);
+ down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
+ keys.set(GHOST_kModifierKeyLeftControl, down);
+ down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
+ keys.set(GHOST_kModifierKeyRightControl, down);
+ }
+ else {
+ bool down = HIBYTE(::GetKeyState(VK_SHIFT)) != 0;
+ keys.set(GHOST_kModifierKeyLeftShift, down);
+ keys.set(GHOST_kModifierKeyRightShift, down);
+ down = HIBYTE(::GetKeyState(VK_MENU)) != 0;
+ keys.set(GHOST_kModifierKeyLeftAlt, down);
+ keys.set(GHOST_kModifierKeyRightAlt, down);
+ down = HIBYTE(::GetKeyState(VK_CONTROL)) != 0;
+ keys.set(GHOST_kModifierKeyLeftControl, down);
+ keys.set(GHOST_kModifierKeyRightControl, down);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons& buttons) const
+{
+ /* Check for swapped buttons (left-handed mouse buttons)
+ * GetAsyncKeyState() will give back the state of the physical mouse buttons.
+ */
+ bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
+
+ bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
+ buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
+
+ down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
+ buttons.set(GHOST_kButtonMaskMiddle, down);
+
+ down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
+ buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::init()
+{
+ GHOST_TSuccess success = GHOST_System::init();
+
+ // Determine whether this system has a high frequency performance counter. */
+ m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
+ if (m_hasPerformanceCounter) {
+ GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer available\n")
+ ::QueryPerformanceCounter((LARGE_INTEGER*)&m_start);
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer not available\n")
+ }
+
+ if (success) {
+ WNDCLASS wc;
+ wc.style= CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc= s_wndProc;
+ wc.cbClsExtra= 0;
+ wc.cbWndExtra= 0;
+ wc.hInstance= ::GetModuleHandle(0);
+ wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
+ if (!wc.hIcon) {
+ ::LoadIcon(NULL, IDI_APPLICATION);
+ }
+ wc.hCursor = ::LoadCursor(0, IDC_ARROW);
+ wc.hbrBackground= (HBRUSH)::GetStockObject(BLACK_BRUSH);
+ wc.lpszMenuName = 0;
+ wc.lpszClassName= GHOST_WindowWin32::getWindowClassName();
+
+ // Use RegisterClassEx for setting small icon
+ if (::RegisterClass(&wc) == 0) {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_SystemWin32::exit()
+{
+ return GHOST_System::exit();
+}
+
+
+GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
+{
+ GHOST_TKey key;
+ bool isExtended = (lParam&(1<<24))?true:false;
+
+ if ((wParam >= '0') && (wParam <= '9')) {
+ // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
+ key = (GHOST_TKey)(wParam - '0' + GHOST_kKey0);
+ }
+ else if ((wParam >= 'A') && (wParam <= 'Z')) {
+ // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A)
+ key = (GHOST_TKey)(wParam - 'A' + GHOST_kKeyA);
+ }
+ else if ((wParam >= VK_F1) && (wParam <= VK_F24)) {
+ key = (GHOST_TKey)(wParam - VK_F1 + GHOST_kKeyF1);
+ }
+ else {
+ switch (wParam) {
+ case VK_RETURN:
+ key = isExtended?GHOST_kKeyNumpadEnter:GHOST_kKeyEnter;
+ break;
+
+ case VK_BACK: key = GHOST_kKeyBackSpace; break;
+ case VK_TAB: key = GHOST_kKeyTab; break;
+ case VK_ESCAPE: key = GHOST_kKeyEsc; break;
+ case VK_SPACE: key = GHOST_kKeySpace; break;
+ case VK_PRIOR: key = GHOST_kKeyUpPage; break;
+ case VK_NEXT: key = GHOST_kKeyDownPage; break;
+ case VK_END: key = GHOST_kKeyEnd; break;
+ case VK_HOME: key = GHOST_kKeyHome; break;
+ case VK_INSERT: key = GHOST_kKeyInsert; break;
+ case VK_DELETE: key = GHOST_kKeyDelete; break;
+ case VK_LEFT: key = GHOST_kKeyLeftArrow; break;
+ case VK_RIGHT: key = GHOST_kKeyRightArrow; break;
+ case VK_UP: key = GHOST_kKeyUpArrow; break;
+ case VK_DOWN: key = GHOST_kKeyDownArrow; break;
+ case VK_NUMPAD0: key = GHOST_kKeyNumpad0; break;
+ case VK_NUMPAD1: key = GHOST_kKeyNumpad1; break;
+ case VK_NUMPAD2: key = GHOST_kKeyNumpad2; break;
+ case VK_NUMPAD3: key = GHOST_kKeyNumpad3; break;
+ case VK_NUMPAD4: key = GHOST_kKeyNumpad4; break;
+ case VK_NUMPAD5: key = GHOST_kKeyNumpad5; break;
+ case VK_NUMPAD6: key = GHOST_kKeyNumpad6; break;
+ case VK_NUMPAD7: key = GHOST_kKeyNumpad7; break;
+ case VK_NUMPAD8: key = GHOST_kKeyNumpad8; break;
+ case VK_NUMPAD9: key = GHOST_kKeyNumpad9; break;
+ case VK_SNAPSHOT: key = GHOST_kKeyPrintScreen; break;
+ case VK_PAUSE: key = GHOST_kKeyPause; break;
+ case VK_MULTIPLY: key = GHOST_kKeyNumpadAsterisk; break;
+ case VK_SUBTRACT: key = GHOST_kKeyNumpadMinus; break;
+ case VK_DECIMAL: key = GHOST_kKeyNumpadPeriod; break;
+ case VK_DIVIDE: key = GHOST_kKeyNumpadSlash; break;
+ case VK_ADD: key = GHOST_kKeyNumpadPlus; break;
+
+ case VK_SEMICOLON: key = GHOST_kKeySemicolon; break;
+ case VK_EQUALS: key = GHOST_kKeyEqual; break;
+ case VK_COMMA: key = GHOST_kKeyComma; break;
+ case VK_MINUS: key = GHOST_kKeyMinus; break;
+ case VK_PERIOD: key = GHOST_kKeyPeriod; break;
+ case VK_SLASH: key = GHOST_kKeySlash; break;
+ case VK_BACK_QUOTE: key = GHOST_kKeyAccentGrave; break;
+ case VK_OPEN_BRACKET: key = GHOST_kKeyLeftBracket; break;
+ case VK_BACK_SLASH: key = GHOST_kKeyBackslash; break;
+ case VK_CLOSE_BRACKET: key = GHOST_kKeyRightBracket; break;
+ case VK_QUOTE: key = GHOST_kKeyQuote; break;
+
+ // Process these keys separately because we need to distinguish right from left modifier keys
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_MENU:
+
+ // Ignore these keys
+ case VK_NUMLOCK:
+ case VK_SCROLL:
+ case VK_CAPITAL:
+ default:
+ key = GHOST_kKeyUnknown;
+ break;
+ }
+ }
+ return key;
+}
+
+
+void GHOST_SystemWin32::processModifierKeys(GHOST_IWindow *window)
+{
+ GHOST_ModifierKeys oldModifiers, newModifiers;
+ // Retrieve old state of the modifier keys
+ ((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers);
+ // Retrieve current state of the modifier keys
+ ((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers);
+
+ // Compare the old and the new
+ if (!newModifiers.equals(oldModifiers)) {
+ // Create events for the masks that changed
+ for (int i = 0; i < GHOST_kModifierKeyNumMasks; i++) {
+ if (newModifiers.get((GHOST_TModifierKeyMask)i) != oldModifiers.get((GHOST_TModifierKeyMask)i)) {
+ // Convert the mask to a key code
+ GHOST_TKey key = GHOST_ModifierKeys::getModifierKeyCode((GHOST_TModifierKeyMask)i);
+ bool keyDown = newModifiers.get((GHOST_TModifierKeyMask)i);
+ GHOST_EventKey* event;
+ if (key != GHOST_kKeyUnknown) {
+ // Create an event
+ event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key);
+ pushEvent(event);
+ }
+ }
+ }
+ }
+
+ // Store new modifier keys state
+ ((GHOST_SystemWin32*)getSystem())->storeModifierKeys(newModifiers);
+}
+
+
+GHOST_EventButton* GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask mask)
+{
+ return new GHOST_EventButton (getSystem()->getMilliSeconds(), type, window, mask);
+}
+
+
+GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_IWindow *window)
+{
+ GHOST_TInt32 x, y;
+ getSystem()->getCursorPosition(x, y);
+ return new GHOST_EventCursor (getSystem()->getMilliSeconds(), type, window, x, y);
+}
+
+
+GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam)
+{
+ GHOST_TKey key = ((GHOST_SystemWin32*)getSystem())->convertKey(wParam, lParam);
+ GHOST_EventKey* event;
+ if (key != GHOST_kKeyUnknown) {
+ MSG keyMsg;
+ char ascii = '\0';
+
+ /* Eat any character related messages */
+ if (::PeekMessage(&keyMsg, NULL, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
+ ascii = (char) keyMsg.wParam;
+ }
+
+ event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii);
+ }
+ else {
+ event = 0;
+ }
+ return event;
+}
+
+
+GHOST_Event* GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window)
+{
+ return new GHOST_Event(getSystem()->getMilliSeconds(), type, window);
+}
+
+
+LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ GHOST_Event* event = 0;
+ LRESULT lResult;
+ GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
+ GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized")
+
+ if (hwnd) {
+ GHOST_WindowWin32* window = (GHOST_WindowWin32*)::GetWindowLong(hwnd, GWL_USERDATA);
+ if (window) {
+ switch (msg) {
+ ////////////////////////////////////////////////////////////////////////
+ // Keyboard events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_KEYDOWN:
+ /* The WM_KEYDOWN message is posted to the window with the keyboard focus when a
+ * nonsystem key is pressed. A nonsystem key is a key that is pressed when the alt
+ * key is not pressed.
+ */
+ case WM_SYSKEYDOWN:
+ /* The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when
+ * the user presses the F10 key (which activates the menu bar) or holds down the
+ * alt key and then presses another key. It also occurs when no window currently
+ * has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the
+ * active window. The window that receives the message can distinguish between these
+ * two contexts by checking the context code in the lKeyData parameter.
+ */
+ switch (wParam) {
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_MENU:
+ if (!system->m_seperateLeftRightInitialized) {
+ // Check whether this system supports seperate left and right keys
+ switch (wParam) {
+ case VK_SHIFT:
+ system->m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
+ true : false;
+ break;
+ case VK_CONTROL:
+ system->m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
+ true : false;
+ break;
+ case VK_MENU:
+ system->m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
+ true : false;
+ break;
+ }
+ system->m_seperateLeftRightInitialized = true;
+ }
+ system->processModifierKeys(window);
+ // Bypass call to DefWindowProc
+ return 0;
+ default:
+ event = processKeyEvent(window, true, wParam, lParam);
+ if (!event) {
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
+ GHOST_PRINT(msg)
+ GHOST_PRINT(" key ignored\n")
+ }
+ break;
+ }
+ break;
+
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ switch (wParam) {
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_MENU:
+ system->processModifierKeys(window);
+ // Bypass call to DefWindowProc
+ return 0;
+ default:
+ event = processKeyEvent(window, false, wParam, lParam);
+ if (!event) {
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
+ GHOST_PRINT(msg)
+ GHOST_PRINT(" key ignored\n")
+ }
+ break;
+ }
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Keyboard events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_CHAR:
+ /* The WM_CHAR message is posted to the window with the keyboard focus when
+ * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
+ * contains the character code of the key that was pressed.
+ */
+ case WM_DEADCHAR:
+ /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
+ * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR
+ * specifies a character code generated by a dead key. A dead key is a key that
+ * generates a character, such as the umlaut (double-dot), that is combined with
+ * another character to form a composite character. For example, the umlaut-O
+ * character (Ö) is generated by typing the dead key for the umlaut character, and
+ * then typing the O key.
+ */
+ case WM_SYSDEADCHAR:
+ /* The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when
+ * a WM_SYSKEYDOWN message is translated by the TranslateMessage function.
+ * WM_SYSDEADCHAR specifies the character code of a system dead key - that is,
+ * a dead key that is pressed while holding down the alt key.
+ */
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Mouse events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_LBUTTONDOWN:
+ window->registerMouseClickEvent(true);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
+ break;
+ case WM_MBUTTONDOWN:
+ window->registerMouseClickEvent(true);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
+ break;
+ case WM_RBUTTONDOWN:
+ window->registerMouseClickEvent(true);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
+ break;
+ case WM_LBUTTONUP:
+ window->registerMouseClickEvent(false);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
+ break;
+ case WM_MBUTTONUP:
+ window->registerMouseClickEvent(false);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
+ break;
+ case WM_RBUTTONUP:
+ window->registerMouseClickEvent(false);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
+ break;
+ case WM_MOUSEMOVE:
+ event = processCursorEvent(GHOST_kEventCursorMove, window);
+ break;
+ case WM_SETCURSOR:
+ /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
+ * to move within a window and mouse input is not captured.
+ * This means we have to set the cursor shape every time the mouse moves!
+ * The DefWindowProc function uses this message to set the cursor to an
+ * arrow if it is not in the client area.
+ */
+ if (LOWORD(lParam) == HTCLIENT) {
+ // Load the current cursor
+ window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+ // Bypass call to DefWindowProc
+ return 0;
+ }
+ else {
+ // Outside of client area show standard cursor
+ window->loadCursor(true, GHOST_kStandardCursorDefault);
+ }
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Mouse events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_NCMOUSEMOVE:
+ /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved
+ * within the nonclient area of the window. This message is posted to the window
+ * that contains the cursor. If a window has captured the mouse, this message is not posted.
+ */
+ case WM_NCHITTEST:
+ /* The WM_NCHITTEST message is sent to a window when the cursor moves, or
+ * when a mouse button is pressed or released. If the mouse is not captured,
+ * the message is sent to the window beneath the cursor. Otherwise, the message
+ * is sent to the window that has captured the mouse.
+ */
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Window events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_CLOSE:
+ /* The WM_CLOSE message is sent as a signal that a window or an application should terminate. */
+ event = processWindowEvent(GHOST_kEventWindowClose, window);
+ break;
+ case WM_ACTIVATE:
+ /* The WM_ACTIVATE message is sent to both the window being activated and the window being
+ * deactivated. If the windows use the same input queue, the message is sent synchronously,
+ * first to the window procedure of the top-level window being deactivated, then to the window
+ * procedure of the top-level window being activated. If the windows use different input queues,
+ * the message is sent asynchronously, so the window is activated immediately.
+ */
+ event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
+ break;
+ case WM_PAINT:
+ /* An application sends the WM_PAINT message when the system or another application
+ * makes a request to paint a portion of an application's window. The message is sent
+ * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
+ * function when the application obtains a WM_PAINT message by using the GetMessage or
+ * PeekMessage function.
+ */
+ event = processWindowEvent(GHOST_kEventWindowUpdate, window);
+ ::ValidateRect(hwnd, NULL);
+ break;
+ case WM_SIZE:
+ /* The WM_SIZE message is sent to a window after its size has changed.
+ * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ event = processWindowEvent(GHOST_kEventWindowSize, window);
+ case WM_CAPTURECHANGED:
+ window->lostMouseCapture();
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Window events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_WINDOWPOSCHANGED:
+ /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place
+ * in the Z order has changed as a result of a call to the SetWindowPos function or
+ * another window-management function.
+ * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ case WM_MOVE:
+ /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ case WM_ERASEBKGND:
+ /* An application sends the WM_ERASEBKGND message when the window background must be
+ * erased (for example, when a window is resized). The message is sent to prepare an
+ * invalidated portion of a window for painting.
+ */
+ case WM_NCPAINT:
+ /* An application sends the WM_NCPAINT message to a window when its frame must be painted. */
+ case WM_NCACTIVATE:
+ /* The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed
+ * to indicate an active or inactive state.
+ */
+ case WM_DESTROY:
+ /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window
+ * procedure of the window being destroyed after the window is removed from the screen.
+ * This message is sent first to the window being destroyed and then to the child windows
+ * (if any) as they are destroyed. During the processing of the message, it can be assumed
+ * that all child windows still exist.
+ */
+ case WM_NCDESTROY:
+ /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The
+ * DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
+ * message. WM_DESTROY is used to free the allocated memory object associated with the window.
+ */
+ case WM_KILLFOCUS:
+ /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. */
+ case WM_SHOWWINDOW:
+ /* The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. */
+ case WM_WINDOWPOSCHANGING:
+ /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in
+ * the Z order is about to change as a result of a call to the SetWindowPos function or
+ * another window-management function.
+ */
+ case WM_SETFOCUS:
+ /* The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. */
+ case WM_MOVING:
+ /* The WM_MOVING message is sent to a window that the user is moving. By processing
+ * this message, an application can monitor the size and position of the drag rectangle
+ * and, if needed, change its size or position.
+ */
+ case WM_ENTERSIZEMOVE:
+ /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving
+ * or sizing modal loop. The window enters the moving or sizing modal loop when the user
+ * clicks the window's title bar or sizing border, or when the window passes the
+ * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the
+ * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when
+ * DefWindowProc returns.
+ */
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Other events
+ ////////////////////////////////////////////////////////////////////////
+ case WM_GETTEXT:
+ /* An application sends a WM_GETTEXT message to copy the text that
+ * corresponds to a window into a buffer provided by the caller.
+ */
+ case WM_ACTIVATEAPP:
+ /* The WM_ACTIVATEAPP message is sent when a window belonging to a
+ * different application than the active window is about to be activated.
+ * The message is sent to the application whose window is being activated
+ * and to the application whose window is being deactivated.
+ */
+ case WM_TIMER:
+ /* The WIN32 docs say:
+ * The WM_TIMER message is posted to the installing thread's message queue
+ * when a timer expires. You can process the message by providing a WM_TIMER
+ * case in the window procedure. Otherwise, the default window procedure will
+ * call the TimerProc callback function specified in the call to the SetTimer
+ * function used to install the timer.
+ *
+ * In GHOST, we let DefWindowProc call the timer callback.
+ */
+ break;
+ }
+ }
+ else {
+ // Event found for a window before the pointer to the class has been set.
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n")
+ /* These are events we typically miss at this point:
+ WM_GETMINMAXINFO 0x24
+ WM_NCCREATE 0x81
+ WM_NCCALCSIZE 0x83
+ WM_CREATE 0x01
+ We let DefWindowProc do the work.
+ */
+ }
+ }
+ else {
+ // Events without valid hwnd
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n")
+ }
+
+ if (event) {
+ system->pushEvent(event);
+ lResult = 0;
+ }
+ else {
+ lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return lResult;
+}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
new file mode 100644
index 00000000000..ac1a7eb6ac5
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -0,0 +1,278 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _GHOST_SYSTEM_WIN32_H_
+#define _GHOST_SYSTEM_WIN32_H_
+
+#ifndef WIN32
+#error WIN32 only!
+#endif // WIN32
+
+#include "GHOST_System.h"
+
+#include <windows.h>
+
+#if defined(__CYGWIN32__)
+# define __int64 long long
+#endif
+
+
+class GHOST_EventButton;
+class GHOST_EventCursor;
+class GHOST_EventKey;
+class GHOST_EventWindow;
+
+/**
+ * WIN32 Implementation of GHOST_System class.
+ * @see GHOST_System.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+class GHOST_SystemWin32 : public GHOST_System {
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemWin32();
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_SystemWin32();
+
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * This overloaded method uses the high frequency timer if available.
+ * @return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const;
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * @return The number of displays.
+ */
+ virtual GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @return The new window (or 0 if creation failed).
+ */
+ virtual GHOST_IWindow* createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
+ GHOST_TWindowState state, GHOST_TDrawingContextType type,
+ const bool stereoVisual);
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Gets events from the system and stores them in the queue.
+ * @param waitForEvent Flag to wait for an event (or return immediately).
+ * @return Indication of the presence of events.
+ */
+ virtual bool processEvents(bool waitForEvent);
+
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of all modifier keys.
+ * @param keys The state of all modifier keys (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * @param buttons The state of the buttons.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+
+protected:
+ /**
+ * Initializes the system.
+ * For now, it justs registers the window class (WNDCLASS).
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess init();
+
+ /**
+ * Closes the system down.
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess exit();
+
+ /**
+ * Converts raw WIN32 key codes from the wndproc to GHOST keys.
+ * @param wParam The wParam from the wndproc
+ * @param lParam The lParam from the wndproc
+ * @return The GHOST key (GHOST_kKeyUnknown if no match).
+ */
+ virtual GHOST_TKey convertKey(WPARAM wParam, LPARAM lParam) const;
+
+ /**
+ * Creates modifier key event(s) and updates the key data stored locally (m_modifierKeys).
+ * With the modifier keys, we want to distinguish left and right keys.
+ * Sometimes this is not possible (Windows ME for instance). Then, we want
+ * events generated for both keys.
+ */
+ void processModifierKeys(GHOST_IWindow *window);
+
+ /**
+ * Creates mouse button event.
+ * @param type The type of event to create.
+ * @param type The button mask of this event.
+ * @return The event created.
+ */
+ static GHOST_EventButton* processButtonEvent(GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask mask);
+
+ /**
+ * Creates cursor event.
+ * @param type The type of event to create.
+ * @return The event created.
+ */
+ static GHOST_EventCursor* processCursorEvent(GHOST_TEventType type, GHOST_IWindow *window);
+
+ /**
+ * Creates a key event and updates the key data stored locally (m_modifierKeys).
+ * In most cases this is a straightforward conversion of key codes.
+ * For the modifier keys however, we want to distinguish left and right keys.
+ */
+ static GHOST_EventKey* processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam);
+
+ /**
+ * Creates a window event.
+ * @param type The type of event to create.
+ * @param window The window receiving the event.
+ * @return The event created.
+ */
+ static GHOST_Event* processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window);
+
+ /**
+ * Returns the local state of the modifier keys (from the message queue).
+ * @param keys The state of the keys.
+ */
+ inline virtual void retrieveModifierKeys(GHOST_ModifierKeys& keys) const;
+
+ /**
+ * Stores the state of the modifier keys locally.
+ * For internal use only!
+ * @param keys The new state of the modifier keys.
+ */
+ inline virtual void storeModifierKeys(const GHOST_ModifierKeys& keys);
+
+ /**
+ * Windows call back routine for our window class.
+ */
+ static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ /** The current state of the modifier keys. */
+ GHOST_ModifierKeys m_modifierKeys;
+ /** State variable set at initialization. */
+ bool m_hasPerformanceCounter;
+ /** High frequency timer variable. */
+ __int64 m_freq;
+ /** High frequency timer variable. */
+ __int64 m_start;
+ /** Stores the capability of this system to distinguish left and right modifier keys. */
+ bool m_seperateLeftRight;
+ /** Stores the initialization state of the member m_leftRightDistinguishable. */
+ bool m_seperateLeftRightInitialized;
+};
+
+inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
+{
+ keys = m_modifierKeys;
+}
+
+inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys)
+{
+ m_modifierKeys = keys;
+}
+
+#endif // _GHOST_SYSTEM_WIN32_H_
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
new file mode 100755
index 00000000000..77c13d66de2
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -0,0 +1,803 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "GHOST_SystemX11.h"
+#include "GHOST_WindowX11.h"
+#include "GHOST_WindowManager.h"
+#include "GHOST_TimerManager.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_DisplayManagerX11.h"
+
+#include "GHOST_Debug.h"
+
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+// For timing
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <vector>
+
+using namespace std;
+
+GHOST_SystemX11::
+GHOST_SystemX11(
+) :
+ GHOST_System(),
+ m_start_time(0)
+{
+ m_display = XOpenDisplay(NULL);
+
+ if (!m_display) return;
+
+ m_delete_window_atom = XInternAtom(m_display, "WM_DELETE_WINDOW", True);
+
+ // compute the initial time
+ timeval tv;
+ if (gettimeofday(&tv,NULL) == -1) {
+ GHOST_ASSERT(false,"Could not instantiate timer!");
+ }
+
+ m_start_time = GHOST_TUns64(tv.tv_sec*1000 + tv.tv_usec/1000);
+}
+
+ GHOST_TSuccess
+GHOST_SystemX11::
+init(
+){
+ GHOST_TSuccess success = GHOST_System::init();
+
+ if (success) {
+ m_keyboard_vector = new char[32];
+
+ m_displayManager = new GHOST_DisplayManagerX11(this);
+
+ if (m_keyboard_vector && m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
+
+ return GHOST_kFailure;
+}
+
+
+
+ GHOST_TUns64
+GHOST_SystemX11::
+getMilliSeconds(
+) const {
+ timeval tv;
+ if (gettimeofday(&tv,NULL) == -1) {
+ GHOST_ASSERT(false,"Could not compute time!");
+ }
+
+ return GHOST_TUns64(tv.tv_sec*1000 + tv.tv_usec/1000) - m_start_time;
+}
+
+ GHOST_TUns8
+GHOST_SystemX11::
+getNumDisplays(
+) const {
+ return GHOST_TUns8(1);
+}
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ void
+GHOST_SystemX11::
+getMainDisplayDimensions(
+ GHOST_TUns32& width,
+ GHOST_TUns32& height
+) const {
+ if (m_display) {
+ width = DisplayWidth(m_display, DefaultScreen(m_display));
+ height = DisplayHeight(m_display, DefaultScreen(m_display));
+ }
+}
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @return The new window (or 0 if creation failed).
+ */
+ GHOST_IWindow*
+GHOST_SystemX11::
+createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool stereoVisual
+){
+ GHOST_WindowX11 * window = 0;
+
+ if (!m_display) return 0;
+
+ window = new GHOST_WindowX11 (
+ this,m_display,title, left, top, width, height, state, type
+ );
+
+ if (window) {
+
+ // Install a new protocol for this window - so we can overide
+ // the default window closure mechanism.
+
+ XSetWMProtocols(m_display, window->getXWindow(), &m_delete_window_atom, 1);
+
+ if (window->getValid()) {
+ // Store the pointer to the window
+ m_windowManager->addWindow(window);
+
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
+ }
+ else {
+ delete window;
+ window = 0;
+ }
+ }
+ return window;
+
+}
+
+ GHOST_WindowX11 *
+GHOST_SystemX11::
+findGhostWindow(
+ Window xwind
+) const {
+
+ if (xwind == 0) return NULL;
+
+ // It is not entirely safe to do this as the backptr may point
+ // to a window that has recently been removed.
+ // We should always check the window manager's list of windows
+ // and only process events on these windows.
+
+ vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
+
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
+
+ for (; win_it != win_end; ++win_it) {
+ GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
+ if (window->getXWindow() == xwind) {
+ return window;
+ }
+ }
+ return NULL;
+
+}
+
+static void SleepTillEvent(Display *display, GHOST_TUns64 maxSleep) {
+ int fd = ConnectionNumber(display);
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ if (maxSleep == -1) {
+ select(fd + 1, &fds, NULL, NULL, NULL);
+ } else {
+ timeval tv;
+
+ tv.tv_sec = maxSleep/1000;
+ tv.tv_usec = (maxSleep - tv.tv_sec*1000)*1000;
+
+ select(fd + 1, &fds, NULL, NULL, &tv);
+ }
+}
+
+ bool
+GHOST_SystemX11::
+processEvents(
+ bool waitForEvent
+){
+ // Get all the current events -- translate them into
+ // ghost events and call base class pushEvent() method.
+
+ bool anyProcessed = false;
+
+ do {
+ GHOST_TimerManager* timerMgr = getTimerManager();
+
+ if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+
+ if (next==GHOST_kFireTimeNever) {
+ SleepTillEvent(m_display, -1);
+ } else {
+ SleepTillEvent(m_display, next - getMilliSeconds());
+ }
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
+
+ while (XPending(m_display)) {
+ XEvent xevent;
+ XNextEvent(m_display, &xevent);
+ processEvent(&xevent);
+ anyProcessed = true;
+ }
+
+ if (generateWindowExposeEvents()) {
+ anyProcessed = true;
+ }
+ } while (waitForEvent && !anyProcessed);
+
+ return anyProcessed;
+}
+
+ void
+GHOST_SystemX11::
+processEvent(
+ XEvent *xe
+){
+ GHOST_WindowX11 * window = findGhostWindow(xe->xany.window);
+ GHOST_Event * g_event = NULL;
+
+ if (!window) {
+ return;
+ }
+
+ switch (xe->type) {
+ case Expose:
+ {
+ XExposeEvent & xee = xe->xexpose;
+
+ if (xee.count == 0) {
+ // Only generate a single expose event
+ // per read of the event queue.
+
+ g_event = new
+ GHOST_Event(
+ getMilliSeconds(),
+ GHOST_kEventWindowUpdate,
+ window
+ );
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ XMotionEvent &xme = xe->xmotion;
+
+ g_event = new
+ GHOST_EventCursor(
+ getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ xme.x_root,
+ xme.y_root
+ );
+ break;
+ }
+
+ case KeyPress:
+ case KeyRelease:
+ {
+ XKeyEvent *xke = &(xe->xkey);
+
+ KeySym key_sym = XLookupKeysym(xke,0);
+ char ascii;
+
+ GHOST_TKey gkey = convertXKey(key_sym);
+ GHOST_TEventType type = (xke->type == KeyPress) ?
+ GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+
+ if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
+ ascii = '\0';
+ }
+
+ g_event = new
+ GHOST_EventKey(
+ getMilliSeconds(),
+ type,
+ window,
+ gkey,
+ ascii
+ );
+
+ break;
+ }
+ case ButtonPress:
+ case ButtonRelease:
+ {
+
+ XButtonEvent & xbe = xe->xbutton;
+ GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
+
+ switch (xbe.button) {
+ case Button1 : gbmask = GHOST_kButtonMaskLeft; break;
+ case Button3 : gbmask = GHOST_kButtonMaskRight; break;
+ default:
+ case Button2 : gbmask = GHOST_kButtonMaskMiddle; break;
+ }
+
+ GHOST_TEventType type = (xbe.type == ButtonPress) ?
+ GHOST_kEventButtonDown : GHOST_kEventButtonUp;
+
+ g_event = new
+ GHOST_EventButton(
+ getMilliSeconds(),
+ type,
+ window,
+ gbmask
+ );
+ break;
+ }
+
+ // change of size, border, layer etc.
+ case ConfigureNotify:
+ {
+ /* XConfigureEvent & xce = xe->xconfigure; */
+
+ g_event = new
+ GHOST_Event(
+ getMilliSeconds(),
+ GHOST_kEventWindowSize,
+ window
+ );
+ break;
+ }
+
+ case FocusIn:
+ case FocusOut:
+ {
+ XFocusChangeEvent &xfe = xe->xfocus;
+
+ // May have to look at the type of event and filter some
+ // out.
+
+ GHOST_TEventType gtype = (xfe.type == FocusIn) ?
+ GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
+
+ g_event = new
+ GHOST_Event(
+ getMilliSeconds(),
+ gtype,
+ window
+ );
+ break;
+
+ }
+ case ClientMessage:
+ {
+ XClientMessageEvent & xcme = xe->xclient;
+
+ if (xcme.data.l[0] == m_delete_window_atom) {
+ g_event = new
+ GHOST_Event(
+ getMilliSeconds(),
+ GHOST_kEventWindowClose,
+ window
+ );
+ } else {
+ /* Unknown client message, ignore */
+ }
+
+ break;
+ }
+
+ // We're not interested in the following things.(yet...)
+ case NoExpose :
+ case GraphicsExpose :
+
+ case EnterNotify:
+ case LeaveNotify:
+ // XCrossingEvents pointer leave enter window.
+ break;
+ case MapNotify:
+ case UnmapNotify:
+ break;
+ case MappingNotify:
+ case ReparentNotify:
+ break;
+
+ default:
+ break;
+ }
+
+ if (g_event) {
+ pushEvent(g_event);
+ }
+}
+
+
+ GHOST_TSuccess
+GHOST_SystemX11::
+getModifierKeys(
+ GHOST_ModifierKeys& keys
+) const {
+
+ // analyse the masks retuned from XQueryPointer.
+
+ memset(m_keyboard_vector,32,0);
+
+ XQueryKeymap(m_display,m_keyboard_vector);
+
+ // now translate key symobols into keycodes and
+ // test with vector.
+
+ const KeyCode shift_l = XKeysymToKeycode(m_display,XK_Shift_L);
+ const KeyCode shift_r = XKeysymToKeycode(m_display,XK_Shift_R);
+ const KeyCode control_l = XKeysymToKeycode(m_display,XK_Control_L);
+ const KeyCode control_r = XKeysymToKeycode(m_display,XK_Control_R);
+ const KeyCode alt_l = XKeysymToKeycode(m_display,XK_Alt_L);
+ const KeyCode alt_r = XKeysymToKeycode(m_display,XK_Alt_R);
+
+ // Shift
+ if ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) {
+ keys.set(GHOST_kModifierKeyLeftShift,true);
+ } else {
+ keys.set(GHOST_kModifierKeyLeftShift,false);
+ }
+ if ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) {
+
+ keys.set(GHOST_kModifierKeyRightShift,true);
+ } else {
+ keys.set(GHOST_kModifierKeyRightShift,false);
+ }
+
+ // control (weep)
+ if ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) {
+ keys.set(GHOST_kModifierKeyLeftControl,true);
+ } else {
+ keys.set(GHOST_kModifierKeyLeftControl,false);
+ }
+ if ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) {
+ keys.set(GHOST_kModifierKeyRightControl,true);
+ } else {
+ keys.set(GHOST_kModifierKeyRightControl,false);
+ }
+
+ // Alt (yawn)
+ if ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) {
+ keys.set(GHOST_kModifierKeyLeftAlt,true);
+ } else {
+ keys.set(GHOST_kModifierKeyLeftAlt,false);
+ }
+ if ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) {
+ keys.set(GHOST_kModifierKeyRightAlt,true);
+ } else {
+ keys.set(GHOST_kModifierKeyRightAlt,false);
+ }
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_SystemX11::
+getButtons(
+ GHOST_Buttons& buttons
+) const {
+
+ Window root_return, child_return;
+ int rx,ry,wx,wy;
+ unsigned int mask_return;
+
+ if (XQueryPointer(
+ m_display,
+ RootWindow(m_display,DefaultScreen(m_display)),
+ &root_return,
+ &child_return,
+ &rx,&ry,
+ &wx,&wy,
+ &mask_return
+ ) == False) {
+ return GHOST_kFailure;
+ } else {
+
+ if (mask_return & Button1Mask) {
+ buttons.set(GHOST_kButtonMaskLeft,true);
+ } else {
+ buttons.set(GHOST_kButtonMaskLeft,false);
+ }
+
+ if (mask_return & Button2Mask) {
+ buttons.set(GHOST_kButtonMaskMiddle,true);
+ } else {
+ buttons.set(GHOST_kButtonMaskMiddle,false);
+ }
+
+ if (mask_return & Button3Mask) {
+ buttons.set(GHOST_kButtonMaskRight,true);
+ } else {
+ buttons.set(GHOST_kButtonMaskRight,false);
+ }
+ }
+
+ return GHOST_kSuccess;
+}
+
+
+ GHOST_TSuccess
+GHOST_SystemX11::
+getCursorPosition(
+ GHOST_TInt32& x,
+ GHOST_TInt32& y
+) const {
+
+ Window root_return, child_return;
+ int rx,ry,wx,wy;
+ unsigned int mask_return;
+
+ if (XQueryPointer(
+ m_display,
+ RootWindow(m_display,DefaultScreen(m_display)),
+ &root_return,
+ &child_return,
+ &rx,&ry,
+ &wx,&wy,
+ &mask_return
+ ) == False) {
+ return GHOST_kFailure;
+ } else {
+ x = rx;
+ y = ry;
+ }
+ return GHOST_kSuccess;
+}
+
+
+ GHOST_TSuccess
+GHOST_SystemX11::
+setCursorPosition(
+ GHOST_TInt32 x,
+ GHOST_TInt32 y
+) const {
+
+ // This is a brute force move in screen coordinates
+ // XWarpPointer does relative moves so first determine the
+ // current pointer position.
+
+ int cx,cy;
+ if (getCursorPosition(cx,cy) == GHOST_kFailure) {
+ return GHOST_kFailure;
+ }
+
+ int relx = x-cx;
+ int rely = y-cy;
+
+ XWarpPointer(m_display,None,None,0,0,0,0,relx,rely);
+ XFlush(m_display);
+
+ return GHOST_kSuccess;
+}
+
+
+ void
+GHOST_SystemX11::
+addDirtyWindow(
+ GHOST_WindowX11 * bad_wind
+){
+
+ GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
+
+ m_dirty_windows.push_back(bad_wind);
+}
+
+
+ bool
+GHOST_SystemX11::
+generateWindowExposeEvents(
+){
+
+ vector<GHOST_WindowX11 *>::iterator w_start = m_dirty_windows.begin();
+ vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
+ bool anyProcessed = false;
+
+ for (;w_start != w_end; ++w_start) {
+ GHOST_Event * g_event = new
+ GHOST_Event(
+ getMilliSeconds(),
+ GHOST_kEventWindowUpdate,
+ *w_start
+ );
+
+ (*w_start)->validate();
+
+ if (g_event) {
+ pushEvent(g_event);
+ anyProcessed = true;
+ }
+ }
+
+ m_dirty_windows.clear();
+ return anyProcessed;
+}
+
+#define GXMAP(k,x,y) case x: k = y; break;
+
+ GHOST_TKey
+GHOST_SystemX11::
+convertXKey(
+ unsigned int key
+){
+ GHOST_TKey type;
+
+ if ((key >= XK_A) && (key <= XK_Z)) {
+ type = GHOST_TKey( key - XK_A + int(GHOST_kKeyA));
+ } else if ((key >= XK_a) && (key <= XK_z)) {
+ type = GHOST_TKey(key - XK_a + int(GHOST_kKeyA));
+ } else if ((key >= XK_0) && (key <= XK_9)) {
+ type = GHOST_TKey(key - XK_0 + int(GHOST_kKey0));
+ } else if ((key >= XK_F1) && (key <= XK_F24)) {
+ type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
+ } else {
+ switch(key) {
+ GXMAP(type,XK_BackSpace, GHOST_kKeyBackSpace);
+ GXMAP(type,XK_Tab, GHOST_kKeyTab);
+ GXMAP(type,XK_Return, GHOST_kKeyEnter);
+ GXMAP(type,XK_Escape, GHOST_kKeyEsc);
+ GXMAP(type,XK_space, GHOST_kKeySpace);
+
+ GXMAP(type,XK_Linefeed, GHOST_kKeyLinefeed);
+ GXMAP(type,XK_semicolon, GHOST_kKeySemicolon);
+ GXMAP(type,XK_period, GHOST_kKeyPeriod);
+ GXMAP(type,XK_comma, GHOST_kKeyComma);
+ GXMAP(type,XK_quoteright, GHOST_kKeyQuote);
+ GXMAP(type,XK_quoteleft, GHOST_kKeyAccentGrave);
+ GXMAP(type,XK_minus, GHOST_kKeyMinus);
+ GXMAP(type,XK_slash, GHOST_kKeySlash);
+ GXMAP(type,XK_backslash, GHOST_kKeyBackslash);
+ GXMAP(type,XK_equal, GHOST_kKeyEqual);
+ GXMAP(type,XK_bracketleft, GHOST_kKeyLeftBracket);
+ GXMAP(type,XK_bracketright, GHOST_kKeyRightBracket);
+ GXMAP(type,XK_Pause, GHOST_kKeyPause);
+
+ GXMAP(type,XK_Shift_L, GHOST_kKeyLeftShift);
+ GXMAP(type,XK_Shift_R, GHOST_kKeyRightShift);
+ GXMAP(type,XK_Control_L, GHOST_kKeyLeftControl);
+ GXMAP(type,XK_Control_R, GHOST_kKeyRightControl);
+ GXMAP(type,XK_Alt_L, GHOST_kKeyLeftAlt);
+ GXMAP(type,XK_Alt_R, GHOST_kKeyRightAlt);
+
+ GXMAP(type,XK_Insert, GHOST_kKeyInsert);
+ GXMAP(type,XK_Delete, GHOST_kKeyDelete);
+ GXMAP(type,XK_Home, GHOST_kKeyHome);
+ GXMAP(type,XK_End, GHOST_kKeyEnd);
+ GXMAP(type,XK_Page_Up, GHOST_kKeyUpPage);
+ GXMAP(type,XK_Page_Down, GHOST_kKeyDownPage);
+
+ GXMAP(type,XK_Left, GHOST_kKeyLeftArrow);
+ GXMAP(type,XK_Right, GHOST_kKeyRightArrow);
+ GXMAP(type,XK_Up, GHOST_kKeyUpArrow);
+ GXMAP(type,XK_Down, GHOST_kKeyDownArrow);
+
+ GXMAP(type,XK_Caps_Lock, GHOST_kKeyCapsLock);
+ GXMAP(type,XK_Scroll_Lock, GHOST_kKeyScrollLock);
+ GXMAP(type,XK_Num_Lock, GHOST_kKeyNumLock);
+
+ /* keypad events */
+
+ GXMAP(type,XK_KP_0, GHOST_kKeyNumpad0);
+ GXMAP(type,XK_KP_1, GHOST_kKeyNumpad1);
+ GXMAP(type,XK_KP_2, GHOST_kKeyNumpad2);
+ GXMAP(type,XK_KP_3, GHOST_kKeyNumpad3);
+ GXMAP(type,XK_KP_4, GHOST_kKeyNumpad4);
+ GXMAP(type,XK_KP_5, GHOST_kKeyNumpad5);
+ GXMAP(type,XK_KP_6, GHOST_kKeyNumpad6);
+ GXMAP(type,XK_KP_7, GHOST_kKeyNumpad7);
+ GXMAP(type,XK_KP_8, GHOST_kKeyNumpad8);
+ GXMAP(type,XK_KP_9, GHOST_kKeyNumpad9);
+ GXMAP(type,XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type,XK_KP_Insert, GHOST_kKeyNumpad0);
+ GXMAP(type,XK_KP_End, GHOST_kKeyNumpad1);
+ GXMAP(type,XK_KP_Down, GHOST_kKeyNumpad2);
+ GXMAP(type,XK_KP_Page_Down, GHOST_kKeyNumpad3);
+ GXMAP(type,XK_KP_Left, GHOST_kKeyNumpad4);
+ GXMAP(type,XK_KP_Begin, GHOST_kKeyNumpad5);
+ GXMAP(type,XK_KP_Right, GHOST_kKeyNumpad6);
+ GXMAP(type,XK_KP_Home, GHOST_kKeyNumpad7);
+ GXMAP(type,XK_KP_Up, GHOST_kKeyNumpad8);
+ GXMAP(type,XK_KP_Page_Up, GHOST_kKeyNumpad9);
+ GXMAP(type,XK_KP_Delete, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type,XK_KP_Enter, GHOST_kKeyNumpadEnter);
+ GXMAP(type,XK_KP_Add, GHOST_kKeyNumpadPlus);
+ GXMAP(type,XK_KP_Subtract, GHOST_kKeyNumpadMinus);
+ GXMAP(type,XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
+ GXMAP(type,XK_KP_Divide, GHOST_kKeyNumpadSlash);
+
+ /* some extra sun cruft (NICE KEYBOARD!) */
+#ifdef __sun__
+ GXMAP(type,0xffde, GHOST_kKeyNumpad1);
+ GXMAP(type,0xffe0, GHOST_kKeyNumpad3);
+ GXMAP(type,0xffdc, GHOST_kKeyNumpad5);
+ GXMAP(type,0xffd8, GHOST_kKeyNumpad7);
+ GXMAP(type,0xffda, GHOST_kKeyNumpad9);
+
+ GXMAP(type,0xffd6, GHOST_kKeyNumpadSlash);
+ GXMAP(type,0xffd7, GHOST_kKeyNumpadAsterisk);
+#endif
+
+ default :
+ type = GHOST_kKeyUnknown;
+ break;
+ }
+ }
+
+ return type;
+}
+
+#undef GXMAP
+
+
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
new file mode 100755
index 00000000000..6dedf1eb457
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -0,0 +1,252 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _GHOST_SYSTEM_X11_H_
+#define _GHOST_SYSTEM_X11_H_
+
+#include "GHOST_System.h"
+#include "../GHOST_Types.h"
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+class GHOST_WindowX11;
+
+/**
+ * X11 Implementation of GHOST_System class.
+ * @see GHOST_System.
+ * @author Laurence Bourn
+ * @date October 26, 2001
+ */
+
+class GHOST_SystemX11 : public GHOST_System {
+public:
+
+ /**
+ * Constructor
+ * this class should only be instanciated by GHOST_ISystem.
+ */
+
+ GHOST_SystemX11(
+ );
+
+ GHOST_TSuccess
+ init(
+ );
+
+
+ /**
+ * @section Interface Inherited from GHOST_ISystem
+ */
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * @return The number of milliseconds.
+ */
+ GHOST_TUns64
+ getMilliSeconds(
+ ) const;
+
+
+ /**
+ * Returns the number of displays on this system.
+ * @return The number of displays.
+ */
+ GHOST_TUns8
+ getNumDisplays(
+ ) const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ void
+ getMainDisplayDimensions(
+ GHOST_TUns32& width,
+ GHOST_TUns32& height
+ ) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Create a stereo visual for quad buffered stereo.
+ * @return The new window (or 0 if creation failed).
+ */
+ GHOST_IWindow*
+ createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual
+ );
+
+ /**
+ * @section Interface Inherited from GHOST_ISystem
+ */
+
+ /**
+ * Retrieves events from the system and stores them in the queue.
+ * @param waitForEvent Flag to wait for an event (or return immediately).
+ * @return Indication of the presence of events.
+ */
+ bool
+ processEvents(
+ bool waitForEvent
+ );
+
+ /**
+ * @section Interface Inherited from GHOST_System
+ */
+ GHOST_TSuccess
+ getCursorPosition(
+ GHOST_TInt32& x,
+ GHOST_TInt32& y
+ ) const;
+
+ GHOST_TSuccess
+ setCursorPosition(
+ GHOST_TInt32 x,
+ GHOST_TInt32 y
+ ) const;
+
+ /**
+ * Returns the state of all modifier keys.
+ * @param keys The state of all modifier keys (true == pressed).
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getModifierKeys(
+ GHOST_ModifierKeys& keys
+ ) const ;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * @param buttons The state of the buttons.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess
+ getButtons(
+ GHOST_Buttons& buttons
+ ) const;
+
+ /**
+ * @section
+ * Flag a window as dirty. This will
+ * generate a GHOST window update event on a call to processEvents()
+ */
+
+ void
+ addDirtyWindow(
+ GHOST_WindowX11 * bad_wind
+ );
+
+
+ /**
+ * return a pointer to the X11 display structure
+ */
+
+ Display *
+ getXDisplay(
+ ) {
+ return m_display;
+ }
+
+
+private :
+
+ Display * m_display;
+
+ /**
+ * Atom used to detect window close events
+ */
+ Atom m_delete_window_atom;
+
+ /// The vector of windows that need to be updated.
+ std::vector<GHOST_WindowX11 *> m_dirty_windows;
+
+ /// Start time at initialization.
+ GHOST_TUns64 m_start_time;
+
+ /// A vector of keyboard key masks
+ char *m_keyboard_vector;
+
+ /**
+ * Return the ghost window associated with the
+ * X11 window xwind
+ */
+
+ GHOST_WindowX11 *
+ findGhostWindow(
+ Window xwind
+ ) const ;
+
+ void
+ processEvent(
+ XEvent *xe
+ );
+
+ bool
+ generateWindowExposeEvents(
+ );
+
+ GHOST_TKey
+ convertXKey(
+ unsigned int key
+ );
+
+};
+
+#endif
+
+
+
+
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
new file mode 100644
index 00000000000..e54dfce86f9
--- /dev/null
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -0,0 +1,163 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#include "GHOST_TimerManager.h"
+
+#include <algorithm>
+
+#include "GHOST_TimerTask.h"
+
+
+GHOST_TimerManager::GHOST_TimerManager()
+{
+}
+
+
+GHOST_TimerManager::~GHOST_TimerManager()
+{
+ disposeTimers();
+}
+
+
+GHOST_TUns32 GHOST_TimerManager::getNumTimers()
+{
+ return (GHOST_TUns32)m_timers.size();
+}
+
+
+bool GHOST_TimerManager::getTimerFound(GHOST_TimerTask* timer)
+{
+ TTimerVector::const_iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
+ return iter != m_timers.end();
+}
+
+
+GHOST_TSuccess GHOST_TimerManager::addTimer(GHOST_TimerTask* timer)
+{
+ GHOST_TSuccess success;
+ if (!getTimerFound(timer)) {
+ // Add the timer task
+ m_timers.push_back(timer);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_TimerManager::removeTimer(GHOST_TimerTask* timer)
+{
+ GHOST_TSuccess success;
+ TTimerVector::iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
+ if (iter != m_timers.end()) {
+ // Remove the timer task
+ m_timers.erase(iter);
+ delete timer;
+ timer = 0;
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+GHOST_TUns64 GHOST_TimerManager::nextFireTime()
+{
+ GHOST_TUns64 smallest = GHOST_kFireTimeNever;
+ TTimerVector::iterator iter;
+
+ for (iter = m_timers.begin(); iter != m_timers.end(); iter++) {
+ GHOST_TUns64 next = (*iter)->getNext();
+
+ if (next<smallest)
+ smallest = next;
+ }
+
+ return smallest;
+}
+
+bool GHOST_TimerManager::fireTimers(GHOST_TUns64 time)
+{
+ TTimerVector::iterator iter;
+ bool anyProcessed = false;
+
+ for (iter = m_timers.begin(); iter != m_timers.end(); iter++) {
+ if (fireTimer(time, *iter))
+ anyProcessed = true;
+ }
+
+ return anyProcessed;
+}
+
+
+bool GHOST_TimerManager::fireTimer(GHOST_TUns64 time, GHOST_TimerTask* task)
+{
+ GHOST_TUns64 next = task->getNext();
+
+ // Check if the timer should be fired
+ if (time > next) {
+ // Fire the timer
+ GHOST_TimerProcPtr timerProc = task->getTimerProc();
+ GHOST_TUns64 start = task->getStart();
+ timerProc(task, time - start);
+
+ // Update the time at which we will fire it again
+ GHOST_TUns64 interval = task->getInterval();
+ GHOST_TUns64 numCalls = (next - start) / interval;
+ numCalls++;
+ next = start + numCalls * interval;
+ task->setNext(next);
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+void GHOST_TimerManager::disposeTimers()
+{
+ while (m_timers.size() > 0) {
+ delete m_timers[0];
+ m_timers.erase(m_timers.begin());
+ }
+}
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
new file mode 100644
index 00000000000..ab6d004cba8
--- /dev/null
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -0,0 +1,133 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#ifndef _GHOST_TIMER_MANAGER_H_
+#define _GHOST_TIMER_MANAGER_H_
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include <vector>
+
+#include "GHOST_Types.h"
+
+class GHOST_TimerTask;
+
+
+/**
+ * Manages a list of timer tasks.
+ * Timer tasks added are owned by the manager.
+ * Don't delete timer task objects.
+ */
+class GHOST_TimerManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_TimerManager();
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_TimerManager();
+
+ /**
+ * Returns the number of timer tasks.
+ * @return The number of events on the stack.
+ */
+ virtual GHOST_TUns32 getNumTimers();
+
+ /**
+ * Returns whther this timer task ins in our list.
+ * @return Indication of presence.
+ */
+ virtual bool getTimerFound(GHOST_TimerTask* timer);
+
+ /**
+ * Adds a timer task to the list.
+ * It is only added when it not already present in the list.
+ * @param timer The timer task added to the list.
+ * @return Indication as to whether addition has succeeded.
+ */
+ virtual GHOST_TSuccess addTimer(GHOST_TimerTask* timer);
+
+ /**
+ * Removes a timer task from the list.
+ * It is only removed when it is found in the list.
+ * @param timer The timer task to be removed from the list.
+ * @return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess removeTimer(GHOST_TimerTask* timer);
+
+ /**
+ * Finds the soonest time the next timer would fire.
+ * @return The soonest time the next timer would fire,
+ * or GHOST_kFireTimeNever if no timers exist.
+ */
+ virtual GHOST_TUns64 nextFireTime();
+
+ /**
+ * Checks all timer tasks to see if they are expired and fires them if needed.
+ * @param time The current time.
+ * @return True if any timers were fired.
+ */
+ virtual bool fireTimers(GHOST_TUns64 time);
+
+ /**
+ * Checks this timer task to see if they are expired and fires them if needed.
+ * @param time The current time.
+ * @param task The timer task to check and optionally fire.
+ * @return True if the timer fired.
+ */
+ virtual bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask* task);
+
+protected:
+ /**
+ * Deletes all timers.
+ */
+ void disposeTimers();
+
+ typedef std::vector<GHOST_TimerTask*> TTimerVector;
+ /** The list with event consumers. */
+ TTimerVector m_timers;
+};
+
+#endif // _GHOST_TIMER_MANAGER_H_
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
new file mode 100644
index 00000000000..4f845a38fa1
--- /dev/null
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -0,0 +1,195 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 28, 2001
+ */
+
+#ifndef _GHOST_TIMER_TASK_H_
+#define _GHOST_TIMER_TASK_H_
+
+#include "GHOST_ITimerTask.h"
+
+
+/**
+ * Implementation of a timer task.
+ * @author Maarten Gribnau
+ * @date May 28, 2001
+ */
+class GHOST_TimerTask : public GHOST_ITimerTask
+{
+public:
+ /**
+ * Constructor.
+ * @param start The timer start time.
+ * @param interval The interval between calls to the timerProc
+ * @param timerProc The callbak invoked when the interval expires.
+ * @param data The timer user data.
+ */
+ GHOST_TimerTask(GHOST_TUns64 start, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0)
+ : m_start(start), m_interval(interval), m_next(start), m_timerProc(timerProc), m_userData(userData), m_auxData(0)
+ {
+ }
+
+ /**
+ * Returns the timer start time.
+ * @return The timer start time.
+ */
+ inline virtual GHOST_TUns64 getStart() const
+ {
+ return m_start;
+ }
+
+ /**
+ * Changes the timer start time.
+ * @param start The timer start time.
+ */
+ virtual void setStart(GHOST_TUns64 start)
+ {
+ m_start = start;
+ }
+
+ /**
+ * Returns the timer interval.
+ * @return The timer interval.
+ */
+ inline virtual GHOST_TUns64 getInterval() const
+ {
+ return m_interval;
+ }
+
+ /**
+ * Changes the timer interval.
+ * @param interval The timer interval.
+ */
+ virtual void setInterval(GHOST_TUns64 interval)
+ {
+ m_interval = interval;
+ }
+
+ /**
+ * Returns the time the timerProc will be called.
+ * @return The time the timerProc will be called.
+ */
+ inline virtual GHOST_TUns64 getNext() const
+ {
+ return m_next;
+ }
+
+ /**
+ * Changes the time the timerProc will be called.
+ * @param next The time the timerProc will be called.
+ */
+ virtual void setNext(GHOST_TUns64 next)
+ {
+ m_next = next;
+ }
+
+ /**
+ * Returns the timer callback.
+ * @return the timer callback.
+ */
+ inline virtual GHOST_TimerProcPtr getTimerProc() const
+ {
+ return m_timerProc;
+ }
+
+ /**
+ * Changes the timer callback.
+ * @param The timer callback.
+ */
+ inline virtual void setTimerProc(const GHOST_TimerProcPtr timerProc)
+ {
+ m_timerProc = timerProc;
+ }
+
+ /**
+ * Returns the timer user data.
+ * @return The timer user data.
+ */
+ inline virtual GHOST_TUserDataPtr getUserData() const
+ {
+ return m_userData;
+ }
+
+ /**
+ * Changes the time user data.
+ * @param data The timer user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData)
+ {
+ m_userData = userData;
+ }
+
+ /**
+ * Returns the auxiliary storage room.
+ * @return The auxiliary storage room.
+ */
+ inline virtual GHOST_TUns32 getAuxData() const
+ {
+ return m_auxData;
+ }
+
+ /**
+ * Changes the auxiliary storage room.
+ * @param auxData The auxiliary storage room.
+ */
+ virtual void setAuxData(GHOST_TUns32 auxData)
+ {
+ m_auxData = auxData;
+ }
+
+protected:
+ /** The time the timer task was started. */
+ GHOST_TUns64 m_start;
+
+ /** The interval between calls. */
+ GHOST_TUns64 m_interval;
+
+ /** The time the timerProc will be called. */
+ GHOST_TUns64 m_next;
+
+ /** The callback invoked when the timer expires. */
+ GHOST_TimerProcPtr m_timerProc;
+
+ /** The timer task user data. */
+ GHOST_TUserDataPtr m_userData;
+
+ /** Auxiliary storage room. */
+ GHOST_TUns32 m_auxData;
+};
+
+
+#endif // _GHOST_TIMER_TASK_H_
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
new file mode 100644
index 00000000000..daa83eedcf6
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -0,0 +1,116 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#include "GHOST_Window.h"
+
+
+GHOST_Window::GHOST_Window(
+ const STR_String& /*title*/,
+ GHOST_TInt32 /*left*/, GHOST_TInt32 /*top*/, GHOST_TUns32 width, GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual)
+:
+ m_drawingContextType(type),
+ m_cursorVisible(true),
+ m_cursorShape(GHOST_kStandardCursorDefault),
+ m_stereoVisual(stereoVisual)
+{
+ m_fullScreen = state == GHOST_kWindowStateFullScreen;
+ if (m_fullScreen) {
+ m_fullScreenWidth = width;
+ m_fullScreenHeight = height;
+ }
+}
+
+
+GHOST_Window::~GHOST_Window()
+{
+}
+
+
+GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type)
+{
+ GHOST_TSuccess success = GHOST_kSuccess;
+ if (type != m_drawingContextType) {
+ success = removeDrawingContext();
+ if (success) {
+ success = installDrawingContext(type);
+ m_drawingContextType = type;
+ }
+ else {
+ m_drawingContextType = GHOST_kDrawingContextTypeNone;
+ }
+ }
+ return success;
+}
+
+GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
+{
+ if (setWindowCursorVisibility(visible)) {
+ m_cursorVisible = visible;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+}
+
+GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
+{
+ if (setWindowCursorShape(cursorShape)) {
+ m_cursorShape = cursorShape;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+}
+
+GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY)
+{
+ if (setWindowCustomCursorShape(bitmap, mask, hotX, hotY)) {
+ m_cursorShape = GHOST_kStandardCursorCustom;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+}
+
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
new file mode 100644
index 00000000000..9bb2be7679f
--- /dev/null
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -0,0 +1,255 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#ifndef _GHOST_WINDOW_H_
+#define _GHOST_WINDOW_H_
+
+
+#include "GHOST_IWindow.h"
+
+class STR_String;
+
+/**
+ * Platform independent implementation of GHOST_IWindow.
+ * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+class GHOST_Window : public GHOST_IWindow
+{
+public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param heigh The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ */
+ GHOST_Window(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false);
+
+ /**
+ * @section Interface inherited from GHOST_IWindow left for derived class
+ * implementation.
+ * virtual bool getValid() const = 0;
+ * virtual void setTitle(const STR_String& title) = 0;
+ * virtual void getTitle(STR_String& title) const = 0;
+ * virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
+ * virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
+ * virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
+ * virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
+ * virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
+ * virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+ * virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+ * virtual GHOST_TWindowState getState() const = 0;
+ * virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
+ * virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
+ * virtual GHOST_TSuccess swapBuffers() = 0;
+ * virtual GHOST_TSuccess activateDrawingContext() = 0;
+ * virtual GHOST_TSuccess invalidate() = 0;
+ */
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ virtual ~GHOST_Window();
+
+ /**
+ * Returns the current cursor shape.
+ * @return The current cursor shape.
+ */
+ inline virtual GHOST_TStandardCursor getCursorShape() const;
+
+ /**
+ * Set the shape of the cursor.
+ * @param cursor The new cursor shape type id.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
+
+ /**
+ * Set the shape of the cursor to a custom cursor.
+ * @param bitmap The bitmap data for the cursor.
+ * @param mask The mask data for the cursor.
+ * @param hotX The X coordinate of the cursor hotspot.
+ * @param hotY The Y coordinate of the cursor hotspot.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ /**
+ * Returns the visibility state of the cursor.
+ * @return The visibility state of the cursor.
+ */
+ inline virtual bool getCursorVisibility() const;
+
+ /**
+ * Shows or hides the cursor.
+ * @param visible The new visibility state of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorVisibility(bool visible);
+
+ /**
+ * Returns the type of drawing context used in this window.
+ * @return The current type of drawing context.
+ */
+ inline virtual GHOST_TDrawingContextType getDrawingContextType();
+
+ /**
+ * Tries to install a rendering context in this window.
+ * Child classes do not need to overload this method.
+ * They should overload the installDrawingContext and removeDrawingContext instead.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
+
+ /**
+ * Returns the window user data.
+ * @return The window user data.
+ */
+ inline virtual GHOST_TUserDataPtr getUserData() const
+ {
+ return m_userData;
+ }
+
+ /**
+ * Changes the window user data.
+ * @param data The window user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData)
+ {
+ m_userData = userData;
+ }
+
+protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type) = 0;
+
+ /**
+ * Removes the current drawing context.
+ * @return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess removeDrawingContext() = 0;
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) = 0;
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY) = 0;
+
+ /** The the of drawing context installed in this window. */
+ GHOST_TDrawingContextType m_drawingContextType;
+
+ /** The window user data */
+ GHOST_TUserDataPtr m_userData;
+
+ /** The current visibility of the cursor */
+ bool m_cursorVisible;
+
+ /** The current shape of the cursor */
+ GHOST_TStandardCursor m_cursorShape;
+
+ /** Stores wether this is a full screen window. */
+ bool m_fullScreen;
+
+ /** Stereo visual created. Only necessary for 'real' stereo support,
+ * ie quad buffered stereo. This is not always possible, depends on
+ * the graphics h/w
+ */
+ bool m_stereoVisual;
+
+ /** Full-screen width */
+ GHOST_TUns32 m_fullScreenWidth;
+ /** Full-screen height */
+ GHOST_TUns32 m_fullScreenHeight;
+};
+
+
+inline GHOST_TDrawingContextType GHOST_Window::getDrawingContextType()
+{
+ return m_drawingContextType;
+}
+
+inline bool GHOST_Window::getCursorVisibility() const
+{
+ return m_cursorVisible;
+}
+
+inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
+{
+ return m_cursorShape;
+}
+
+#endif // _GHOST_WINDOW_H
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
new file mode 100644
index 00000000000..0e894a2dd43
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -0,0 +1,581 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#include "GHOST_WindowCarbon.h"
+
+#include "GHOST_Debug.h"
+
+AGLContext GHOST_WindowCarbon::s_firstaglCtx = NULL;
+
+static const GLint sPreferredFormatWindow[7] = {
+AGL_RGBA, GL_TRUE,
+AGL_DOUBLEBUFFER, GL_TRUE,
+AGL_DEPTH_SIZE, 16,
+AGL_NONE,
+};
+
+static const GLint sPreferredFormatFullScreen[7] = {
+AGL_RGBA,
+AGL_DOUBLEBUFFER,
+AGL_ACCELERATED,
+AGL_FULLSCREEN,
+AGL_DEPTH_SIZE, 16,
+AGL_NONE,
+};
+
+GHOST_WindowCarbon::GHOST_WindowCarbon(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual
+) :
+ GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
+ m_windowRef(0),
+ m_grafPtr(0),
+ m_aglCtx(0),
+ m_customCursor(0),
+ m_fullScreenDirty(false)
+{
+ Str255 title255;
+
+ if (state != GHOST_kWindowStateFullScreen) {
+ Rect bnds = { top, left, top+height, left+width };
+ Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized);
+ gen2mac(title, title255);
+
+ m_windowRef = ::NewCWindow(
+ nil, // Storage
+ &bnds, // Bounding rectangle of the window
+ title255, // Title of the window
+ visible, // Window initially visible
+ kWindowFullZoomGrowDocumentProc, //kWindowGrowDocumentProc, // procID
+ (WindowRef)-1L, // Put window before all other windows
+ true, // Window has minimize box
+ (SInt32)this); // Store a pointer to the class in the refCon
+ if (m_windowRef) {
+ m_grafPtr = ::GetWindowPort(m_windowRef);
+ setDrawingContextType(type);
+ updateDrawingContext();
+ activateDrawingContext();
+ }
+ }
+ else {
+ /*
+ Rect bnds = { top, left, top+height, left+width };
+ gen2mac("", title255);
+ m_windowRef = ::NewCWindow(
+ nil, // Storage
+ &bnds, // Bounding rectangle of the window
+ title255, // Title of the window
+ 0, // Window initially visible
+ plainDBox, // procID
+ (WindowRef)-1L, // Put window before all other windows
+ 0, // Window has minimize box
+ (SInt32)this); // Store a pointer to the class in the refCon
+ */
+ //GHOST_PRINT("GHOST_WindowCarbon::GHOST_WindowCarbon(): creating full-screen OpenGL context\n");
+ setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
+ updateDrawingContext();
+ activateDrawingContext();
+ }
+}
+
+
+GHOST_WindowCarbon::~GHOST_WindowCarbon()
+{
+ if (m_customCursor) delete m_customCursor;
+
+ //GHOST_PRINT("GHOST_WindowCarbon::~GHOST_WindowCarbon(): removing drawing context\n");
+ setDrawingContextType(GHOST_kDrawingContextTypeNone);
+ if (m_windowRef) {
+ ::DisposeWindow(m_windowRef);
+ m_windowRef = 0;
+ }
+}
+
+bool GHOST_WindowCarbon::getValid() const
+{
+ bool valid;
+ if (!m_fullScreen) {
+ valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
+ }
+ else {
+ valid = true;
+ }
+ return valid;
+}
+
+
+void GHOST_WindowCarbon::setTitle(const STR_String& title)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setTitle(): window invalid")
+ Str255 title255;
+ gen2mac(title, title255);
+ ::SetWTitle(m_windowRef, title255);
+}
+
+
+void GHOST_WindowCarbon::getTitle(STR_String& title) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::getTitle(): window invalid")
+ Str255 title255;
+ ::GetWTitle(m_windowRef, title255);
+ mac2gen(title255, title);
+}
+
+
+void GHOST_WindowCarbon::getWindowBounds(GHOST_Rect& bounds) const
+{
+ OSStatus success;
+ Rect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::getWindowBounds(): window invalid")
+ success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+}
+
+
+void GHOST_WindowCarbon::getClientBounds(GHOST_Rect& bounds) const
+{
+ Rect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::getClientBounds(): window invalid")
+ ::GetPortBounds(m_grafPtr, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setClientWidth(GHOST_TUns32 width)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setClientWidth(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (((GHOST_TUns32)cBnds.getWidth()) != width) {
+ ::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setClientHeight(GHOST_TUns32 height)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setClientHeight(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (((GHOST_TUns32)cBnds.getHeight()) != height) {
+ ::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setClientSize(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+ (((GHOST_TUns32)cBnds.getHeight()) != height)) {
+ ::SizeWindow(m_windowRef, width, height, true);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TWindowState GHOST_WindowCarbon::getState() const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::getState(): window invalid")
+ GHOST_TWindowState state;
+ if (::IsWindowVisible(m_windowRef)) {
+ state = GHOST_kWindowStateMinimized;
+ }
+ else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
+ state = GHOST_kWindowStateMaximized;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ return state;
+}
+
+
+void GHOST_WindowCarbon::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::screenToClient(): window invalid")
+ Point point;
+ point.h = inX;
+ point.v = inY;
+ GrafPtr oldPort;
+ ::GetPort(&oldPort);
+ ::SetPort(m_grafPtr);
+ ::GlobalToLocal(&point);
+ ::SetPort(oldPort);
+ outX = point.h;
+ outY = point.v;
+}
+
+
+void GHOST_WindowCarbon::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::clientToScreen(): window invalid")
+ Point point;
+ point.h = inX;
+ point.v = inY;
+ GrafPtr oldPort;
+ ::GetPort(&oldPort);
+ ::SetPort(m_grafPtr);
+ ::LocalToGlobal(&point);
+ ::SetPort(oldPort);
+ outX = point.h;
+ outY = point.v;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setState(GHOST_TWindowState state)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setState(): window invalid")
+ switch (state) {
+ case GHOST_kWindowStateMinimized:
+ ::HideWindow(m_windowRef);
+ break;
+ case GHOST_kWindowStateMaximized:
+ case GHOST_kWindowStateNormal:
+ default:
+ ::ShowWindow(m_windowRef);
+ break;
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setOrder(GHOST_TWindowOrder order)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::setOrder(): window invalid")
+ if (order == GHOST_kWindowOrderTop) {
+ ::BringToFront(m_windowRef);
+ }
+ else {
+ ::SendBehind(m_windowRef, nil);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::swapBuffers()
+{
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglSwapBuffers(m_aglCtx);
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCarbon::updateDrawingContext()
+{
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglUpdateContext(m_aglCtx);
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCarbon::activateDrawingContext()
+{
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglSetCurrentContext(m_aglCtx);
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::installDrawingContext(GHOST_TDrawingContextType type)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ switch (type) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ {
+ if (!getValid()) break;
+
+ AGLPixelFormat pixelFormat;
+ if (!m_fullScreen) {
+ pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
+ m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
+ if (!m_aglCtx) break;
+ if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+ success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ //GHOST_PRINT("GHOST_WindowCarbon::installDrawingContext(): init full-screen OpenGL\n");
+ pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatFullScreen);
+ m_aglCtx = ::aglCreateContext(pixelFormat, 0);
+ if (!m_aglCtx) break;
+ if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+ //GHOST_PRINT("GHOST_WindowCarbon::installDrawingContext(): created OpenGL context\n");
+ //::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
+ success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ /*
+ if (success == GHOST_kSuccess) {
+ GHOST_PRINT("GHOST_WindowCarbon::installDrawingContext(): init full-screen OpenGL succeeded\n");
+ }
+ else {
+ GHOST_PRINT("GHOST_WindowCarbon::installDrawingContext(): init full-screen OpenGL failed\n");
+ }
+ */
+ }
+ ::aglDestroyPixelFormat(pixelFormat);
+ }
+ break;
+
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+
+ default:
+ break;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::removeDrawingContext()
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ switch (m_drawingContextType) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ if (m_aglCtx) {
+ aglSetCurrentContext(NULL);
+ aglSetDrawable(m_aglCtx, NULL);
+ //aglDestroyContext(m_aglCtx);
+ if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
+ success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ m_aglCtx = 0;
+ }
+ break;
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+ default:
+ break;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::invalidate()
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCarbon::invalidate(): window invalid")
+ if (!m_fullScreen) {
+ Rect rect;
+ ::GetPortBounds(m_grafPtr, &rect);
+ ::InvalWindowRect(m_windowRef, &rect);
+ }
+ else {
+ //EventRef event;
+ //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
+ //GHOST_PRINT("GHOST_WindowCarbon::invalidate(): created event " << status << " \n");
+ //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
+ //GHOST_PRINT("GHOST_WindowCarbon::invalidate(): set event parameter " << status << " \n");
+ //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
+ //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
+ //GHOST_PRINT("GHOST_WindowCarbon::invalidate(): added event to queue " << status << " \n");
+ m_fullScreenDirty = true;
+ }
+ return GHOST_kSuccess;
+}
+
+
+void GHOST_WindowCarbon::gen2mac(const STR_String& in, Str255 out) const
+{
+ STR_String tempStr = in;
+ int num = tempStr.Length();
+ if (num > 255) num = 255;
+ ::memcpy(out+1, tempStr.Ptr(), num);
+ out[0] = num;
+}
+
+
+void GHOST_WindowCarbon::mac2gen(const Str255 in, STR_String& out) const
+{
+ char tmp[256];
+ ::memcpy(tmp, in+1, in[0]);
+ tmp[in[0]] = '\0';
+ out = tmp;
+}
+
+void GHOST_WindowCarbon::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+{
+ static bool systemCursorVisible = true;
+
+ if (visible != systemCursorVisible) {
+ if (visible) {
+ ::ShowCursor();
+ systemCursorVisible = true;
+ }
+ else {
+ ::HideCursor();
+ systemCursorVisible = false;
+ }
+ }
+
+ if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+ ::SetCursor( m_customCursor );
+ } else {
+ int carbon_cursor;
+
+#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break
+ switch (cursor) {
+ default:
+ GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorRightArrow, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor);
+ GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor);
+ GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor);
+ GCMAP( GHOST_kStandardCursorUpDown, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorLeftRight, kThemeResizeLeftRightCursor);
+ GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor);
+ GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor);
+ GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor);
+ };
+#undef GCMAP
+
+ ::SetThemeCursor(carbon_cursor);
+ }
+}
+
+
+bool GHOST_WindowCarbon::getFullScreenDirty()
+{
+ return m_fullScreen && m_fullScreenDirty;
+}
+
+
+GHOST_TSuccess GHOST_WindowCarbon::setWindowCursorVisibility(bool visible)
+{
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(visible, getCursorShape());
+ }
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowCarbon::setWindowCursorShape(GHOST_TStandardCursor shape)
+{
+ if (m_customCursor) {
+ delete m_customCursor;
+ m_customCursor = 0;
+ }
+
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(getCursorVisibility(), shape);
+ }
+
+ return GHOST_kSuccess;
+}
+
+/** Reverse the bits in a GHOST_TUns16 */
+static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
+{
+ shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
+ shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
+ shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
+ shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
+ return shrt;
+}
+
+GHOST_TSuccess GHOST_WindowCarbon::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY)
+{
+ int y;
+
+ if (m_customCursor) {
+ delete m_customCursor;
+ m_customCursor = 0;
+ }
+
+ m_customCursor = new Cursor;
+ if (!m_customCursor) return GHOST_kFailure;
+
+ for (y=0; y<16; y++) {
+ m_customCursor->data[y] = uns16ReverseBits((bitmap[y][0]<<0) | (bitmap[y][1]<<8));
+ m_customCursor->mask[y] = uns16ReverseBits((mask[y][0]<<0) | (mask[y][1]<<8));
+ }
+
+ m_customCursor->hotSpot.h = hotX;
+ m_customCursor->hotSpot.v = hotY;
+
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+ }
+
+ return GHOST_kSuccess;
+}
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.h b/intern/ghost/intern/GHOST_WindowCarbon.h
new file mode 100644
index 00000000000..694bb8e9a5d
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowCarbon.h
@@ -0,0 +1,273 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _GHOST_WINDOW_CARBON_H_
+#define _GHOST_WINDOW_CARBON_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+#include "GHOST_Window.h"
+#include "STR_String.h"
+
+#include <Carbon/Carbon.h>
+#include <AGL/agl.h>
+
+
+/**
+ * Window on Mac OSX/Carbon.
+ * @author Maarten Gribnau
+ * @date May 23, 2001
+ */
+
+class GHOST_WindowCarbon : public GHOST_Window {
+public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ */
+ GHOST_WindowCarbon(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false
+ );
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ virtual ~GHOST_WindowCarbon();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * @return The validity of the window.
+ */
+ virtual bool getValid() const;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * @param title The title to display in the title bar.
+ */
+ virtual void setTitle(const STR_String& title);
+
+ /**
+ * Returns the title displayed in the title bar.
+ * @param title The title displayed in the title bar.
+ */
+ virtual void getTitle(STR_String& title) const;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @param bounds The bounding rectangle of the window.
+ */
+ virtual void getWindowBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * @param bounds The bounding rectangle of the cleient area of the window.
+ */
+ virtual void getClientBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Resizes client rectangle width.
+ * @param width The new width of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ /**
+ * Resizes client rectangle height.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ /**
+ * Resizes client rectangle.
+ * @param width The new width of the client area of the window.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * @return The state of the window.
+ */
+ virtual GHOST_TWindowState getState() const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate on the screen.
+ * @param inY The y-coordinate on the screen.
+ * @param outX The x-coordinate in the client rectangle.
+ * @param outY The y-coordinate in the client rectangle.
+ */
+ virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate in the client rectangle.
+ * @param inY The y-coordinate in the client rectangle.
+ * @param outX The x-coordinate on the screen.
+ * @param outY The y-coordinate on the screen.
+ */
+ virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * @param state The state of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * @param order The order of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ /**
+ * Swaps front and back buffers of a window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers();
+
+ /**
+ * Updates the drawing context of this window. Needed
+ * whenever the window is changed.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess updateDrawingContext();
+
+ /**
+ * Activates the drawing context of this window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext();
+
+ virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
+
+ /**
+ * Returns the dirty state of the window when in full-screen mode.
+ * @return Whether it is dirty.
+ */
+ virtual bool getFullScreenDirty();
+
+protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Removes the current drawing context.
+ * @return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess removeDrawingContext();
+
+ /**
+ * Invalidates the contents of this window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess invalidate();
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
+
+ /**
+ * Converts a string object to a Mac Pascal string.
+ * @param in The string object to be converted.
+ * @param out The converted string.
+ */
+ virtual void gen2mac(const STR_String& in, Str255 out) const;
+
+ /**
+ * Converts a Mac Pascal string to a string object.
+ * @param in The string to be converted.
+ * @param out The converted string object.
+ */
+ virtual void mac2gen(const Str255 in, STR_String& out) const;
+
+ WindowRef m_windowRef;
+ CGrafPtr m_grafPtr;
+ AGLContext m_aglCtx;
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static AGLContext s_firstaglCtx;
+
+ Cursor* m_customCursor;
+
+ /** When running in full-screen this tells whether to refresh the window. */
+ bool m_fullScreenDirty;
+};
+
+#endif // _GHOST_WINDOW_CARBON_H_
diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp
new file mode 100644
index 00000000000..a281145ac29
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowManager.cpp
@@ -0,0 +1,190 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#include "GHOST_WindowManager.h"
+
+#include <algorithm>
+
+#include "GHOST_Debug.h"
+#include "GHOST_Window.h"
+
+
+GHOST_WindowManager::GHOST_WindowManager()
+: m_fullScreenWindow(0), m_activeWindow(0)
+{
+}
+
+
+GHOST_WindowManager::~GHOST_WindowManager()
+{
+}
+
+
+GHOST_TSuccess GHOST_WindowManager::addWindow(GHOST_IWindow* window)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (window) {
+ if (!getWindowFound(window)) {
+ // Store the pointer to the window
+ m_windows.push_back(window);
+ success = GHOST_kSuccess;
+ }
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowManager::removeWindow(const GHOST_IWindow* window)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (window) {
+ if (window == m_fullScreenWindow) {
+ endFullScreen();
+ }
+ else {
+ vector<GHOST_IWindow*>::iterator result = find(m_windows.begin(), m_windows.end(), window);
+ if (result != m_windows.end()) {
+ setWindowInactive(window);
+ m_windows.erase(result);
+ success = GHOST_kSuccess;
+ }
+ }
+ }
+ return success;
+}
+
+
+bool GHOST_WindowManager::getWindowFound(const GHOST_IWindow* window) const
+{
+ bool found = false;
+ if (window) {
+ if (getFullScreen() && (window == m_fullScreenWindow)) {
+ found = true;
+ }
+ else {
+ vector<GHOST_IWindow*>::const_iterator result = find(m_windows.begin(), m_windows.end(), window);
+ if (result != m_windows.end()) {
+ found = true;
+ }
+ }
+ }
+ return found;
+}
+
+
+bool GHOST_WindowManager::getFullScreen(void) const
+{
+ return m_fullScreenWindow != 0;
+}
+
+
+GHOST_IWindow* GHOST_WindowManager::getFullScreenWindow(void) const
+{
+ return m_fullScreenWindow;
+}
+
+
+GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow* window,
+ bool stereoVisual)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(window, "GHOST_WindowManager::beginFullScreen(): invalid window");
+ GHOST_ASSERT(window->getValid(), "GHOST_WindowManager::beginFullScreen(): invalid window");
+ if (!getFullScreen()) {
+ m_fullScreenWindow = window;
+ setActiveWindow(m_fullScreenWindow);
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowManager::endFullScreen(void)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (getFullScreen()) {
+ if (m_fullScreenWindow != 0) {
+ //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n");
+ setWindowInactive(m_fullScreenWindow);
+ delete m_fullScreenWindow;
+ //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n");
+ m_fullScreenWindow = 0;
+ }
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowManager::setActiveWindow(GHOST_IWindow* window)
+{
+ GHOST_TSuccess success = GHOST_kSuccess;
+ if (window != m_activeWindow) {
+ if (getWindowFound(window)) {
+ m_activeWindow = window;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
+}
+
+
+GHOST_IWindow* GHOST_WindowManager::getActiveWindow(void) const
+{
+ return m_activeWindow;
+}
+
+
+void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow* window)
+{
+ if (window == m_activeWindow) {
+ m_activeWindow = 0;
+ }
+}
+
+
+ std::vector<GHOST_IWindow *> &
+GHOST_WindowManager::
+getWindows(
+){
+ return m_windows;
+}
+
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
new file mode 100644
index 00000000000..7af86a1113c
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -0,0 +1,165 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 11, 2001
+ */
+
+#ifndef _GHOST_WINDOW_MANAGER_H_
+#define _GHOST_WINDOW_MANAGER_H_
+
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include <vector>
+
+#include "GHOST_Rect.h"
+#include "GHOST_IWindow.h"
+
+//class GHOST_Window;
+
+/**
+ * Manages system windows (platform independent implementation).
+ */
+
+class GHOST_WindowManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_WindowManager();
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_WindowManager();
+
+ /**
+ * Add a window to our list.
+ * It is only added if it is not already in the list.
+ * @param window Pointer to the window to be added.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess addWindow(GHOST_IWindow* window);
+
+ /**
+ * Remove a window from our list.
+ * @param window Pointer to the window to be removed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess removeWindow(const GHOST_IWindow* window);
+
+ /**
+ * Returns whether the window is in our list.
+ * @param window Pointer to the window to query.
+ * @return A boolean indicator.
+ */
+ virtual bool getWindowFound(const GHOST_IWindow* window) const;
+
+ /**
+ * Returns whether one of the windows is fullscreen.
+ * @return A boolean indicator.
+ */
+ virtual bool getFullScreen(void) const;
+
+ /**
+ * Returns pointer to the full-screen window.
+ * @return The fll-screen window (0 if not in full-screen).
+ */
+ virtual GHOST_IWindow* getFullScreenWindow(void) const;
+
+ /**
+ * Activates fullscreen mode for a window.
+ * @param window The window displayed fullscreen.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess beginFullScreen(GHOST_IWindow* window, const bool stereoVisual);
+
+ /**
+ * Closes fullscreen mode down.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess endFullScreen(void);
+
+ /**
+ * Sets new window as active window (the window receiving events).
+ * There can be only one window active which should be in the current window list.
+ * @param window The new active window.
+ */
+ virtual GHOST_TSuccess setActiveWindow(GHOST_IWindow* window);
+
+ /**
+ * Returns the active window (the window receiving events).
+ * There can be only one window active which should be in the current window list.
+ * @return window The active window (or NULL if there is none).
+ */
+ virtual GHOST_IWindow* getActiveWindow(void) const;
+
+
+ /**
+ * Set this window to be inactive (not receiving events).
+ * @param window The window to decativate.
+ */
+ virtual void setWindowInactive(const GHOST_IWindow* window);
+
+
+ /**
+ * Return a vector of the windows currently managed by this
+ * class.
+ * @warning It is very dangerous to mess with the contents of
+ * this vector. Please do not destroy or add windows use the
+ * interface above for this,
+ */
+
+ std::vector<GHOST_IWindow *> &
+ getWindows(
+ );
+
+
+protected:
+ /** The list of windows managed */
+ std::vector<GHOST_IWindow*> m_windows;
+
+ /** Window in fullscreen state. There can be only one of this which is not in or window list. */
+ GHOST_IWindow* m_fullScreenWindow;
+
+ /** The active window. */
+ GHOST_IWindow* m_activeWindow;
+};
+
+#endif // _GHOST_WINDOW_MANAGER_H_
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
new file mode 100644
index 00000000000..239a020083b
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -0,0 +1,584 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#include <string.h>
+
+#include "GHOST_WindowWin32.h"
+
+#include <GL/gl.h>
+
+LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass";
+const int GHOST_WindowWin32::s_maxTitleLength = 128;
+HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL;
+
+/*
+ * Color and depth bit values are not to be trusted.
+ * For instance, on TNT2:
+ * When the screen color depth is set to 16 bit, we get 5 color bits
+ * and 16 depth bits.
+ * When the screen color depth is set to 32 bit, we get 8 color bits
+ * and 24 depth bits.
+ * Just to be safe, we request high waulity settings.
+ */
+static PIXELFORMATDESCRIPTOR sPreferredFormat = {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size */
+ 1, /* version */
+ PFD_SUPPORT_OPENGL |
+ PFD_DRAW_TO_WINDOW |
+ PFD_DOUBLEBUFFER, /* support double-buffering */
+ PFD_TYPE_RGBA, /* color type */
+ 32, /* prefered color depth */
+ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
+ 0, /* no alpha buffer */
+ 0, /* alpha bits (ignored) */
+ 0, /* no accumulation buffer */
+ 0, 0, 0, 0, /* accum bits (ignored) */
+ 32, /* depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0, 0, 0 /* no layer, visible, damage masks */
+};
+
+GHOST_WindowWin32::GHOST_WindowWin32(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual)
+:
+ GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone,
+ stereoVisual),
+ m_hDC(0),
+ m_hGlRc(0),
+ m_hasMouseCaptured(false),
+ m_nPressedButtons(0),
+ m_customCursor(0)
+{
+ if (state != GHOST_kWindowStateFullScreen) {
+ /* Convert client size into window size */
+ width += GetSystemMetrics(SM_CXSIZEFRAME)*2;
+ height += GetSystemMetrics(SM_CYSIZEFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
+
+ m_hWnd = ::CreateWindow(
+ s_windowClassName, // pointer to registered class name
+ title, // pointer to window name
+ WS_OVERLAPPEDWINDOW, // window style
+ left, // horizontal position of window
+ top, // vertical position of window
+ width, // window width
+ height, // window height
+ 0, // handle to parent or owner window
+ 0, // handle to menu or child-window identifier
+ ::GetModuleHandle(0), // handle to application instance
+ 0); // pointer to window-creation data
+ }
+ else {
+ m_hWnd = ::CreateWindow(
+ s_windowClassName, // pointer to registered class name
+ title, // pointer to window name
+ WS_POPUP | WS_MAXIMIZE, // window style
+ left, // horizontal position of window
+ top, // vertical position of window
+ width, // window width
+ height, // window height
+ 0, // handle to parent or owner window
+ 0, // handle to menu or child-window identifier
+ ::GetModuleHandle(0), // handle to application instance
+ 0); // pointer to window-creation data
+ }
+ if (m_hWnd) {
+ // Store a pointer to this class in the window structure
+ LONG result = ::SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
+
+ // Store the device context
+ m_hDC = ::GetDC(m_hWnd);
+
+ // Show the window
+ int nCmdShow;
+ switch (state) {
+ case GHOST_kWindowStateMaximized:
+ nCmdShow = SW_SHOWMAXIMIZED;
+ break;
+ case GHOST_kWindowStateMinimized:
+ nCmdShow = SW_SHOWMINIMIZED;
+ break;
+ case GHOST_kWindowStateNormal:
+ default:
+ nCmdShow = SW_SHOWNORMAL;
+ break;
+ }
+ setDrawingContextType(type);
+ ::ShowWindow(m_hWnd, nCmdShow);
+ // Force an initial paint of the window
+ ::UpdateWindow(m_hWnd);
+ }
+}
+
+
+GHOST_WindowWin32::~GHOST_WindowWin32()
+{
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
+
+ setDrawingContextType(GHOST_kDrawingContextTypeNone);
+ if (m_hDC) {
+ ::ReleaseDC(m_hWnd, m_hDC);
+ m_hDC = 0;
+ }
+ if (m_hWnd) {
+ ::DestroyWindow(m_hWnd);
+ m_hWnd = 0;
+ }
+}
+
+bool GHOST_WindowWin32::getValid() const
+{
+ return m_hWnd != 0;
+}
+
+
+void GHOST_WindowWin32::setTitle(const STR_String& title)
+{
+ ::SetWindowText(m_hWnd, title);
+}
+
+
+void GHOST_WindowWin32::getTitle(STR_String& title) const
+{
+ char buf[s_maxTitleLength];
+ ::GetWindowText(m_hWnd, buf, s_maxTitleLength);
+ STR_String temp (buf);
+ title = buf;
+}
+
+
+void GHOST_WindowWin32::getWindowBounds(GHOST_Rect& bounds) const
+{
+ RECT rect;
+ ::GetWindowRect(m_hWnd, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+}
+
+
+void GHOST_WindowWin32::getClientBounds(GHOST_Rect& bounds) const
+{
+ RECT rect;
+ ::GetClientRect(m_hWnd, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::setClientWidth(GHOST_TUns32 width)
+{
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (cBnds.getWidth() != width) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth() + width - cBnds.getWidth();
+ int cy = wBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::setClientHeight(GHOST_TUns32 height)
+{
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (cBnds.getHeight() != height) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth();
+ int cy = wBnds.getHeight() + height - cBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+{
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if ((cBnds.getWidth() != width) || (cBnds.getHeight() != height)) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth() + width - cBnds.getWidth();
+ int cy = wBnds.getHeight() + height - cBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TWindowState GHOST_WindowWin32::getState() const
+{
+ GHOST_TWindowState state;
+ if (::IsIconic(m_hWnd)) {
+ state = GHOST_kWindowStateMinimized;
+ }
+ else if (::IsZoomed(m_hWnd)) {
+ state = GHOST_kWindowStateMaximized;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ return state;
+}
+
+
+void GHOST_WindowWin32::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ POINT point = { inX, inY };
+ ::ScreenToClient(m_hWnd, &point);
+ outX = point.x;
+ outY = point.y;
+}
+
+
+void GHOST_WindowWin32::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ POINT point = { inX, inY };
+ ::ClientToScreen(m_hWnd, &point);
+ outX = point.x;
+ outY = point.y;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::setState(GHOST_TWindowState state)
+{
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(WINDOWPLACEMENT);
+ ::GetWindowPlacement(m_hWnd, &wp);
+ switch (state) {
+ case GHOST_kWindowStateMinimized: wp.showCmd = SW_SHOWMAXIMIZED; break;
+ case GHOST_kWindowStateMaximized: wp.showCmd = SW_SHOWMINIMIZED; break;
+ case GHOST_kWindowStateNormal: default: wp.showCmd = SW_SHOWNORMAL; break;
+ }
+ return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::setOrder(GHOST_TWindowOrder order)
+{
+ HWND hWndInsertAfter = order == GHOST_kWindowOrderTop ? HWND_TOP : HWND_BOTTOM;
+ return ::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::swapBuffers()
+{
+ return ::SwapBuffers(m_hDC) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::activateDrawingContext()
+{
+ GHOST_TSuccess success;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_hDC && m_hGlRc) {
+ success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::invalidate()
+{
+ GHOST_TSuccess success;
+ if (m_hWnd) {
+ success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextType type)
+{
+ GHOST_TSuccess success;
+ switch (type) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ {
+ if(m_stereoVisual)
+ sPreferredFormat.dwFlags |= PFD_STEREO;
+
+ // Attempt to match device context pixel format to the preferred format
+ int iPixelFormat = ::ChoosePixelFormat(m_hDC, &sPreferredFormat);
+ if (iPixelFormat == 0) {
+ success = GHOST_kFailure;
+ break;
+ }
+ if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) {
+ success = GHOST_kFailure;
+ break;
+ }
+ // For debugging only: retrieve the pixel format chosen
+ PIXELFORMATDESCRIPTOR preferredFormat;
+ ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &preferredFormat);
+ // Create the context
+ m_hGlRc = ::wglCreateContext(m_hDC);
+ if (m_hGlRc) {
+ if (s_firsthGLRc) {
+ wglShareLists(s_firsthGLRc, m_hGlRc);
+ } else {
+ s_firsthGLRc = m_hGlRc;
+ }
+
+ success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ break;
+
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+
+ default:
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
+{
+ GHOST_TSuccess success;
+ switch (m_drawingContextType) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ if (m_hGlRc) {
+ success = ::wglDeleteContext(m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ if (m_hGlRc == s_firsthGLRc) {
+ s_firsthGLRc = NULL;
+ }
+ m_hGlRc = 0;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ break;
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+ default:
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+void GHOST_WindowWin32::lostMouseCapture()
+{
+ if (m_hasMouseCaptured) {
+ m_hasMouseCaptured = false;
+ m_nPressedButtons = 0;
+ }
+}
+
+void GHOST_WindowWin32::registerMouseClickEvent(bool press)
+{
+ if (press) {
+ if (!m_hasMouseCaptured) {
+ ::SetCapture(m_hWnd);
+ m_hasMouseCaptured = true;
+ }
+ m_nPressedButtons++;
+ } else {
+ if (m_nPressedButtons) {
+ m_nPressedButtons--;
+ if (!m_nPressedButtons) {
+ ::ReleaseCapture();
+ m_hasMouseCaptured = false;
+ }
+ }
+ }
+}
+
+
+void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+{
+ if (!visible) {
+ while (::ShowCursor(FALSE) >= 0);
+ }
+ else {
+ while (::ShowCursor(TRUE) < 0);
+ }
+
+ if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+ ::SetCursor( m_customCursor );
+ } else {
+ // Convert GHOST cursor to Windows OEM cursor
+ bool success = true;
+ LPCSTR id;
+ switch (cursor) {
+ case GHOST_kStandardCursorDefault: id = IDC_ARROW;
+ case GHOST_kStandardCursorRightArrow: id = IDC_ARROW; break;
+ case GHOST_kStandardCursorLeftArrow: id = IDC_ARROW; break;
+ case GHOST_kStandardCursorInfo: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
+ case GHOST_kStandardCursorDestroy: id = IDC_NO; break; // Slashed circle
+ case GHOST_kStandardCursorHelp: id = IDC_HELP; break; // Arrow and question mark
+ case GHOST_kStandardCursorCycle: id = IDC_NO; break; // Slashed circle
+ case GHOST_kStandardCursorSpray: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
+ case GHOST_kStandardCursorWait: id = IDC_WAIT; break; // Hourglass
+ case GHOST_kStandardCursorText: id = IDC_IBEAM; break; // I-beam
+ case GHOST_kStandardCursorCrosshair: id = IDC_CROSS; break; // Crosshair
+ case GHOST_kStandardCursorUpDown: id = IDC_SIZENS; break; // Double-pointed arrow pointing north and south
+ case GHOST_kStandardCursorLeftRight: id = IDC_SIZEWE; break; // Double-pointed arrow pointing west and east
+ case GHOST_kStandardCursorTopSide: id = IDC_UPARROW; break; // Vertical arrow
+ case GHOST_kStandardCursorBottomSide: id = IDC_SIZENS; break;
+ case GHOST_kStandardCursorLeftSide: id = IDC_SIZEWE; break;
+ case GHOST_kStandardCursorTopLeftCorner: id = IDC_SIZENWSE; break;
+ case GHOST_kStandardCursorTopRightCorner: id = IDC_SIZENESW; break;
+ case GHOST_kStandardCursorBottomRightCorner: id = IDC_SIZENWSE; break;
+ case GHOST_kStandardCursorBottomLeftCorner: id = IDC_SIZENESW; break;
+ default:
+ success = false;
+ }
+
+ if (success) {
+ HCURSOR hCursor = ::SetCursor(::LoadCursor(0, id));
+ }
+ }
+}
+
+GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible)
+{
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(visible, getCursorShape());
+ }
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape)
+{
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
+
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(getCursorVisibility(), cursorShape);
+ }
+
+ return GHOST_kSuccess;
+}
+
+/** Reverse the bits in a GHOST_TUns16 */
+static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
+{
+ shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
+ shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
+ shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
+ shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
+ return shrt;
+}
+
+GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY)
+{
+ GHOST_TUns32 andData[32];
+ GHOST_TUns32 xorData[32];
+ int y;
+
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
+
+ memset(&andData, 0xFF, sizeof(andData));
+ memset(&xorData, 0, sizeof(xorData));
+
+ for (y=0; y<16; y++) {
+ GHOST_TUns32 fullBitRow = uns16ReverseBits((bitmap[y][0]<<8) | (bitmap[y][1]<<0));
+ GHOST_TUns32 fullMaskRow = uns16ReverseBits((mask[y][0]<<8) | (mask[y][1]<<0));
+
+ xorData[y]= fullBitRow & fullMaskRow;
+ andData[y]= ~fullMaskRow;
+ }
+
+ m_customCursor = ::CreateCursor(::GetModuleHandle(0), hotX, hotY, 32, 32, andData, xorData);
+ if (!m_customCursor) {
+ return GHOST_kFailure;
+ }
+
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+ }
+
+ return GHOST_kSuccess;
+}
+
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
new file mode 100644
index 00000000000..c29e61aabbb
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -0,0 +1,276 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifndef _GHOST_WINDOW_WIN32_H_
+#define _GHOST_WINDOW_WIN32_H_
+
+#ifndef WIN32
+#error WIN32 only!
+#endif // WIN32
+
+#include "GHOST_Window.h"
+
+#include <windows.h>
+
+
+/**
+ * GHOST window on M$ Windows OSs.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+class GHOST_WindowWin32 : public GHOST_Window {
+public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ */
+ GHOST_WindowWin32(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false
+ );
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ virtual ~GHOST_WindowWin32();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * @return The validity of the window.
+ */
+ virtual bool getValid() const;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * @param title The title to display in the title bar.
+ */
+ virtual void setTitle(const STR_String& title);
+
+ /**
+ * Returns the title displayed in the title bar.
+ * @param title The title displayed in the title bar.
+ */
+ virtual void getTitle(STR_String& title) const;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @param bounds The bounding rectangle of the window.
+ */
+ virtual void getWindowBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * @param bounds The bounding rectangle of the cleient area of the window.
+ */
+ virtual void getClientBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Resizes client rectangle width.
+ * @param width The new width of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ /**
+ * Resizes client rectangle height.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ /**
+ * Resizes client rectangle.
+ * @param width The new width of the client area of the window.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * @return The state of the window.
+ */
+ virtual GHOST_TWindowState getState() const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate on the screen.
+ * @param inY The y-coordinate on the screen.
+ * @param outX The x-coordinate in the client rectangle.
+ * @param outY The y-coordinate in the client rectangle.
+ */
+ virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate in the client rectangle.
+ * @param inY The y-coordinate in the client rectangle.
+ * @param outX The x-coordinate on the screen.
+ * @param outY The y-coordinate on the screen.
+ */
+ virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * @param state The state of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * @param order The order of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ /**
+ * Swaps front and back buffers of a window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Invalidates the contents of this window.
+ */
+ virtual GHOST_TSuccess invalidate();
+
+ /**
+ * Returns the name of the window class.
+ * @return The name of the window class.
+ */
+ static LPCSTR getWindowClassName() { return s_windowClassName; }
+
+ /**
+ * Register a mouse click event (should be called
+ * for any real button press, controls mouse
+ * capturing).
+ *
+ * @param press True the event was a button press.
+ */
+ void registerMouseClickEvent(bool press);
+
+ /**
+ * Inform the window that it has lost mouse capture,
+ * called in response to native window system messages.
+ */
+ void lostMouseCapture();
+
+ /**
+ * Loads the windows equivalent of a standard GHOST cursor.
+ * @param visible Flag for cursor visibility.
+ * @param cursorShape The cursor shape.
+ */
+ void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
+
+
+protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Removes the current drawing context.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess removeDrawingContext();
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
+
+ /** Window handle. */
+ HWND m_hWnd;
+ /** Device context handle. */
+ HDC m_hDC;
+ /** OpenGL rendering context. */
+ HGLRC m_hGlRc;
+ /** The first created OpenGL context (for sharing display lists) */
+ static HGLRC s_firsthGLRc;
+ /** Flag for if window has captured the mouse */
+ bool m_hasMouseCaptured;
+ /** Count of number of pressed buttons */
+ int m_nPressedButtons;
+ /** HCURSOR structure of the custom cursor */
+ HCURSOR m_customCursor;
+
+ static LPCSTR s_windowClassName;
+ static const int s_maxTitleLength;
+};
+
+#endif // _GHOST_WINDOW_WIN32_H_
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
new file mode 100755
index 00000000000..81592c1984c
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -0,0 +1,714 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "GHOST_WindowX11.h"
+
+#include "GHOST_SystemX11.h"
+#include "STR_String.h"
+#include "GHOST_Debug.h"
+
+// For standard X11 cursors
+#include <X11/cursorfont.h>
+
+// For obscure full screen mode stuuf
+// lifted verbatim from blut.
+
+typedef struct {
+ long flags;
+ long functions;
+ long decorations;
+ long input_mode;
+} MotifWmHints;
+
+#define MWM_HINTS_DECORATIONS (1L << 1)
+
+GLXContext GHOST_WindowX11::s_firstContext = NULL;
+
+GHOST_WindowX11::
+GHOST_WindowX11(
+ GHOST_SystemX11 *system,
+ Display * display,
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual
+) :
+ GHOST_Window(title,left,top,width,height,state,type),
+ m_display(display),
+ m_valid_setup (false),
+ m_system (system),
+ m_invalid_window(false),
+ m_context(NULL),
+ m_empty_cursor(None),
+ m_custom_cursor(None)
+{
+
+ // Set up the minimum atrributes that we require and see if
+ // X can find us a visual matching those requirements.
+
+ int attributes[40], i = 0;
+
+ if(m_stereoVisual)
+ attributes[i++] = GLX_STEREO;
+
+ attributes[i++] = GLX_RGBA;
+ attributes[i++] = GLX_DOUBLEBUFFER;
+ attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
+ attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
+ attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
+ attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
+ attributes[i] = None;
+
+ m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
+
+ if (m_visual == NULL) {
+ // barf : no visual meeting these requirements could be found.
+ return;
+ }
+
+ // Create a bunch of attributes needed to create an X window.
+
+
+ // First create a colormap for the window and visual.
+ // This seems pretty much a legacy feature as we are in rgba mode anyway.
+
+ XSetWindowAttributes xattributes;
+ memset(&xattributes, 0, sizeof(xattributes));
+
+ xattributes.colormap= XCreateColormap(
+ m_display,
+ RootWindow(m_display, m_visual->screen),
+ m_visual->visual,
+ AllocNone
+ );
+
+ xattributes.border_pixel= 0;
+
+ // Specify which events we are interested in hearing.
+
+ xattributes.event_mask=
+ ExposureMask | StructureNotifyMask |
+ KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | FocusChangeMask;
+
+ // create the window!
+
+ m_window =
+ XCreateWindow(
+ m_display,
+ RootWindow(m_display, m_visual->screen),
+ left,
+ top,
+ width,
+ height,
+ 0, // no border.
+ m_visual->depth,
+ InputOutput,
+ m_visual->visual,
+ CWBorderPixel|CWColormap|CWEventMask,
+ &xattributes
+ );
+
+ // Are we in fullscreen mode - then include
+ // some obscure blut code to remove decorations.
+
+ if (state == GHOST_kWindowStateFullScreen) {
+
+ MotifWmHints hints;
+ Atom atom;
+
+ atom = XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
+
+ if (atom == None) {
+ GHOST_PRINT("Could not intern X atom for _MOTIF_WM_HINTS.\n");
+ } else {
+ hints.flags = MWM_HINTS_DECORATIONS;
+ hints.decorations = 0; /* Absolutely no decorations. */
+ // other hints.decorations make no sense
+ // you can't select individual decorations
+
+ XChangeProperty(m_display, m_window,
+ atom, atom, 32,
+ PropModeReplace, (unsigned char *) &hints, 4);
+ }
+ }
+
+ // Create some hints for the window manager on how
+ // we want this window treated.
+
+ XSizeHints * xsizehints = XAllocSizeHints();
+ xsizehints->flags = USPosition | USSize;
+ xsizehints->x = left;
+ xsizehints->y = top;
+ xsizehints->width = width;
+ xsizehints->height = height;
+ XSetWMNormalHints(m_display, m_window, xsizehints);
+ XFree(xsizehints);
+
+ setTitle(title);
+
+ // now set up the rendering context.
+ if (installDrawingContext(type) == GHOST_kSuccess) {
+ m_valid_setup = true;
+ GHOST_PRINT("Created window\n");
+ }
+
+ XMapWindow(m_display, m_window);
+ GHOST_PRINT("Mapped window\n");
+
+ XFlush(m_display);
+}
+
+ Window
+GHOST_WindowX11::
+getXWindow(
+){
+ return m_window;
+}
+
+ bool
+GHOST_WindowX11::
+getValid(
+) const {
+ return m_valid_setup;
+}
+
+ void
+GHOST_WindowX11::
+setTitle(
+ const STR_String& title
+){
+ XStoreName(m_display,m_window,title);
+ XFlush(m_display);
+}
+
+ void
+GHOST_WindowX11::
+getTitle(
+ STR_String& title
+) const {
+ char *name = NULL;
+
+ XFetchName(m_display,m_window,&name);
+ title= name?name:"untitled";
+ XFree(name);
+}
+
+ void
+GHOST_WindowX11::
+getWindowBounds(
+ GHOST_Rect& bounds
+) const {
+ // Getting the window bounds under X11 is not
+ // really supported (nor should it be desired).
+ getClientBounds(bounds);
+}
+
+ void
+GHOST_WindowX11::
+getClientBounds(
+ GHOST_Rect& bounds
+) const {
+ Window root_return;
+ int x_return,y_return;
+ unsigned int w_return,h_return,border_w_return,depth_return;
+ GHOST_TInt32 screen_x, screen_y;
+
+ XGetGeometry(m_display,m_window,&root_return,&x_return,&y_return,
+ &w_return,&h_return,&border_w_return,&depth_return);
+
+ clientToScreen(0, 0, screen_x, screen_y);
+
+ bounds.m_l = screen_x;
+ bounds.m_r = bounds.m_l + w_return;
+ bounds.m_t = screen_y;
+ bounds.m_b = bounds.m_t + h_return;
+
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setClientWidth(
+ GHOST_TUns32 width
+){
+ XWindowChanges values;
+ unsigned int value_mask= CWWidth;
+ values.width = width;
+ XConfigureWindow(m_display,m_window,value_mask,&values);
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setClientHeight(
+ GHOST_TUns32 height
+){
+ XWindowChanges values;
+ unsigned int value_mask= CWHeight;
+ values.height = height;
+ XConfigureWindow(m_display,m_window,value_mask,&values);
+ return GHOST_kSuccess;
+
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setClientSize(
+ GHOST_TUns32 width,
+ GHOST_TUns32 height
+){
+ XWindowChanges values;
+ unsigned int value_mask= CWWidth | CWHeight;
+ values.width = width;
+ values.height = height;
+ XConfigureWindow(m_display,m_window,value_mask,&values);
+ return GHOST_kSuccess;
+
+}
+
+ void
+GHOST_WindowX11::
+screenToClient(
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32& outX,
+ GHOST_TInt32& outY
+) const {
+ // not sure about this one!
+
+ int ax,ay;
+ Window temp;
+
+ XTranslateCoordinates(
+ m_display,
+ RootWindow(m_display, m_visual->screen),
+ m_window,
+ inX,
+ inY,
+ &ax,
+ &ay,
+ &temp
+ );
+ outX = ax;
+ outY = ay;
+}
+
+ void
+GHOST_WindowX11::
+clientToScreen(
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32& outX,
+ GHOST_TInt32& outY
+) const {
+ int ax,ay;
+ Window temp;
+
+ XTranslateCoordinates(
+ m_display,
+ m_window,
+ RootWindow(m_display, m_visual->screen),
+ inX,
+ inY,
+ &ax,
+ &ay,
+ &temp
+ );
+ outX = ax;
+ outY = ay;
+}
+
+
+ GHOST_TWindowState
+GHOST_WindowX11::
+getState(
+) const {
+ //FIXME
+ return GHOST_kWindowStateNormal;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setState(
+ GHOST_TWindowState state
+){
+ //TODO
+
+ if (state == getState()) {
+ return GHOST_kSuccess;
+ } else {
+ return GHOST_kFailure;
+ }
+
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setOrder(
+ GHOST_TWindowOrder order
+){
+ if (order == GHOST_kWindowOrderTop) {
+ XRaiseWindow(m_display,m_window);
+ XFlush(m_display);
+ } else if (order == GHOST_kWindowOrderBottom) {
+ XLowerWindow(m_display,m_window);
+ XFlush(m_display);
+ } else {
+ return GHOST_kFailure;
+ }
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+swapBuffers(
+){
+ if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
+ glXSwapBuffers(m_display,m_window);
+ return GHOST_kSuccess;
+ } else {
+ return GHOST_kFailure;
+ }
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+activateDrawingContext(
+){
+ if (m_context !=NULL) {
+ glXMakeCurrent(m_display, m_window,m_context);
+ return GHOST_kSuccess;
+ }
+ return GHOST_kFailure;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+invalidate(
+){
+
+ // So the idea of this function is to generate an expose event
+ // for the window.
+ // Unfortunately X does not handle expose events for you and
+ // it is the client's job to refresh the dirty part of the window.
+ // We need to queue up invalidate calls and generate GHOST events
+ // for them in the system.
+
+ // We implement this by setting a boolean in this class to concatenate
+ // all such calls into a single event for this window.
+
+ // At the same time we queue the dirty windows in the system class
+ // and generate events for them at the next processEvents call.
+
+ if (m_invalid_window == false) {
+ m_system->addDirtyWindow(this);
+ m_invalid_window = true;
+ }
+
+ return GHOST_kSuccess;
+}
+
+/**
+ * called by the X11 system implementation when expose events
+ * for the window have been pushed onto the GHOST queue
+ */
+
+ void
+GHOST_WindowX11::
+validate(
+){
+ m_invalid_window = false;
+}
+
+
+/**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+
+GHOST_WindowX11::
+~GHOST_WindowX11(
+){
+ std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
+ for (; it != m_standard_cursors.end(); it++) {
+ XFreeCursor(m_display, it->second);
+ }
+
+ if (m_empty_cursor) {
+ XFreeCursor(m_display, m_empty_cursor);
+ }
+ if (m_custom_cursor) {
+ XFreeCursor(m_display, m_custom_cursor);
+ }
+
+ XDestroyWindow(m_display, m_window);
+ if (m_context) {
+ if (m_context == s_firstContext) {
+ s_firstContext = NULL;
+ }
+ glXDestroyContext(m_display, m_context);
+ }
+ XFree(m_visual);
+}
+
+
+
+
+/**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ GHOST_TSuccess
+GHOST_WindowX11::
+installDrawingContext(
+ GHOST_TDrawingContextType type
+){
+ // only support openGL for now.
+ GHOST_TSuccess success;
+ switch (type) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
+ if (m_context !=NULL) {
+ if (!s_firstContext) {
+ s_firstContext = m_context;
+ }
+ glXMakeCurrent(m_display, m_window,m_context);
+ success = GHOST_kSuccess;
+ } else {
+ success = GHOST_kFailure;
+ }
+
+ break;
+
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+
+ default:
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+
+/**
+ * Removes the current drawing context.
+ * @return Indication as to whether removal has succeeded.
+ */
+ GHOST_TSuccess
+GHOST_WindowX11::
+removeDrawingContext(
+){
+ GHOST_TSuccess success;
+
+ if (m_context != NULL) {
+ glXDestroyContext(m_display, m_context);
+ success = GHOST_kSuccess;
+ } else {
+ success = GHOST_kFailure;
+ }
+ return success;
+}
+
+
+ Cursor
+GHOST_WindowX11::
+getStandardCursor(
+ GHOST_TStandardCursor g_cursor
+){
+ unsigned int xcursor_id;
+
+#define GtoX(gcurs, xcurs) case gcurs: xcursor_id = xcurs
+ switch (g_cursor) {
+ GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
+ GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
+ GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
+ GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
+ GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break;
+ GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
+ GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
+ GtoX(GHOST_kStandardCursorWait, XC_watch); break;
+ GtoX(GHOST_kStandardCursorText, XC_xterm); break;
+ GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
+ GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
+ GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
+ GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
+ GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
+ GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
+ GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
+ GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
+ GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
+ GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
+ GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
+ default:
+ xcursor_id = 0;
+ }
+#undef GtoX
+
+ if (xcursor_id) {
+ Cursor xcursor = m_standard_cursors[xcursor_id];
+
+ if (!xcursor) {
+ xcursor = XCreateFontCursor(m_display, xcursor_id);
+
+ m_standard_cursors[xcursor_id] = xcursor;
+ }
+
+ return xcursor;
+ } else {
+ return None;
+ }
+}
+
+ Cursor
+GHOST_WindowX11::
+getEmptyCursor(
+) {
+ if (!m_empty_cursor) {
+ Pixmap blank;
+ XColor dummy;
+ char data[1] = {0};
+
+ /* make a blank cursor */
+ blank = XCreateBitmapFromData (
+ m_display,
+ RootWindow(m_display,DefaultScreen(m_display)),
+ data, 1, 1
+ );
+
+ m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
+ XFreePixmap(m_display, blank);
+ }
+
+ return m_empty_cursor;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setWindowCursorVisibility(
+ bool visible
+){
+ Cursor xcursor;
+
+ if (visible) {
+ xcursor = getStandardCursor( getCursorShape() );
+ } else {
+ xcursor = getEmptyCursor();
+ }
+
+ XDefineCursor(m_display, m_window, xcursor);
+ XFlush(m_display);
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setWindowCursorShape(
+ GHOST_TStandardCursor shape
+){
+ Cursor xcursor = getStandardCursor( shape );
+
+ XDefineCursor(m_display, m_window, xcursor);
+ XFlush(m_display);
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
+setWindowCustomCursorShape(
+ GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY
+){
+ Pixmap bitmap_pix, mask_pix;
+ XColor fg, bg;
+
+ if(XAllocNamedColor(m_display, DefaultColormap(m_display, DefaultScreen(m_display)),
+ "White", &fg, &fg) == 0) return GHOST_kFailure;
+ if(XAllocNamedColor(m_display, DefaultColormap(m_display, DefaultScreen(m_display)),
+ "Red", &bg, &bg) == 0) return GHOST_kFailure;
+
+ if (m_custom_cursor) {
+ XFreeCursor(m_display, m_custom_cursor);
+ }
+
+ bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char*) bitmap, 16, 16);
+ mask_pix = XCreateBitmapFromData(m_display, m_window, (char*) mask, 16, 16);
+
+ m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
+ XDefineCursor(m_display, m_window, m_custom_cursor);
+ XFlush(m_display);
+
+ XFreePixmap(m_display, bitmap_pix);
+ XFreePixmap(m_display, mask_pix);
+
+ return GHOST_kSuccess;
+}
+
+/*
+
+void glutCustomCursor(char *data1, char *data2, int size)
+{
+ Pixmap source, mask;
+ Cursor cursor;
+ XColor fg, bg;
+
+ if(XAllocNamedColor(__glutDisplay, DefaultColormap(__glutDisplay, __glutScreen),
+ "White", &fg, &fg) == 0) return;
+ if(XAllocNamedColor(__glutDisplay, DefaultColormap(__glutDisplay, __glutScreen),
+ "Red", &bg, &bg) == 0) return;
+
+
+ source= XCreateBitmapFromData(__glutDisplay, xdraw, data2, size, size);
+ mask= XCreateBitmapFromData(__glutDisplay, xdraw, data1, size, size);
+
+ cursor= XCreatePixmapCursor(__glutDisplay, source, mask, &fg, &bg, 7, 7);
+
+ XFreePixmap(__glutDisplay, source);
+ XFreePixmap(__glutDisplay, mask);
+
+ XDefineCursor(__glutDisplay, xdraw, cursor);
+}
+
+*/
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
new file mode 100755
index 00000000000..dd38496c903
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -0,0 +1,292 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 7, 2001
+ */
+
+#ifndef _GHOST_WINDOWX11_H_
+#define _GHOST_WINDOWX11_H_
+
+#include "GHOST_Window.h"
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+#include <map>
+
+class STR_String;
+class GHOST_SystemX11;
+
+/**
+ * X11 implementation of GHOST_IWindow.
+ * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @author Laurence Bourn
+ * @date October 26, 2001
+ */
+
+class GHOST_WindowX11 : public GHOST_Window
+{
+public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ */
+ GHOST_WindowX11(
+ GHOST_SystemX11 *system,
+ Display * display,
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false
+ );
+
+ bool
+ getValid(
+ ) const;
+
+ void
+ setTitle(const STR_String& title);
+
+ void
+ getTitle(
+ STR_String& title
+ ) const;
+
+ void
+ getWindowBounds(
+ GHOST_Rect& bounds
+ ) const;
+
+ void
+ getClientBounds(
+ GHOST_Rect& bounds
+ ) const;
+
+ GHOST_TSuccess
+ setClientWidth(
+ GHOST_TUns32 width
+ );
+
+ GHOST_TSuccess
+ setClientHeight(
+ GHOST_TUns32 height
+ );
+
+ GHOST_TSuccess
+ setClientSize(
+ GHOST_TUns32 width,
+ GHOST_TUns32 height
+ );
+
+ void
+ screenToClient(
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32& outX,
+ GHOST_TInt32& outY
+ ) const;
+
+ void
+ clientToScreen(
+ GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32& outX,
+ GHOST_TInt32& outY
+ ) const;
+
+ GHOST_TWindowState
+ getState(
+ ) const ;
+
+ GHOST_TSuccess
+ setState(
+ GHOST_TWindowState state
+ );
+
+ GHOST_TSuccess
+ setOrder(
+ GHOST_TWindowOrder order
+ );
+
+ GHOST_TSuccess
+ swapBuffers(
+ );
+
+ GHOST_TSuccess
+ activateDrawingContext(
+ );
+ GHOST_TSuccess
+ invalidate(
+ );
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ ~GHOST_WindowX11();
+
+ /**
+ * @section
+ * X11 system specific calls.
+ */
+
+ /**
+ * The reverse of invalidate! Tells this window
+ * that all events for it have been pushed into
+ * the GHOST event queue.
+ */
+
+ void
+ validate(
+ );
+
+ /**
+ * Return a handle to the x11 window type.
+ */
+ Window
+ getXWindow(
+ );
+
+protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ GHOST_TSuccess
+ installDrawingContext(
+ GHOST_TDrawingContextType type
+ );
+
+ /**
+ * Removes the current drawing context.
+ * @return Indication as to whether removal has succeeded.
+ */
+ GHOST_TSuccess
+ removeDrawingContext(
+ );
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess
+ setWindowCursorVisibility(
+ bool visible
+ );
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess
+ setWindowCursorShape(
+ GHOST_TStandardCursor shape
+ );
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess
+ setWindowCustomCursorShape(
+ GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY
+ );
+
+private :
+
+ /// Force use of public constructor.
+
+ GHOST_WindowX11(
+ );
+
+ GHOST_WindowX11(
+ const GHOST_WindowX11 &
+ );
+
+ Cursor
+ getStandardCursor(
+ GHOST_TStandardCursor g_cursor
+ );
+
+ Cursor
+ getEmptyCursor(
+ );
+
+ GLXContext m_context;
+ Window m_window;
+ Display *m_display;
+ XVisualInfo *m_visual;
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static GLXContext s_firstContext;
+
+ /// A pointer to the typed system class.
+
+ GHOST_SystemX11 * m_system;
+
+ bool m_valid_setup;
+
+ /** Used to concatenate calls to invalidate() on this window. */
+ bool m_invalid_window;
+
+ /** XCursor structure of an empty (blank) cursor */
+ Cursor m_empty_cursor;
+
+ /** XCursor structure of the custom cursor */
+ Cursor m_custom_cursor;
+
+ /** Cache of XC_* ID's to XCursor structures */
+ std::map<unsigned int, Cursor> m_standard_cursors;
+};
+
+
+#endif // _GHOST_WINDOWX11_H_
diff --git a/intern/ghost/intern/Makefile b/intern/ghost/intern/Makefile
new file mode 100644
index 00000000000..8107a73ce58
--- /dev/null
+++ b/intern/ghost/intern/Makefile
@@ -0,0 +1,65 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# ghost intern Makefile
+#
+
+LIBNAME = ghost
+DIR = $(OCGDIR)/intern/$(LIBNAME)
+
+CCSRCS = GHOST_Buttons.cpp GHOST_System.cpp GHOST_Window.cpp
+CCSRCS += GHOST_EventManager.cpp GHOST_EventPrinter.cpp GHOST_WindowManager.cpp
+CCSRCS += GHOST_ISystem.cpp GHOST_ModifierKeys.cpp GHOST_TimerManager.cpp
+CCSRCS += GHOST_Rect.cpp GHOST_DisplayManager.cpp GHOST_C-api.cpp
+CCSRCS += GHOST_CallbackEventConsumer.cpp
+
+include nan_definitions.mk
+
+ifeq ($(OS),$(findstring $(OS), "darwin"))
+ CCSRCS += $(wildcard *Carbon.cpp)
+endif
+
+ifeq ($(OS),$(findstring $(OS), "windows"))
+ CCSRCS += $(wildcard *Win32.cpp)
+endif
+
+ifeq ($(OS),$(findstring $(OS), "freebsd irix linux openbsd solaris"))
+ CCSRCS += $(wildcard *X11.cpp)
+endif
+
+include nan_compile.mk
+
+#CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MEMUTIL)/include
+CPPFLAGS += -I..
+CPPFLAGS += -I$(OPENGL_HEADERS)
+
diff --git a/intern/ghost/make/msvc/ghost.dsp b/intern/ghost/make/msvc/ghost.dsp
new file mode 100644
index 00000000000..e58b4e8783e
--- /dev/null
+++ b/intern/ghost/make/msvc/ghost.dsp
@@ -0,0 +1,576 @@
+# Microsoft Developer Studio Project File - Name="ghost" - Package Owner=<4>
+
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+
+# ** DO NOT EDIT **
+
+
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+
+
+CFG=ghost - Win32 Debug
+
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+
+!MESSAGE use the Export Makefile command and run
+
+!MESSAGE
+
+!MESSAGE NMAKE /f "ghost.mak".
+
+!MESSAGE
+
+!MESSAGE You can specify a configuration when running NMAKE
+
+!MESSAGE by defining the macro CFG on the command line. For example:
+
+!MESSAGE
+
+!MESSAGE NMAKE /f "ghost.mak" CFG="ghost - Win32 Debug"
+
+!MESSAGE
+
+!MESSAGE Possible choices for configuration are:
+
+!MESSAGE
+
+!MESSAGE "ghost - Win32 Release" (based on "Win32 (x86) Static Library")
+
+!MESSAGE "ghost - Win32 Debug" (based on "Win32 (x86) Static Library")
+
+!MESSAGE
+
+
+
+# Begin Project
+
+# PROP AllowPerConfigDependencies 0
+
+# PROP Scc_ProjName ""
+
+# PROP Scc_LocalPath ""
+
+CPP=cl.exe
+
+RSC=rc.exe
+
+
+
+!IF "$(CFG)" == "ghost - Win32 Release"
+
+
+
+# PROP BASE Use_MFC 0
+
+# PROP BASE Use_Debug_Libraries 0
+
+# PROP BASE Output_Dir "Release"
+
+# PROP BASE Intermediate_Dir "Release"
+
+# PROP BASE Target_Dir ""
+
+# PROP Use_MFC 0
+
+# PROP Use_Debug_Libraries 0
+
+# PROP Output_Dir "../../../../../obj/windows/intern/ghost/"
+
+# PROP Intermediate_Dir "../../../../../obj/windows/intern/ghost/"
+
+# PROP Target_Dir ""
+
+LINK32=link.exe -lib
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../.." /I "../../../../lib/windows/string/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+
+# ADD RSC /l 0x409 /d "NDEBUG"
+
+BSC32=bscmake.exe
+
+# ADD BASE BSC32 /nologo
+
+# ADD BSC32 /nologo
+
+LIB32=link.exe -lib
+
+# ADD BASE LIB32 /nologo
+
+# ADD LIB32 /nologo
+
+# Begin Special Build Tool
+
+SOURCE="$(InputPath)"
+
+PostBuild_Desc=Copying GHOST files library (release target) to lib tree.
+
+PostBuild_Cmds=ECHO Copying header files COPY "..\..\*.h" "..\..\..\..\..\develop\lib\windows\ghost\include\" ECHO Copying lib COPY "..\..\..\..\..\obj\windows\intern\ghost\ghost.lib" "..\..\..\..\..\develop\lib\windows\ghost\lib\libghost.a" ECHO Done
+
+# End Special Build Tool
+
+
+
+!ELSEIF "$(CFG)" == "ghost - Win32 Debug"
+
+
+
+# PROP BASE Use_MFC 0
+
+# PROP BASE Use_Debug_Libraries 1
+
+# PROP BASE Output_Dir "Debug"
+
+# PROP BASE Intermediate_Dir "Debug"
+
+# PROP BASE Target_Dir ""
+
+# PROP Use_MFC 0
+
+# PROP Use_Debug_Libraries 1
+
+# PROP Output_Dir "../../../../../obj/windows/intern/ghost/debug"
+
+# PROP Intermediate_Dir "../../../../../obj/windows/intern/ghost/debug"
+
+# PROP Target_Dir ""
+
+LINK32=link.exe -lib
+
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../.." /I "../../../../lib/windows/string/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
+
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+
+# ADD RSC /l 0x409 /d "_DEBUG"
+
+BSC32=bscmake.exe
+
+# ADD BASE BSC32 /nologo
+
+# ADD BSC32 /nologo
+
+LIB32=link.exe -lib
+
+# ADD BASE LIB32 /nologo
+
+# ADD LIB32 /nologo
+
+# Begin Special Build Tool
+
+SOURCE="$(InputPath)"
+
+PostBuild_Desc=Copying GHOST files library (debug target) to lib tree.
+
+PostBuild_Cmds=ECHO Copying header files COPY "..\..\*.h" "..\..\..\..\..\develop\lib\windows\ghost\include" ECHO Copying lib COPY "..\..\..\..\..\obj\windows\intern\ghost\debug\ghost.lib" "..\..\..\..\..\develop\lib\windows\ghost\lib\debug\libghost.a" ECHO Done
+
+# End Special Build Tool
+
+
+
+!ENDIF
+
+
+
+# Begin Target
+
+
+
+# Name "ghost - Win32 Release"
+
+# Name "ghost - Win32 Debug"
+
+# Begin Group "Header Files"
+
+
+
+# PROP Default_Filter ""
+
+# Begin Group "intern"
+
+
+
+# PROP Default_Filter ""
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Buttons.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Debug.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_DisplayManager.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_DisplayManagerWin32.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Event.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventButton.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventCursor.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventKey.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventManager.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventPrinter.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventWindow.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_ModifierKeys.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_System.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_SystemWin32.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_TimerManager.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_TimerTask.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Window.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_WindowManager.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_WindowWin32.h
+
+# End Source File
+
+# End Group
+
+# Begin Group "extern"
+
+
+
+# PROP Default_Filter ""
+
+# Begin Source File
+
+
+
+SOURCE="..\..\GHOST_C-api.h"
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_IEvent.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_IEventConsumer.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_ISystem.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_ITimerTask.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_IWindow.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_Rect.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\GHOST_Types.h
+
+# End Source File
+
+# End Group
+
+# End Group
+
+# Begin Group "Source Files"
+
+
+
+# PROP Default_Filter ""
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Buttons.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE="..\..\intern\GHOST_C-api.cpp"
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_CallbackEventConsumer.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_CallbackEventConsumer.h
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_DisplayManager.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_DisplayManagerWin32.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventManager.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_EventPrinter.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_ISystem.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_ModifierKeys.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Rect.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_System.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_SystemWin32.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_TimerManager.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_Window.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_WindowManager.cpp
+
+# End Source File
+
+# Begin Source File
+
+
+
+SOURCE=..\..\intern\GHOST_WindowWin32.cpp
+
+# End Source File
+
+# End Group
+
+# End Target
+
+# End Project
+
diff --git a/intern/ghost/make/msvc/ghost.dsw b/intern/ghost/make/msvc/ghost.dsw
new file mode 100644
index 00000000000..7ae428a5fb5
--- /dev/null
+++ b/intern/ghost/make/msvc/ghost.dsw
@@ -0,0 +1,58 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+
+
+###############################################################################
+
+
+
+Project: "ghost"=".\ghost.dsp" - Package Owner=<4>
+
+
+
+Package=<5>
+
+{{{
+
+}}}
+
+
+
+Package=<4>
+
+{{{
+
+}}}
+
+
+
+###############################################################################
+
+
+
+Global:
+
+
+
+Package=<5>
+
+{{{
+
+}}}
+
+
+
+Package=<3>
+
+{{{
+
+}}}
+
+
+
+###############################################################################
+
+
+
diff --git a/intern/ghost/test/Makefile b/intern/ghost/test/Makefile
new file mode 100755
index 00000000000..bbd1988a778
--- /dev/null
+++ b/intern/ghost/test/Makefile
@@ -0,0 +1,86 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST test applications makefile.
+# This bounces to test application directories.
+#
+
+LIBNAME = ghost
+SOURCEDIR = intern/$(LIBNAME)/test
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = gears
+
+include nan_subdirs.mk
+
+include nan_compile.mk
+include nan_link.mk
+
+OCGGHOST = $(OCGDIR)/intern/$(LIBNAME)
+GEARDIR = $(OCGGHOST)/test/$(DEBUG_DIR)gears.app
+
+LIBS = $(OCGGHOST)/$(DEBUG_DIR)libghost.a
+SLIBS += $(LCGDIR)/string/lib/libstring.a
+
+all debug:: $(LIBS)
+ @echo "****> linking $@ in $(SOURCEDIR)"
+ifeq ($(OS),darwin)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears $(DIR)/$(DEBUG_DIR)GHOST_Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+ @# set up directory structure for the OSX application bundle
+ @[ -d $(OCGGHOST)/test/ ] || mkdir $(OCGGHOST)/test/
+ @[ -d $(OCGGHOST)/test/debug ] || mkdir $(OCGGHOST)/test/debug
+ @[ -d $(GEARDIR) ] || mkdir $(GEARDIR)
+ @[ -d $(GEARDIR)/Contents ] || mkdir $(GEARDIR)/Contents
+ @[ -d $(GEARDIR)/Contents/MacOS ] || mkdir $(GEARDIR)/Contents/MacOS
+ @[ -d $(GEARDIR)/Contents/Resources ] || mkdir $(GEARDIR)/Contents/Resources
+ @[ -d $(GEARDIR)/Contents/Resources/English.lproj ] || mkdir $(GEARDIR)/Contents/Resources/English.lproj
+ @[ -d $(GEARDIR)/Contents/Resources/English.lproj/MainMenu.nib ] || mkdir $(GEARDIR)/Contents/Resources/English.lproj/MainMenu.nib
+ @# copy the files into the bundle directory tree
+ cp -f $(DIR)/$(DEBUG_DIR)gears $(GEARDIR)/Contents/MacOS
+ cp -f gears/resources/osx/PkgInfo $(GEARDIR)/Contents/
+ cp -f gears/resources/osx/Info.plist $(GEARDIR)/Contents/
+ cp -f gears/resources/osx/English.lproj/InfoPlist.strings $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/classes.nib $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/info.nib $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/objects.nib $(GEARDIR)/Contents/Resources/English.lproj
+else
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears_cpp $(DIR)/$(DEBUG_DIR)GHOST_Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears_c $(DIR)/$(DEBUG_DIR)GHOST_C-Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+endif
+
+clean::
+ @# mac stuff. well ok, only the binary
+ @rm -f $(DIR)/gears $(DIR)/debug/gears
+ @# others
+ @rm -f $(DIR)/gears_c $(DIR)/debug/gears_c
+ @rm -f $(DIR)/gears_cpp $(DIR)/debug/gears_cpp
+
+test:: all
+ $(DIR)/gears_cpp
+ $(DIR)/gears_c
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
new file mode 100644
index 00000000000..16d8b421d5b
--- /dev/null
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -0,0 +1,543 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ *
+ * Simple test file for the GHOST library.
+ * The OpenGL gear code is taken from the Qt sample code which,
+ * in turn, is probably taken from somewhere as well.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "GHOST_C-api.h"
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else /* WIN32 */
+ /* __APPLE__ is defined */
+ #include <AGL/gl.h>
+ #endif /* WIN32 */
+#else /* defined(WIN32) || defined(__APPLE__) */
+ #include <GL/gl.h>
+#endif /* defined(WIN32) || defined(__APPLE__) */
+
+
+static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
+
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLfloat fAngle = 0.0;
+static int sExitRequested = 0;
+static GHOST_SystemHandle shSystem = NULL;
+static GHOST_WindowHandle sMainWindow = NULL;
+static GHOST_WindowHandle sSecondaryWindow = NULL;
+static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
+static GHOST_WindowHandle sFullScreenWindow = NULL;
+static GHOST_TimerTaskHandle sTestTimer;
+static GHOST_TimerTaskHandle sGearsTimer;
+
+
+static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
+{
+ printf("timer1, time=%d\n", (int)time);
+}
+
+
+static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+ const double pi = 3.14159264;
+
+ r0 = inner_radius;
+ r1 = (float)(outer_radius - tooth_depth/2.0);
+ r2 = (float)(outer_radius + tooth_depth/2.0);
+
+ da = (float)(2.0*pi / teeth / 4.0);
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0*pi / teeth / 4.0);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0*pi / teeth / 4.0);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ u = (float)(r2*cos(angle+da) - r1*cos(angle));
+ v = (float)(r2*sin(angle+da) - r1*sin(angle));
+ len = (float)(sqrt(u*u + v*v));
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
+ u = (float)(r1*cos(angle+3*da) - r2*cos(angle+2*da));
+ v = (float)(r1*sin(angle+3*da) - r2*sin(angle+2*da));
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ }
+ glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(-width*0.5));
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ }
+ glEnd();
+}
+
+
+
+static void drawGearGL(int id)
+{
+ static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
+ static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id)
+ {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
+}
+
+
+static void drawGL(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+static void setViewPortGL(GHOST_WindowHandle hWindow)
+{
+ GHOST_RectangleHandle hRect = NULL;
+ GLfloat w, h;
+
+ GHOST_ActivateWindowDrawingContext(hWindow);
+ hRect = GHOST_GetClientBounds(hWindow);
+
+ w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
+ h = 1.0;
+
+ glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-w, w, -h, h, 5.0, 60.0);
+ /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ glClearColor(.2f,0.0f,0.0f,0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ GHOST_DisposeRectangle(hRect);
+}
+
+
+
+int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
+{
+ int handled = 1;
+ int cursor;
+ int visibility;
+ GHOST_TEventKeyData* keyData = NULL;
+ GHOST_DisplaySetting setting;
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+
+ switch (GHOST_GetEventType(hEvent))
+ {
+ /*
+ case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ break;
+ case GHOST_kEventCursorMove:
+ break;
+ */
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown:
+ {
+ keyData = (GHOST_TEventKeyData*)GHOST_GetEventData(hEvent);
+ switch (keyData->key)
+ {
+ case GHOST_kKeyC:
+ {
+ cursor = sCursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors)
+ {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ sCursor = (GHOST_TStandardCursor)cursor;
+ GHOST_SetCursorShape(window, sCursor);
+ }
+ break;
+ case GHOST_kKeyF:
+ if (!GHOST_GetFullScreen(shSystem))
+ {
+ /* Begin fullscreen mode */
+ setting.bpp = 24;
+ setting.frequency = 85;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+
+ /*
+ setting.bpp = 16;
+ setting.frequency = 75;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+ */
+
+ sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting,
+ false /* stereo flag */);
+ }
+ else
+ {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ break;
+ case GHOST_kKeyH:
+ {
+ visibility = GHOST_GetCursorVisibility(window);
+ GHOST_SetCursorVisibility(window, !visibility);
+ }
+ break;
+ case GHOST_kKeyQ:
+ if (GHOST_GetFullScreen(shSystem))
+ {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ sExitRequested = 1;
+ case GHOST_kKeyT:
+ if (!sTestTimer)
+ {
+ sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
+ }
+ else
+ {
+ GHOST_RemoveTimer(shSystem, sTestTimer);
+ sTestTimer = 0;
+ }
+ break;
+ case GHOST_kKeyW:
+ {
+ if (sMainWindow)
+ {
+ char *title = GHOST_GetTitle(sMainWindow);
+ char *ntitle = malloc(strlen(title)+2);
+
+ sprintf(ntitle, "%s-", title);
+ GHOST_SetTitle(sMainWindow, ntitle);
+
+ free(ntitle);
+ free(title);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowClose:
+ {
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+ if (window == sMainWindow)
+ {
+ sExitRequested = 1;
+ }
+ else
+ {
+ if (sGearsTimer)
+ {
+ GHOST_RemoveTimer(shSystem, sGearsTimer);
+ sGearsTimer = 0;
+ }
+ GHOST_DisposeWindow(shSystem, window);
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowActivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowDeactivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowUpdate:
+ {
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+ if (!GHOST_ValidWindow(shSystem, window))
+ break;
+ //if (!m_fullScreenWindow)
+ {
+ setViewPortGL(window);
+ drawGL();
+ GHOST_SwapWindowBuffers(window);
+ }
+ }
+ break;
+
+ default:
+ handled = 0;
+ break;
+ }
+ return handled;
+}
+
+
+int main(int argc, char** argv)
+{
+ char* title1 = "gears - main window";
+ char* title2 = "gears - secondary window";
+ GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
+
+ /* Create the system */
+ shSystem = GHOST_CreateSystem();
+ GHOST_AddEventConsumer(shSystem, consumer);
+
+ if (shSystem)
+ {
+ /* Create the main window */
+ sMainWindow = GHOST_CreateWindow(shSystem,
+ title1,
+ 10,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL);
+ if (!sMainWindow)
+ {
+ printf("could not create main window\n");
+ exit(-1);
+ }
+
+ /* Create a secondary window */
+ sSecondaryWindow = GHOST_CreateWindow(shSystem,
+ title2,
+ 340,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL);
+ if (!sSecondaryWindow)
+ {
+ printf("could not create secondary window\n");
+ exit(-1);
+ }
+
+ /* Install a timer to have the gears running */
+ sGearsTimer = GHOST_InstallTimer(shSystem,
+ 0,
+ 10,
+ gearsTimerProc,
+ sMainWindow);
+
+ /* Enter main loop */
+ while (!sExitRequested)
+ {
+ if (!GHOST_ProcessEvents(shSystem, 0))
+ {
+#ifdef WIN32
+ /* If there were no events, be nice to other applications */
+ Sleep(10);
+#endif
+ }
+ GHOST_DispatchEvents(shSystem);
+ }
+ }
+
+ /* Dispose windows */
+ if (GHOST_ValidWindow(shSystem, sMainWindow))
+ {
+ GHOST_DisposeWindow(shSystem, sMainWindow);
+ }
+ if (GHOST_ValidWindow(shSystem, sSecondaryWindow))
+ {
+ GHOST_DisposeWindow(shSystem, sSecondaryWindow);
+ }
+
+ /* Dispose the system */
+ GHOST_DisposeSystem(shSystem);
+ GHOST_DisposeEventConsumer(consumer);
+
+ return 0;
+}
+
+
+static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
+{
+ GHOST_WindowHandle hWindow = NULL;
+ fAngle += 2.0;
+ view_roty += 1.0;
+ hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
+ if (GHOST_GetFullScreen(shSystem))
+ {
+ /* Running full screen */
+ GHOST_InvalidateWindow(sFullScreenWindow);
+ }
+ else
+ {
+ if (GHOST_ValidWindow(shSystem, hWindow))
+ {
+ GHOST_InvalidateWindow(hWindow);
+ }
+ }
+}
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
new file mode 100755
index 00000000000..a5459c9da9b
--- /dev/null
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -0,0 +1,745 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * Simple test file for the GHOST library.
+ * The OpenGL gear code is taken from the Qt sample code which,
+ * in turn, is probably taken from somewhere as well.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ * Stereo code by Raymond de Vries, januari 2002
+ */
+
+#include <iostream>
+#include <math.h>
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #include <windows.h>
+ #include <atlbase.h>
+
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif // defined(WIN32) || defined(__APPLE__)
+
+#include "STR_String.h"
+#include "GHOST_Rect.h"
+
+#include "GHOST_ISystem.h"
+#include "GHOST_IEvent.h"
+#include "GHOST_IEventConsumer.h"
+
+
+#define LEFT_EYE 0
+#define RIGHT_EYE 1
+
+static bool nVidiaWindows; // very dirty but hey, it's for testing only
+
+static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
+
+static class Application* fApp;
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLfloat fAngle = 0.0;
+static GHOST_ISystem* fSystem = 0;
+
+
+void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
+ float zero_plane, float dist,
+ float eye);
+
+
+static void testTimerProc(GHOST_ITimerTask* /*task*/, GHOST_TUns64 time)
+{
+ std::cout << "timer1, time=" << (int)time << "\n";
+}
+
+
+static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth/2.0;
+ r2 = outer_radius + tooth_depth/2.0;
+
+ const double pi = 3.14159264;
+ da = 2.0*pi / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ u = r2*cos(angle+da) - r1*cos(angle);
+ v = r2*sin(angle+da) - r1*sin(angle);
+ len = sqrt(u*u + v*v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5);
+ u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
+ v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+ glVertex3f(r1*cos(0.0), r1*sin(0.0), width*0.5);
+ glVertex3f(r1*cos(0.0), r1*sin(0.0), -width*0.5);
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ }
+ glEnd();
+}
+
+
+
+static void drawGearGL(int id)
+{
+ static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
+ static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id)
+ {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
+}
+
+
+void RenderCamera()
+{
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+}
+
+
+void RenderScene()
+{
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
+}
+
+
+static void View(GHOST_IWindow* window, bool stereo, int eye = 0)
+{
+ window->activateDrawingContext();
+ GHOST_Rect bnds;
+ int noOfScanlines = 0, lowerScanline;
+ int verticalBlankingInterval = 32; // hard coded for testing purposes, display device dependant
+ float left, right, bottom, top;
+ float nearplane, farplane, zeroPlane, distance;
+ float eyeSeparation = 0.62;
+ window->getClientBounds(bnds);
+ GLfloat w = float(bnds.getWidth()) / float(bnds.getHeight());
+ GLfloat h = 1.0;
+
+ // viewport
+ if(stereo)
+ {
+ if(nVidiaWindows)
+ {
+ // handled by nVidia driver so act as normal (explicitly put here since
+ // it -is- stereo)
+ glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
+ }
+ else
+ { // generic cross platform above-below stereo
+ noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
+ switch(eye)
+ {
+ case LEFT_EYE:
+ // upper half of window
+ lowerScanline = bnds.getHeight() - noOfScanlines;
+ break;
+ case RIGHT_EYE:
+ // lower half of window
+ lowerScanline = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ noOfScanlines = bnds.getHeight();
+ lowerScanline = 0;
+ }
+
+ glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
+
+ // projection
+ left = -6.0;
+ right = 6.0;
+ bottom = -4.8;
+ top = 4.8;
+ nearplane = 5.0;
+ farplane = 60.0;
+
+ if(stereo)
+ {
+ zeroPlane = 0.0;
+ distance = 14.5;
+ switch(eye)
+ {
+ case LEFT_EYE:
+ StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0);
+ break;
+ case RIGHT_EYE:
+ StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0);
+ break;
+ }
+ }
+ else
+ {
+// left = -w;
+// right = w;
+// bottom = -h;
+// top = h;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(left, right, bottom, top, 5.0, 60.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ }
+
+ glClearColor(.2f,0.0f,0.0f,0.0f);
+}
+
+
+void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
+ float zero_plane, float dist,
+ float eye)
+/* Perform the perspective projection for one eye's subfield.
+The projection is in the direction of the negative z axis.
+
+-6.0, 6.0, -4.8, 4.8,
+left, right, bottom, top = the coordinate range, in the plane of zero
+parallax setting, which will be displayed on the screen. The
+ratio between (right-left) and (top-bottom) should equal the aspect
+ratio of the display.
+
+6.0, -6.0,
+near, far = the z-coordinate values of the clipping planes.
+
+0.0,
+zero_plane = the z-coordinate of the plane of zero parallax setting.
+
+14.5,
+dist = the distance from the center of projection to the plane
+of zero parallax.
+
+-0.31
+eye = half the eye separation; positive for the right eye subfield,
+negative for the left eye subfield.
+*/
+{
+ float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw,
+ dx, dy, n_over_d;
+
+ dx = right - left;
+ dy = top - bottom;
+
+ xmid = (right + left) / 2.0;
+ ymid = (top + bottom) / 2.0;
+
+ clip_near = dist + zero_plane - nearplane;
+ clip_far = dist + zero_plane - farplane;
+
+ n_over_d = clip_near / dist;
+
+ topw = n_over_d * dy / 2.0;
+ bottomw = -topw;
+ rightw = n_over_d * (dx / 2.0 - eye);
+ leftw = n_over_d *(-dx / 2.0 - eye);
+
+ /* Need to be in projection mode for this. */
+ glLoadIdentity();
+ glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far);
+
+ glTranslatef(-xmid - eye, -ymid, -zero_plane - dist);
+ return;
+} /* stereoproj */
+
+
+class Application : public GHOST_IEventConsumer {
+public:
+ Application(GHOST_ISystem* system);
+ ~Application(void);
+ virtual bool processEvent(GHOST_IEvent* event);
+
+ GHOST_ISystem* m_system;
+ GHOST_IWindow* m_mainWindow;
+ GHOST_IWindow* m_secondaryWindow;
+ GHOST_IWindow* m_fullScreenWindow;
+ GHOST_ITimerTask* m_gearsTimer, *m_testTimer;
+ GHOST_TStandardCursor m_cursor;
+ bool m_exitRequested;
+
+ bool stereo;
+};
+
+
+Application::Application(GHOST_ISystem* system)
+ : m_system(system), m_mainWindow(0), m_secondaryWindow(0), m_fullScreenWindow(0),
+ m_gearsTimer(0), m_testTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor),
+ m_exitRequested(false), stereo(false)
+{
+ fApp = this;
+
+ // Create the main window
+ STR_String title1 ("gears - main window");
+ m_mainWindow = system->createWindow(title1, 10, 64, 320, 200, GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL, true /* stereo flag */);
+
+ if (!m_mainWindow) {
+ std::cout << "could not create main window\n";
+ exit(-1);
+ }
+
+ // Create a secondary window
+ STR_String title2 ("gears - secondary window");
+ m_secondaryWindow = system->createWindow(title2, 340, 64, 320, 200, GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL, false /* stereo flag */);
+ if (!m_secondaryWindow) {
+ cout << "could not create secondary window\n";
+ exit(-1);
+ }
+
+ // Install a timer to have the gears running
+ m_gearsTimer = system->installTimer(0 /*delay*/, 20/*interval*/, gearsTimerProc, m_mainWindow);
+}
+
+
+Application::~Application(void)
+{
+ // Dispose windows
+ if (m_system->validWindow(m_mainWindow)) {
+ m_system->disposeWindow(m_mainWindow);
+ }
+ if (m_system->validWindow(m_secondaryWindow)) {
+ m_system->disposeWindow(m_secondaryWindow);
+ }
+}
+
+
+bool Application::processEvent(GHOST_IEvent* event)
+{
+ GHOST_IWindow* window = event->getWindow();
+ bool handled = true;
+
+ switch (event->getType()) {
+/* case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ std::cout << "GHOST_kEventCursorButton"; break;
+ case GHOST_kEventCursorMove:
+ std::cout << "GHOST_kEventCursorMove"; break;
+*/
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown:
+ {
+ GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*) event->getData();
+ switch (keyData->key) {
+ case GHOST_kKeyC:
+ {
+ int cursor = m_cursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors) {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ m_cursor = (GHOST_TStandardCursor)cursor;
+ window->setCursorShape(m_cursor);
+ }
+ break;
+
+ case GHOST_kKeyE:
+ {
+ int x = 200, y= 200;
+ m_system->setCursorPosition(x,y);
+ break;
+ }
+
+ case GHOST_kKeyF:
+ if (!m_system->getFullScreen()) {
+ // Begin fullscreen mode
+ GHOST_DisplaySetting setting;
+
+ setting.bpp = 16;
+ setting.frequency = 50;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+ m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */);
+ }
+ else {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ break;
+
+ case GHOST_kKeyH:
+ window->setCursorVisibility(!window->getCursorVisibility());
+ break;
+
+ case GHOST_kKeyM:
+ {
+ bool down = false;
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift,down);
+ if (down) {
+ std::cout << "left shift down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightShift,down);
+ if (down) {
+ std::cout << "right shift down\n"; }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt,down);
+ if (down) {
+ std::cout << "left Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt,down);
+ if (down) {
+ std::cout << "right Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl,down);
+ if (down) {
+ std::cout << "left control down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightControl,down);
+ if (down) {
+ std::cout << "right control down\n";
+ }
+ }
+ break;
+
+ case GHOST_kKeyQ:
+ if (m_system->getFullScreen())
+ {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ m_exitRequested = true;
+ break;
+
+ case GHOST_kKeyS: // toggle mono and stereo
+ if(stereo)
+ stereo = false;
+ else
+ stereo = true;
+ break;
+
+ case GHOST_kKeyT:
+ if (!m_testTimer) {
+ m_testTimer = m_system->installTimer(0, 1000, testTimerProc);
+ }
+
+ else {
+ m_system->removeTimer(m_testTimer);
+ m_testTimer = 0;
+ }
+
+ break;
+
+ case GHOST_kKeyW:
+ if (m_mainWindow)
+ {
+ STR_String title;
+ m_mainWindow->getTitle(title);
+ title += "-";
+ m_mainWindow->setTitle(title);
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowClose:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if (window == m_mainWindow) {
+ m_exitRequested = true;
+ }
+ else {
+ m_system->disposeWindow(window);
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowActivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowDeactivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowUpdate:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if(!m_system->validWindow(window))
+ break;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if(stereo)
+ {
+ View(window, stereo, LEFT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+
+ View(window, stereo, RIGHT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ else
+ {
+ View(window, stereo);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ window->swapBuffers();
+ }
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+ return handled;
+}
+
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ nVidiaWindows = false;
+// nVidiaWindows = true;
+
+#ifdef WIN32
+ /* Set a couple of settings in the registry for the nVidia detonator driver.
+ * So this is very specific...
+ */
+ if(nVidiaWindows)
+ {
+ LONG lresult;
+ HKEY hkey = 0;
+ DWORD dwd = 0;
+ unsigned char buffer[128];
+
+ CRegKey regkey;
+ DWORD keyValue;
+// lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
+ lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
+ KEY_ALL_ACCESS );
+
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully opened key\n");
+#if 0
+ lresult = regkey.QueryValue(&keyValue, "StereoEnable");
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully queried key\n");
+#endif
+ lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
+ "1");
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully set value for key\n");
+ regkey.Close();
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully closed key\n");
+// regkey.Write("2");
+ }
+#endif // WIN32
+
+ // Create the system
+ GHOST_ISystem::createSystem();
+ fSystem = GHOST_ISystem::getSystem();
+
+ if (fSystem) {
+ // Create an application object
+ Application app (fSystem);
+
+ // Add the application as event consumer
+ fSystem->addEventConsumer(&app);
+
+ // Enter main loop
+ while (!app.m_exitRequested) {
+ //printf("main: loop\n");
+ fSystem->processEvents(true);
+ fSystem->dispatchEvents();
+ }
+ }
+
+ // Dispose the system
+ GHOST_ISystem::disposeSystem();
+
+ return 0;
+}
+
+
+static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 /*time*/)
+{
+ fAngle += 2.0;
+ view_roty += 1.0;
+ GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData();
+ if (fApp->m_fullScreenWindow) {
+ // Running full screen
+ fApp->m_fullScreenWindow->invalidate();
+ }
+ else {
+ if (fSystem->validWindow(window)) {
+ window->invalidate();
+ }
+ }
+}
diff --git a/intern/ghost/test/gears/Makefile b/intern/ghost/test/gears/Makefile
new file mode 100755
index 00000000000..b7966b4d157
--- /dev/null
+++ b/intern/ghost/test/gears/Makefile
@@ -0,0 +1,48 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST gears test application Makefile
+#
+
+LIBNAME = gearstest
+DIR = $(OCGDIR)/intern/ghost/test
+
+# we don't want a library here, only object files:
+ALLTARGETS = $(OBJS)
+
+include nan_compile.mk
+
+CFLAGS += $(LEVEL_2_C_WARNINGS)
+CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../..
+
diff --git a/intern/ghost/test/make/msvc_6_0/gears.dsp b/intern/ghost/test/make/msvc_6_0/gears.dsp
new file mode 100644
index 00000000000..3e809a6b604
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/gears.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="gears" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=gears - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "gears.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "gears.mak" CFG="gears - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "gears - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "gears - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "gears - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../.." /I "../../../../string" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "gears - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../.." /I "../../../../string" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "gears - Win32 Release"
+# Name "gears - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\gears\GHOST_Test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/intern/ghost/test/make/msvc_6_0/gears_C.dsp b/intern/ghost/test/make/msvc_6_0/gears_C.dsp
new file mode 100644
index 00000000000..5972d123268
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/gears_C.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="gears_C" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=gears_C - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "gears_C.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "gears_C.mak" CFG="gears_C - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "gears_C - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "gears_C - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "gears_C - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../.." /I "../../../../string" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "gears_C - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../.." /I "../../../../string" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "gears_C - Win32 Release"
+# Name "gears_C - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\gears\GHOST_C-Test.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/intern/ghost/test/make/msvc_6_0/ghost_test.dsw b/intern/ghost/test/make/msvc_6_0/ghost_test.dsw
new file mode 100644
index 00000000000..03bf5eb5c9a
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/ghost_test.dsw
@@ -0,0 +1,77 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "gears"=.\gears.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name ghost
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name string
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "gears_C"=.\gears_C.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name ghost
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name string
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ghost"=..\..\..\make\msvc\ghost.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "string"=..\..\..\..\string\make\msvc_6_0\string.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/intern/ghost/test/multitest/Basic.c b/intern/ghost/test/multitest/Basic.c
new file mode 100644
index 00000000000..c26cf7c92ca
--- /dev/null
+++ b/intern/ghost/test/multitest/Basic.c
@@ -0,0 +1,68 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "Basic.h"
+
+
+int min_i(int a, int b) {
+ return (a<b)?a:b;
+}
+int max_i(int a, int b) {
+ return (b<a)?a:b;
+}
+int clamp_i(int val, int min, int max) {
+ return min_i(max_i(val, min), max);
+}
+
+float min_f(float a, float b) {
+ return (a<b)?a:b;
+}
+float max_f(float a, float b) {
+ return (b<a)?a:b;
+}
+float clamp_f(float val, float min, float max) {
+ return min_f(max_f(val, min), max);
+}
+
+void rect_copy(int dst[2][2], int src[2][2]) {
+ dst[0][0]= src[0][0], dst[0][1]= src[0][1];
+ dst[1][0]= src[1][0], dst[1][1]= src[1][1];
+}
+int rect_contains_pt(int rect[2][2], int pt[2]){
+ return ((rect[0][0] <= pt[0] && pt[0] <= rect[1][0]) &&
+ (rect[0][1] <= pt[1] && pt[1] <= rect[1][1]));
+}
+int rect_width(int rect[2][2]) {
+ return (rect[1][0]-rect[0][0]);
+}
+int rect_height(int rect[2][2]) {
+ return (rect[1][1]-rect[0][1]);
+}
diff --git a/intern/ghost/test/multitest/Basic.h b/intern/ghost/test/multitest/Basic.h
new file mode 100644
index 00000000000..f81f4684bcc
--- /dev/null
+++ b/intern/ghost/test/multitest/Basic.h
@@ -0,0 +1,44 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+int min_i (int a, int b);
+
+int max_i (int a, int b);
+int clamp_i (int val, int min, int max);
+
+float min_f (float a, float b);
+float max_f (float a, float b);
+float clamp_f (float val, float min, float max);
+
+void rect_copy (int dst[2][2], int src[2][2]);
+int rect_contains_pt (int rect[2][2], int pt[2]);
+int rect_width (int rect[2][2]);
+int rect_height (int rect[2][2]);
diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c
new file mode 100644
index 00000000000..950d80a2468
--- /dev/null
+++ b/intern/ghost/test/multitest/EventToBuf.c
@@ -0,0 +1,236 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+#include "EventToBuf.h"
+
+char *eventtype_to_string(GHOST_TEventType type) {
+ switch(type) {
+ case GHOST_kEventCursorMove: return "CursorMove";
+ case GHOST_kEventButtonDown: return "ButtonDown";
+ case GHOST_kEventButtonUp: return "ButtonUp";
+
+ case GHOST_kEventKeyDown: return "KeyDown";
+ case GHOST_kEventKeyUp: return "KeyUp";
+
+ case GHOST_kEventQuit: return "Quit";
+
+ case GHOST_kEventWindowClose: return "WindowClose";
+ case GHOST_kEventWindowActivate: return "WindowActivate";
+ case GHOST_kEventWindowDeactivate: return "WindowDeactivate";
+ case GHOST_kEventWindowUpdate: return "WindowUpdate";
+ case GHOST_kEventWindowSize: return "WindowSize";
+ default:
+ return "<invalid>";
+ }
+}
+
+static char *keytype_to_string(GHOST_TKey key) {
+#define K(key) case GHOST_k##key: return #key;
+ switch (key) {
+ K(KeyBackSpace);
+ K(KeyTab);
+ K(KeyLinefeed);
+ K(KeyClear);
+ K(KeyEnter);
+
+ K(KeyEsc);
+ K(KeySpace);
+ K(KeyQuote);
+ K(KeyComma);
+ K(KeyMinus);
+ K(KeyPeriod);
+ K(KeySlash);
+
+ K(Key0);
+ K(Key1);
+ K(Key2);
+ K(Key3);
+ K(Key4);
+ K(Key5);
+ K(Key6);
+ K(Key7);
+ K(Key8);
+ K(Key9);
+
+ K(KeySemicolon);
+ K(KeyEqual);
+
+ K(KeyA);
+ K(KeyB);
+ K(KeyC);
+ K(KeyD);
+ K(KeyE);
+ K(KeyF);
+ K(KeyG);
+ K(KeyH);
+ K(KeyI);
+ K(KeyJ);
+ K(KeyK);
+ K(KeyL);
+ K(KeyM);
+ K(KeyN);
+ K(KeyO);
+ K(KeyP);
+ K(KeyQ);
+ K(KeyR);
+ K(KeyS);
+ K(KeyT);
+ K(KeyU);
+ K(KeyV);
+ K(KeyW);
+ K(KeyX);
+ K(KeyY);
+ K(KeyZ);
+
+ K(KeyLeftBracket);
+ K(KeyRightBracket);
+ K(KeyBackslash);
+ K(KeyAccentGrave);
+
+ K(KeyLeftShift);
+ K(KeyRightShift);
+ K(KeyLeftControl);
+ K(KeyRightControl);
+ K(KeyLeftAlt);
+ K(KeyRightAlt);
+ K(KeyCommand);
+
+ K(KeyCapsLock);
+ K(KeyNumLock);
+ K(KeyScrollLock);
+
+ K(KeyLeftArrow);
+ K(KeyRightArrow);
+ K(KeyUpArrow);
+ K(KeyDownArrow);
+
+ K(KeyPrintScreen);
+ K(KeyPause);
+
+ K(KeyInsert);
+ K(KeyDelete);
+ K(KeyHome);
+ K(KeyEnd);
+ K(KeyUpPage);
+ K(KeyDownPage);
+
+ K(KeyNumpad0);
+ K(KeyNumpad1);
+ K(KeyNumpad2);
+ K(KeyNumpad3);
+ K(KeyNumpad4);
+ K(KeyNumpad5);
+ K(KeyNumpad6);
+ K(KeyNumpad7);
+ K(KeyNumpad8);
+ K(KeyNumpad9);
+ K(KeyNumpadPeriod);
+ K(KeyNumpadEnter);
+ K(KeyNumpadPlus);
+ K(KeyNumpadMinus);
+ K(KeyNumpadAsterisk);
+ K(KeyNumpadSlash);
+
+ K(KeyF1);
+ K(KeyF2);
+ K(KeyF3);
+ K(KeyF4);
+ K(KeyF5);
+ K(KeyF6);
+ K(KeyF7);
+ K(KeyF8);
+ K(KeyF9);
+ K(KeyF10);
+ K(KeyF11);
+ K(KeyF12);
+ K(KeyF13);
+ K(KeyF14);
+ K(KeyF15);
+ K(KeyF16);
+ K(KeyF17);
+ K(KeyF18);
+ K(KeyF19);
+ K(KeyF20);
+ K(KeyF21);
+ K(KeyF22);
+ K(KeyF23);
+ K(KeyF24);
+
+ default:
+ return "KeyUnknown";
+ }
+#undef K
+}
+
+void event_to_buf(GHOST_EventHandle evt, char buf[128]) {
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ double time= (double) ((GHOST_TInt64) GHOST_GetEventTime(evt))/1000;
+ GHOST_WindowHandle win= GHOST_GetEventWindow(evt);
+ void *data= GHOST_GetEventData(evt);
+ char *pos= buf;
+
+ pos+= sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type));
+ if (win) {
+ char *s= GHOST_GetTitle(win);
+ pos+= sprintf(pos, " - win: %s", s);
+ free(s);
+ } else {
+ pos+= sprintf(pos, " - sys evt");
+ }
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= data;
+ pos+= sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= data;
+ pos+= sprintf(pos, " - but: %d", bd->button);
+ break;
+ }
+
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= data;
+ pos+= sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key);
+ if (kd->ascii) pos+= sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii);
+ break;
+ }
+ }
+}
diff --git a/intern/ghost/test/multitest/EventToBuf.h b/intern/ghost/test/multitest/EventToBuf.h
new file mode 100644
index 00000000000..be6f37d869b
--- /dev/null
+++ b/intern/ghost/test/multitest/EventToBuf.h
@@ -0,0 +1,35 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+char *eventtype_to_string(GHOST_TEventType type);
+
+void event_to_buf(GHOST_EventHandle evt, char buf[128]);
+
diff --git a/intern/ghost/test/multitest/GL.h b/intern/ghost/test/multitest/GL.h
new file mode 100644
index 00000000000..b395627d1d8
--- /dev/null
+++ b/intern/ghost/test/multitest/GL.h
@@ -0,0 +1,43 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#if defined(WIN32) || defined(__APPLE__)
+
+ #ifdef WIN32
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif // defined(WIN32) || defined(__APPLE__)
diff --git a/intern/ghost/test/multitest/Makefile b/intern/ghost/test/multitest/Makefile
new file mode 100644
index 00000000000..a424a397502
--- /dev/null
+++ b/intern/ghost/test/multitest/Makefile
@@ -0,0 +1,60 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST gears test application Makefile
+#
+
+DIR = $(OCGDIR)/intern/ghost/test
+
+# we don't want a library here, only object files:
+ALLTARGETS = $(OBJS)
+
+include nan_compile.mk
+include nan_link.mk
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../..
+
+OCGGHOST = $(OCGDIR)/intern/ghost
+
+LIBS = $(OCGGHOST)/$(DEBUG_DIR)libghost.a
+SLIBS += $(LCGDIR)/string/lib/libstring.a
+SLIBS += $(LCGDIR)/bmfont/lib/libbmfont.a
+SLIBS += $(LCGDIR)/guardedalloc/lib/libguardedalloc.a
+
+all::
+ @echo "- link $(DIR)/$(DEBUG_DIR)multitest -"
+ @$(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)multitest $(OBJS) $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
new file mode 100755
index 00000000000..c78d9045022
--- /dev/null
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -0,0 +1,855 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+#pragma warning(disable: 4244 4305)
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "GL.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+#include "BMF_Api.h"
+
+#include "Util.h"
+#include "Basic.h"
+#include "ScrollBar.h"
+#include "EventToBuf.h"
+
+#include "WindowData.h"
+
+/***/
+
+typedef struct _MultiTestApp MultiTestApp;
+typedef struct _LoggerWindow LoggerWindow;
+
+void loggerwindow_log(LoggerWindow *lw, char *line);
+
+void multitestapp_toggle_extra_window(MultiTestApp *app);
+void multitestapp_free_extrawindow(MultiTestApp *app);
+LoggerWindow *multitestapp_get_logger(MultiTestApp *app);
+GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app);
+void multitestapp_exit(MultiTestApp *app);
+
+/**/
+
+void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, float *col, int width) {
+ int ltidx= (side/2)%4;
+ int dkidx= (ltidx + 1 + (side&1))%4;
+ int i, corner;
+
+ glBegin(GL_LINES);
+ for (i=0; i<width; i++) {
+ float ltf= pow(lt[i], 1.0/2.2), dkf= pow(dk[i], 1.0/2.2);
+ float stf= (dkidx>ltidx)?dkf:ltf;
+ int lx= rect[1][0]-i-1;
+ int ly= rect[0][1]+i;
+
+ glColor3f(col[0]*stf, col[1]*stf, col[2]*stf);
+ for (corner=0; corner<4; corner++) {
+ int x= (corner==0 || corner==1)?(rect[0][0]+i):(rect[1][0]-i-1);
+ int y= (corner==0 || corner==3)?(rect[0][1]+i):(rect[1][1]-i-1);
+
+ if (ltidx==corner)
+ glColor3f(col[0]*ltf, col[1]*ltf, col[2]*ltf);
+ if (dkidx==corner)
+ glColor3f(col[0]*dkf, col[1]*dkf, col[2]*dkf);
+
+ glVertex2i(lx, ly);
+ glVertex2i(lx= x, ly= y);
+ }
+ }
+ glEnd();
+
+ glColor3fv(col);
+ glRecti(rect[0][0]+width, rect[0][1]+width, rect[1][0]-width, rect[1][1]-width);
+}
+
+void rect_bevel_smooth(int rect[2][2], int width) {
+ float *lt= malloc(sizeof(*lt)*width);
+ float *dk= malloc(sizeof(*dk)*width);
+ float col[4];
+ int i;
+
+ for (i=0; i<width; i++) {
+ float v= width-1?((float) i/(width-1)):0;
+ lt[i]= 1.2 + (1.0-1.2)*v;
+ dk[i]= 0.2 + (1.0-0.2)*v;
+ }
+
+ glGetFloatv(GL_CURRENT_COLOR, col);
+
+ rect_bevel_side(rect, 3, lt, dk, col, width);
+
+ free(lt);
+ free(dk);
+}
+
+ /*
+ * MainWindow
+ */
+
+typedef struct {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ int size[2];
+
+ int lmouse[2], lmbut[3];
+
+ int tmouse[2];
+} MainWindow;
+
+static void mainwindow_log(MainWindow *mw, char *str) {
+ loggerwindow_log(multitestapp_get_logger(mw->app), str);
+}
+
+static void mainwindow_do_draw(MainWindow *mw) {
+ GHOST_ActivateWindowDrawingContext(mw->win);
+
+ if (mw->lmbut[0]) {
+ glClearColor(0.5, 0.5, 0.5, 1);
+ } else {
+ glClearColor(1, 1, 1, 1);
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.5, 0.6, 0.8);
+ glRecti(mw->tmouse[0]-5, mw->tmouse[1]-5, mw->tmouse[0]+5, mw->tmouse[1]+5);
+
+ GHOST_SwapWindowBuffers(mw->win);
+}
+
+static void mainwindow_do_reshape(MainWindow *mw) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(mw->win);
+
+ GHOST_ActivateWindowDrawingContext(mw->win);
+
+ mw->size[0]= GHOST_GetWidthRectangle(bounds);
+ mw->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ glViewport(0, 0, mw->size[0], mw->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press) {
+ switch(key) {
+ case GHOST_kKeyC:
+ if (press)
+ GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor) (rand()%(GHOST_kStandardCursorNumCursors)));
+ break;
+ case GHOST_kKeyLeftBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 0);
+ break;
+ case GHOST_kKeyRightBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 1);
+ break;
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(mw->app);
+ break;
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(mw->app);
+ break;
+ case GHOST_kKeyT:
+ if (press)
+ mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
+ break;
+ case GHOST_kKeyR:
+ if (press) {
+ int i;
+
+ mainwindow_log(mw, "Invalidating window 10 times");
+ for (i=0; i<10; i++)
+ GHOST_InvalidateWindow(mw->win);
+ }
+ break;
+ case GHOST_kKeyF11:
+ if (press) {
+ GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
+ }
+ break;
+ }
+}
+
+static void mainwindow_do_move(MainWindow *mw, int x, int y) {
+ mw->lmouse[0]= x, mw->lmouse[1]= y;
+
+ if (mw->lmbut[0]) {
+ mw->tmouse[0]= x, mw->tmouse[1]= y;
+ GHOST_InvalidateWindow(mw->win);
+ }
+}
+
+static void mainwindow_do_button(MainWindow *mw, int which, int press) {
+ if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[0]= press;
+ mw->tmouse[0]= mw->lmouse[0], mw->tmouse[1]= mw->lmouse[1];
+ GHOST_InvalidateWindow(mw->win);
+ } else if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[1]= press;
+ } else if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[2]= press;
+ }
+}
+
+static void mainwindow_handle(void *priv, GHOST_EventHandle evt) {
+ MainWindow *mw= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ mainwindow_log(mw, buf);
+
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
+ mainwindow_do_move(mw, x, mw->size[1]-y-1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
+ mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ mainwindow_do_draw(mw);
+ break;
+ case GHOST_kEventWindowSize:
+ mainwindow_do_reshape(mw);
+ break;
+ }
+}
+
+/**/
+
+static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) {
+ MainWindow *mw= GHOST_GetTimerTaskUserData(task);
+ char buf[64];
+
+ sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time)/1000);
+ mainwindow_log(mw, buf);
+}
+
+MainWindow *mainwindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_WindowHandle win;
+
+ win= GHOST_CreateWindow(sys, "MultiTest:Main", 40, 40, 400, 400, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ MainWindow *mw= MEM_callocN(sizeof(*mw), "mainwindow_new");
+ mw->app= app;
+ mw->win= win;
+
+ GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
+
+ GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
+
+ return mw;
+ } else {
+ return NULL;
+ }
+}
+
+void mainwindow_free(MainWindow *mw) {
+ GHOST_SystemHandle sys= multitestapp_get_system(mw->app);
+
+ windowdata_free(GHOST_GetWindowUserData(mw->win));
+ GHOST_DisposeWindow(sys, mw->win);
+ MEM_freeN(mw);
+}
+
+ /*
+ * LoggerWindow
+ */
+
+struct _LoggerWindow {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ BMF_Font *font;
+ int fonttexid;
+ int fontheight;
+
+ int size[2];
+
+ int ndisplines;
+ int textarea[2][2];
+ ScrollBar *scroll;
+
+ char **loglines;
+ int nloglines, logsize;
+
+ int lmbut[3];
+ int lmouse[2];
+};
+
+#define SCROLLBAR_PAD 2
+#define SCROLLBAR_WIDTH 14
+#define TEXTAREA_PAD 2
+static void loggerwindow_recalc_regions(LoggerWindow *lw) {
+ int nscroll[2][2];
+
+ nscroll[0][0]= SCROLLBAR_PAD;
+ nscroll[0][1]= SCROLLBAR_PAD;
+ nscroll[1][0]= nscroll[0][0] + SCROLLBAR_WIDTH;
+ nscroll[1][1]= lw->size[1] - SCROLLBAR_PAD - 1;
+
+ lw->textarea[0][0]= nscroll[1][0] + TEXTAREA_PAD;
+ lw->textarea[0][1]= TEXTAREA_PAD;
+ lw->textarea[1][0]= lw->size[0] - TEXTAREA_PAD - 1;
+ lw->textarea[1][1]= lw->size[1] - TEXTAREA_PAD - 1;
+
+ lw->ndisplines= (lw->textarea[1][1]-lw->textarea[0][1])/lw->fontheight;
+
+ scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
+ scrollbar_set_rect(lw->scroll, nscroll);
+}
+
+static void loggerwindow_setup_window_gl(LoggerWindow *lw) {
+ glViewport(0, 0, lw->size[0], lw->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void loggerwindow_do_reshape(LoggerWindow *lw) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(lw->win);
+
+ GHOST_ActivateWindowDrawingContext(lw->win);
+
+ lw->size[0]= GHOST_GetWidthRectangle(bounds);
+ lw->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ loggerwindow_recalc_regions(lw);
+ loggerwindow_setup_window_gl(lw);
+}
+
+static void loggerwindow_do_draw(LoggerWindow *lw) {
+ int i, ndisplines, startline;
+ int sb_rect[2][2], sb_thumb[2][2];
+
+ GHOST_ActivateWindowDrawingContext(lw->win);
+
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8, 0.8, 0.8);
+ rect_bevel_smooth(lw->textarea, 4);
+
+ scrollbar_get_rect(lw->scroll, sb_rect);
+ scrollbar_get_thumb(lw->scroll, sb_thumb);
+
+ glColor3f(0.6, 0.6, 0.6);
+ rect_bevel_smooth(sb_rect, 1);
+
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ glColor3f(0.6, 0.7, 0.5);
+ } else {
+ glColor3f(0.9, 0.9, 0.92);
+ }
+ rect_bevel_smooth(sb_thumb, 1);
+
+ startline= scrollbar_get_thumbpos(lw->scroll)*(lw->nloglines-1);
+ ndisplines= min_i(lw->ndisplines, lw->nloglines-startline);
+
+ if (lw->fonttexid!=-1) {
+ glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ }
+ glColor3f(0, 0, 0);
+ for (i=0; i<ndisplines; i++) {
+ /* stored in reverse order */
+ char *line= lw->loglines[(lw->nloglines-1)-(i+startline)];
+ int x_pos= lw->textarea[0][0] + 4;
+ int y_pos= lw->textarea[0][1] + 4 + i*lw->fontheight;
+
+ if (lw->fonttexid==-1) {
+ glRasterPos2i(x_pos, y_pos);
+ BMF_DrawString(lw->font, line);
+ } else {
+ BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0);
+ }
+ }
+ if (lw->fonttexid!=-1) {
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ }
+
+ GHOST_SwapWindowBuffers(lw->win);
+}
+
+static void loggerwindow_do_move(LoggerWindow *lw, int x, int y) {
+ lw->lmouse[0]= x, lw->lmouse[1]= y;
+
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_keep_scrolling(lw->scroll, y);
+ GHOST_InvalidateWindow(lw->win);
+ }
+}
+
+static void loggerwindow_do_button(LoggerWindow *lw, int which, int press) {
+ if (which==GHOST_kButtonMaskLeft) {
+ lw->lmbut[0]= press;
+
+ if (press) {
+ if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
+ scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ } else {
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_stop_scrolling(lw->scroll);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ }
+ } else if (which==GHOST_kButtonMaskMiddle) {
+ lw->lmbut[1]= press;
+ } else if (which==GHOST_kButtonMaskRight) {
+ lw->lmbut[2]= press;
+ }
+}
+
+static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press) {
+ switch (key) {
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(lw->app);
+ break;
+ }
+}
+
+static void loggerwindow_handle(void *priv, GHOST_EventHandle evt) {
+ LoggerWindow *lw= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+
+ switch(type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
+ loggerwindow_do_move(lw, x, lw->size[1]-y-1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
+ loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ loggerwindow_do_draw(lw);
+ break;
+ case GHOST_kEventWindowSize:
+ loggerwindow_do_reshape(lw);
+ break;
+ }
+}
+
+/**/
+
+LoggerWindow *loggerwindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_TUns32 screensize[2];
+ GHOST_WindowHandle win;
+
+ GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
+ win= GHOST_CreateWindow(sys, "MultiTest:Logger", 40, screensize[1]-432, 800, 300, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ LoggerWindow *lw= MEM_callocN(sizeof(*lw), "loggerwindow_new");
+ int bbox[2][2];
+ lw->app= app;
+ lw->win= win;
+
+ lw->font= BMF_GetFont(BMF_kScreen12);
+ lw->fonttexid= BMF_GetFontTexture(lw->font);
+
+ BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]);
+ lw->fontheight= rect_height(bbox);
+
+ lw->nloglines= lw->logsize= 0;
+ lw->loglines= MEM_mallocN(sizeof(*lw->loglines)*lw->nloglines, "loglines");
+
+ lw->scroll= scrollbar_new(2, 40);
+
+ GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
+
+ loggerwindow_do_reshape(lw);
+
+ return lw;
+ } else {
+ return NULL;
+ }
+}
+
+void loggerwindow_log(LoggerWindow *lw, char *line) {
+ if (lw->nloglines==lw->logsize) {
+ lw->loglines= memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
+ }
+
+ lw->loglines[lw->nloglines++]= string_dup(line);
+ scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
+
+ GHOST_InvalidateWindow(lw->win);
+}
+
+void loggerwindow_free(LoggerWindow *lw) {
+ GHOST_SystemHandle sys= multitestapp_get_system(lw->app);
+ int i;
+
+ for (i=0; i<lw->nloglines; i++) {
+ MEM_freeN(lw->loglines[i]);
+ }
+ MEM_freeN(lw->loglines);
+
+ windowdata_free(GHOST_GetWindowUserData(lw->win));
+ GHOST_DisposeWindow(sys, lw->win);
+ MEM_freeN(lw);
+}
+
+ /*
+ * ExtraWindow
+ */
+
+
+typedef struct {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ int size[2];
+} ExtraWindow;
+
+static void extrawindow_do_draw(ExtraWindow *ew) {
+ GHOST_ActivateWindowDrawingContext(ew->win);
+
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8, 0.8, 0.8);
+ glRecti(10, 10, ew->size[0]-10, ew->size[1]-10);
+
+ GHOST_SwapWindowBuffers(ew->win);
+}
+
+static void extrawindow_do_reshape(ExtraWindow *ew) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(ew->win);
+
+ GHOST_ActivateWindowDrawingContext(ew->win);
+
+ ew->size[0]= GHOST_GetWidthRectangle(bounds);
+ ew->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ glViewport(0, 0, ew->size[0], ew->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press) {
+ switch (key) {
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(ew->app);
+ break;
+ }
+}
+
+static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time) {
+ GHOST_TUns8 bitmap[16][2];
+ GHOST_TUns8 mask[16][2];
+ double ftime= (double) ((GHOST_TInt64) time)/1000;
+ float angle= fmod(ftime, 1.0) * 3.1415*2;
+ int i;
+
+ memset(&bitmap, 0, sizeof(bitmap));
+ memset(&mask, 0, sizeof(mask));
+
+ bitmap[0][0] |= mask[0][0] |= 0xF;
+ bitmap[1][0] |= mask[1][0] |= 0xF;
+ bitmap[2][0] |= mask[2][0] |= 0xF;
+ bitmap[3][0] |= mask[3][0] |= 0xF;
+
+ for (i=0; i<7; i++) {
+ int x = 7 + cos(angle)*i;
+ int y = 7 + sin(angle)*i;
+
+ mask[y][x/8] |= (1 << (x%8));
+ }
+ for (i=0; i<64; i++) {
+ float v= (i/63.0) * 3.1415*2;
+ int x = 7 + cos(v)*7;
+ int y = 7 + sin(v)*7;
+
+ mask[y][x/8] |= (1 << (x%8));
+ }
+
+ GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
+}
+
+static void extrawindow_handle(void *priv, GHOST_EventHandle evt) {
+ ExtraWindow *ew= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ loggerwindow_log(multitestapp_get_logger(ew->app), buf);
+
+ switch (type) {
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventCursorMove: {
+ extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
+ break;
+ }
+
+ case GHOST_kEventWindowClose:
+ multitestapp_free_extrawindow(ew->app);
+ break;
+ case GHOST_kEventWindowUpdate:
+ extrawindow_do_draw(ew);
+ break;
+ case GHOST_kEventWindowSize:
+ extrawindow_do_reshape(ew);
+ break;
+ }
+}
+
+/**/
+
+ExtraWindow *extrawindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_WindowHandle win;
+
+ win= GHOST_CreateWindow(sys, "MultiTest:Extra", 500, 40, 400, 400, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ ExtraWindow *ew= MEM_callocN(sizeof(*ew), "mainwindow_new");
+ ew->app= app;
+ ew->win= win;
+
+ GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
+
+ return ew;
+ } else {
+ return NULL;
+ }
+}
+
+void extrawindow_free(ExtraWindow *ew) {
+ GHOST_SystemHandle sys= multitestapp_get_system(ew->app);
+
+ windowdata_free(GHOST_GetWindowUserData(ew->win));
+ GHOST_DisposeWindow(sys, ew->win);
+ MEM_freeN(ew);
+}
+
+ /*
+ * MultiTestApp
+ */
+
+struct _MultiTestApp {
+ GHOST_SystemHandle sys;
+ MainWindow *main;
+ LoggerWindow *logger;
+ ExtraWindow *extra;
+
+ int exit;
+};
+
+static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data) {
+ MultiTestApp *app= data;
+ GHOST_WindowHandle win;
+
+ win= GHOST_GetEventWindow(evt);
+ if (win && !GHOST_ValidWindow(app->sys, win)) {
+ loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
+ return 1;
+ }
+
+ if (win) {
+ WindowData *wb= GHOST_GetWindowUserData(win);
+
+ windowdata_handle(wb, evt);
+ } else {
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+
+ /* GHOST_kEventQuit are the only 'system' events,
+ * that is, events without a window.
+ */
+ switch(type) {
+ case GHOST_kEventQuit:
+ app->exit= 1;
+ break;
+
+ default:
+ fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/**/
+
+MultiTestApp *multitestapp_new(void) {
+ MultiTestApp *app= MEM_mallocN(sizeof(*app), "multitestapp_new");
+ GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(multitest_event_handler, app);
+
+ app->sys= GHOST_CreateSystem();
+ if (!app->sys)
+ fatal("Unable to create ghost system");
+
+ if (!GHOST_AddEventConsumer(app->sys, consumer))
+ fatal("Unable to add multitest event consumer ");
+
+ app->main= mainwindow_new(app);
+ if (!app->main)
+ fatal("Unable to create main window");
+
+ app->logger= loggerwindow_new(app);
+ if (!app->logger)
+ fatal("Unable to create logger window");
+
+ app->extra= NULL;
+ app->exit= 0;
+
+ return app;
+}
+
+LoggerWindow *multitestapp_get_logger(MultiTestApp *app) {
+ return app->logger;
+}
+
+GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) {
+ return app->sys;
+}
+
+void multitestapp_free_extrawindow(MultiTestApp *app) {
+ extrawindow_free(app->extra);
+ app->extra= NULL;
+}
+
+void multitestapp_toggle_extra_window(MultiTestApp *app) {
+ if (app->extra) {
+ multitestapp_free_extrawindow(app);
+ } else {
+ app->extra= extrawindow_new(app);
+ }
+}
+
+void multitestapp_exit(MultiTestApp *app) {
+ app->exit= 1;
+}
+
+void multitestapp_run(MultiTestApp *app) {
+ while (!app->exit) {
+ GHOST_ProcessEvents(app->sys, 1);
+ GHOST_DispatchEvents(app->sys);
+ }
+}
+
+void multitestapp_free(MultiTestApp *app) {
+ mainwindow_free(app->main);
+ loggerwindow_free(app->logger);
+ GHOST_DisposeSystem(app->sys);
+ MEM_freeN(app);
+}
+
+ /***/
+
+int main(int argc, char **argv) {
+ MultiTestApp *app= multitestapp_new();
+
+ multitestapp_run(app);
+ multitestapp_free(app);
+
+ return 0;
+}
diff --git a/intern/ghost/test/multitest/ScrollBar.c b/intern/ghost/test/multitest/ScrollBar.c
new file mode 100644
index 00000000000..cd690f6f14e
--- /dev/null
+++ b/intern/ghost/test/multitest/ScrollBar.c
@@ -0,0 +1,145 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "Basic.h"
+#include "ScrollBar.h"
+
+struct _ScrollBar {
+ int rect[2][2];
+ float thumbpos, thumbpct;
+
+ int inset;
+ int minthumb;
+
+ int scrolling;
+ float scrolloffs;
+};
+
+static int scrollbar_get_thumbH(ScrollBar *sb) {
+ int scrollable_h= rect_height(sb->rect) - 2*sb->inset;
+
+ return clamp_i(sb->thumbpct*scrollable_h, sb->minthumb, scrollable_h);
+}
+static int scrollbar_get_thumbableH(ScrollBar *sb) {
+ int scrollable_h= rect_height(sb->rect) - 2*sb->inset;
+ int thumb_h= scrollbar_get_thumbH(sb);
+
+ return scrollable_h - thumb_h;
+}
+
+static float scrollbar_co_to_pos(ScrollBar *sb, int yco) {
+ int thumb_h= scrollbar_get_thumbH(sb);
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+ int thumbable_y= (sb->rect[0][1]+sb->inset) + thumb_h/2;
+
+ return (float) (yco-thumbable_y)/thumbable_h;
+}
+
+/**/
+
+ScrollBar *scrollbar_new(int inset, int minthumb) {
+ ScrollBar *sb= MEM_callocN(sizeof(*sb), "scrollbar_new");
+ sb->inset= inset;
+ sb->minthumb= minthumb;
+
+ return sb;
+}
+
+void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2]) {
+ int thumb_h= scrollbar_get_thumbH(sb);
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+
+ thumb_r[0][0]= sb->rect[0][0]+sb->inset;
+ thumb_r[1][0]= sb->rect[1][0]-sb->inset;
+
+ thumb_r[0][1]= sb->rect[0][1]+sb->inset + sb->thumbpos*thumbable_h;
+ thumb_r[1][1]= thumb_r[0][1] + thumb_h;
+}
+
+int scrollbar_is_scrolling(ScrollBar *sb) {
+ return sb->scrolling;
+}
+int scrollbar_contains_pt(ScrollBar *sb, int pt[2]) {
+ return rect_contains_pt(sb->rect, pt);
+}
+
+void scrollbar_start_scrolling(ScrollBar *sb, int yco) {
+ int thumb_h_2= scrollbar_get_thumbH(sb)/2;
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+ float npos= scrollbar_co_to_pos(sb, yco);
+
+ sb->scrolloffs= sb->thumbpos - npos;
+ if (fabs(sb->scrolloffs) >= (float) thumb_h_2/thumbable_h) {
+ sb->scrolloffs= 0.0;
+ }
+
+ sb->scrolling= 1;
+ sb->thumbpos= clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+}
+void scrollbar_keep_scrolling(ScrollBar *sb, int yco) {
+ float npos= scrollbar_co_to_pos(sb, yco);
+
+ sb->thumbpos= clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+}
+void scrollbar_stop_scrolling(ScrollBar *sb) {
+ sb->scrolling= 0;
+ sb->scrolloffs= 0.0;
+}
+
+void scrollbar_set_thumbpct(ScrollBar *sb, float pct) {
+ sb->thumbpct= pct;
+}
+void scrollbar_set_thumbpos(ScrollBar *sb, float pos) {
+ sb->thumbpos= clamp_f(pos, 0.0, 1.0);
+}
+void scrollbar_set_rect(ScrollBar *sb, int rect[2][2]) {
+ rect_copy(sb->rect, rect);
+}
+
+float scrollbar_get_thumbpct(ScrollBar *sb) {
+ return sb->thumbpct;
+}
+float scrollbar_get_thumbpos(ScrollBar *sb) {
+ return sb->thumbpos;
+}
+void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2]) {
+ rect_copy(rect_r, sb->rect);
+}
+
+void scrollbar_free(ScrollBar *sb) {
+ MEM_freeN(sb);
+}
diff --git a/intern/ghost/test/multitest/ScrollBar.h b/intern/ghost/test/multitest/ScrollBar.h
new file mode 100644
index 00000000000..30e49e8b531
--- /dev/null
+++ b/intern/ghost/test/multitest/ScrollBar.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+typedef struct _ScrollBar ScrollBar;
+
+
+ /***/
+
+ScrollBar* scrollbar_new (int inset, int minthumb);
+
+int scrollbar_is_scrolling (ScrollBar *sb);
+int scrollbar_contains_pt (ScrollBar *sb, int pt[2]);
+
+void scrollbar_start_scrolling (ScrollBar *sb, int yco);
+void scrollbar_keep_scrolling (ScrollBar *sb, int yco);
+void scrollbar_stop_scrolling (ScrollBar *sb);
+
+void scrollbar_set_thumbpct (ScrollBar *sb, float pct);
+void scrollbar_set_thumbpos (ScrollBar *sb, float pos);
+void scrollbar_set_rect (ScrollBar *sb, int rect[2][2]);
+
+float scrollbar_get_thumbpct (ScrollBar *sb);
+float scrollbar_get_thumbpos (ScrollBar *sb);
+void scrollbar_get_rect (ScrollBar *sb, int rect_r[2][2]);
+
+void scrollbar_get_thumb (ScrollBar *sb, int thumb_r[2][2]);
+
+void scrollbar_free (ScrollBar *sb);
diff --git a/intern/ghost/test/multitest/Util.c b/intern/ghost/test/multitest/Util.c
new file mode 100644
index 00000000000..31e43f6f5da
--- /dev/null
+++ b/intern/ghost/test/multitest/Util.c
@@ -0,0 +1,73 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "Util.h"
+
+void* memdbl(void *mem, int *size_pr, int item_size) {
+ int cur_size= *size_pr;
+ int new_size= cur_size?(cur_size*2):1;
+ void *nmem= MEM_mallocN(new_size*item_size, "memdbl");
+
+ memcpy(nmem, mem, cur_size*item_size);
+ MEM_freeN(mem);
+
+ *size_pr= new_size;
+ return nmem;
+}
+
+char* string_dup(char *str) {
+ int len= strlen(str);
+ char *nstr= MEM_mallocN(len + 1, "string_dup");
+
+ memcpy(nstr, str, len+1);
+
+ return nstr;
+}
+
+void fatal(char *fmt, ...) {
+ va_list ap;
+
+ fprintf(stderr, "FATAL: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+
+ exit(1);
+}
diff --git a/intern/ghost/test/multitest/Util.h b/intern/ghost/test/multitest/Util.h
new file mode 100644
index 00000000000..1146112c9c4
--- /dev/null
+++ b/intern/ghost/test/multitest/Util.h
@@ -0,0 +1,35 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+void* memdbl (void *mem, int *size_pr, int item_size);
+
+char* string_dup (char *str);
+void fatal (char *fmt, ...);
diff --git a/intern/ghost/test/multitest/WindowData.c b/intern/ghost/test/multitest/WindowData.c
new file mode 100644
index 00000000000..ee377c98b58
--- /dev/null
+++ b/intern/ghost/test/multitest/WindowData.c
@@ -0,0 +1,60 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+
+#include "WindowData.h"
+
+struct _WindowData {
+ void *data;
+ WindowDataHandler handler;
+};
+
+WindowData *windowdata_new(void *data, WindowDataHandler handler) {
+ WindowData *wb= MEM_mallocN(sizeof(*wb), "windowdata_new");
+ wb->data= data;
+ wb->handler= handler;
+
+ return wb;
+}
+
+void windowdata_handle(WindowData *wb, GHOST_EventHandle evt) {
+ wb->handler(wb->data, evt);
+}
+
+void windowdata_free(WindowData *wb) {
+ MEM_freeN(wb);
+}
diff --git a/intern/ghost/test/multitest/WindowData.h b/intern/ghost/test/multitest/WindowData.h
new file mode 100644
index 00000000000..a046c41d90c
--- /dev/null
+++ b/intern/ghost/test/multitest/WindowData.h
@@ -0,0 +1,40 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+typedef void (*WindowDataHandler)(void *priv, GHOST_EventHandle evt);
+
+typedef struct _WindowData WindowData;
+
+ /***/
+
+WindowData* windowdata_new (void *data, WindowDataHandler handler);
+void windowdata_handle (WindowData *wb, GHOST_EventHandle evt);
+void windowdata_free (WindowData *wb);