Initial revision

This commit is contained in:
Hans Lambermont
2002-10-12 11:37:38 +00:00
commit 12315f4d0e
1699 changed files with 444708 additions and 0 deletions

733
intern/ghost/GHOST_C-api.h Normal file
View File

@@ -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

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

237
intern/ghost/GHOST_Rect.h Normal file
View File

@@ -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

354
intern/ghost/GHOST_Types.h Normal file
View File

@@ -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_

52
intern/ghost/Makefile Normal file
View File

@@ -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/

View File

@@ -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 =

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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 //

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

View File

@@ -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();
}
}

View File

@@ -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_

View File

@@ -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;
}
}
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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<69>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;
}

View File

@@ -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_

View File

@@ -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_

View File

@@ -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 (<28>) 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;
}

View File

@@ -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_

View File

@@ -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

View File

@@ -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

View File

@@ -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());
}
}

View File

@@ -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_

View File

@@ -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_

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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);
}
*/

View File

@@ -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_

View File

@@ -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)

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

86
intern/ghost/test/Makefile Executable file
View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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../..

View File

@@ -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

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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]);
}

View File

@@ -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]);

View File

@@ -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;
}
}
}

View File

@@ -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]);

View File

@@ -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__)

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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, ...);

View File

@@ -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);
}

View File

@@ -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);