diff options
Diffstat (limited to 'intern/ghost')
129 files changed, 25147 insertions, 24570 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index a43906cea85..b096fecced8 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -19,329 +19,329 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - . - ../glew-mx - ../string - ../../source/blender/imbuf - ../../source/blender/makesdna + . + ../glew-mx + ../string + ../../source/blender/imbuf + ../../source/blender/makesdna ) set(INC_SYS - ${GLEW_INCLUDE_PATH} + ${GLEW_INCLUDE_PATH} ) set(SRC - intern/GHOST_Buttons.cpp - intern/GHOST_C-api.cpp - intern/GHOST_CallbackEventConsumer.cpp - intern/GHOST_Context.cpp - intern/GHOST_ContextNone.cpp - intern/GHOST_DisplayManager.cpp - intern/GHOST_EventManager.cpp - intern/GHOST_ISystem.cpp - intern/GHOST_ISystemPaths.cpp - intern/GHOST_ModifierKeys.cpp - intern/GHOST_Path-api.cpp - intern/GHOST_Rect.cpp - intern/GHOST_System.cpp - intern/GHOST_TimerManager.cpp - intern/GHOST_Window.cpp - intern/GHOST_WindowManager.cpp - - GHOST_C-api.h - GHOST_IContext.h - GHOST_IEvent.h - GHOST_IEventConsumer.h - GHOST_ISystem.h - GHOST_ISystemPaths.h - GHOST_ITimerTask.h - GHOST_IWindow.h - GHOST_Path-api.h - GHOST_Rect.h - GHOST_Types.h - - intern/GHOST_Buttons.h - intern/GHOST_CallbackEventConsumer.h - intern/GHOST_Context.h - intern/GHOST_ContextNone.h - intern/GHOST_Debug.h - intern/GHOST_DisplayManager.h - intern/GHOST_Event.h - intern/GHOST_EventButton.h - intern/GHOST_EventCursor.h - intern/GHOST_EventDragnDrop.h - intern/GHOST_EventKey.h - intern/GHOST_EventManager.h - intern/GHOST_EventString.h - intern/GHOST_EventTrackpad.h - intern/GHOST_EventWheel.h - intern/GHOST_ModifierKeys.h - intern/GHOST_System.h - intern/GHOST_SystemPaths.h - intern/GHOST_TimerManager.h - intern/GHOST_TimerTask.h - intern/GHOST_Window.h - intern/GHOST_WindowManager.h + intern/GHOST_Buttons.cpp + intern/GHOST_C-api.cpp + intern/GHOST_CallbackEventConsumer.cpp + intern/GHOST_Context.cpp + intern/GHOST_ContextNone.cpp + intern/GHOST_DisplayManager.cpp + intern/GHOST_EventManager.cpp + intern/GHOST_ISystem.cpp + intern/GHOST_ISystemPaths.cpp + intern/GHOST_ModifierKeys.cpp + intern/GHOST_Path-api.cpp + intern/GHOST_Rect.cpp + intern/GHOST_System.cpp + intern/GHOST_TimerManager.cpp + intern/GHOST_Window.cpp + intern/GHOST_WindowManager.cpp + + GHOST_C-api.h + GHOST_IContext.h + GHOST_IEvent.h + GHOST_IEventConsumer.h + GHOST_ISystem.h + GHOST_ISystemPaths.h + GHOST_ITimerTask.h + GHOST_IWindow.h + GHOST_Path-api.h + GHOST_Rect.h + GHOST_Types.h + + intern/GHOST_Buttons.h + intern/GHOST_CallbackEventConsumer.h + intern/GHOST_Context.h + intern/GHOST_ContextNone.h + intern/GHOST_Debug.h + intern/GHOST_DisplayManager.h + intern/GHOST_Event.h + intern/GHOST_EventButton.h + intern/GHOST_EventCursor.h + intern/GHOST_EventDragnDrop.h + intern/GHOST_EventKey.h + intern/GHOST_EventManager.h + intern/GHOST_EventString.h + intern/GHOST_EventTrackpad.h + intern/GHOST_EventWheel.h + intern/GHOST_ModifierKeys.h + intern/GHOST_System.h + intern/GHOST_SystemPaths.h + intern/GHOST_TimerManager.h + intern/GHOST_TimerTask.h + intern/GHOST_Window.h + intern/GHOST_WindowManager.h ) set(LIB - bf_intern_glew_mx - bf_intern_string - ${GLEW_LIBRARY} + bf_intern_glew_mx + bf_intern_string + ${GLEW_LIBRARY} ) if(WITH_GHOST_DEBUG) - list(APPEND SRC - intern/GHOST_EventPrinter.cpp + list(APPEND SRC + intern/GHOST_EventPrinter.cpp - intern/GHOST_EventPrinter.h - ) - add_definitions(-DWITH_GHOST_DEBUG) + intern/GHOST_EventPrinter.h + ) + add_definitions(-DWITH_GHOST_DEBUG) endif() if(WITH_INPUT_NDOF) - add_definitions(-DWITH_INPUT_NDOF) + add_definitions(-DWITH_INPUT_NDOF) - list(APPEND SRC - intern/GHOST_NDOFManager.cpp + list(APPEND SRC + intern/GHOST_NDOFManager.cpp - intern/GHOST_EventNDOF.h - intern/GHOST_NDOFManager.h - ) + intern/GHOST_EventNDOF.h + intern/GHOST_NDOFManager.h + ) - list(APPEND INC_SYS - ${NDOF_INCLUDE_DIRS} - ) + list(APPEND INC_SYS + ${NDOF_INCLUDE_DIRS} + ) endif() if(WITH_HEADLESS OR WITH_GHOST_SDL) - if(WITH_HEADLESS) - list(APPEND SRC - intern/GHOST_DisplayManagerNULL.h - intern/GHOST_SystemNULL.h - intern/GHOST_WindowNULL.h - ) - add_definitions(-DWITH_HEADLESS) - else() - list(APPEND SRC - intern/GHOST_ContextSDL.cpp - intern/GHOST_DisplayManagerSDL.cpp - intern/GHOST_SystemSDL.cpp - intern/GHOST_WindowSDL.cpp - - intern/GHOST_ContextSDL.h - intern/GHOST_DisplayManagerSDL.h - intern/GHOST_SystemSDL.h - intern/GHOST_WindowSDL.h - ) - add_definitions(-DWITH_GHOST_SDL) - endif() - - if(NOT WITH_HEADLESS) - list(APPEND INC_SYS - ${SDL_INCLUDE_DIR} - ) - endif() + if(WITH_HEADLESS) + list(APPEND SRC + intern/GHOST_DisplayManagerNULL.h + intern/GHOST_SystemNULL.h + intern/GHOST_WindowNULL.h + ) + add_definitions(-DWITH_HEADLESS) + else() + list(APPEND SRC + intern/GHOST_ContextSDL.cpp + intern/GHOST_DisplayManagerSDL.cpp + intern/GHOST_SystemSDL.cpp + intern/GHOST_WindowSDL.cpp + + intern/GHOST_ContextSDL.h + intern/GHOST_DisplayManagerSDL.h + intern/GHOST_SystemSDL.h + intern/GHOST_WindowSDL.h + ) + add_definitions(-DWITH_GHOST_SDL) + endif() + + if(NOT WITH_HEADLESS) + list(APPEND INC_SYS + ${SDL_INCLUDE_DIR} + ) + endif() elseif(APPLE AND NOT WITH_X11) - list(APPEND SRC - intern/GHOST_DisplayManagerCocoa.mm - intern/GHOST_SystemCocoa.mm - intern/GHOST_WindowCocoa.mm + list(APPEND SRC + intern/GHOST_DisplayManagerCocoa.mm + intern/GHOST_SystemCocoa.mm + intern/GHOST_WindowCocoa.mm - intern/GHOST_DisplayManagerCocoa.h - intern/GHOST_SystemCocoa.h - intern/GHOST_WindowCocoa.h - ) + intern/GHOST_DisplayManagerCocoa.h + intern/GHOST_SystemCocoa.h + intern/GHOST_WindowCocoa.h + ) - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextCGL.mm + if(NOT WITH_GL_EGL) + list(APPEND SRC + intern/GHOST_ContextCGL.mm - intern/GHOST_ContextCGL.h - ) - endif() + intern/GHOST_ContextCGL.h + ) + endif() - if(WITH_INPUT_NDOF) - list(APPEND SRC - intern/GHOST_NDOFManagerCocoa.mm + if(WITH_INPUT_NDOF) + list(APPEND SRC + intern/GHOST_NDOFManagerCocoa.mm - intern/GHOST_NDOFManagerCocoa.h - ) - endif() + intern/GHOST_NDOFManagerCocoa.h + ) + endif() elseif(WITH_X11) - list(APPEND INC_SYS - ${X11_X11_INCLUDE_PATH} - ) - - list(APPEND SRC - intern/GHOST_DisplayManagerX11.cpp - intern/GHOST_SystemX11.cpp - intern/GHOST_TaskbarX11.cpp - intern/GHOST_WindowX11.cpp - - intern/GHOST_DisplayManagerX11.h - intern/GHOST_SystemX11.h - intern/GHOST_TaskbarX11.h - intern/GHOST_WindowX11.h - ) - - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextGLX.cpp - - intern/GHOST_ContextGLX.h - ) - endif() - - if(WITH_GHOST_XDND) - add_definitions(-DWITH_XDND) - - list(APPEND LIB - extern_xdnd - ) - - list(APPEND INC - ../../extern/xdnd - ) - - list(APPEND SRC - intern/GHOST_DropTargetX11.cpp - - intern/GHOST_DropTargetX11.h - ) - endif() - - if(X11_XF86keysym_INCLUDE_PATH) - add_definitions(-DWITH_XF86KEYSYM) - list(APPEND INC_SYS - ${X11_XF86keysym_INCLUDE_PATH} - ) - endif() - - if(WITH_X11_XF86VMODE) - add_definitions(-DWITH_X11_XF86VMODE) - list(APPEND INC_SYS - ${X11_xf86vmode_INCLUDE_PATH} - ) - endif() - - if(WITH_X11_XFIXES) - add_definitions(-DWITH_X11_XFIXES) - list(APPEND INC_SYS - ${X11_Xfixes_INCLUDE_PATH} - ) - endif() - - if(WITH_X11_ALPHA) - add_definitions(-DWITH_X11_ALPHA) - endif() - - if(WITH_INPUT_NDOF) - list(APPEND SRC - intern/GHOST_NDOFManagerUnix.cpp - - intern/GHOST_NDOFManagerUnix.h - ) - endif() - - if(NOT WITH_INSTALL_PORTABLE) - add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}") - endif() - - if(WITH_X11_XINPUT) - add_definitions(-DWITH_X11_XINPUT) - list(APPEND INC_SYS - ${X11_Xinput_INCLUDE_PATH} - ) - endif() - - add_definitions(-DWITH_X11) + list(APPEND INC_SYS + ${X11_X11_INCLUDE_PATH} + ) + + list(APPEND SRC + intern/GHOST_DisplayManagerX11.cpp + intern/GHOST_SystemX11.cpp + intern/GHOST_TaskbarX11.cpp + intern/GHOST_WindowX11.cpp + + intern/GHOST_DisplayManagerX11.h + intern/GHOST_SystemX11.h + intern/GHOST_TaskbarX11.h + intern/GHOST_WindowX11.h + ) + + if(NOT WITH_GL_EGL) + list(APPEND SRC + intern/GHOST_ContextGLX.cpp + + intern/GHOST_ContextGLX.h + ) + endif() + + if(WITH_GHOST_XDND) + add_definitions(-DWITH_XDND) + + list(APPEND LIB + extern_xdnd + ) + + list(APPEND INC + ../../extern/xdnd + ) + + list(APPEND SRC + intern/GHOST_DropTargetX11.cpp + + intern/GHOST_DropTargetX11.h + ) + endif() + + if(X11_XF86keysym_INCLUDE_PATH) + add_definitions(-DWITH_XF86KEYSYM) + list(APPEND INC_SYS + ${X11_XF86keysym_INCLUDE_PATH} + ) + endif() + + if(WITH_X11_XF86VMODE) + add_definitions(-DWITH_X11_XF86VMODE) + list(APPEND INC_SYS + ${X11_xf86vmode_INCLUDE_PATH} + ) + endif() + + if(WITH_X11_XFIXES) + add_definitions(-DWITH_X11_XFIXES) + list(APPEND INC_SYS + ${X11_Xfixes_INCLUDE_PATH} + ) + endif() + + if(WITH_X11_ALPHA) + add_definitions(-DWITH_X11_ALPHA) + endif() + + if(WITH_INPUT_NDOF) + list(APPEND SRC + intern/GHOST_NDOFManagerUnix.cpp + + intern/GHOST_NDOFManagerUnix.h + ) + endif() + + if(NOT WITH_INSTALL_PORTABLE) + add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}") + endif() + + if(WITH_X11_XINPUT) + add_definitions(-DWITH_X11_XINPUT) + list(APPEND INC_SYS + ${X11_Xinput_INCLUDE_PATH} + ) + endif() + + add_definitions(-DWITH_X11) elseif(WIN32) - ## Warnings as errors, this is too strict! - #if(MSVC) - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") - #endif() - - list(APPEND INC_SYS - ${WINTAB_INC} - ) - - list(APPEND SRC - intern/GHOST_DisplayManagerWin32.cpp - intern/GHOST_DropTargetWin32.cpp - intern/GHOST_SystemWin32.cpp - intern/GHOST_WindowWin32.cpp - - intern/GHOST_DisplayManagerWin32.h - intern/GHOST_DropTargetWin32.h - intern/GHOST_SystemWin32.h - intern/GHOST_TaskbarWin32.h - intern/GHOST_WindowWin32.h - ) - - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextWGL.cpp - - intern/GHOST_ContextWGL.h - ) - endif() - - if(WITH_INPUT_IME) - add_definitions(-DWITH_INPUT_IME) - - list(APPEND SRC - intern/GHOST_ImeWin32.cpp - - intern/GHOST_ImeWin32.h - ) - endif() - - if(WITH_INPUT_NDOF) - list(APPEND SRC - intern/GHOST_NDOFManagerWin32.cpp - - intern/GHOST_NDOFManagerWin32.h - ) - endif() + ## Warnings as errors, this is too strict! + #if(MSVC) + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") + #endif() + + list(APPEND INC_SYS + ${WINTAB_INC} + ) + + list(APPEND SRC + intern/GHOST_DisplayManagerWin32.cpp + intern/GHOST_DropTargetWin32.cpp + intern/GHOST_SystemWin32.cpp + intern/GHOST_WindowWin32.cpp + + intern/GHOST_DisplayManagerWin32.h + intern/GHOST_DropTargetWin32.h + intern/GHOST_SystemWin32.h + intern/GHOST_TaskbarWin32.h + intern/GHOST_WindowWin32.h + ) + + if(NOT WITH_GL_EGL) + list(APPEND SRC + intern/GHOST_ContextWGL.cpp + + intern/GHOST_ContextWGL.h + ) + endif() + + if(WITH_INPUT_IME) + add_definitions(-DWITH_INPUT_IME) + + list(APPEND SRC + intern/GHOST_ImeWin32.cpp + + intern/GHOST_ImeWin32.h + ) + endif() + + if(WITH_INPUT_NDOF) + list(APPEND SRC + intern/GHOST_NDOFManagerWin32.cpp + + intern/GHOST_NDOFManagerWin32.h + ) + endif() endif() if(WITH_GL_EGL AND NOT (WITH_HEADLESS OR WITH_GHOST_SDL)) - list(APPEND SRC - intern/GHOST_ContextEGL.cpp + list(APPEND SRC + intern/GHOST_ContextEGL.cpp - intern/GHOST_ContextEGL.h - ) + intern/GHOST_ContextEGL.h + ) endif() if(APPLE) - list(APPEND SRC - intern/GHOST_SystemPathsCocoa.h - intern/GHOST_SystemPathsCocoa.mm - ) + list(APPEND SRC + intern/GHOST_SystemPathsCocoa.h + intern/GHOST_SystemPathsCocoa.mm + ) elseif(UNIX) - list(APPEND SRC - intern/GHOST_SystemPathsUnix.cpp - intern/GHOST_SystemPathsUnix.h - ) + list(APPEND SRC + intern/GHOST_SystemPathsUnix.cpp + intern/GHOST_SystemPathsUnix.h + ) - if(NOT WITH_INSTALL_PORTABLE) - add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}") - endif() + if(NOT WITH_INSTALL_PORTABLE) + add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}") + endif() elseif(WIN32) - list(APPEND SRC - intern/GHOST_SystemPathsWin32.cpp - intern/GHOST_SystemPathsWin32.h - ) - - list(APPEND INC - ../utfconv - ) + list(APPEND SRC + intern/GHOST_SystemPathsWin32.cpp + intern/GHOST_SystemPathsWin32.h + ) + + list(APPEND INC + ../utfconv + ) endif() diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index fbc0662ca4f..8bb6a670754 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -45,7 +45,6 @@ GHOST_DECLARE_HANDLE(GHOST_RectangleHandle); GHOST_DECLARE_HANDLE(GHOST_EventConsumerHandle); GHOST_DECLARE_HANDLE(GHOST_ContextHandle); - /** * Definition of a callback routine that receives events. * \param event The event received. @@ -53,7 +52,6 @@ GHOST_DECLARE_HANDLE(GHOST_ContextHandle); */ typedef int (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata); - /** * Creates the one and only system. * \return a handle to the system. @@ -67,14 +65,13 @@ extern GHOST_SystemHandle GHOST_CreateSystem(void); */ 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); +extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer( + GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata); /** * Disposes an event consumer object @@ -150,9 +147,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, * \return void. */ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height); - + GHOST_TUns32 *width, + GHOST_TUns32 *height); /** * Create a new window. @@ -169,16 +165,15 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, * \param glSettings: Misc OpenGL options. * \return A handle to the new window ( == NULL if creation failed). */ -extern GHOST_WindowHandle GHOST_CreateWindow( - GHOST_SystemHandle systemhandle, - const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - GHOST_GLSettings glSettings); +extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, + const char *title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + GHOST_GLSettings glSettings); /** * Create a new offscreen context. @@ -195,7 +190,7 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha * \return Indication of success. */ extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle, - GHOST_ContextHandle contexthandle); + GHOST_ContextHandle contexthandle); /** * Returns the window user data. @@ -209,8 +204,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl * \param windowhandle The handle to the window * \param userdata The window user data. */ -extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, - GHOST_TUserDataPtr userdata); +extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata); /** * Dispose a window. @@ -227,8 +221,7 @@ extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle, * \param windowhandle Handle to the window to be checked. * \return Indication of validity. */ -extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, - GHOST_WindowHandle windowhandle); +extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle); /** * Begins full screen mode. @@ -359,9 +352,12 @@ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle extern GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle, GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, - int sizex, int sizey, - int hotX, int hotY, - int fg_color, int bg_color); + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); /** * Returns the visibility state of the cursor. @@ -376,8 +372,7 @@ extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle); * \param visible The new visibility state of the cursor. * \return Indication of success. */ -extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, - int visible); +extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible); /** * Returns the current location of the cursor (location in screen coordinates) @@ -414,7 +409,8 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, - int bounds[4], const int mouse_ungrab_xy[2]); + int bounds[4], + const int mouse_ungrab_xy[2]); /*************************************************************************************** * Access to mouse button and keyboard states. @@ -454,7 +450,6 @@ extern GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle, extern void GHOST_setNDOFDeadZone(float deadzone); #endif - /*************************************************************************************** * Drag'n'drop operations ***************************************************************************************/ @@ -551,8 +546,7 @@ extern GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandl * \param windowhandle The handle to the window * \param title The title to display in the title bar. */ -extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, - const char *title); +extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title); /** * Returns the title displayed in the title bar. The title @@ -591,8 +585,7 @@ void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle); * \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); +extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width); /** * Resizes client rectangle height. @@ -600,8 +593,7 @@ extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, * \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); +extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height); /** * Resizes client rectangle. @@ -658,7 +650,6 @@ extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle); extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state); - /** * Sets the window "modified" status, indicating unsaved changes * \param windowhandle The handle to the window @@ -697,7 +688,7 @@ extern GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int * \param intervalOut pointer to location to return swap interval (left untouched if there is an error) * \return A boolean success indicator of if swap interval was successfully read. */ -extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut); +extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int *intervalOut); /** * Gets the current swap interval for swapBuffers. @@ -811,8 +802,7 @@ extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehand * \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); +extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i); /** * Does a union of the rectangle given and this rectangle. @@ -851,8 +841,8 @@ extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehan * \param anotherrectanglehandle The rectangle to test. * \return visibility (not, partially or fully visible). */ -extern GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle, - GHOST_RectangleHandle anotherrectanglehandle); +extern GHOST_TVisibility GHOST_GetRectangleVisibility( + GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle); /** * Sets rectangle members. @@ -906,8 +896,6 @@ extern GHOST_TUns8 *GHOST_getClipboard(int selection); */ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); - - /** * Toggles console * \param action @@ -920,7 +908,6 @@ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); */ extern int GHOST_toggleConsole(int action); - /** * Confirms quitting he program when there is just one window left open * in the application @@ -965,11 +952,11 @@ extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle); * false: Move the IME windows to the given position without finishing it. */ extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle, - GHOST_TInt32 x, - GHOST_TInt32 y, - GHOST_TInt32 w, - GHOST_TInt32 h, - int complete); + GHOST_TInt32 x, + GHOST_TInt32 y, + GHOST_TInt32 w, + GHOST_TInt32 h, + int complete); /** * Disable the IME attached to the given window, i.e. prohibits any user-input * events from being dispatched to the IME. diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h index 3bc18b9a6c7..a341e18ca0a 100644 --- a/intern/ghost/GHOST_IContext.h +++ b/intern/ghost/GHOST_IContext.h @@ -28,7 +28,6 @@ #include "STR_String.h" #include "GHOST_Types.h" - /** * Interface for GHOST context. * @@ -36,31 +35,30 @@ * GHOST_ISystem::createOffscreenContext method. * \see GHOST_ISystem#createOffscreenContext */ -class GHOST_IContext -{ -public: - /** - * Destructor. - */ - virtual ~GHOST_IContext() - { - } +class GHOST_IContext { + public: + /** + * Destructor. + */ + virtual ~GHOST_IContext() + { + } - /** - * Activates the drawing context. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess activateDrawingContext() = 0; + /** + * Activates the drawing context. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess activateDrawingContext() = 0; - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess releaseDrawingContext() = 0; + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess releaseDrawingContext() = 0; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext") #endif }; -#endif // __GHOST_IContext_H__ +#endif // __GHOST_IContext_H__ diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h index eadb29ef61c..fc7e563e1d8 100644 --- a/intern/ghost/GHOST_IEvent.h +++ b/intern/ghost/GHOST_IEvent.h @@ -40,44 +40,43 @@ class GHOST_IWindow; * \see GHOST_IEventConsumer#processEvent * \see GHOST_TEventType */ -class GHOST_IEvent -{ -public: - /** - * Destructor. - */ - virtual ~GHOST_IEvent() - { - } +class GHOST_IEvent { + public: + /** + * Destructor. + */ + virtual ~GHOST_IEvent() + { + } - /** - * Returns the event type. - * \return The event type. - */ - virtual GHOST_TEventType getType() = 0; + /** + * 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 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 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; + /** + * Returns the event data. + * \return The event data. + */ + virtual GHOST_TEventDataPtr getData() = 0; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent") #endif }; -#endif // __GHOST_IEVENT_H__ +#endif // __GHOST_IEVENT_H__ diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h index 1568a5e4600..d677a632a4b 100644 --- a/intern/ghost/GHOST_IEventConsumer.h +++ b/intern/ghost/GHOST_IEventConsumer.h @@ -35,27 +35,26 @@ * for every installed event consumer to pass events. * \see GHOST_ISystem#addEventConsumer */ -class GHOST_IEventConsumer -{ -public: - /** - * Destructor. - */ - virtual ~GHOST_IEventConsumer() - { - } +class GHOST_IEventConsumer { + public: + /** + * Destructor. + */ + virtual ~GHOST_IEventConsumer() + { + } - /** - * This method is called by the system when it has events to dispatch. - * \see GHOST_ISystem#dispatchEvents - * \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; + /** + * This method is called by the system when it has events to dispatch. + * \see GHOST_ISystem#dispatchEvents + * \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; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer") #endif }; -#endif /* __GHOST_IEVENTCONSUMER_H__ */ +#endif /* __GHOST_IEVENTCONSUMER_H__ */ diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index c640b016a5e..66e37a525c0 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -128,338 +128,343 @@ class GHOST_IEventConsumer; * -# Menus for windows with events generated when they are accessed (this is * work in progress). */ -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 = NULL) = 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; - - /** - * Returns the combine dimensions of all monitors. - * \return The dimension of the workspace. - */ - virtual void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. - * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent (embedder) 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, - GHOST_GLSettings glSettings, - const bool exclusive = false, - const GHOST_TEmbedderWindowID parentWindow = 0) = 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; - - /** - * Create a new offscreen context. - * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). - */ - virtual GHOST_IContext *createOffscreenContext() = 0; - - /** - * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. - */ - virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 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, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0) = 0; - - /** - * Updates the resolution while in fullscreen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. - * - * \return Indication of success. - */ - virtual GHOST_TSuccess updateFullScreen( - const GHOST_DisplaySetting& setting, GHOST_IWindow **window) = 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; - - /** - * Native pixel size support (MacBook 'retina'). - */ - virtual bool useNativePixel(void) = 0; - - /** - * Focus window after opening, or put them in the background. - */ - virtual void useWindowFocus(const bool use_focus) = 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. - */ - virtual void 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; - - /** - * Removes the given event consumer to our list. - * \param consumer The event consumer to remove. - * \return Indication of success. - */ - virtual GHOST_TSuccess removeEventConsumer(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) = 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; - - /** - * Set which tablet API to use. Only affects Windows, other platforms have a single API. - * \param api Enum indicating which API to use. - */ - virtual void setTabletAPI(GHOST_TTabletAPI api) = 0; +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 = NULL) = 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; + + /** + * Returns the combine dimensions of all monitors. + * \return The dimension of the workspace. + */ + virtual void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. + * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). + * \param parentWindow Parent (embedder) 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, + GHOST_GLSettings glSettings, + const bool exclusive = false, + const GHOST_TEmbedderWindowID parentWindow = 0) = 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; + + /** + * Create a new offscreen context. + * Never explicitly delete the context, use disposeContext() instead. + * \return The new context (or 0 if creation failed). + */ + virtual GHOST_IContext *createOffscreenContext() = 0; + + /** + * Dispose of a context. + * \param context Pointer to the context to be disposed. + * \return Indication of success. + */ + virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 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, + const bool alphaBackground = 0, + const GHOST_TUns16 numOfAASamples = 0) = 0; + + /** + * Updates the resolution while in fullscreen mode. + * \param setting The new setting of the display. + * \param window Window displayed in full screen. + * + * \return Indication of success. + */ + virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, + GHOST_IWindow **window) = 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; + + /** + * Native pixel size support (MacBook 'retina'). + */ + virtual bool useNativePixel(void) = 0; + + /** + * Focus window after opening, or put them in the background. + */ + virtual void useWindowFocus(const bool use_focus) = 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. + */ + virtual void 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; + + /** + * Removes the given event consumer to our list. + * \param consumer The event consumer to remove. + * \return Indication of success. + */ + virtual GHOST_TSuccess removeEventConsumer(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) = 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; + + /** + * Set which tablet API to use. Only affects Windows, other platforms have a single API. + * \param api Enum indicating which API to use. + */ + virtual void setTabletAPI(GHOST_TTabletAPI api) = 0; #ifdef WITH_INPUT_NDOF - /** - * Sets 3D mouse deadzone - * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range - */ - virtual void setNDOFDeadZone(float deadzone) = 0; + /** + * Sets 3D mouse deadzone + * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range + */ + virtual void setNDOFDeadZone(float deadzone) = 0; #endif - /** - * Toggles console - * \param action - * - 0: Hides - * - 1: Shows - * - 2: Toggles - * - 3: Hides if it runs not from command line - * - *: Does nothing - * \return current status (1 -visible, 0 - hidden) - */ - virtual int toggleConsole(int action) = 0; - - /*************************************************************************************** - * Access to clipboard. - ***************************************************************************************/ - - /** - * Returns the selection buffer - * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer - * - */ - virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; - - /** - * Put data to the Clipboard - */ - virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; - - /** - * Confirms quitting he program when there is just one window left open - * in the application - */ - virtual int confirmQuit(GHOST_IWindow *window) const = 0; - - /** - * Informs if the system provides native dialogs (eg. confirm quit) - */ - virtual bool supportsNativeDialogs(void) = 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; - + /** + * Toggles console + * \param action + * - 0: Hides + * - 1: Shows + * - 2: Toggles + * - 3: Hides if it runs not from command line + * - *: Does nothing + * \return current status (1 -visible, 0 - hidden) + */ + virtual int toggleConsole(int action) = 0; + + /*************************************************************************************** + * Access to clipboard. + ***************************************************************************************/ + + /** + * Returns the selection buffer + * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer + * + */ + virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; + + /** + * Put data to the Clipboard + */ + virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; + + /** + * Confirms quitting he program when there is just one window left open + * in the application + */ + virtual int confirmQuit(GHOST_IWindow *window) const = 0; + + /** + * Informs if the system provides native dialogs (eg. confirm quit) + */ + virtual bool supportsNativeDialogs(void) = 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; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem") #endif }; -#endif // __GHOST_ISYSTEM_H__ +#endif // __GHOST_ISYSTEM_H__ diff --git a/intern/ghost/GHOST_ISystemPaths.h b/intern/ghost/GHOST_ISystemPaths.h index 1b79613252d..297f6333a77 100644 --- a/intern/ghost/GHOST_ISystemPaths.h +++ b/intern/ghost/GHOST_ISystemPaths.h @@ -26,75 +26,75 @@ #include "GHOST_Types.h" -class GHOST_ISystemPaths -{ -public: - /** - * Creates the one and only system. - * \return An indication of success. - */ - static GHOST_TSuccess create(); - - /** - * Disposes the one and only system. - * \return An indication of success. - */ - static GHOST_TSuccess dispose(); - - /** - * Returns a pointer to the one and only system (nil if it hasn't been created). - * \return A pointer to the system. - */ - static GHOST_ISystemPaths *get(); - -protected: - /** - * Constructor. - * Protected default constructor to force use of static createSystem member. - */ - GHOST_ISystemPaths() { - } - - /** - * Destructor. - * Protected default constructor to force use of static dispose member. - */ - virtual ~GHOST_ISystemPaths() { - } - -public: - /** - * Determine the base dir in which shared resources are located. It will first try to use - * "unpack and run" path, then look for properly installed path, including versioning. - * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). - */ - virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; - - /** - * Determine the base dir in which user configuration is stored, including versioning. - * If needed, it will create the base directory. - * \return Unsigned char string pointing to user dir (eg ~/.blender/). - */ - virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; - - /** - * Determine the directory of the current binary - * \return Unsigned char string pointing to the binary dir - */ - virtual const GHOST_TUns8 *getBinaryDir() const = 0; - - /** - * Add the file to the operating system most recently used files - */ - virtual void addToSystemRecentFiles(const char *filename) const = 0; - -private: - /** The one and only system paths*/ - static GHOST_ISystemPaths *m_systemPaths; - +class GHOST_ISystemPaths { + public: + /** + * Creates the one and only system. + * \return An indication of success. + */ + static GHOST_TSuccess create(); + + /** + * Disposes the one and only system. + * \return An indication of success. + */ + static GHOST_TSuccess dispose(); + + /** + * Returns a pointer to the one and only system (nil if it hasn't been created). + * \return A pointer to the system. + */ + static GHOST_ISystemPaths *get(); + + protected: + /** + * Constructor. + * Protected default constructor to force use of static createSystem member. + */ + GHOST_ISystemPaths() + { + } + + /** + * Destructor. + * Protected default constructor to force use of static dispose member. + */ + virtual ~GHOST_ISystemPaths() + { + } + + public: + /** + * Determine the base dir in which shared resources are located. It will first try to use + * "unpack and run" path, then look for properly installed path, including versioning. + * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). + */ + virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; + + /** + * Determine the base dir in which user configuration is stored, including versioning. + * If needed, it will create the base directory. + * \return Unsigned char string pointing to user dir (eg ~/.blender/). + */ + virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; + + /** + * Determine the directory of the current binary + * \return Unsigned char string pointing to the binary dir + */ + virtual const GHOST_TUns8 *getBinaryDir() const = 0; + + /** + * Add the file to the operating system most recently used files + */ + virtual void addToSystemRecentFiles(const char *filename) const = 0; + + private: + /** The one and only system paths*/ + static GHOST_ISystemPaths *m_systemPaths; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystemPaths") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystemPaths") #endif }; diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h index 283bc49a84b..46f4fdbc303 100644 --- a/intern/ghost/GHOST_ITimerTask.h +++ b/intern/ghost/GHOST_ITimerTask.h @@ -27,7 +27,6 @@ #include "GHOST_Types.h" - /** * Interface for a timer task. * Timer tasks are created by the system and can be installed by the system. @@ -40,44 +39,42 @@ * \see GHOST_ISystem#installTimer * \see GHOST_TimerProcPtr */ -class GHOST_ITimerTask -{ -public: - /** - * Destructor. - */ - virtual ~GHOST_ITimerTask() - { - } - - /** - * Returns the timer callback. - * \return The timer callback. - */ - virtual GHOST_TimerProcPtr getTimerProc() const = 0; +class GHOST_ITimerTask { + public: + /** + * Destructor. + */ + virtual ~GHOST_ITimerTask() + { + } - /** - * Changes the timer callback. - * \param timerProc The timer callback. - */ - virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0; + /** + * Returns the timer callback. + * \return The timer callback. + */ + virtual GHOST_TimerProcPtr getTimerProc() const = 0; - /** - * Returns the timer user data. - * \return The timer user data. - */ - virtual GHOST_TUserDataPtr getUserData() const = 0; + /** + * Changes the timer callback. + * \param timerProc The timer callback. + */ + virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0; - /** - * Changes the time user data. - * \param userData: The timer user data. - */ - virtual void setUserData(const GHOST_TUserDataPtr userData) = 0; + /** + * Returns the timer user data. + * \return The timer user data. + */ + virtual GHOST_TUserDataPtr getUserData() const = 0; + /** + * Changes the time user data. + * \param userData: The timer user data. + */ + virtual void setUserData(const GHOST_TUserDataPtr userData) = 0; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ITimerTask") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ITimerTask") #endif }; -#endif // __GHOST_ITIMERTASK_H__ +#endif // __GHOST_ITIMERTASK_H__ diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 5236567b398..0b1b83c36a7 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -29,7 +29,6 @@ #include "GHOST_Rect.h" #include "GHOST_Types.h" - /** * Interface for GHOST windows. * @@ -44,316 +43,325 @@ * - The client rectangle coordinate system. The client rectangle of a window * is the area that is drawable by the application (excluding title bars etc.). */ -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 associated OS object/handle - * \return The associated OS object/handle - */ - virtual void *getOSWindow() const = 0; - - /** - * Returns the type of drawing context used in this window. - * \return The current type of drawing context. - */ - 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; - - /** - * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop - */ - virtual void setAcceptDragOperation(bool canAccept) = 0; - - /** - * Returns acceptance of the dropped object - * Usually called by the "object dropped" event handling function - */ - virtual bool canAcceptDragOperation() 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 window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not - * \return Indication of success. - */ - virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0; - - /** - * Gets the window "modified" status, indicating unsaved changes - * \return True if there are unsaved changes - */ - virtual bool getModifiedState() = 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; - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess setSwapInterval(int interval) = 0; - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut pointer to location to return swap interval (left untouched if there is an error) - * \return A boolean success indicator of if swap interval was successfully read. - */ - virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0; - - /** - * Gets the current swap interval for swapBuffers. - * \return Number of AA Samples (0 if there is no multisample buffer) - */ - virtual GHOST_TUns16 getNumOfAASamples() = 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. - */ - virtual GHOST_TUserDataPtr getUserData() const = 0; - - /** - * Changes the window user data. - * \param userData The window user data. - */ - virtual void setUserData(const GHOST_TUserDataPtr userData) = 0; - - /** - * Returns the tablet data (pressure etc). - * \return The tablet data (pressure etc). - */ - virtual const GHOST_TabletData *GetTabletData() = 0; - - /*************************************************************************************** - * Progress bar functionality - ***************************************************************************************/ - - /** - * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % - */ - virtual GHOST_TSuccess setProgressBar(float progress) = 0; - - /** - * Hides the progress bar in the icon - */ - virtual GHOST_TSuccess endProgressBar() = 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 cursorShape: 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; - - virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, int sizey, - int hotX, int hotY, - int fg_color, int bg_color) = 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; - - /** - * Grabs the cursor for a modal operation. - * \param grab The new grab state of the cursor. - * \return Indication of success. - */ - virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/, - GHOST_Rect * /*bounds*/, - GHOST_TInt32 /*mouse_ungrab_xy*/[2]) { return GHOST_kSuccess; } - - /** */ - virtual GHOST_TSuccess beginFullScreen() const = 0; - virtual GHOST_TSuccess endFullScreen() const = 0; - - virtual float getNativePixelSize(void) = 0; - - /** - * Returns the recommended DPI for this window. - * \return The recommended DPI for this window. - */ - virtual GHOST_TUns16 getDPIHint() = 0; +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 associated OS object/handle + * \return The associated OS object/handle + */ + virtual void *getOSWindow() const = 0; + + /** + * Returns the type of drawing context used in this window. + * \return The current type of drawing context. + */ + 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; + + /** + * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop + */ + virtual void setAcceptDragOperation(bool canAccept) = 0; + + /** + * Returns acceptance of the dropped object + * Usually called by the "object dropped" event handling function + */ + virtual bool canAcceptDragOperation() 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 window "modified" status, indicating unsaved changes + * \param isUnsavedChanges Unsaved changes or not + * \return Indication of success. + */ + virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0; + + /** + * Gets the window "modified" status, indicating unsaved changes + * \return True if there are unsaved changes + */ + virtual bool getModifiedState() = 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; + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess setSwapInterval(int interval) = 0; + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut pointer to location to return swap interval (left untouched if there is an error) + * \return A boolean success indicator of if swap interval was successfully read. + */ + virtual GHOST_TSuccess getSwapInterval(int &intervalOut) = 0; + + /** + * Gets the current swap interval for swapBuffers. + * \return Number of AA Samples (0 if there is no multisample buffer) + */ + virtual GHOST_TUns16 getNumOfAASamples() = 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. + */ + virtual GHOST_TUserDataPtr getUserData() const = 0; + + /** + * Changes the window user data. + * \param userData The window user data. + */ + virtual void setUserData(const GHOST_TUserDataPtr userData) = 0; + + /** + * Returns the tablet data (pressure etc). + * \return The tablet data (pressure etc). + */ + virtual const GHOST_TabletData *GetTabletData() = 0; + + /*************************************************************************************** + * Progress bar functionality + ***************************************************************************************/ + + /** + * Sets the progress bar value displayed in the window/application icon + * \param progress The progress % + */ + virtual GHOST_TSuccess setProgressBar(float progress) = 0; + + /** + * Hides the progress bar in the icon + */ + virtual GHOST_TSuccess endProgressBar() = 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 cursorShape: 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; + + virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color) = 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; + + /** + * Grabs the cursor for a modal operation. + * \param grab The new grab state of the cursor. + * \return Indication of success. + */ + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/, + GHOST_Rect * /*bounds*/, + GHOST_TInt32 /*mouse_ungrab_xy*/[2]) + { + return GHOST_kSuccess; + } + + /** */ + virtual GHOST_TSuccess beginFullScreen() const = 0; + virtual GHOST_TSuccess endFullScreen() const = 0; + + virtual float getNativePixelSize(void) = 0; + + /** + * Returns the recommended DPI for this window. + * \return The recommended DPI for this window. + */ + virtual GHOST_TUns16 getDPIHint() = 0; #ifdef WITH_INPUT_IME - /** - * Enable IME attached to the given window, i.e. allows user-input - * events to be dispatched to the IME. - * \param x Requested x-coordinate of the rectangle - * \param y Requested y-coordinate of the rectangle - * \param w Requested width of the rectangle - * \param h Requested height of the rectangle - * \param complete Whether or not to complete the ongoing composition - * true: Start a new composition - * false: Move the IME windows to the given position without finishing it. - */ - virtual void beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, - GHOST_TInt32 w, GHOST_TInt32 h, - int completed) = 0; - - /** - * Disable the IME attached to the given window, i.e. prohibits any user-input - * events from being dispatched to the IME. - */ - virtual void endIME() = 0; + /** + * Enable IME attached to the given window, i.e. allows user-input + * events to be dispatched to the IME. + * \param x Requested x-coordinate of the rectangle + * \param y Requested y-coordinate of the rectangle + * \param w Requested width of the rectangle + * \param h Requested height of the rectangle + * \param complete Whether or not to complete the ongoing composition + * true: Start a new composition + * false: Move the IME windows to the given position without finishing it. + */ + virtual void beginIME( + GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) = 0; + + /** + * Disable the IME attached to the given window, i.e. prohibits any user-input + * events from being dispatched to the IME. + */ + virtual void endIME() = 0; #endif /* WITH_INPUT_IME */ #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow") #endif }; -#endif // __GHOST_IWINDOW_H__ +#endif // __GHOST_IWINDOW_H__ diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h index 4cdfbf842fe..53abdf68bb4 100644 --- a/intern/ghost/GHOST_Path-api.h +++ b/intern/ghost/GHOST_Path-api.h @@ -21,7 +21,6 @@ * \ingroup GHOST */ - #ifndef __GHOST_PATH_API_H__ #define __GHOST_PATH_API_H__ @@ -58,7 +57,6 @@ extern const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr */ extern const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr); - /** * Determine the dir in which the binary file is found. * \return Unsigned char string pointing to binary dir (eg ~/usr/local/bin/). diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index 057b7fa37df..cd4eb936066 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -27,7 +27,6 @@ #include "GHOST_Types.h" - /** * Implements rectangle functionality. * The four extreme coordinates are stored as left, top, right and bottom. @@ -36,214 +35,230 @@ */ 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, empty 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); - - /** - * 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 wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs); - - /** - * 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; + 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, empty 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); + + /** + * 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 wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs); + + /** + * 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; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect") #endif }; - inline GHOST_TInt32 GHOST_Rect::getWidth() const { - return m_r - m_l; + return m_r - m_l; } inline GHOST_TInt32 GHOST_Rect::getHeight() const { - return m_b - m_t; + 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; + m_l = l; + m_t = t; + m_r = r; + m_b = b; } inline bool GHOST_Rect::isEmpty() const { - return (getWidth() == 0) || (getHeight() == 0); + return (getWidth() == 0) || (getHeight() == 0); } inline bool GHOST_Rect::isValid() const { - return (m_l <= m_r) && (m_t <= m_b); + return (m_l <= m_r) && (m_t <= m_b); } -inline void GHOST_Rect::unionRect(const GHOST_Rect& r) +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; + 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; + 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; } #include <stdio.h> inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs) { - GHOST_TInt32 w = getWidth(); - GHOST_TInt32 h = getHeight(); - - /* highly unlikely but avoid eternal loop */ - if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) { - return; - } - - while (x - ofs < m_l) x += w - (ofs * 2); - while (y - ofs < m_t) y += h - (ofs * 2); - while (x + ofs > m_r) x -= w - (ofs * 2); - while (y + ofs > m_b) y -= h - (ofs * 2); + GHOST_TInt32 w = getWidth(); + GHOST_TInt32 h = getHeight(); + + /* highly unlikely but avoid eternal loop */ + if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) { + return; + } + + while (x - ofs < m_l) + x += w - (ofs * 2); + while (y - ofs < m_t) + y += h - (ofs * 2); + while (x + ofs > m_r) + x -= w - (ofs * 2); + while (y + ofs > m_b) + y -= h - (ofs * 2); } 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); + return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b); } -#endif // __GHOST_RECT_H__ +#endif // __GHOST_RECT_H__ diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 8f6fd45d753..36678bcc913 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -21,18 +21,24 @@ * \ingroup GHOST */ - #ifndef __GHOST_TYPES_H__ #define __GHOST_TYPES_H__ #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif #if defined(WITH_CXX_GUARDEDALLOC) && defined(__cplusplus) -# define GHOST_DECLARE_HANDLE(name) typedef struct name##__ { int unused; MEM_CXX_CLASS_ALLOC_FUNCS(#name) } *name +# define GHOST_DECLARE_HANDLE(name) \ + typedef struct name##__ { \ + int unused; \ + MEM_CXX_CLASS_ALLOC_FUNCS(#name) \ + } * name #else -# define GHOST_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name +# define GHOST_DECLARE_HANDLE(name) \ + typedef struct name##__ { \ + int unused; \ + } * name #endif typedef char GHOST_TInt8; @@ -43,17 +49,16 @@ typedef int GHOST_TInt32; typedef unsigned int GHOST_TUns32; typedef struct { - GHOST_TUns16 numOfAASamples; - int flags; + GHOST_TUns16 numOfAASamples; + int flags; } GHOST_GLSettings; typedef enum { - GHOST_glStereoVisual = (1 << 0), - GHOST_glDebugContext = (1 << 1), - GHOST_glAlphaBackground = (1 << 2), + GHOST_glStereoVisual = (1 << 0), + GHOST_glDebugContext = (1 << 1), + GHOST_glAlphaBackground = (1 << 2), } GHOST_GLFlags; - #ifdef _MSC_VER typedef __int64 GHOST_TInt64; typedef unsigned __int64 GHOST_TUns64; @@ -64,10 +69,7 @@ typedef unsigned long long GHOST_TUns64; typedef void *GHOST_TUserDataPtr; -typedef enum { - GHOST_kFailure = 0, - GHOST_kSuccess -} GHOST_TSuccess; +typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess; /* Xtilt and Ytilt represent how much the pen is tilted away from * vertically upright in either the X or Y direction, with X and Y the @@ -77,469 +79,448 @@ typedef enum { * --Matt */ typedef enum { - GHOST_kTabletModeNone = 0, - GHOST_kTabletModeStylus, - GHOST_kTabletModeEraser + GHOST_kTabletModeNone = 0, + GHOST_kTabletModeStylus, + GHOST_kTabletModeEraser } GHOST_TTabletMode; typedef enum { - GHOST_kTabletAutomatic = 0, - GHOST_kTabletNative, - GHOST_kTabletWintab, + GHOST_kTabletAutomatic = 0, + GHOST_kTabletNative, + GHOST_kTabletWintab, } GHOST_TTabletAPI; typedef struct GHOST_TabletData { - GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */ - float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */ - float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */ - float Ytilt; /* as above */ + GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */ + float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */ + float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */ + float Ytilt; /* as above */ } GHOST_TabletData; - typedef enum { - GHOST_kNotVisible = 0, - GHOST_kPartiallyVisible, - GHOST_kFullyVisible + GHOST_kNotVisible = 0, + GHOST_kPartiallyVisible, + GHOST_kFullyVisible } GHOST_TVisibility; +typedef enum { GHOST_kFireTimeNever = 0xFFFFFFFF } GHOST_TFireTimeConstant; typedef enum { - GHOST_kFireTimeNever = 0xFFFFFFFF -} GHOST_TFireTimeConstant; - -typedef enum { - GHOST_kModifierKeyLeftShift = 0, - GHOST_kModifierKeyRightShift, - GHOST_kModifierKeyLeftAlt, - GHOST_kModifierKeyRightAlt, - GHOST_kModifierKeyLeftControl, - GHOST_kModifierKeyRightControl, - GHOST_kModifierKeyOS, - GHOST_kModifierKeyNumMasks + GHOST_kModifierKeyLeftShift = 0, + GHOST_kModifierKeyRightShift, + GHOST_kModifierKeyLeftAlt, + GHOST_kModifierKeyRightAlt, + GHOST_kModifierKeyLeftControl, + GHOST_kModifierKeyRightControl, + GHOST_kModifierKeyOS, + GHOST_kModifierKeyNumMasks } GHOST_TModifierKeyMask; - typedef enum { - GHOST_kWindowStateNormal = 0, - GHOST_kWindowStateMaximized, - GHOST_kWindowStateMinimized, - GHOST_kWindowStateFullScreen, - GHOST_kWindowStateEmbedded, - // GHOST_kWindowStateModified, - // GHOST_kWindowStateUnModified, + GHOST_kWindowStateNormal = 0, + GHOST_kWindowStateMaximized, + GHOST_kWindowStateMinimized, + GHOST_kWindowStateFullScreen, + GHOST_kWindowStateEmbedded, + // GHOST_kWindowStateModified, + // GHOST_kWindowStateUnModified, } GHOST_TWindowState; - /** Constants for the answer to the blender exit request */ -typedef enum { - GHOST_kExitCancel = 0, - GHOST_kExitNow -} GHOST_TExitRequestResponse; - -typedef enum { - GHOST_kWindowOrderTop = 0, - GHOST_kWindowOrderBottom -} GHOST_TWindowOrder; +typedef enum { GHOST_kExitCancel = 0, GHOST_kExitNow } GHOST_TExitRequestResponse; +typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWindowOrder; typedef enum { - GHOST_kDrawingContextTypeNone = 0, - GHOST_kDrawingContextTypeOpenGL + GHOST_kDrawingContextTypeNone = 0, + GHOST_kDrawingContextTypeOpenGL } GHOST_TDrawingContextType; - typedef enum { - GHOST_kButtonMaskLeft = 0, - GHOST_kButtonMaskMiddle, - GHOST_kButtonMaskRight, - GHOST_kButtonMaskButton4, - GHOST_kButtonMaskButton5, - /* Trackballs and programmable buttons */ - GHOST_kButtonMaskButton6, - GHOST_kButtonMaskButton7, - GHOST_kButtonNumMasks + GHOST_kButtonMaskLeft = 0, + GHOST_kButtonMaskMiddle, + GHOST_kButtonMaskRight, + GHOST_kButtonMaskButton4, + GHOST_kButtonMaskButton5, + /* Trackballs and programmable buttons */ + GHOST_kButtonMaskButton6, + GHOST_kButtonMaskButton7, + GHOST_kButtonNumMasks } GHOST_TButtonMask; - typedef enum { - GHOST_kEventUnknown = 0, + GHOST_kEventUnknown = 0, - GHOST_kEventCursorMove, /// Mouse move event - GHOST_kEventButtonDown, /// Mouse button event - GHOST_kEventButtonUp, /// Mouse button event - GHOST_kEventWheel, /// Mouse wheel event - GHOST_kEventTrackpad, /// Trackpad event + GHOST_kEventCursorMove, /// Mouse move event + GHOST_kEventButtonDown, /// Mouse button event + GHOST_kEventButtonUp, /// Mouse button event + GHOST_kEventWheel, /// Mouse wheel event + GHOST_kEventTrackpad, /// Trackpad event #ifdef WITH_INPUT_NDOF - GHOST_kEventNDOFMotion, /// N degree of freedom device motion event - GHOST_kEventNDOFButton, /// N degree of freedom device button event + GHOST_kEventNDOFMotion, /// N degree of freedom device motion event + GHOST_kEventNDOFButton, /// N degree of freedom device button event #endif - GHOST_kEventKeyDown, - GHOST_kEventKeyUp, -// GHOST_kEventKeyAuto, + GHOST_kEventKeyDown, + GHOST_kEventKeyUp, + // GHOST_kEventKeyAuto, - GHOST_kEventQuit, + GHOST_kEventQuit, - GHOST_kEventWindowClose, - GHOST_kEventWindowActivate, - GHOST_kEventWindowDeactivate, - GHOST_kEventWindowUpdate, - GHOST_kEventWindowSize, - GHOST_kEventWindowMove, - GHOST_kEventWindowDPIHintChanged, + GHOST_kEventWindowClose, + GHOST_kEventWindowActivate, + GHOST_kEventWindowDeactivate, + GHOST_kEventWindowUpdate, + GHOST_kEventWindowSize, + GHOST_kEventWindowMove, + GHOST_kEventWindowDPIHintChanged, - GHOST_kEventDraggingEntered, - GHOST_kEventDraggingUpdated, - GHOST_kEventDraggingExited, - GHOST_kEventDraggingDropDone, + GHOST_kEventDraggingEntered, + GHOST_kEventDraggingUpdated, + GHOST_kEventDraggingExited, + GHOST_kEventDraggingDropDone, - GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup - GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display + GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup + GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display - GHOST_kEventTimer, + GHOST_kEventTimer, - GHOST_kEventImeCompositionStart, - GHOST_kEventImeComposition, - GHOST_kEventImeCompositionEnd, + GHOST_kEventImeCompositionStart, + GHOST_kEventImeComposition, + GHOST_kEventImeCompositionEnd, - GHOST_kNumEventTypes + 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_kStandardCursorCopy, - GHOST_kStandardCursorCustom, - GHOST_kStandardCursorPencil, - - GHOST_kStandardCursorNumCursors + 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_kStandardCursorCopy, + GHOST_kStandardCursorCustom, + GHOST_kStandardCursorPencil, + + 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_kKeyPlus = '+', - 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_kKeyOS, // Command key on Apple, Windows key(s) on Windows - GHOST_kKeyGrLess, // German PC 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, - - // Multimedia keypad buttons - GHOST_kKeyMediaPlay, - GHOST_kKeyMediaStop, - GHOST_kKeyMediaFirst, - GHOST_kKeyMediaLast + 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_kKeyPlus = '+', + 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_kKeyOS, // Command key on Apple, Windows key(s) on Windows + GHOST_kKeyGrLess, // German PC 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, + + // Multimedia keypad buttons + GHOST_kKeyMediaPlay, + GHOST_kKeyMediaStop, + GHOST_kKeyMediaFirst, + GHOST_kKeyMediaLast } GHOST_TKey; typedef enum { - GHOST_kGrabDisable = 0, /* grab not set */ - GHOST_kGrabNormal, /* no cursor adjustments */ - GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */ - GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */ + GHOST_kGrabDisable = 0, /* grab not set */ + GHOST_kGrabNormal, /* no cursor adjustments */ + GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */ + GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */ } GHOST_TGrabCursorMode; 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; + /** 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; + /** The mask of the mouse button. */ + GHOST_TButtonMask button; } GHOST_TEventButtonData; typedef struct { - /** Displacement of a mouse wheel. */ - GHOST_TInt32 z; + /** Displacement of a mouse wheel. */ + GHOST_TInt32 z; } GHOST_TEventWheelData; typedef enum { - GHOST_kTrackpadEventUnknown = 0, - GHOST_kTrackpadEventScroll, - GHOST_kTrackpadEventRotate, - GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */ - GHOST_kTrackpadEventMagnify + GHOST_kTrackpadEventUnknown = 0, + GHOST_kTrackpadEventScroll, + GHOST_kTrackpadEventRotate, + GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */ + GHOST_kTrackpadEventMagnify } GHOST_TTrackpadEventSubTypes; - typedef struct { - /** The event subtype */ - GHOST_TTrackpadEventSubTypes subtype; - /** The x-location of the trackpad event */ - GHOST_TInt32 x; - /** The y-location of the trackpad event */ - GHOST_TInt32 y; - /** The x-delta or value of the trackpad event */ - GHOST_TInt32 deltaX; - /** The y-delta (currently only for scroll subtype) of the trackpad event */ - GHOST_TInt32 deltaY; + /** The event subtype */ + GHOST_TTrackpadEventSubTypes subtype; + /** The x-location of the trackpad event */ + GHOST_TInt32 x; + /** The y-location of the trackpad event */ + GHOST_TInt32 y; + /** The x-delta or value of the trackpad event */ + GHOST_TInt32 deltaX; + /** The y-delta (currently only for scroll subtype) of the trackpad event */ + GHOST_TInt32 deltaY; } GHOST_TEventTrackpadData; - typedef enum { - GHOST_kDragnDropTypeUnknown = 0, - GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */ - GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */ - GHOST_kDragnDropTypeBitmap /*Bitmap image data */ + GHOST_kDragnDropTypeUnknown = 0, + GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */ + GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */ + GHOST_kDragnDropTypeBitmap /*Bitmap image data */ } GHOST_TDragnDropTypes; typedef struct { - /** The x-coordinate of the cursor position. */ - GHOST_TInt32 x; - /** The y-coordinate of the cursor position. */ - GHOST_TInt32 y; - /** The dropped item type */ - GHOST_TDragnDropTypes dataType; - /** The "dropped content" */ - GHOST_TEventDataPtr data; + /** The x-coordinate of the cursor position. */ + GHOST_TInt32 x; + /** The y-coordinate of the cursor position. */ + GHOST_TInt32 y; + /** The dropped item type */ + GHOST_TDragnDropTypes dataType; + /** The "dropped content" */ + GHOST_TEventDataPtr data; } GHOST_TEventDragnDropData; /** similar to wmImeData */ typedef struct { - /** size_t */ - GHOST_TUserDataPtr result_len, composite_len; - /** char * utf8 encoding */ - GHOST_TUserDataPtr result, composite; - /** Cursor position in the IME composition. */ - int cursor_position; - /** Represents the position of the beginning of the selection */ - int target_start; - /** Represents the position of the end of the selection */ - int target_end; - /** custom temporal data */ - GHOST_TUserDataPtr tmp; + /** size_t */ + GHOST_TUserDataPtr result_len, composite_len; + /** char * utf8 encoding */ + GHOST_TUserDataPtr result, composite; + /** Cursor position in the IME composition. */ + int cursor_position; + /** Represents the position of the beginning of the selection */ + int target_start; + /** Represents the position of the end of the selection */ + int target_end; + /** custom temporal data */ + GHOST_TUserDataPtr tmp; } GHOST_TEventImeData; typedef struct { - int count; - GHOST_TUns8 **strings; + int count; + GHOST_TUns8 **strings; } GHOST_TStringArray; typedef enum { - GHOST_kNotStarted, - GHOST_kStarting, - GHOST_kInProgress, - GHOST_kFinishing, - GHOST_kFinished + GHOST_kNotStarted, + GHOST_kStarting, + GHOST_kInProgress, + GHOST_kFinishing, + GHOST_kFinished } GHOST_TProgress; #ifdef WITH_INPUT_NDOF typedef struct { - /** N-degree of freedom device data v3 [GSoC 2010] */ - // Each component normally ranges from -1 to +1, but can exceed that. - // These use blender standard view coordinates, with positive rotations being CCW about the axis. - float tx, ty, tz; // translation - float rx, ry, rz; // rotation: - // axis = (rx,ry,rz).normalized - // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] - float dt; // time since previous NDOF Motion event - GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers) + /** N-degree of freedom device data v3 [GSoC 2010] */ + // Each component normally ranges from -1 to +1, but can exceed that. + // These use blender standard view coordinates, with positive rotations being CCW about the axis. + float tx, ty, tz; // translation + float rx, ry, rz; // rotation: + // axis = (rx,ry,rz).normalized + // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] + float dt; // time since previous NDOF Motion event + GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers) } GHOST_TEventNDOFMotionData; typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction; // good for mouse or other buttons too, hmmm? typedef struct { - GHOST_TButtonAction action; - short button; + GHOST_TButtonAction action; + short button; } GHOST_TEventNDOFButtonData; -#endif // WITH_INPUT_NDOF +#endif // WITH_INPUT_NDOF typedef struct { - /** The key code. */ - GHOST_TKey key; - - /* ascii / utf8: both should always be set when possible, - * - ascii may be '\0' however if the user presses a non ascii key - * - unicode may not be set if the system has no unicode support - * - * These values are intended to be used as follows. - * For text input use unicode when available, fallback to ascii. - * For areas where unicode is not needed, number input for example, always - * use ascii, unicode is ignored - campbell. - */ - /** The ascii code for the key event ('\0' if none). */ - char ascii; - /** The unicode character. if the length is 6, not NULL terminated if all 6 are set */ - char utf8_buf[6]; + /** The key code. */ + GHOST_TKey key; + + /* ascii / utf8: both should always be set when possible, + * - ascii may be '\0' however if the user presses a non ascii key + * - unicode may not be set if the system has no unicode support + * + * These values are intended to be used as follows. + * For text input use unicode when available, fallback to ascii. + * For areas where unicode is not needed, number input for example, always + * use ascii, unicode is ignored - campbell. + */ + /** The ascii code for the key event ('\0' if none). */ + char ascii; + /** The unicode character. if the length is 6, not NULL terminated if all 6 are set */ + char utf8_buf[6]; } 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; + /** 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; - #ifdef _WIN32 -typedef void* GHOST_TEmbedderWindowID; -#endif // _WIN32 +typedef void *GHOST_TEmbedderWindowID; +#endif // _WIN32 #ifndef _WIN32 // I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h typedef int GHOST_TEmbedderWindowID; -#endif // _WIN32 +#endif // _WIN32 /** * A timer task callback routine. @@ -554,4 +535,4 @@ struct GHOST_TimerTaskHandle__; typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_TUns64 time); #endif -#endif // __GHOST_TYPES_H__ +#endif // __GHOST_TYPES_H__ diff --git a/intern/ghost/intern/GHOST_Buttons.cpp b/intern/ghost/intern/GHOST_Buttons.cpp index a470c7cfbd5..36205201176 100644 --- a/intern/ghost/intern/GHOST_Buttons.cpp +++ b/intern/ghost/intern/GHOST_Buttons.cpp @@ -21,51 +21,51 @@ * \ingroup GHOST */ - #include "GHOST_Buttons.h" - - GHOST_Buttons::GHOST_Buttons() { - clear(); + 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; - } + 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; - } + 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; + m_ButtonLeft = false; + m_ButtonMiddle = false; + m_ButtonRight = false; } -GHOST_Buttons::~GHOST_Buttons() { +GHOST_Buttons::~GHOST_Buttons() +{ } diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h index 0c6c5f89323..0b824739950 100644 --- a/intern/ghost/intern/GHOST_Buttons.h +++ b/intern/ghost/intern/GHOST_Buttons.h @@ -27,41 +27,40 @@ #include "GHOST_Types.h" - /** * This struct stores the state of the mouse buttons. * Buttons can be set using button masks. */ struct GHOST_Buttons { - /** - * Constructor. - */ - GHOST_Buttons(); + /** + * Constructor. + */ + GHOST_Buttons(); - ~GHOST_Buttons(); + ~GHOST_Buttons(); - /** - * Returns the state of a single button. - * \param mask Key button to return. - * \return The state of the button (pressed == true). - */ - bool get(GHOST_TButtonMask mask) const; + /** + * Returns the state of a single button. + * \param mask Key button to return. + * \return The state of the button (pressed == true). + */ + 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. - */ - void set(GHOST_TButtonMask mask, bool down); + /** + * Updates the state of a single button. + * \param mask Button state to update. + * \param down The new state of the button. + */ + void set(GHOST_TButtonMask mask, bool down); - /** - * Sets the state of all buttons to up. - */ - void clear(); + /** + * Sets the state of all buttons to up. + */ + void clear(); - GHOST_TUns8 m_ButtonLeft : 1; - GHOST_TUns8 m_ButtonMiddle : 1; - GHOST_TUns8 m_ButtonRight : 1; + GHOST_TUns8 m_ButtonLeft : 1; + GHOST_TUns8 m_ButtonMiddle : 1; + GHOST_TUns8 m_ButtonRight : 1; }; -#endif // __GHOST_BUTTONS_H__ +#endif // __GHOST_BUTTONS_H__ diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 24456b841da..8d9570a39f3 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -34,110 +34,97 @@ GHOST_SystemHandle GHOST_CreateSystem(void) { - GHOST_ISystem::createSystem(); - GHOST_ISystem *system = GHOST_ISystem::getSystem(); + GHOST_ISystem::createSystem(); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return (GHOST_SystemHandle)system; + return (GHOST_SystemHandle)system; } - - GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->disposeSystem(); + return system->disposeSystem(); } - GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata) { - return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer(eventCallback, userdata); + return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer(eventCallback, userdata); } - GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle) { - delete ((GHOST_CallbackEventConsumer *)consumerhandle); - return GHOST_kSuccess; + delete ((GHOST_CallbackEventConsumer *)consumerhandle); + return GHOST_kSuccess; } - GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->getMilliSeconds(); + 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; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return (GHOST_TimerTaskHandle) system->installTimer(delay, interval, timerproc, userdata); + 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; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle; - return system->removeTimer(timertask); + return system->removeTimer(timertask); } - - GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->getNumDisplays(); + return system->getNumDisplays(); } - - void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, GHOST_TUns32 *width, GHOST_TUns32 *height) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - system->getMainDisplayDimensions(*width, *height); + system->getMainDisplayDimensions(*width, *height); } void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height) + GHOST_TUns32 *width, + GHOST_TUns32 *height) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - system->getAllDisplayDimensions(*width, *height); + system->getAllDisplayDimensions(*width, *height); } GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return (GHOST_ContextHandle) system->createOffscreenContext(); + return (GHOST_ContextHandle)system->createOffscreenContext(); } GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle, - GHOST_ContextHandle contexthandle) + GHOST_ContextHandle contexthandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; - GHOST_IContext *context = (GHOST_IContext *) contexthandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_IContext *context = (GHOST_IContext *)contexthandle; - return system->disposeContext(context); + return system->disposeContext(context); } GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, @@ -150,146 +137,131 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height, - state, type, glSettings, false); + return (GHOST_WindowHandle)system->createWindow( + title, left, top, width, height, state, type, glSettings, false); } GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getUserData(); + return window->getUserData(); } void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - window->setUserData(userdata); + 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; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return system->disposeWindow(window); + return system->disposeWindow(window); } - - -int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, - GHOST_WindowHandle windowhandle) +int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return (int) system->validWindow(window); + 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; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_IWindow *window = NULL; + bool bstereoVisual; - if (stereoVisual) - bstereoVisual = true; - else - bstereoVisual = false; + if (stereoVisual) + bstereoVisual = true; + else + bstereoVisual = false; - system->beginFullScreen(*setting, &window, bstereoVisual); + system->beginFullScreen(*setting, &window, bstereoVisual); - return (GHOST_WindowHandle)window; + return (GHOST_WindowHandle)window; } - - GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->endFullScreen(); + return system->endFullScreen(); } - - int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return (int) system->getFullScreen(); + return (int)system->getFullScreen(); } - - int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return (int) system->processEvents(waitForEvent ? true : false); + return (int)system->processEvents(waitForEvent ? true : false); } - - void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - system->dispatchEvents(); + system->dispatchEvents(); } - -GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle) +GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, + GHOST_EventConsumerHandle consumerhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle); + return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle); } -GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle) +GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle, + GHOST_EventConsumerHandle consumerhandle) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->removeEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle); + return system->removeEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle); } GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, float progress) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setProgressBar(progress); + return window->setProgressBar(progress); } GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->endProgressBar(); + return window->endProgressBar(); } - GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getCursorShape(); + return window->getCursorShape(); } - - GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle, GHOST_TStandardCursor cursorshape) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setCursorShape(cursorshape); + return window->setCursorShape(cursorshape); } GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, @@ -298,9 +270,9 @@ GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, int hotX, int hotY) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setCustomCursorShape(bitmap, mask, hotX, hotY); + return window->setCustomCursorShape(bitmap, mask, hotX, hotY); } GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle, @@ -313,664 +285,571 @@ GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle, int fg_color, int bg_color) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setCustomCursorShape(bitmap, mask, sizex, sizey, - hotX, hotY, fg_color, bg_color); + return window->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color); } - - int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return (int) window->getCursorVisibility(); + return (int)window->getCursorVisibility(); } - - -GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, - int visible) +GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setCursorVisibility(visible ? true : false); + 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; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->getCursorPosition(*x, *y); + return system->getCursorPosition(*x, *y); } - - GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TInt32 x, GHOST_TInt32 y) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; - return system->setCursorPosition(x, y); + return system->setCursorPosition(x, y); } - GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, - int bounds[4], const int mouse_ungrab_xy[2]) + int bounds[4], + const int mouse_ungrab_xy[2]) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect bounds_rect; - GHOST_TInt32 mouse_xy[2]; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + GHOST_Rect bounds_rect; + GHOST_TInt32 mouse_xy[2]; - if (bounds) { - bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); - } - if (mouse_ungrab_xy) { - mouse_xy[0] = mouse_ungrab_xy[0]; - mouse_xy[1] = mouse_ungrab_xy[1]; - } + if (bounds) { + bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); + } + if (mouse_ungrab_xy) { + mouse_xy[0] = mouse_ungrab_xy[0]; + mouse_xy[1] = mouse_ungrab_xy[1]; + } - return window->setCursorGrab(mode, - bounds ? &bounds_rect : NULL, - mouse_ungrab_xy ? mouse_xy : NULL); + return window->setCursorGrab( + mode, bounds ? &bounds_rect : NULL, mouse_ungrab_xy ? mouse_xy : NULL); } - GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, GHOST_TModifierKeyMask mask, int *isDown) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; - GHOST_TSuccess result; - bool isdown = false; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_TSuccess result; + bool isdown = false; - result = system->getModifierKeyState(mask, isdown); - *isDown = (int) isdown; + result = system->getModifierKeyState(mask, isdown); + *isDown = (int)isdown; - return result; + 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 = false; + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_TSuccess result; + bool isdown = false; - result = system->getButtonState(mask, isdown); - *isDown = (int) isdown; + result = system->getButtonState(mask, isdown); + *isDown = (int)isdown; - return result; + return result; } - #ifdef WITH_INPUT_NDOF void GHOST_setNDOFDeadZone(float deadzone) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - system->setNDOFDeadZone(deadzone); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + system->setNDOFDeadZone(deadzone); } #endif void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 canAccept) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - window->setAcceptDragOperation(canAccept); + window->setAcceptDragOperation(canAccept); } - GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle) { - GHOST_IEvent *event = (GHOST_IEvent *) eventhandle; + GHOST_IEvent *event = (GHOST_IEvent *)eventhandle; - return event->getType(); + return event->getType(); } - - GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle) { - GHOST_IEvent *event = (GHOST_IEvent *) eventhandle; + GHOST_IEvent *event = (GHOST_IEvent *)eventhandle; - return event->getTime(); + return event->getTime(); } - GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle) { - GHOST_IEvent *event = (GHOST_IEvent *) eventhandle; + GHOST_IEvent *event = (GHOST_IEvent *)eventhandle; - return (GHOST_WindowHandle) event->getWindow(); + return (GHOST_WindowHandle)event->getWindow(); } - GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle) { - GHOST_IEvent *event = (GHOST_IEvent *) eventhandle; + GHOST_IEvent *event = (GHOST_IEvent *)eventhandle; - return event->getData(); + return event->getData(); } - - GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle) { - GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle; + GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle; - return timertask->getTimerProc(); + return timertask->getTimerProc(); } - - -void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, - GHOST_TimerProcPtr timerproc) +void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, GHOST_TimerProcPtr timerproc) { - GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle; + GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle; - timertask->setTimerProc(timerproc); + timertask->setTimerProc(timerproc); } - - GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle) { - GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle; + GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle; - return timertask->getUserData(); + return timertask->getUserData(); } - - -void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, - GHOST_TUserDataPtr userdata) +void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUserDataPtr userdata) { - GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle; + GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle; - timertask->setUserData(userdata); + timertask->setUserData(userdata); } - - int GHOST_GetValid(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return (int) window->getValid(); + return (int)window->getValid(); } - - GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getDrawingContextType(); + return window->getDrawingContextType(); } - - GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle, GHOST_TDrawingContextType type) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setDrawingContextType(type); + return window->setDrawingContextType(type); } - - -void GHOST_SetTitle(GHOST_WindowHandle windowhandle, - const char *title) +void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - window->setTitle(title); + window->setTitle(title); } - char *GHOST_GetTitle(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - STR_String title; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + STR_String title; - window->getTitle(title); + window->getTitle(title); - char *ctitle = (char *) malloc(title.Length() + 1); + char *ctitle = (char *)malloc(title.Length() + 1); - if (ctitle == NULL) { - return NULL; - } + if (ctitle == NULL) { + return NULL; + } - strcpy(ctitle, title.Ptr()); + strcpy(ctitle, title.Ptr()); - return ctitle; + return ctitle; } - - GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect *rectangle = NULL; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + GHOST_Rect *rectangle = NULL; - rectangle = new GHOST_Rect(); - window->getWindowBounds(*rectangle); + rectangle = new GHOST_Rect(); + window->getWindowBounds(*rectangle); - return (GHOST_RectangleHandle)rectangle; + return (GHOST_RectangleHandle)rectangle; } - - GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect *rectangle = NULL; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + GHOST_Rect *rectangle = NULL; - rectangle = new GHOST_Rect(); - window->getClientBounds(*rectangle); + rectangle = new GHOST_Rect(); + window->getClientBounds(*rectangle); - return (GHOST_RectangleHandle)rectangle; + return (GHOST_RectangleHandle)rectangle; } - - void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle) { - delete (GHOST_Rect *) rectanglehandle; + delete (GHOST_Rect *)rectanglehandle; } - - -GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, - GHOST_TUns32 width) +GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setClientWidth(width); + return window->setClientWidth(width); } - - -GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, - GHOST_TUns32 height) +GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setClientHeight(height); + return window->setClientHeight(height); } - - GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, GHOST_TUns32 width, GHOST_TUns32 height) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setClientSize(width, height); + 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; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - window->screenToClient(inX, inY, *outX, *outY); + 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; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - window->clientToScreen(inX, inY, *outX, *outY); + window->clientToScreen(inX, inY, *outX, *outY); } - - GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getState(); + return window->getState(); } - - -GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, - GHOST_TWindowState state) +GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setState(state); + return window->setState(state); } - -GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges) +GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, + GHOST_TUns8 isUnsavedChanges) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setModifiedState(isUnsavedChanges); + return window->setModifiedState(isUnsavedChanges); } - -GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, - GHOST_TWindowOrder order) +GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, GHOST_TWindowOrder order) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setOrder(order); + return window->setOrder(order); } - - GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->swapBuffers(); + return window->swapBuffers(); } GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int interval) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->setSwapInterval(interval); + return window->setSwapInterval(interval); } -GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut) +GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int *intervalOut) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getSwapInterval(*intervalOut); + return window->getSwapInterval(*intervalOut); } - GHOST_TUns16 GHOST_GetNumOfAASamples(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getNumOfAASamples(); + return window->getNumOfAASamples(); } GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->activateDrawingContext(); + return window->activateDrawingContext(); } GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle) { - GHOST_IContext *context = (GHOST_IContext *) contexthandle; + GHOST_IContext *context = (GHOST_IContext *)contexthandle; - return context->activateDrawingContext(); + return context->activateDrawingContext(); } GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle) { - GHOST_IContext *context = (GHOST_IContext *) contexthandle; + GHOST_IContext *context = (GHOST_IContext *)contexthandle; - return context->releaseDrawingContext(); + return context->releaseDrawingContext(); } GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->invalidate(); + return window->invalidate(); } void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api) { - GHOST_ISystem *system = (GHOST_ISystem *) systemhandle; - system->setTabletAPI(api); + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + system->setTabletAPI(api); } const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle) { - return ((GHOST_IWindow *)windowhandle)->GetTabletData(); + return ((GHOST_IWindow *)windowhandle)->GetTabletData(); } - GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle) { - return ((GHOST_Rect *)rectanglehandle)->getWidth(); + return ((GHOST_Rect *)rectanglehandle)->getWidth(); } - - GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle) { - return ((GHOST_Rect *)rectanglehandle)->getHeight(); + 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; + GHOST_Rect *rect = (GHOST_Rect *)rectanglehandle; - *l = rect->m_l; - *t = rect->m_t; - *r = rect->m_r; - *b = rect->m_b; + *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_Rect *)rectanglehandle)->set(l, t, r, b); } - - GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle) { - GHOST_TSuccess result = GHOST_kFailure; + GHOST_TSuccess result = GHOST_kFailure; - if (((GHOST_Rect *)rectanglehandle)->isEmpty()) - result = GHOST_kSuccess; + if (((GHOST_Rect *)rectanglehandle)->isEmpty()) + result = GHOST_kSuccess; - return result; + return result; } - - GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle) { - GHOST_TSuccess result = GHOST_kFailure; + GHOST_TSuccess result = GHOST_kFailure; - if (((GHOST_Rect *)rectanglehandle)->isValid()) - result = GHOST_kSuccess; + if (((GHOST_Rect *)rectanglehandle)->isValid()) + result = GHOST_kSuccess; - return result; + return result; } - - -void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 i) +void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i) { - ((GHOST_Rect *)rectanglehandle)->inset(i); + ((GHOST_Rect *)rectanglehandle)->inset(i); } - - void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle) { - ((GHOST_Rect *)rectanglehandle)->unionRect(*(GHOST_Rect *)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_Rect *)rectanglehandle)->unionPoint(x, y); } - - GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 x, GHOST_TInt32 y) { - GHOST_TSuccess result = GHOST_kFailure; + GHOST_TSuccess result = GHOST_kFailure; - if (((GHOST_Rect *)rectanglehandle)->isInside(x, y)) - result = GHOST_kSuccess; + if (((GHOST_Rect *)rectanglehandle)->isInside(x, y)) + result = GHOST_kSuccess; - return result; + return result; } - - GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle) { - GHOST_TVisibility visible = GHOST_kNotVisible; + GHOST_TVisibility visible = GHOST_kNotVisible; - visible = ((GHOST_Rect *)rectanglehandle)->getVisibility(*(GHOST_Rect *)anotherrectanglehandle); + visible = ((GHOST_Rect *)rectanglehandle)->getVisibility(*(GHOST_Rect *)anotherrectanglehandle); - return visible; + return visible; } - - void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 cx, GHOST_TInt32 cy) { - ((GHOST_Rect *)rectanglehandle)->setCenter(cx, 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_Rect *)rectanglehandle)->setCenter(cx, cy, w, h); } - - GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle) { - GHOST_TSuccess result = GHOST_kFailure; + GHOST_TSuccess result = GHOST_kFailure; - if (((GHOST_Rect *)rectanglehandle)->clip(*(GHOST_Rect *)anotherrectanglehandle)) - result = GHOST_kSuccess; + if (((GHOST_Rect *)rectanglehandle)->clip(*(GHOST_Rect *)anotherrectanglehandle)) + result = GHOST_kSuccess; - return result; + return result; } GHOST_TUns8 *GHOST_getClipboard(int selection) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->getClipboard(selection); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->getClipboard(selection); } void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - system->putClipboard(buffer, selection); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + system->putClipboard(buffer, selection); } int GHOST_toggleConsole(int action) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->toggleConsole(action); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->toggleConsole(action); } int GHOST_SupportsNativeDialogs(void) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->supportsNativeDialogs(); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->supportsNativeDialogs(); } int GHOST_confirmQuit(GHOST_WindowHandle windowhandle) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->confirmQuit((GHOST_IWindow *) windowhandle); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->confirmQuit((GHOST_IWindow *)windowhandle); } int GHOST_UseNativePixels(void) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->useNativePixel(); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->useNativePixel(); } void GHOST_UseWindowFocus(int use_focus) { - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->useWindowFocus(use_focus); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->useWindowFocus(use_focus); } float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - if (window) - return window->getNativePixelSize(); - return 1.0f; + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + if (window) + return window->getNativePixelSize(); + return 1.0f; } GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; - return window->getDPIHint(); + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + return window->getDPIHint(); } #ifdef WITH_INPUT_IME void GHOST_BeginIME(GHOST_WindowHandle windowhandle, - GHOST_TInt32 x, GHOST_TInt32 y, - GHOST_TInt32 w, GHOST_TInt32 h, + GHOST_TInt32 x, + GHOST_TInt32 y, + GHOST_TInt32 w, + GHOST_TInt32 h, int complete) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - window->beginIME(x, y, w, h, complete); + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + window->beginIME(x, y, w, h, complete); } void GHOST_EndIME(GHOST_WindowHandle windowhandle) { - GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - window->endIME(); + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + window->endIME(); } -#endif /* WITH_INPUT_IME */ +#endif /* WITH_INPUT_IME */ diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp index a73931f48e9..843c8adc6cb 100644 --- a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp +++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -33,12 +32,11 @@ GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userData) { - m_eventCallback = eventCallback; - m_userData = userData; + m_eventCallback = eventCallback; + m_userData = userData; } - bool GHOST_CallbackEventConsumer::processEvent(GHOST_IEvent *event) { - return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0; + return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0; } diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h index 46f983f2dff..7abe0253f75 100644 --- a/intern/ghost/intern/GHOST_CallbackEventConsumer.h +++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h @@ -32,41 +32,39 @@ * Event consumer that will forward events to a call-back routine. * Especially useful for the C-API. */ -class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer -{ -public: - /** - * Constructor. - * \param eventCallback The call-back routine invoked. - * \param userData The data passed back though the call-back routine. - */ - GHOST_CallbackEventConsumer( - GHOST_EventCallbackProcPtr eventCallback, - GHOST_TUserDataPtr userData); +class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer { + public: + /** + * Constructor. + * \param eventCallback The call-back routine invoked. + * \param userData The data passed back though the call-back routine. + */ + GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback, + GHOST_TUserDataPtr userData); - /** - * Destructor. - */ - ~GHOST_CallbackEventConsumer(void) - { - } + /** + * Destructor. + */ + ~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. - */ - bool processEvent(GHOST_IEvent *event); + /** + * 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. + */ + bool processEvent(GHOST_IEvent *event); -protected: - /** The call-back routine invoked. */ - GHOST_EventCallbackProcPtr m_eventCallback; - /** The data passed back though the call-back routine. */ - GHOST_TUserDataPtr m_userData; + protected: + /** The call-back routine invoked. */ + GHOST_EventCallbackProcPtr m_eventCallback; + /** The data passed back though the call-back routine. */ + GHOST_TUserDataPtr m_userData; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_CallbackEventConsumer") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_CallbackEventConsumer") #endif }; -#endif // __GHOST_CALLBACKEVENTCONSUMER_H__ +#endif // __GHOST_CALLBACKEVENTCONSUMER_H__ diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp index 0aae38eed2c..0d167209909 100644 --- a/intern/ghost/intern/GHOST_Context.cpp +++ b/intern/ghost/intern/GHOST_Context.cpp @@ -26,7 +26,7 @@ #include "GHOST_Context.h" #ifdef _WIN32 -# include <GL/wglew.h> // only for symbolic constants, do not use API functions +# include <GL/wglew.h> // only for symbolic constants, do not use API functions # include <tchar.h> # # ifndef ERROR_PROFILE_DOES_NOT_MATCH_DEVICE @@ -37,123 +37,115 @@ #include <cstdio> #include <cstring> - #ifdef _WIN32 bool win32_silent_chk(bool result) { - if (!result) { - SetLastError(NO_ERROR); - } + if (!result) { + SetLastError(NO_ERROR); + } - return result; + return result; } bool win32_chk(bool result, const char *file, int line, const char *text) { - if (!result) { - LPTSTR formattedMsg = NULL; - - DWORD error = GetLastError(); - - const char *msg; - - DWORD count = 0; - - /* Some drivers returns a HRESULT instead of a standard error message. - * i.e: 0xC0072095 instead of 0x2095 for ERROR_INVALID_VERSION_ARB - * So strip down the error to the valid error code range. */ - switch (error & 0x0000FFFF) { - case ERROR_INVALID_VERSION_ARB: - msg = "The specified OpenGL version and feature set are either invalid or not supported.\n"; - break; - - case ERROR_INVALID_PROFILE_ARB: - msg = "The specified OpenGL profile and feature set are either invalid or not supported.\n"; - break; - - case ERROR_INVALID_PIXEL_TYPE_ARB: - msg = "The specified pixel type is invalid.\n"; - break; - - case ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB: - msg = ("The device contexts specified are not compatible. " - "This can occur if the device contexts are managed by " - "different drivers or possibly on different graphics adapters.\n"); - break; - -#ifdef WITH_GLEW_ES - case ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV: - msg = "The device context(s) and rendering context have non-matching affinity masks.\n"; - break; - - case ERROR_MISSING_AFFINITY_MASK_NV: - msg = "The rendering context does not have an affinity mask set.\n"; - break; -#endif + if (!result) { + LPTSTR formattedMsg = NULL; + + DWORD error = GetLastError(); + + const char *msg; + + DWORD count = 0; + + /* Some drivers returns a HRESULT instead of a standard error message. + * i.e: 0xC0072095 instead of 0x2095 for ERROR_INVALID_VERSION_ARB + * So strip down the error to the valid error code range. */ + switch (error & 0x0000FFFF) { + case ERROR_INVALID_VERSION_ARB: + msg = + "The specified OpenGL version and feature set are either invalid or not supported.\n"; + break; + + case ERROR_INVALID_PROFILE_ARB: + msg = + "The specified OpenGL profile and feature set are either invalid or not supported.\n"; + break; + + case ERROR_INVALID_PIXEL_TYPE_ARB: + msg = "The specified pixel type is invalid.\n"; + break; + + case ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB: + msg = + ("The device contexts specified are not compatible. " + "This can occur if the device contexts are managed by " + "different drivers or possibly on different graphics adapters.\n"); + break; + +# ifdef WITH_GLEW_ES + case ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV: + msg = "The device context(s) and rendering context have non-matching affinity masks.\n"; + break; + + case ERROR_MISSING_AFFINITY_MASK_NV: + msg = "The rendering context does not have an affinity mask set.\n"; + break; +# endif - case ERROR_PROFILE_DOES_NOT_MATCH_DEVICE: - msg = ("The specified profile is intended for a device of a " - "different type than the specified device.\n"); - break; - - default: - { - count = - FormatMessage( - (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS), - NULL, - error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)(&formattedMsg), - 0, - NULL); - - msg = count > 0 ? formattedMsg : "<no system message>\n"; - break; - } - } - -#ifndef NDEBUG - _ftprintf( - stderr, - "%s(%d):[%s] -> Win32 Error# (%lu): %s", - file, - line, - text, - (unsigned long)error, - msg); -#else - _ftprintf( - stderr, - "Win32 Error# (%lu): %s", - (unsigned long)error, - msg); -#endif + case ERROR_PROFILE_DOES_NOT_MATCH_DEVICE: + msg = + ("The specified profile is intended for a device of a " + "different type than the specified device.\n"); + break; + + default: { + count = FormatMessage((FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)(&formattedMsg), + 0, + NULL); + + msg = count > 0 ? formattedMsg : "<no system message>\n"; + break; + } + } + +# ifndef NDEBUG + _ftprintf(stderr, + "%s(%d):[%s] -> Win32 Error# (%lu): %s", + file, + line, + text, + (unsigned long)error, + msg); +# else + _ftprintf(stderr, "Win32 Error# (%lu): %s", (unsigned long)error, msg); +# endif - SetLastError(NO_ERROR); + SetLastError(NO_ERROR); - if (count != 0) - LocalFree(formattedMsg); - } + if (count != 0) + LocalFree(formattedMsg); + } - return result; + return result; } -#endif // _WIN32 - +#endif // _WIN32 void GHOST_Context::initContextGLEW() { - GLEW_CHK(glewInit()); + GLEW_CHK(glewInit()); } - void GHOST_Context::initClearGL() { - glClearColor(0.447, 0.447, 0.447, 0.000); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.000, 0.000, 0.000, 0.000); + glClearColor(0.447, 0.447, 0.447, 0.000); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0.000, 0.000, 0.000, 0.000); } diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h index decafd10b75..ed7b63aa436 100644 --- a/intern/ghost/intern/GHOST_Context.h +++ b/intern/ghost/intern/GHOST_Context.h @@ -30,126 +30,128 @@ #include "glew-mx.h" -#include <cstdlib> // for NULL - - -class GHOST_Context : public GHOST_IContext -{ -public: - /** - * Constructor. - * \param stereoVisual Stereo visual for quad buffered stereo. - * \param numOfAASamples Number of samples used for AA (zero if no AA) - */ - GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples) - : m_stereoVisual(stereoVisual), - m_numOfAASamples(numOfAASamples) - {} - - /** - * Destructor. - */ - virtual ~GHOST_Context() { - } - - /** - * 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; - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess releaseDrawingContext()= 0; - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - virtual GHOST_TSuccess initializeDrawingContext() = 0; - - /** - * Updates the drawing context of this window. Needed - * whenever the window is changed. - * \return Indication of success. - */ - virtual GHOST_TSuccess updateDrawingContext() { - return GHOST_kFailure; - } - - /** - * Checks if it is OK for a remove the native display - * \return Indication as to whether removal has succeeded. - */ - virtual GHOST_TSuccess releaseNativeHandles() = 0; - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess setSwapInterval(int /*interval*/) { - return GHOST_kFailure; - } - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - virtual GHOST_TSuccess getSwapInterval(int&) { - return GHOST_kFailure; - } - - /** - * Stereo visual created. Only necessary for 'real' stereo support, - * ie quad buffered stereo. This is not always possible, depends on - * the graphics h/w - */ - inline bool isStereoVisual() const { - return m_stereoVisual; - } - - /** Number of samples used in anti-aliasing, set to 0 if no AA */ - inline GHOST_TUns16 getNumOfAASamples() const { - return m_numOfAASamples; - } - -protected: - void initContextGLEW(); - - bool m_stereoVisual; - - GHOST_TUns16 m_numOfAASamples; - - static void initClearGL(); +#include <cstdlib> // for NULL + +class GHOST_Context : public GHOST_IContext { + public: + /** + * Constructor. + * \param stereoVisual Stereo visual for quad buffered stereo. + * \param numOfAASamples Number of samples used for AA (zero if no AA) + */ + GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples) + : m_stereoVisual(stereoVisual), m_numOfAASamples(numOfAASamples) + { + } + + /** + * Destructor. + */ + virtual ~GHOST_Context() + { + } + + /** + * 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; + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess releaseDrawingContext() = 0; + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + virtual GHOST_TSuccess initializeDrawingContext() = 0; + + /** + * Updates the drawing context of this window. Needed + * whenever the window is changed. + * \return Indication of success. + */ + virtual GHOST_TSuccess updateDrawingContext() + { + return GHOST_kFailure; + } + + /** + * Checks if it is OK for a remove the native display + * \return Indication as to whether removal has succeeded. + */ + virtual GHOST_TSuccess releaseNativeHandles() = 0; + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess setSwapInterval(int /*interval*/) + { + return GHOST_kFailure; + } + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + virtual GHOST_TSuccess getSwapInterval(int &) + { + return GHOST_kFailure; + } + + /** + * Stereo visual created. Only necessary for 'real' stereo support, + * ie quad buffered stereo. This is not always possible, depends on + * the graphics h/w + */ + inline bool isStereoVisual() const + { + return m_stereoVisual; + } + + /** Number of samples used in anti-aliasing, set to 0 if no AA */ + inline GHOST_TUns16 getNumOfAASamples() const + { + return m_numOfAASamples; + } + + protected: + void initContextGLEW(); + + bool m_stereoVisual; + + GHOST_TUns16 m_numOfAASamples; + + static void initClearGL(); #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context") #endif }; - #ifdef _WIN32 bool win32_chk(bool result, const char *file = NULL, int line = 0, const char *text = NULL); bool win32_silent_chk(bool result); # ifndef NDEBUG -# define WIN32_CHK(x) win32_chk((x), __FILE__, __LINE__, #x) +# define WIN32_CHK(x) win32_chk((x), __FILE__, __LINE__, # x) # else # define WIN32_CHK(x) win32_chk(x) # endif -#define WIN32_CHK_SILENT(x, silent) ((silent) ? win32_silent_chk(x) : WIN32_CHK(x)) -#endif /* _WIN32 */ - +# define WIN32_CHK_SILENT(x, silent) ((silent) ? win32_silent_chk(x) : WIN32_CHK(x)) +#endif /* _WIN32 */ -#endif // __GHOST_CONTEXT_H__ +#endif // __GHOST_CONTEXT_H__ diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index 13125e39f30..648af1cc9c7 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -27,107 +27,103 @@ #include "GHOST_Context.h" #ifndef GHOST_OPENGL_CGL_CONTEXT_FLAGS -#define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0 +# define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0 #endif #ifndef GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY -#define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0 +# define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0 #endif - @class NSWindow; @class NSOpenGLView; @class NSOpenGLContext; - -class GHOST_ContextCGL : public GHOST_Context -{ -public: - /** - * Constructor. - */ - GHOST_ContextCGL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - NSWindow *window, - NSOpenGLView *openGLView, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy); - - /** - * Destructor. - */ - ~GHOST_ContextCGL(); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - GHOST_TSuccess activateDrawingContext(); - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - GHOST_TSuccess releaseDrawingContext(); - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - GHOST_TSuccess initializeDrawingContext(); - - /** - * Removes references to native handles from this context and then returns - * \return GHOST_kSuccess if it is OK for the parent to release the handles and - * GHOST_kFailure if releasing the handles will interfere with sharing - */ - GHOST_TSuccess releaseNativeHandles(); - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - GHOST_TSuccess getSwapInterval(int&); - - /** - * Updates the drawing context of this window. - * Needed whenever the window is changed. - * \return Indication of success. - */ - GHOST_TSuccess updateDrawingContext(); - -private: - /** The openGL view */ - NSOpenGLView *m_openGLView; - - /** The OpenGL drawing context */ - NSOpenGLContext *m_openGLContext; - - bool m_coreProfile; - - const bool m_debug; - - /** The first created OpenGL context (for sharing display lists) */ - static NSOpenGLContext *s_sharedOpenGLContext; - static int s_sharedCount; +class GHOST_ContextCGL : public GHOST_Context { + public: + /** + * Constructor. + */ + GHOST_ContextCGL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + NSWindow *window, + NSOpenGLView *openGLView, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy); + + /** + * Destructor. + */ + ~GHOST_ContextCGL(); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + GHOST_TSuccess activateDrawingContext(); + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + GHOST_TSuccess releaseDrawingContext(); + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + GHOST_TSuccess initializeDrawingContext(); + + /** + * Removes references to native handles from this context and then returns + * \return GHOST_kSuccess if it is OK for the parent to release the handles and + * GHOST_kFailure if releasing the handles will interfere with sharing + */ + GHOST_TSuccess releaseNativeHandles(); + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + GHOST_TSuccess getSwapInterval(int &); + + /** + * Updates the drawing context of this window. + * Needed whenever the window is changed. + * \return Indication of success. + */ + GHOST_TSuccess updateDrawingContext(); + + private: + /** The openGL view */ + NSOpenGLView *m_openGLView; + + /** The OpenGL drawing context */ + NSOpenGLContext *m_openGLContext; + + bool m_coreProfile; + + const bool m_debug; + + /** The first created OpenGL context (for sharing display lists) */ + static NSOpenGLContext *s_sharedOpenGLContext; + static int s_sharedCount; }; -#endif // __GHOST_CONTEXTCGL_H__ +#endif // __GHOST_CONTEXTCGL_H__ diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 913ba459e9a..9b4e1864adf 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -30,380 +30,384 @@ //#define GHOST_MULTITHREADED_OPENGL #ifdef GHOST_MULTITHREADED_OPENGL -#include <OpenGL/OpenGL.h> +# include <OpenGL/OpenGL.h> #endif #include <vector> #include <cassert> - NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil; -int GHOST_ContextCGL::s_sharedCount = 0; - - -GHOST_ContextCGL::GHOST_ContextCGL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - NSWindow *window, - NSOpenGLView *openGLView, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy) +int GHOST_ContextCGL::s_sharedCount = 0; + +GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + NSWindow *window, + NSOpenGLView *openGLView, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_openGLView(openGLView), m_openGLContext(nil), m_debug(contextFlags) { - // for now be very strict about OpenGL version requested - switch (contextMajorVersion) { - case 2: - assert(contextMinorVersion == 1); - assert(contextProfileMask == 0); - m_coreProfile = false; - break; - case 3: - // Apple didn't implement 3.0 or 3.1 - assert(contextMinorVersion == 3); - assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT); - m_coreProfile = true; - break; - default: - assert(false); - } + // for now be very strict about OpenGL version requested + switch (contextMajorVersion) { + case 2: + assert(contextMinorVersion == 1); + assert(contextProfileMask == 0); + m_coreProfile = false; + break; + case 3: + // Apple didn't implement 3.0 or 3.1 + assert(contextMinorVersion == 3); + assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT); + m_coreProfile = true; + break; + default: + assert(false); + } } - GHOST_ContextCGL::~GHOST_ContextCGL() { - if (m_openGLContext != nil) { - if (m_openGLContext == [NSOpenGLContext currentContext]) { - [NSOpenGLContext clearCurrentContext]; + if (m_openGLContext != nil) { + if (m_openGLContext == [NSOpenGLContext currentContext]) { + [NSOpenGLContext clearCurrentContext]; - if(m_openGLView) { - [m_openGLView clearGLContext]; - } - } + if (m_openGLView) { + [m_openGLView clearGLContext]; + } + } - if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) { - assert(s_sharedCount > 0); + if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) { + assert(s_sharedCount > 0); - s_sharedCount--; + s_sharedCount--; - if (s_sharedCount == 0) - s_sharedOpenGLContext = nil; + if (s_sharedCount == 0) + s_sharedOpenGLContext = nil; - [m_openGLContext release]; - } - } + [m_openGLContext release]; + } + } } - GHOST_TSuccess GHOST_ContextCGL::swapBuffers() { - if (m_openGLContext != nil) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext flushBuffer]; - [pool drain]; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLContext flushBuffer]; + [pool drain]; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextCGL::setSwapInterval(int interval) { - if (m_openGLContext != nil) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval]; - [pool drain]; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval]; + [pool drain]; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextCGL::getSwapInterval(int &intervalOut) { - if (m_openGLContext != nil) { - GLint interval; + if (m_openGLContext != nil) { + GLint interval; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval]; + [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval]; - [pool drain]; + [pool drain]; - intervalOut = static_cast<int>(interval); + intervalOut = static_cast<int>(interval); - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext() { - if (m_openGLContext != nil) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext makeCurrentContext]; - [pool drain]; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLContext makeCurrentContext]; + [pool drain]; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } GHOST_TSuccess GHOST_ContextCGL::releaseDrawingContext() { - if (m_openGLContext != nil) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSOpenGLContext clearCurrentContext]; - [pool drain]; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [NSOpenGLContext clearCurrentContext]; + [pool drain]; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext() { - if (m_openGLContext != nil) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext update]; - [pool drain]; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLContext update]; + [pool drain]; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - -static void makeAttribList( - std::vector<NSOpenGLPixelFormatAttribute>& attribs, - bool coreProfile, - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool softwareGL) +static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs, + bool coreProfile, + bool stereoVisual, + int numOfAASamples, + bool needAlpha, + bool needStencil, + bool softwareGL) { - attribs.clear(); + attribs.clear(); - attribs.push_back(NSOpenGLPFAOpenGLProfile); - attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy); + attribs.push_back(NSOpenGLPFAOpenGLProfile); + attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy); - // Pixel Format Attributes for the windowed NSOpenGLContext - attribs.push_back(NSOpenGLPFADoubleBuffer); + // Pixel Format Attributes for the windowed NSOpenGLContext + attribs.push_back(NSOpenGLPFADoubleBuffer); - if (softwareGL) { - attribs.push_back(NSOpenGLPFARendererID); - attribs.push_back(kCGLRendererGenericFloatID); - } - else { - attribs.push_back(NSOpenGLPFAAccelerated); - attribs.push_back(NSOpenGLPFANoRecovery); - } + if (softwareGL) { + attribs.push_back(NSOpenGLPFARendererID); + attribs.push_back(kCGLRendererGenericFloatID); + } + else { + attribs.push_back(NSOpenGLPFAAccelerated); + attribs.push_back(NSOpenGLPFANoRecovery); + } - attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching + attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching - attribs.push_back(NSOpenGLPFADepthSize); - attribs.push_back((NSOpenGLPixelFormatAttribute) 32); + attribs.push_back(NSOpenGLPFADepthSize); + attribs.push_back((NSOpenGLPixelFormatAttribute)32); - if (stereoVisual) - attribs.push_back(NSOpenGLPFAStereo); + if (stereoVisual) + attribs.push_back(NSOpenGLPFAStereo); - if (needAlpha) { - attribs.push_back(NSOpenGLPFAAlphaSize); - attribs.push_back((NSOpenGLPixelFormatAttribute) 8); - } + if (needAlpha) { + attribs.push_back(NSOpenGLPFAAlphaSize); + attribs.push_back((NSOpenGLPixelFormatAttribute)8); + } - if (needStencil) { - attribs.push_back(NSOpenGLPFAStencilSize); - attribs.push_back((NSOpenGLPixelFormatAttribute) 8); - } + if (needStencil) { + attribs.push_back(NSOpenGLPFAStencilSize); + attribs.push_back((NSOpenGLPixelFormatAttribute)8); + } - if (numOfAASamples > 0) { - // Multisample anti-aliasing - attribs.push_back(NSOpenGLPFAMultisample); + if (numOfAASamples > 0) { + // Multisample anti-aliasing + attribs.push_back(NSOpenGLPFAMultisample); - attribs.push_back(NSOpenGLPFASampleBuffers); - attribs.push_back((NSOpenGLPixelFormatAttribute) 1); + attribs.push_back(NSOpenGLPFASampleBuffers); + attribs.push_back((NSOpenGLPixelFormatAttribute)1); - attribs.push_back(NSOpenGLPFASamples); - attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples); - } + attribs.push_back(NSOpenGLPFASamples); + attribs.push_back((NSOpenGLPixelFormatAttribute)numOfAASamples); + } - attribs.push_back((NSOpenGLPixelFormatAttribute) 0); + attribs.push_back((NSOpenGLPixelFormatAttribute)0); } // TODO(merwin): make this available to all platforms static void getVersion(int *major, int *minor) { -#if 1 // legacy GL - sscanf((const char*)glGetString(GL_VERSION), "%d.%d", major, minor); -#else // 3.0+ - glGetIntegerv(GL_MAJOR_VERSION, major); - glGetIntegerv(GL_MINOR_VERSION, minor); +#if 1 // legacy GL + sscanf((const char *)glGetString(GL_VERSION), "%d.%d", major, minor); +#else // 3.0+ + glGetIntegerv(GL_MAJOR_VERSION, major); + glGetIntegerv(GL_MINOR_VERSION, minor); #endif } GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - std::vector<NSOpenGLPixelFormatAttribute> attribs; - attribs.reserve(40); + std::vector<NSOpenGLPixelFormatAttribute> attribs; + attribs.reserve(40); - NSOpenGLContext *prev_openGLContext = (m_openGLView) ? [m_openGLView openGLContext] : NULL; + NSOpenGLContext *prev_openGLContext = (m_openGLView) ? [m_openGLView openGLContext] : NULL; #ifdef GHOST_OPENGL_ALPHA - static const bool needAlpha = true; + static const bool needAlpha = true; #else - static const bool needAlpha = false; + static const bool needAlpha = false; #endif #ifdef GHOST_OPENGL_STENCIL - static const bool needStencil = true; + static const bool needStencil = true; #else - static const bool needStencil = false; + static const bool needStencil = false; #endif - static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better - GLint major = 0, minor = 0; - NSOpenGLPixelFormat *pixelFormat; - // TODO: keep pixel format for subsequent windows/contexts instead of recreating each time - - makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL); - - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; - - // Fall back to no multisampling if Antialiasing init failed - if (m_numOfAASamples > 0 && pixelFormat == nil) { - // XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples? - // Does this need to explicitly try for a lesser match before giving up? - // (Now that I think about it, does WGL really require the code that it has for finding a lesser match?) - - attribs.clear(); - makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL); - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; - } - - if (pixelFormat == nil) - goto error; - - if (m_numOfAASamples > 0) { //Set m_numOfAASamples to the actual value - GLint actualSamples; - [pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0]; - - if (m_numOfAASamples != (GHOST_TUns16)actualSamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - m_numOfAASamples, actualSamples); - - m_numOfAASamples = (GHOST_TUns16)actualSamples; - } - } - - m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; - [pixelFormat release]; - - [m_openGLContext makeCurrentContext]; - - getVersion(&major, &minor); - if (m_debug) { - fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); - fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); - } - - if (major < 2 || (major == 2 && minor < 1)) { - // fall back to software renderer if GL < 2.1 - fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software"); - softwareGL = true; - - // discard hardware GL context - [NSOpenGLContext clearCurrentContext]; - [m_openGLContext release]; - - // create software GL context - makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL); - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; - m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; - [pixelFormat release]; - - [m_openGLContext makeCurrentContext]; - - getVersion(&major, &minor); - if (m_debug) { - fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); - fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); - } - } + static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better + GLint major = 0, minor = 0; + NSOpenGLPixelFormat *pixelFormat; + // TODO: keep pixel format for subsequent windows/contexts instead of recreating each time + + makeAttribList(attribs, + m_coreProfile, + m_stereoVisual, + m_numOfAASamples, + needAlpha, + needStencil, + softwareGL); + + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; + + // Fall back to no multisampling if Antialiasing init failed + if (m_numOfAASamples > 0 && pixelFormat == nil) { + // XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples? + // Does this need to explicitly try for a lesser match before giving up? + // (Now that I think about it, does WGL really require the code that it has for finding a lesser match?) + + attribs.clear(); + makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL); + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; + } + + if (pixelFormat == nil) + goto error; + + if (m_numOfAASamples > 0) { //Set m_numOfAASamples to the actual value + GLint actualSamples; + [pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0]; + + if (m_numOfAASamples != (GHOST_TUns16)actualSamples) { + fprintf( + stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + m_numOfAASamples, + actualSamples); + + m_numOfAASamples = (GHOST_TUns16)actualSamples; + } + } + + m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:s_sharedOpenGLContext]; + [pixelFormat release]; + + [m_openGLContext makeCurrentContext]; + + getVersion(&major, &minor); + if (m_debug) { + fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); + fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); + } + + if (major < 2 || (major == 2 && minor < 1)) { + // fall back to software renderer if GL < 2.1 + fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software"); + softwareGL = true; + + // discard hardware GL context + [NSOpenGLContext clearCurrentContext]; + [m_openGLContext release]; + + // create software GL context + makeAttribList(attribs, + m_coreProfile, + m_stereoVisual, + m_numOfAASamples, + needAlpha, + needStencil, + softwareGL); + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; + m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:s_sharedOpenGLContext]; + [pixelFormat release]; + + [m_openGLContext makeCurrentContext]; + + getVersion(&major, &minor); + if (m_debug) { + fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); + fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); + } + } #ifdef GHOST_MULTITHREADED_OPENGL - //Switch openGL to multhreaded mode - if (CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine) == kCGLNoError) - if (m_debug) - fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n"); + //Switch openGL to multhreaded mode + if (CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine) == kCGLNoError) + if (m_debug) + fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n"); #endif #ifdef GHOST_WAIT_FOR_VSYNC - { - GLint swapInt = 1; - /* wait for vsync, to avoid tearing artifacts */ - [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; - } + { + GLint swapInt = 1; + /* wait for vsync, to avoid tearing artifacts */ + [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; + } #endif - initContextGLEW(); - - if (m_openGLView) { - [m_openGLView setOpenGLContext:m_openGLContext]; - [m_openGLContext setView:m_openGLView]; - } + initContextGLEW(); - if (s_sharedCount == 0) - s_sharedOpenGLContext = m_openGLContext; + if (m_openGLView) { + [m_openGLView setOpenGLContext:m_openGLContext]; + [m_openGLContext setView:m_openGLView]; + } - s_sharedCount++; + if (s_sharedCount == 0) + s_sharedOpenGLContext = m_openGLContext; + s_sharedCount++; - initClearGL(); - [m_openGLContext flushBuffer]; + initClearGL(); + [m_openGLContext flushBuffer]; - [pool drain]; + [pool drain]; - return GHOST_kSuccess; + return GHOST_kSuccess; error: - if (m_openGLView) { - [m_openGLView setOpenGLContext:prev_openGLContext]; - } + if (m_openGLView) { + [m_openGLView setOpenGLContext:prev_openGLContext]; + } - [pixelFormat release]; + [pixelFormat release]; - [pool drain]; + [pool drain]; - return GHOST_kFailure; + return GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles() { - m_openGLContext = NULL; - m_openGLView = NULL; + m_openGLContext = NULL; + m_openGLView = NULL; - return GHOST_kSuccess; + return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp index 0fc99c4c343..34df5f3119d 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.cpp +++ b/intern/ghost/intern/GHOST_ContextEGL.cpp @@ -33,183 +33,185 @@ #include <cstdio> #include <cstring> - -#define CASE_CODE_RETURN_STR(code) case code: return #code; +#define CASE_CODE_RETURN_STR(code) \ + case code: \ + return #code; static const char *get_egl_error_enum_string(EGLenum error) { - switch (error) { - CASE_CODE_RETURN_STR(EGL_SUCCESS) - CASE_CODE_RETURN_STR(EGL_NOT_INITIALIZED) - CASE_CODE_RETURN_STR(EGL_BAD_ACCESS) - CASE_CODE_RETURN_STR(EGL_BAD_ALLOC) - CASE_CODE_RETURN_STR(EGL_BAD_ATTRIBUTE) - CASE_CODE_RETURN_STR(EGL_BAD_CONTEXT) - CASE_CODE_RETURN_STR(EGL_BAD_CONFIG) - CASE_CODE_RETURN_STR(EGL_BAD_CURRENT_SURFACE) - CASE_CODE_RETURN_STR(EGL_BAD_DISPLAY) - CASE_CODE_RETURN_STR(EGL_BAD_SURFACE) - CASE_CODE_RETURN_STR(EGL_BAD_MATCH) - CASE_CODE_RETURN_STR(EGL_BAD_PARAMETER) - CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_PIXMAP) - CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_WINDOW) - CASE_CODE_RETURN_STR(EGL_CONTEXT_LOST) - default: - return NULL; - } + switch (error) { + CASE_CODE_RETURN_STR(EGL_SUCCESS) + CASE_CODE_RETURN_STR(EGL_NOT_INITIALIZED) + CASE_CODE_RETURN_STR(EGL_BAD_ACCESS) + CASE_CODE_RETURN_STR(EGL_BAD_ALLOC) + CASE_CODE_RETURN_STR(EGL_BAD_ATTRIBUTE) + CASE_CODE_RETURN_STR(EGL_BAD_CONTEXT) + CASE_CODE_RETURN_STR(EGL_BAD_CONFIG) + CASE_CODE_RETURN_STR(EGL_BAD_CURRENT_SURFACE) + CASE_CODE_RETURN_STR(EGL_BAD_DISPLAY) + CASE_CODE_RETURN_STR(EGL_BAD_SURFACE) + CASE_CODE_RETURN_STR(EGL_BAD_MATCH) + CASE_CODE_RETURN_STR(EGL_BAD_PARAMETER) + CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_PIXMAP) + CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_WINDOW) + CASE_CODE_RETURN_STR(EGL_CONTEXT_LOST) + default: + return NULL; + } } static const char *get_egl_error_message_string(EGLenum error) { - switch (error) { - case EGL_SUCCESS: - return "The last function succeeded without error."; + switch (error) { + case EGL_SUCCESS: + return "The last function succeeded without error."; - case EGL_NOT_INITIALIZED: - return ("EGL is not initialized, or could not be initialized, " - "for the specified EGL display connection."); + case EGL_NOT_INITIALIZED: + return ( + "EGL is not initialized, or could not be initialized, " + "for the specified EGL display connection."); - case EGL_BAD_ACCESS: - return ("EGL cannot access a requested resource " - "(for example a context is bound in another thread)."); + case EGL_BAD_ACCESS: + return ( + "EGL cannot access a requested resource " + "(for example a context is bound in another thread)."); - case EGL_BAD_ALLOC: - return "EGL failed to allocate resources for the requested operation."; + case EGL_BAD_ALLOC: + return "EGL failed to allocate resources for the requested operation."; - case EGL_BAD_ATTRIBUTE: - return "An unrecognized attribute or attribute value was passed in the attribute list."; + case EGL_BAD_ATTRIBUTE: + return "An unrecognized attribute or attribute value was passed in the attribute list."; - case EGL_BAD_CONTEXT: - return "An EGLContext argument does not name a valid EGL rendering context."; + case EGL_BAD_CONTEXT: + return "An EGLContext argument does not name a valid EGL rendering context."; - case EGL_BAD_CONFIG: - return "An EGLConfig argument does not name a valid EGL frame buffer configuration."; + case EGL_BAD_CONFIG: + return "An EGLConfig argument does not name a valid EGL frame buffer configuration."; - case EGL_BAD_CURRENT_SURFACE: - return ("The current surface of the calling thread is a window, " - "pixel buffer or pixmap that is no longer valid."); + case EGL_BAD_CURRENT_SURFACE: + return ( + "The current surface of the calling thread is a window, " + "pixel buffer or pixmap that is no longer valid."); - case EGL_BAD_DISPLAY: - return "An EGLDisplay argument does not name a valid EGL display connection."; + case EGL_BAD_DISPLAY: + return "An EGLDisplay argument does not name a valid EGL display connection."; - case EGL_BAD_SURFACE: - return ("An EGLSurface argument does not name a valid surface " - "(window, pixel buffer or pixmap) configured for GL rendering."); + case EGL_BAD_SURFACE: + return ( + "An EGLSurface argument does not name a valid surface " + "(window, pixel buffer or pixmap) configured for GL rendering."); - case EGL_BAD_MATCH: - return ("Arguments are inconsistent " - "(for example, a valid context requires buffers not supplied by a valid surface)."); + case EGL_BAD_MATCH: + return ( + "Arguments are inconsistent " + "(for example, a valid context requires buffers not supplied by a valid surface)."); - case EGL_BAD_PARAMETER: - return "One or more argument values are invalid."; + case EGL_BAD_PARAMETER: + return "One or more argument values are invalid."; - case EGL_BAD_NATIVE_PIXMAP: - return "A NativePixmapType argument does not refer to a valid native pixmap."; + case EGL_BAD_NATIVE_PIXMAP: + return "A NativePixmapType argument does not refer to a valid native pixmap."; - case EGL_BAD_NATIVE_WINDOW: - return "A NativeWindowType argument does not refer to a valid native window."; + case EGL_BAD_NATIVE_WINDOW: + return "A NativeWindowType argument does not refer to a valid native window."; - case EGL_CONTEXT_LOST: - return ("A power management event has occurred. " - "The application must destroy all contexts and reinitialise OpenGL ES state " - "and objects to continue rendering."); + case EGL_CONTEXT_LOST: + return ( + "A power management event has occurred. " + "The application must destroy all contexts and reinitialise OpenGL ES state " + "and objects to continue rendering."); - default: - return NULL; - } + default: + return NULL; + } } - static bool egl_chk(bool result, const char *file = NULL, int line = 0, const char *text = NULL) { - if (!result) { - EGLenum error = eglGetError(); + if (!result) { + EGLenum error = eglGetError(); - const char *code = get_egl_error_enum_string(error); - const char *msg = get_egl_error_message_string(error); + const char *code = get_egl_error_enum_string(error); + const char *msg = get_egl_error_message_string(error); #ifndef NDEBUG - fprintf(stderr, - "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n", - file, line, text, error, - code ? code : "<Unknown>", - msg ? msg : "<Unknown>"); + fprintf(stderr, + "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n", + file, + line, + text, + error, + code ? code : "<Unknown>", + msg ? msg : "<Unknown>"); #else - fprintf(stderr, - "EGL Error (0x%04X): %s: %s\n", - error, - code ? code : "<Unknown>", - msg ? msg : "<Unknown>"); + fprintf(stderr, + "EGL Error (0x%04X): %s: %s\n", + error, + code ? code : "<Unknown>", + msg ? msg : "<Unknown>"); #endif - } + } - return result; + return result; } #ifndef NDEBUG -#define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, #x) +# define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, # x) #else -#define EGL_CHK(x) egl_chk(x) +# define EGL_CHK(x) egl_chk(x) #endif - static inline bool bindAPI(EGLenum api) { - if (EGLEW_VERSION_1_2) { - return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE); - } + if (EGLEW_VERSION_1_2) { + return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE); + } - return false; + return false; } - #ifdef WITH_GL_ANGLE HMODULE GHOST_ContextEGL::s_d3dcompiler = NULL; #endif - -EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT; -EGLint GHOST_ContextEGL::s_gl_sharedCount = 0; +EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT; +EGLint GHOST_ContextEGL::s_gl_sharedCount = 0; EGLContext GHOST_ContextEGL::s_gles_sharedContext = EGL_NO_CONTEXT; -EGLint GHOST_ContextEGL::s_gles_sharedCount = 0; - -EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT; -EGLint GHOST_ContextEGL::s_vg_sharedCount = 0; +EGLint GHOST_ContextEGL::s_gles_sharedCount = 0; +EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT; +EGLint GHOST_ContextEGL::s_vg_sharedCount = 0; #pragma warning(disable : 4715) -template <typename T> -T &choose_api(EGLenum api, T &a, T &b, T &c) +template<typename T> T &choose_api(EGLenum api, T &a, T &b, T &c) { - switch (api) { - case EGL_OPENGL_API: - return a; - case EGL_OPENGL_ES_API: - return b; - case EGL_OPENVG_API: - return c; - default: - abort(); - } + switch (api) { + case EGL_OPENGL_API: + return a; + case EGL_OPENGL_ES_API: + return b; + case EGL_OPENVG_API: + return c; + default: + abort(); + } } - -GHOST_ContextEGL::GHOST_ContextEGL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - EGLNativeWindowType nativeWindow, - EGLNativeDisplayType nativeDisplay, - EGLint contextProfileMask, - EGLint contextMajorVersion, - EGLint contextMinorVersion, - EGLint contextFlags, - EGLint contextResetNotificationStrategy, - EGLenum api) +GHOST_ContextEGL::GHOST_ContextEGL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + EGLNativeWindowType nativeWindow, + EGLNativeDisplayType nativeDisplay, + EGLint contextProfileMask, + EGLint contextMajorVersion, + EGLint contextMinorVersion, + EGLint contextFlags, + EGLint contextResetNotificationStrategy, + EGLenum api) : GHOST_Context(stereoVisual, numOfAASamples), m_nativeDisplay(nativeDisplay), - m_nativeWindow (nativeWindow), + m_nativeWindow(nativeWindow), m_contextProfileMask(contextProfileMask), m_contextMajorVersion(contextMajorVersion), m_contextMinorVersion(contextMinorVersion), @@ -220,395 +222,395 @@ GHOST_ContextEGL::GHOST_ContextEGL( m_surface(EGL_NO_SURFACE), m_display(EGL_NO_DISPLAY), m_swap_interval(1), - m_sharedContext(choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)), - m_sharedCount (choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount)) + m_sharedContext( + choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)), + m_sharedCount(choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount)) { - assert(m_nativeWindow != 0); - assert(m_nativeDisplay != NULL); + assert(m_nativeWindow != 0); + assert(m_nativeDisplay != NULL); } - GHOST_ContextEGL::~GHOST_ContextEGL() { - if (m_display != EGL_NO_DISPLAY) { + if (m_display != EGL_NO_DISPLAY) { - bindAPI(m_api); + bindAPI(m_api); - if (m_context != EGL_NO_CONTEXT) { - if (m_context == ::eglGetCurrentContext()) - EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); + if (m_context != EGL_NO_CONTEXT) { + if (m_context == ::eglGetCurrentContext()) + EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); - if (m_context != m_sharedContext || m_sharedCount == 1) { - assert(m_sharedCount > 0); + if (m_context != m_sharedContext || m_sharedCount == 1) { + assert(m_sharedCount > 0); - m_sharedCount--; + m_sharedCount--; - if (m_sharedCount == 0) - m_sharedContext = EGL_NO_CONTEXT; + if (m_sharedCount == 0) + m_sharedContext = EGL_NO_CONTEXT; - EGL_CHK(::eglDestroyContext(m_display, m_context)); - } - } + EGL_CHK(::eglDestroyContext(m_display, m_context)); + } + } - if (m_surface != EGL_NO_SURFACE) - EGL_CHK(::eglDestroySurface(m_display, m_surface)); + if (m_surface != EGL_NO_SURFACE) + EGL_CHK(::eglDestroySurface(m_display, m_surface)); - EGL_CHK(::eglTerminate(m_display)); - } + EGL_CHK(::eglTerminate(m_display)); + } } - GHOST_TSuccess GHOST_ContextEGL::swapBuffers() { - return EGL_CHK(::eglSwapBuffers(m_display, m_surface)) ? GHOST_kSuccess : GHOST_kFailure; + return EGL_CHK(::eglSwapBuffers(m_display, m_surface)) ? GHOST_kSuccess : GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextEGL::setSwapInterval(int interval) { - if (EGLEW_VERSION_1_1) { - if (EGL_CHK(::eglSwapInterval(m_display, interval))) { - m_swap_interval = interval; - - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } - } - else { - return GHOST_kFailure; - } + if (EGLEW_VERSION_1_1) { + if (EGL_CHK(::eglSwapInterval(m_display, interval))) { + m_swap_interval = interval; + + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut) { - // This is a bit of a kludge because there does not seem to - // be a way to query the swap interval with EGL. - intervalOut = m_swap_interval; + // This is a bit of a kludge because there does not seem to + // be a way to query the swap interval with EGL. + intervalOut = m_swap_interval; - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext() { - if (m_display) { - bindAPI(m_api); - - return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_display) { + bindAPI(m_api); + + return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess : + GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } GHOST_TSuccess GHOST_ContextEGL::releaseDrawingContext() { - if (m_display) { - bindAPI(m_api); - - return EGL_CHK(::eglMakeCurrent(m_display, None, None, NULL)) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_display) { + bindAPI(m_api); + + return EGL_CHK(::eglMakeCurrent(m_display, None, None, NULL)) ? GHOST_kSuccess : + GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } void GHOST_ContextEGL::initContextEGLEW() { - if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK) - fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n"); + if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK) + fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n"); } - static const std::string &api_string(EGLenum api) { - static const std::string a("OpenGL"); - static const std::string b("OpenGL ES"); - static const std::string c("OpenVG"); + static const std::string a("OpenGL"); + static const std::string b("OpenGL ES"); + static const std::string c("OpenVG"); - return choose_api(api, a, b, c); + return choose_api(api, a, b, c); } GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() { - // objects have to be declared here due to the use of goto - std::vector<EGLint> attrib_list; - EGLint num_config = 0; + // objects have to be declared here due to the use of goto + std::vector<EGLint> attrib_list; + EGLint num_config = 0; - if (m_stereoVisual) - fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n"); + if (m_stereoVisual) + fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n"); - m_stereoVisual = false; // It doesn't matter what the Window wants. + m_stereoVisual = false; // It doesn't matter what the Window wants. #ifdef WITH_GL_ANGLE - // d3dcompiler_XX.dll needs to be loaded before ANGLE will work - if (s_d3dcompiler == NULL) { - s_d3dcompiler = LoadLibrary(D3DCOMPILER); + // d3dcompiler_XX.dll needs to be loaded before ANGLE will work + if (s_d3dcompiler == NULL) { + s_d3dcompiler = LoadLibrary(D3DCOMPILER); - WIN32_CHK(s_d3dcompiler != NULL); + WIN32_CHK(s_d3dcompiler != NULL); - if (s_d3dcompiler == NULL) { - fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n"); - return GHOST_kFailure; - } - } + if (s_d3dcompiler == NULL) { + fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n"); + return GHOST_kFailure; + } + } #endif - EGLDisplay prev_display = eglGetCurrentDisplay(); - EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW); - EGLSurface prev_read = eglGetCurrentSurface(EGL_READ); - EGLContext prev_context = eglGetCurrentContext(); - - m_display = ::eglGetDisplay(m_nativeDisplay); + EGLDisplay prev_display = eglGetCurrentDisplay(); + EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW); + EGLSurface prev_read = eglGetCurrentSurface(EGL_READ); + EGLContext prev_context = eglGetCurrentContext(); - if (!EGL_CHK(m_display != EGL_NO_DISPLAY)) - return GHOST_kFailure; + m_display = ::eglGetDisplay(m_nativeDisplay); - EGLint egl_major, egl_minor; + if (!EGL_CHK(m_display != EGL_NO_DISPLAY)) + return GHOST_kFailure; - if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) - goto error; + EGLint egl_major, egl_minor; - fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor); + if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) + goto error; - if (!EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))) - goto error; + fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor); - initContextEGLEW(); + if (!EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))) + goto error; - if (!bindAPI(m_api)) - goto error; + initContextEGLEW(); + if (!bindAPI(m_api)) + goto error; - // build attribute list + // build attribute list - attrib_list.reserve(20); + attrib_list.reserve(20); - if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) { - // According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE, - // but some implementations (ANGLE) do not seem to care. + if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) { + // According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE, + // but some implementations (ANGLE) do not seem to care. - if (m_contextMajorVersion == 1) { - attrib_list.push_back(EGL_RENDERABLE_TYPE); - attrib_list.push_back(EGL_OPENGL_ES_BIT); - } - else if (m_contextMajorVersion == 2) { - attrib_list.push_back(EGL_RENDERABLE_TYPE); - attrib_list.push_back(EGL_OPENGL_ES2_BIT); - } - else if (m_contextMajorVersion == 3) { - attrib_list.push_back(EGL_RENDERABLE_TYPE); - attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR); - } - else { - fprintf(stderr, - "Warning! Unable to request an ES context of version %d.%d\n", - m_contextMajorVersion, m_contextMinorVersion); - } + if (m_contextMajorVersion == 1) { + attrib_list.push_back(EGL_RENDERABLE_TYPE); + attrib_list.push_back(EGL_OPENGL_ES_BIT); + } + else if (m_contextMajorVersion == 2) { + attrib_list.push_back(EGL_RENDERABLE_TYPE); + attrib_list.push_back(EGL_OPENGL_ES2_BIT); + } + else if (m_contextMajorVersion == 3) { + attrib_list.push_back(EGL_RENDERABLE_TYPE); + attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR); + } + else { + fprintf(stderr, + "Warning! Unable to request an ES context of version %d.%d\n", + m_contextMajorVersion, + m_contextMinorVersion); + } - if (!((m_contextMajorVersion == 1) || - (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) || - (m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) || - (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) - { - fprintf(stderr, - "Warning! May not be able to create a version %d.%d ES context with version %d.%d of EGL\n", - m_contextMajorVersion, m_contextMinorVersion, egl_major, egl_minor); - } - } + if (!((m_contextMajorVersion == 1) || (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) || + (m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) || + (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) { + fprintf(stderr, + "Warning! May not be able to create a version %d.%d ES context with version %d.%d " + "of EGL\n", + m_contextMajorVersion, + m_contextMinorVersion, + egl_major, + egl_minor); + } + } - attrib_list.push_back(EGL_RED_SIZE); - attrib_list.push_back(8); + attrib_list.push_back(EGL_RED_SIZE); + attrib_list.push_back(8); - attrib_list.push_back(EGL_GREEN_SIZE); - attrib_list.push_back(8); + attrib_list.push_back(EGL_GREEN_SIZE); + attrib_list.push_back(8); - attrib_list.push_back(EGL_BLUE_SIZE); - attrib_list.push_back(8); + attrib_list.push_back(EGL_BLUE_SIZE); + attrib_list.push_back(8); #ifdef GHOST_OPENGL_ALPHA - attrib_list.push_back(EGL_ALPHA_SIZE); - attrib_list.push_back(8); + attrib_list.push_back(EGL_ALPHA_SIZE); + attrib_list.push_back(8); #endif - attrib_list.push_back(EGL_DEPTH_SIZE); - attrib_list.push_back(24); + attrib_list.push_back(EGL_DEPTH_SIZE); + attrib_list.push_back(24); #ifdef GHOST_OPENGL_STENCIL - attrib_list.push_back(EGL_STENCIL_SIZE); - attrib_list.push_back(8); + attrib_list.push_back(EGL_STENCIL_SIZE); + attrib_list.push_back(8); #endif - if (m_numOfAASamples > 0) { - attrib_list.push_back(EGL_SAMPLE_BUFFERS); - attrib_list.push_back(1); - - attrib_list.push_back(EGL_SAMPLES); - attrib_list.push_back(m_numOfAASamples); - } - - attrib_list.push_back(EGL_NONE); - - EGLConfig config; - - if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config))) - goto error; - - // A common error is to assume that ChooseConfig worked because it returned EGL_TRUE - if (num_config != 1) // num_config should be exactly 1 - goto error; - - if (m_numOfAASamples > 0) { - EGLint actualSamples; - - if (!EGL_CHK(::eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &actualSamples))) - goto error; - - if (m_numOfAASamples != actualSamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - m_numOfAASamples, - actualSamples); - - m_numOfAASamples = (GHOST_TUns16)actualSamples; - } - } - - m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL); - - if (!EGL_CHK(m_surface != EGL_NO_SURFACE)) - goto error; - - attrib_list.clear(); - - if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) { - if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) { - if (m_contextMajorVersion != 0) { - attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); - attrib_list.push_back(m_contextMajorVersion); - } - - if (m_contextMinorVersion != 0) { - attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); - attrib_list.push_back(m_contextMinorVersion); - } - - if (m_contextFlags != 0) { - attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR); - attrib_list.push_back(m_contextFlags); - } - } - else { - if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) { - fprintf(stderr, - "Warning! Cannot request specific versions of %s contexts.", - api_string(m_api).c_str()); - } - - if (m_contextFlags != 0) { - fprintf(stderr, - "Warning! Flags cannot be set on %s contexts.", - api_string(m_api).c_str()); - } - } - - if (m_api == EGL_OPENGL_API) { - if (m_contextProfileMask != 0) { - attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); - attrib_list.push_back(m_contextProfileMask); - } - } - else { - if (m_contextProfileMask != 0) - fprintf(stderr, - "Warning! Cannot select profile for %s contexts.", - api_string(m_api).c_str()); - } - - if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) { - if (m_contextResetNotificationStrategy != 0) { - attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR); - attrib_list.push_back(m_contextResetNotificationStrategy); - } - } - else { - if (m_contextResetNotificationStrategy != 0) { - fprintf(stderr, - "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.", - egl_major, egl_minor, api_string(m_api).c_str()); - } - } - } - else { - if (m_api == EGL_OPENGL_ES_API) { - if (m_contextMajorVersion != 0) { - attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION); - attrib_list.push_back(m_contextMajorVersion); - } - } - else { - if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) { - fprintf(stderr, - "Warning! EGL %d.%d is unable to select between versions of %s.", - egl_major, egl_minor, api_string(m_api).c_str()); - } - } - - if (m_contextFlags != 0) { - fprintf(stderr, - "Warning! EGL %d.%d is unable to set context flags.", - egl_major, egl_minor); - } - if (m_contextProfileMask != 0) { - fprintf(stderr, - "Warning! EGL %d.%d is unable to select between profiles.", - egl_major, egl_minor); - } - if (m_contextResetNotificationStrategy != 0) { - fprintf(stderr, - "Warning! EGL %d.%d is unable to set the reset notification strategies.", - egl_major, egl_minor); - } - } - - attrib_list.push_back(EGL_NONE); - - m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0])); - - if (!EGL_CHK(m_context != EGL_NO_CONTEXT)) - goto error; - - if (m_sharedContext == EGL_NO_CONTEXT) - m_sharedContext = m_context; - - m_sharedCount++; - - if (!EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context))) - goto error; - - initContextGLEW(); - - initClearGL(); - ::eglSwapBuffers(m_display, m_surface); - - return GHOST_kSuccess; + if (m_numOfAASamples > 0) { + attrib_list.push_back(EGL_SAMPLE_BUFFERS); + attrib_list.push_back(1); + + attrib_list.push_back(EGL_SAMPLES); + attrib_list.push_back(m_numOfAASamples); + } + + attrib_list.push_back(EGL_NONE); + + EGLConfig config; + + if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config))) + goto error; + + // A common error is to assume that ChooseConfig worked because it returned EGL_TRUE + if (num_config != 1) // num_config should be exactly 1 + goto error; + + if (m_numOfAASamples > 0) { + EGLint actualSamples; + + if (!EGL_CHK(::eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &actualSamples))) + goto error; + + if (m_numOfAASamples != actualSamples) { + fprintf( + stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + m_numOfAASamples, + actualSamples); + + m_numOfAASamples = (GHOST_TUns16)actualSamples; + } + } + + m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL); + + if (!EGL_CHK(m_surface != EGL_NO_SURFACE)) + goto error; + + attrib_list.clear(); + + if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) { + if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) { + if (m_contextMajorVersion != 0) { + attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); + attrib_list.push_back(m_contextMajorVersion); + } + + if (m_contextMinorVersion != 0) { + attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); + attrib_list.push_back(m_contextMinorVersion); + } + + if (m_contextFlags != 0) { + attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR); + attrib_list.push_back(m_contextFlags); + } + } + else { + if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) { + fprintf(stderr, + "Warning! Cannot request specific versions of %s contexts.", + api_string(m_api).c_str()); + } + + if (m_contextFlags != 0) { + fprintf(stderr, "Warning! Flags cannot be set on %s contexts.", api_string(m_api).c_str()); + } + } + + if (m_api == EGL_OPENGL_API) { + if (m_contextProfileMask != 0) { + attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); + attrib_list.push_back(m_contextProfileMask); + } + } + else { + if (m_contextProfileMask != 0) + fprintf( + stderr, "Warning! Cannot select profile for %s contexts.", api_string(m_api).c_str()); + } + + if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) { + if (m_contextResetNotificationStrategy != 0) { + attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR); + attrib_list.push_back(m_contextResetNotificationStrategy); + } + } + else { + if (m_contextResetNotificationStrategy != 0) { + fprintf(stderr, + "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.", + egl_major, + egl_minor, + api_string(m_api).c_str()); + } + } + } + else { + if (m_api == EGL_OPENGL_ES_API) { + if (m_contextMajorVersion != 0) { + attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION); + attrib_list.push_back(m_contextMajorVersion); + } + } + else { + if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) { + fprintf(stderr, + "Warning! EGL %d.%d is unable to select between versions of %s.", + egl_major, + egl_minor, + api_string(m_api).c_str()); + } + } + + if (m_contextFlags != 0) { + fprintf(stderr, "Warning! EGL %d.%d is unable to set context flags.", egl_major, egl_minor); + } + if (m_contextProfileMask != 0) { + fprintf(stderr, + "Warning! EGL %d.%d is unable to select between profiles.", + egl_major, + egl_minor); + } + if (m_contextResetNotificationStrategy != 0) { + fprintf(stderr, + "Warning! EGL %d.%d is unable to set the reset notification strategies.", + egl_major, + egl_minor); + } + } + + attrib_list.push_back(EGL_NONE); + + m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0])); + + if (!EGL_CHK(m_context != EGL_NO_CONTEXT)) + goto error; + + if (m_sharedContext == EGL_NO_CONTEXT) + m_sharedContext = m_context; + + m_sharedCount++; + + if (!EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context))) + goto error; + + initContextGLEW(); + + initClearGL(); + ::eglSwapBuffers(m_display, m_surface); + + return GHOST_kSuccess; error: - if (prev_display != EGL_NO_DISPLAY) - EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context)); + if (prev_display != EGL_NO_DISPLAY) + EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context)); - return GHOST_kFailure; + return GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextEGL::releaseNativeHandles() { - m_nativeWindow = 0; - m_nativeDisplay = NULL; + m_nativeWindow = 0; + m_nativeDisplay = NULL; - return GHOST_kSuccess; + return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h index cced618ac7e..0a759493e4d 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.h +++ b/intern/ghost/intern/GHOST_ContextEGL.h @@ -29,117 +29,114 @@ #include <GL/eglew.h> #ifndef GHOST_OPENGL_EGL_CONTEXT_FLAGS -#define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0 +# define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0 #endif #ifndef GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY -#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY 0 +# define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY 0 #endif - -class GHOST_ContextEGL : public GHOST_Context -{ -public: - /** - * Constructor. - */ - GHOST_ContextEGL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - EGLNativeWindowType nativeWindow, - EGLNativeDisplayType nativeDisplay, - EGLint contextProfileMask, - EGLint contextMajorVersion, - EGLint contextMinorVersion, - EGLint contextFlags, - EGLint contextResetNotificationStrategy, - EGLenum api); - - /** - * Destructor. - */ - ~GHOST_ContextEGL(); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - GHOST_TSuccess activateDrawingContext(); - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - GHOST_TSuccess releaseDrawingContext(); - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - GHOST_TSuccess initializeDrawingContext(); - - /** - * Removes references to native handles from this context and then returns - * \return GHOST_kSuccess if it is OK for the parent to release the handles and - * GHOST_kFailure if releasing the handles will interfere with sharing - */ - GHOST_TSuccess releaseNativeHandles(); - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - GHOST_TSuccess getSwapInterval(int &intervalOut); - -private: - void initContextEGLEW(); - - EGLNativeDisplayType m_nativeDisplay; - EGLNativeWindowType m_nativeWindow; - - const EGLint m_contextProfileMask; - const EGLint m_contextMajorVersion; - const EGLint m_contextMinorVersion; - const EGLint m_contextFlags; - const EGLint m_contextResetNotificationStrategy; - - const EGLenum m_api; - - EGLContext m_context; - EGLSurface m_surface; - EGLDisplay m_display; - - EGLint m_swap_interval; - - EGLContext &m_sharedContext; - EGLint &m_sharedCount; - - static EGLContext s_gl_sharedContext; - static EGLint s_gl_sharedCount; - - static EGLContext s_gles_sharedContext; - static EGLint s_gles_sharedCount; - - static EGLContext s_vg_sharedContext; - static EGLint s_vg_sharedCount; +class GHOST_ContextEGL : public GHOST_Context { + public: + /** + * Constructor. + */ + GHOST_ContextEGL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + EGLNativeWindowType nativeWindow, + EGLNativeDisplayType nativeDisplay, + EGLint contextProfileMask, + EGLint contextMajorVersion, + EGLint contextMinorVersion, + EGLint contextFlags, + EGLint contextResetNotificationStrategy, + EGLenum api); + + /** + * Destructor. + */ + ~GHOST_ContextEGL(); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + GHOST_TSuccess activateDrawingContext(); + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + GHOST_TSuccess releaseDrawingContext(); + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + GHOST_TSuccess initializeDrawingContext(); + + /** + * Removes references to native handles from this context and then returns + * \return GHOST_kSuccess if it is OK for the parent to release the handles and + * GHOST_kFailure if releasing the handles will interfere with sharing + */ + GHOST_TSuccess releaseNativeHandles(); + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); + + private: + void initContextEGLEW(); + + EGLNativeDisplayType m_nativeDisplay; + EGLNativeWindowType m_nativeWindow; + + const EGLint m_contextProfileMask; + const EGLint m_contextMajorVersion; + const EGLint m_contextMinorVersion; + const EGLint m_contextFlags; + const EGLint m_contextResetNotificationStrategy; + + const EGLenum m_api; + + EGLContext m_context; + EGLSurface m_surface; + EGLDisplay m_display; + + EGLint m_swap_interval; + + EGLContext &m_sharedContext; + EGLint &m_sharedCount; + + static EGLContext s_gl_sharedContext; + static EGLint s_gl_sharedCount; + + static EGLContext s_gles_sharedContext; + static EGLint s_gles_sharedCount; + + static EGLContext s_vg_sharedContext; + static EGLint s_vg_sharedCount; #ifdef WITH_GL_ANGLE - static HMODULE s_d3dcompiler; + static HMODULE s_d3dcompiler; #endif }; -#endif // __GHOST_CONTEXTEGL_H__ +#endif // __GHOST_CONTEXTEGL_H__ diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index bbf82c188bc..6a5126d59b8 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -41,20 +41,18 @@ static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, co #endif GLXContext GHOST_ContextGLX::s_sharedContext = None; -int GHOST_ContextGLX::s_sharedCount = 0; - - -GHOST_ContextGLX::GHOST_ContextGLX( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - Window window, - Display *display, - GLXFBConfig fbconfig, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy) +int GHOST_ContextGLX::s_sharedCount = 0; + +GHOST_ContextGLX::GHOST_ContextGLX(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + Window window, + Display *display, + GLXFBConfig fbconfig, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_display(display), m_fbconfig(fbconfig), @@ -66,312 +64,301 @@ GHOST_ContextGLX::GHOST_ContextGLX( m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_context(None) { - assert(m_display != NULL); + assert(m_display != NULL); } - GHOST_ContextGLX::~GHOST_ContextGLX() { - if (m_display != NULL) { - if (m_context != None) { - if (m_window != 0 && m_context == ::glXGetCurrentContext()) - ::glXMakeCurrent(m_display, None, NULL); + if (m_display != NULL) { + if (m_context != None) { + if (m_window != 0 && m_context == ::glXGetCurrentContext()) + ::glXMakeCurrent(m_display, None, NULL); - if (m_context != s_sharedContext || s_sharedCount == 1) { - assert(s_sharedCount > 0); + if (m_context != s_sharedContext || s_sharedCount == 1) { + assert(s_sharedCount > 0); - s_sharedCount--; + s_sharedCount--; - if (s_sharedCount == 0) - s_sharedContext = NULL; + if (s_sharedCount == 0) + s_sharedContext = NULL; - ::glXDestroyContext(m_display, m_context); - } - } - } + ::glXDestroyContext(m_display, m_context); + } + } + } } - GHOST_TSuccess GHOST_ContextGLX::swapBuffers() { - ::glXSwapBuffers(m_display, m_window); + ::glXSwapBuffers(m_display, m_window); - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextGLX::activateDrawingContext() { - if (m_display) { - return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_display) { + return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } GHOST_TSuccess GHOST_ContextGLX::releaseDrawingContext() { - if (m_display) { - return ::glXMakeCurrent(m_display, None, NULL) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_display) { + return ::glXMakeCurrent(m_display, None, NULL) ? GHOST_kSuccess : GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } void GHOST_ContextGLX::initContextGLXEW() { - initContextGLEW(); + initContextGLEW(); } GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() { - GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); + GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); - /* -------------------------------------------------------------------- */ - /* Begin Inline Glew */ + /* -------------------------------------------------------------------- */ + /* Begin Inline Glew */ #ifdef USE_GLXEW_INIT_WORKAROUND - const GLubyte *extStart = (GLubyte *)""; - const GLubyte *extEnd; - if (glXQueryExtension(m_display, NULL, NULL)) { - extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); - if ((extStart == NULL) || - (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( - (const GLubyte *)"glXChooseFBConfig")) == NULL || - (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( - (const GLubyte *)"glXCreateContextAttribsARB")) == NULL || - (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB( - (const GLubyte *)"glXCreatePbuffer")) == NULL) - { - extStart = (GLubyte *)""; - } - } - extEnd = extStart + _glewStrLen(extStart); - -#undef GLXEW_ARB_create_context - const bool GLXEW_ARB_create_context = - _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); -#undef GLXEW_ARB_create_context_profile - const bool GLXEW_ARB_create_context_profile = - _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); -#undef GLXEW_ARB_create_context_robustness -const bool GLXEW_ARB_create_context_robustness = - _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); -#ifdef WITH_GLEW_ES -#undef GLXEW_EXT_create_context_es_profile - const bool GLXEW_EXT_create_context_es_profile = - _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); -#undef GLXEW_EXT_create_context_es2_profile - const bool GLXEW_EXT_create_context_es2_profile = - _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); -#endif /* WITH_GLEW_ES */ - - /* End Inline Glew */ - /* -------------------------------------------------------------------- */ + const GLubyte *extStart = (GLubyte *)""; + const GLubyte *extEnd; + if (glXQueryExtension(m_display, NULL, NULL)) { + extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); + if ((extStart == NULL) || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) == NULL || + (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreateContextAttribsARB")) == NULL || + (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreatePbuffer")) == NULL) { + extStart = (GLubyte *)""; + } + } + extEnd = extStart + _glewStrLen(extStart); + +# undef GLXEW_ARB_create_context + const bool GLXEW_ARB_create_context = _glewSearchExtension( + "GLX_ARB_create_context", extStart, extEnd); +# undef GLXEW_ARB_create_context_profile + const bool GLXEW_ARB_create_context_profile = _glewSearchExtension( + "GLX_ARB_create_context_profile", extStart, extEnd); +# undef GLXEW_ARB_create_context_robustness + const bool GLXEW_ARB_create_context_robustness = _glewSearchExtension( + "GLX_ARB_create_context_robustness", extStart, extEnd); +# ifdef WITH_GLEW_ES +# undef GLXEW_EXT_create_context_es_profile + const bool GLXEW_EXT_create_context_es_profile = _glewSearchExtension( + "GLX_EXT_create_context_es_profile", extStart, extEnd); +# undef GLXEW_EXT_create_context_es2_profile + const bool GLXEW_EXT_create_context_es2_profile = _glewSearchExtension( + "GLX_EXT_create_context_es2_profile", extStart, extEnd); +# endif /* WITH_GLEW_ES */ + + /* End Inline Glew */ + /* -------------------------------------------------------------------- */ #else - /* important to initialize only glxew (_not_ glew), - * since this breaks w/ Mesa's `swrast`, see: T46431 */ - glxewInit(); -#endif /* USE_GLXEW_INIT_WORKAROUND */ - + /* important to initialize only glxew (_not_ glew), + * since this breaks w/ Mesa's `swrast`, see: T46431 */ + glxewInit(); +#endif /* USE_GLXEW_INIT_WORKAROUND */ - - if (GLXEW_ARB_create_context) { - int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + if (GLXEW_ARB_create_context) { + int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #ifdef WITH_GLEW_ES - int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT; + int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT; #endif - if (!GLXEW_ARB_create_context_profile && profileBitCore) - fprintf(stderr, "Warning! OpenGL core profile not available.\n"); + if (!GLXEW_ARB_create_context_profile && profileBitCore) + fprintf(stderr, "Warning! OpenGL core profile not available.\n"); - if (!GLXEW_ARB_create_context_profile && profileBitCompat) - fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); + if (!GLXEW_ARB_create_context_profile && profileBitCompat) + fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); #ifdef WITH_GLEW_ES - if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) - fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); + if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) + fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); - if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) - fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); + if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) + fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); #endif - int profileMask = 0; + int profileMask = 0; - if (GLXEW_ARB_create_context_profile && profileBitCore) - profileMask |= profileBitCore; + if (GLXEW_ARB_create_context_profile && profileBitCore) + profileMask |= profileBitCore; - if (GLXEW_ARB_create_context_profile && profileBitCompat) - profileMask |= profileBitCompat; + if (GLXEW_ARB_create_context_profile && profileBitCompat) + profileMask |= profileBitCompat; #ifdef WITH_GLEW_ES - if (GLXEW_EXT_create_context_es_profile && profileBitES) - profileMask |= profileBitES; + if (GLXEW_EXT_create_context_es_profile && profileBitES) + profileMask |= profileBitES; #endif - if (profileMask != m_contextProfileMask) - fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); - - - /* max 10 attributes plus terminator */ - int attribs[11]; - int i = 0; - - if (profileMask) { - attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = profileMask; - } - - if (m_contextMajorVersion != 0) { - attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = m_contextMajorVersion; - attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = m_contextMinorVersion; - } - - if (m_contextFlags != 0) { - attribs[i++] = GLX_CONTEXT_FLAGS_ARB; - attribs[i++] = m_contextFlags; - } - - if (m_contextResetNotificationStrategy != 0) { - if (GLXEW_ARB_create_context_robustness) { - attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; - attribs[i++] = m_contextResetNotificationStrategy; - } - else { - fprintf(stderr, "Warning! Cannot set the reset notification strategy."); - } - } - attribs[i++] = 0; - - /* Some drivers don't like having a true offscreen context. - * Create a pixel buffer instead of a window to render to. - * even if it will never be used for drawing. */ - int pbuffer_attribs[] = { - GLX_PBUFFER_WIDTH, 1, - GLX_PBUFFER_HEIGHT, 1, - None - }; - - /* Create a GL 3.x context */ - if (m_fbconfig) { - m_context = glXCreateContextAttribsARB(m_display, m_fbconfig, s_sharedContext, true, attribs); - - if (!m_window) { - m_window = (Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs); - } - } - else { - GLXFBConfig *framebuffer_config = NULL; - { - int glx_attribs[64]; - int fbcount = 0; - - GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true); - - framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount); - } - - if (framebuffer_config) { - m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); - - if (!m_window) { - m_window = (Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs); - } - - XFree(framebuffer_config); - } - } - } - else { - /* Don't create legacy context */ - fprintf(stderr, "Error! GLX_ARB_create_context not available.\n"); - } - - GHOST_TSuccess success; - - if (m_context != NULL) { - const unsigned char *version; - - if (!s_sharedContext) - s_sharedContext = m_context; - - s_sharedCount++; - - glXMakeCurrent(m_display, m_window, m_context); - - // Seems that this has to be called after MakeCurrent, - // which means we cannot use glX extensions until after we create a context - initContextGLXEW(); - - if (m_window) { - initClearGL(); - ::glXSwapBuffers(m_display, m_window); - } - - /* re initialize to get the extensions properly */ - initContextGLXEW(); - - version = glGetString(GL_VERSION); - - if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) { - success = GHOST_kFailure; - } - else { - success = GHOST_kSuccess; - } - } - else { - /* freeing well clean up the context initialized above */ - success = GHOST_kFailure; - } - - GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); - - return success; + if (profileMask != m_contextProfileMask) + fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); + + /* max 10 attributes plus terminator */ + int attribs[11]; + int i = 0; + + if (profileMask) { + attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = profileMask; + } + + if (m_contextMajorVersion != 0) { + attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = m_contextMajorVersion; + attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = m_contextMinorVersion; + } + + if (m_contextFlags != 0) { + attribs[i++] = GLX_CONTEXT_FLAGS_ARB; + attribs[i++] = m_contextFlags; + } + + if (m_contextResetNotificationStrategy != 0) { + if (GLXEW_ARB_create_context_robustness) { + attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; + attribs[i++] = m_contextResetNotificationStrategy; + } + else { + fprintf(stderr, "Warning! Cannot set the reset notification strategy."); + } + } + attribs[i++] = 0; + + /* Some drivers don't like having a true offscreen context. + * Create a pixel buffer instead of a window to render to. + * even if it will never be used for drawing. */ + int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None}; + + /* Create a GL 3.x context */ + if (m_fbconfig) { + m_context = glXCreateContextAttribsARB( + m_display, m_fbconfig, s_sharedContext, true, attribs); + + if (!m_window) { + m_window = (Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs); + } + } + else { + GLXFBConfig *framebuffer_config = NULL; + { + int glx_attribs[64]; + int fbcount = 0; + + GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true); + + framebuffer_config = glXChooseFBConfig( + m_display, DefaultScreen(m_display), glx_attribs, &fbcount); + } + + if (framebuffer_config) { + m_context = glXCreateContextAttribsARB( + m_display, framebuffer_config[0], s_sharedContext, True, attribs); + + if (!m_window) { + m_window = (Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs); + } + + XFree(framebuffer_config); + } + } + } + else { + /* Don't create legacy context */ + fprintf(stderr, "Error! GLX_ARB_create_context not available.\n"); + } + + GHOST_TSuccess success; + + if (m_context != NULL) { + const unsigned char *version; + + if (!s_sharedContext) + s_sharedContext = m_context; + + s_sharedCount++; + + glXMakeCurrent(m_display, m_window, m_context); + + // Seems that this has to be called after MakeCurrent, + // which means we cannot use glX extensions until after we create a context + initContextGLXEW(); + + if (m_window) { + initClearGL(); + ::glXSwapBuffers(m_display, m_window); + } + + /* re initialize to get the extensions properly */ + initContextGLXEW(); + + version = glGetString(GL_VERSION); + + if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) { + success = GHOST_kFailure; + } + else { + success = GHOST_kSuccess; + } + } + else { + /* freeing well clean up the context initialized above */ + success = GHOST_kFailure; + } + + GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); + + return success; } - GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles() { - m_window = 0; + m_window = 0; - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval) { - if (GLXEW_EXT_swap_control) { - ::glXSwapIntervalEXT(m_display, m_window, interval); - - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (GLXEW_EXT_swap_control) { + ::glXSwapIntervalEXT(m_display, m_window, interval); + + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut) { - if (GLXEW_EXT_swap_control) { - unsigned int interval = 0; + if (GLXEW_EXT_swap_control) { + unsigned int interval = 0; - ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval); + ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval); - intervalOut = static_cast<int>(interval); + intervalOut = static_cast<int>(interval); - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } /** @@ -382,117 +369,123 @@ GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut) * * \note Similar to SDL's 'X11_GL_GetAttributes' */ -int GHOST_X11_GL_GetAttributes( - int *attribs, int attribs_max, - int samples, bool is_stereo_visual, - bool need_alpha, - bool for_fb_config) +int GHOST_X11_GL_GetAttributes(int *attribs, + int attribs_max, + int samples, + bool is_stereo_visual, + bool need_alpha, + bool for_fb_config) { - int i = 0; + int i = 0; #ifdef GHOST_OPENGL_STENCIL - const bool need_stencil = true; + const bool need_stencil = true; #else - const bool need_stencil = false; + const bool need_stencil = false; #endif - if (is_stereo_visual) { - attribs[i++] = GLX_STEREO; - if (for_fb_config) { - attribs[i++] = True; - } - } + if (is_stereo_visual) { + attribs[i++] = GLX_STEREO; + if (for_fb_config) { + attribs[i++] = True; + } + } - if (for_fb_config) { - attribs[i++] = GLX_RENDER_TYPE; - attribs[i++] = GLX_RGBA_BIT; - } - else { - attribs[i++] = GLX_RGBA; - } + if (for_fb_config) { + attribs[i++] = GLX_RENDER_TYPE; + attribs[i++] = GLX_RGBA_BIT; + } + else { + attribs[i++] = GLX_RGBA; + } - attribs[i++] = GLX_DOUBLEBUFFER; - if (for_fb_config) { - attribs[i++] = True; - } + attribs[i++] = GLX_DOUBLEBUFFER; + if (for_fb_config) { + attribs[i++] = True; + } - attribs[i++] = GLX_RED_SIZE; - attribs[i++] = True; + attribs[i++] = GLX_RED_SIZE; + attribs[i++] = True; - attribs[i++] = GLX_BLUE_SIZE; - attribs[i++] = True; + attribs[i++] = GLX_BLUE_SIZE; + attribs[i++] = True; - attribs[i++] = GLX_GREEN_SIZE; - attribs[i++] = True; + attribs[i++] = GLX_GREEN_SIZE; + attribs[i++] = True; - attribs[i++] = GLX_DEPTH_SIZE; - attribs[i++] = True; + attribs[i++] = GLX_DEPTH_SIZE; + attribs[i++] = True; - if (need_alpha) { - attribs[i++] = GLX_ALPHA_SIZE; - attribs[i++] = True; - } + if (need_alpha) { + attribs[i++] = GLX_ALPHA_SIZE; + attribs[i++] = True; + } - if (need_stencil) { - attribs[i++] = GLX_STENCIL_SIZE; - attribs[i++] = True; - } + if (need_stencil) { + attribs[i++] = GLX_STENCIL_SIZE; + attribs[i++] = True; + } - if (samples) { - attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; - attribs[i++] = True; + if (samples) { + attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; + attribs[i++] = True; - attribs[i++] = GLX_SAMPLES_ARB; - attribs[i++] = samples; - } + attribs[i++] = GLX_SAMPLES_ARB; + attribs[i++] = samples; + } - attribs[i++] = 0; + attribs[i++] = 0; - GHOST_ASSERT(i <= attribs_max, "attribute size too small"); + GHOST_ASSERT(i <= attribs_max, "attribute size too small"); - (void)attribs_max; + (void)attribs_max; - return i; + return i; } - /* excuse inlining part of glew */ #ifdef USE_GLXEW_INIT_WORKAROUND static GLuint _glewStrLen(const GLubyte *s) { - GLuint i = 0; - if (s == NULL) return 0; - while (s[i] != '\0') i++; - return i; + GLuint i = 0; + if (s == NULL) + return 0; + while (s[i] != '\0') + i++; + return i; } static GLuint _glewStrCLen(const GLubyte *s, GLubyte c) { - GLuint i = 0; - if (s == NULL) return 0; - while (s[i] != '\0' && s[i] != c) i++; - return (s[i] == '\0' || s[i] == c) ? i : 0; + GLuint i = 0; + if (s == NULL) + return 0; + while (s[i] != '\0' && s[i] != c) + i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; } static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n) { - GLuint i = 0; - if (a == NULL || b == NULL) - return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; - while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; - return i == n ? GL_TRUE : GL_FALSE; + GLuint i = 0; + if (a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) + i++; + return i == n ? GL_TRUE : GL_FALSE; } static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end) { - const GLubyte *p; - GLuint len = _glewStrLen((const GLubyte *)name); - p = start; - while (p < end) { - GLuint n = _glewStrCLen(p, ' '); - if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE; - p += n + 1; - } - return GL_FALSE; + const GLubyte *p; + GLuint len = _glewStrLen((const GLubyte *)name); + p = start; + while (p < end) { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte *)name, p, n)) + return GL_TRUE; + p += n + 1; + } + return GL_FALSE; } -#endif /* USE_GLXEW_INIT_WORKAROUND */ +#endif /* USE_GLXEW_INIT_WORKAROUND */ diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h index ec2baf49767..5b631ea55de 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.h +++ b/intern/ghost/intern/GHOST_ContextGLX.h @@ -28,109 +28,107 @@ #include <GL/glxew.h> - #ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS /* leave as convenience define for the future */ -#define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0 +# define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0 #endif #ifndef GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY -#define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0 +# define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0 #endif -class GHOST_ContextGLX : public GHOST_Context -{ -public: - /** - * Constructor. - */ - GHOST_ContextGLX( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - Window window, - Display *display, - GLXFBConfig fbconfig, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy); - - /** - * Destructor. - */ - ~GHOST_ContextGLX(); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - GHOST_TSuccess activateDrawingContext(); - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - GHOST_TSuccess releaseDrawingContext(); - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - GHOST_TSuccess initializeDrawingContext(); - - /** - * Removes references to native handles from this context and then returns - * \return GHOST_kSuccess if it is OK for the parent to release the handles and - * GHOST_kFailure if releasing the handles will interfere with sharing - */ - GHOST_TSuccess releaseNativeHandles(); - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - GHOST_TSuccess getSwapInterval(int &intervalOut); - -private: - void initContextGLXEW(); - - Display *m_display; - GLXFBConfig m_fbconfig; - Window m_window; - - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const int m_contextResetNotificationStrategy; - - GLXContext m_context; - - /** The first created OpenGL context (for sharing display lists) */ - static GLXContext s_sharedContext; - static int s_sharedCount; +class GHOST_ContextGLX : public GHOST_Context { + public: + /** + * Constructor. + */ + GHOST_ContextGLX(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + Window window, + Display *display, + GLXFBConfig fbconfig, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy); + + /** + * Destructor. + */ + ~GHOST_ContextGLX(); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + GHOST_TSuccess activateDrawingContext(); + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + GHOST_TSuccess releaseDrawingContext(); + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + GHOST_TSuccess initializeDrawingContext(); + + /** + * Removes references to native handles from this context and then returns + * \return GHOST_kSuccess if it is OK for the parent to release the handles and + * GHOST_kFailure if releasing the handles will interfere with sharing + */ + GHOST_TSuccess releaseNativeHandles(); + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); + + private: + void initContextGLXEW(); + + Display *m_display; + GLXFBConfig m_fbconfig; + Window m_window; + + const int m_contextProfileMask; + const int m_contextMajorVersion; + const int m_contextMinorVersion; + const int m_contextFlags; + const int m_contextResetNotificationStrategy; + + GLXContext m_context; + + /** The first created OpenGL context (for sharing display lists) */ + static GLXContext s_sharedContext; + static int s_sharedCount; }; /* used to get GLX info */ -int GHOST_X11_GL_GetAttributes( - int *attribs, int attribs_max, - int samples, bool is_stereo_visual, - bool need_alpha, - bool for_fb_config); - -#endif // __GHOST_CONTEXTGLX_H__ +int GHOST_X11_GL_GetAttributes(int *attribs, + int attribs_max, + int samples, + bool is_stereo_visual, + bool need_alpha, + bool for_fb_config); + +#endif // __GHOST_CONTEXTGLX_H__ diff --git a/intern/ghost/intern/GHOST_ContextNone.cpp b/intern/ghost/intern/GHOST_ContextNone.cpp index df5e91738da..a59cee0444f 100644 --- a/intern/ghost/intern/GHOST_ContextNone.cpp +++ b/intern/ghost/intern/GHOST_ContextNone.cpp @@ -25,53 +25,45 @@ #include "GHOST_ContextNone.h" - GHOST_TSuccess GHOST_ContextNone::swapBuffers() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::activateDrawingContext() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::releaseDrawingContext() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::updateDrawingContext() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::initializeDrawingContext() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::releaseNativeHandles() { - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::setSwapInterval(int interval) { - m_swapInterval = interval; + m_swapInterval = interval; - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextNone::getSwapInterval(int &intervalOut) { - intervalOut = m_swapInterval; - return GHOST_kSuccess; + intervalOut = m_swapInterval; + return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_ContextNone.h b/intern/ghost/intern/GHOST_ContextNone.h index 65bad70d1fa..b7297d2497c 100644 --- a/intern/ghost/intern/GHOST_ContextNone.h +++ b/intern/ghost/intern/GHOST_ContextNone.h @@ -28,68 +28,64 @@ #include "GHOST_Context.h" -class GHOST_ContextNone : public GHOST_Context -{ -public: +class GHOST_ContextNone : public GHOST_Context { + public: + GHOST_ContextNone(bool stereoVisual, GHOST_TUns16 numOfAASamples) + : GHOST_Context(stereoVisual, numOfAASamples), m_swapInterval(1) + { + } - GHOST_ContextNone( - bool stereoVisual, - GHOST_TUns16 numOfAASamples) - : GHOST_Context(stereoVisual, numOfAASamples), - m_swapInterval(1) - {} + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess swapBuffers(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess swapBuffers(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess activateDrawingContext(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess activateDrawingContext(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess releaseDrawingContext(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess releaseDrawingContext(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess updateDrawingContext(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess updateDrawingContext(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess initializeDrawingContext(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess initializeDrawingContext(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess releaseNativeHandles(); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess releaseNativeHandles(); + /** + * Dummy function + * \return Always succeeds + */ + GHOST_TSuccess setSwapInterval(int interval); - /** - * Dummy function - * \return Always succeeds - */ - GHOST_TSuccess setSwapInterval(int interval); + /** + * Dummy function + * \param intervalOut Gets whatever was set by setSwapInterval + * \return Always succeeds + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); - /** - * Dummy function - * \param intervalOut Gets whatever was set by setSwapInterval - * \return Always succeeds - */ - GHOST_TSuccess getSwapInterval(int &intervalOut); - -private: - int m_swapInterval; + private: + int m_swapInterval; }; -#endif // __GHOST_CONTEXTNONE_H__ +#endif // __GHOST_CONTEXTNONE_H__ diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp index efdf6353ab8..600cab6f6d5 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.cpp +++ b/intern/ghost/intern/GHOST_ContextSDL.cpp @@ -31,20 +31,17 @@ #include <cstdio> #include <cstring> - SDL_GLContext GHOST_ContextSDL::s_sharedContext = NULL; -int GHOST_ContextSDL::s_sharedCount = 0; - - -GHOST_ContextSDL::GHOST_ContextSDL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - SDL_Window *window, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy) +int GHOST_ContextSDL::s_sharedCount = 0; + +GHOST_ContextSDL::GHOST_ContextSDL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + SDL_Window *window, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_window(window), m_hidden_window(NULL), @@ -55,168 +52,159 @@ GHOST_ContextSDL::GHOST_ContextSDL( m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_context(NULL) { - // assert(m_window != NULL); + // assert(m_window != NULL); } - GHOST_ContextSDL::~GHOST_ContextSDL() { - if (m_context != NULL) { - if (m_window != NULL && m_context == SDL_GL_GetCurrentContext()) - SDL_GL_MakeCurrent(m_window, NULL); + if (m_context != NULL) { + if (m_window != NULL && m_context == SDL_GL_GetCurrentContext()) + SDL_GL_MakeCurrent(m_window, NULL); - if (m_context != s_sharedContext || s_sharedCount == 1) { - assert(s_sharedCount > 0); + if (m_context != s_sharedContext || s_sharedCount == 1) { + assert(s_sharedCount > 0); - s_sharedCount--; + s_sharedCount--; - if (s_sharedCount == 0) - s_sharedContext = NULL; + if (s_sharedCount == 0) + s_sharedContext = NULL; - SDL_GL_DeleteContext(m_context); - } + SDL_GL_DeleteContext(m_context); + } - if (m_hidden_window != NULL) - SDL_DestroyWindow(m_hidden_window); - } + if (m_hidden_window != NULL) + SDL_DestroyWindow(m_hidden_window); + } } - GHOST_TSuccess GHOST_ContextSDL::swapBuffers() { - SDL_GL_SwapWindow(m_window); + SDL_GL_SwapWindow(m_window); - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextSDL::activateDrawingContext() { - if (m_context) { - return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_context) { + return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextSDL::releaseDrawingContext() { - if (m_context) { - /* Untested, may not work */ - return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kFailure; - } + if (m_context) { + /* Untested, may not work */ + return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext() { #ifdef GHOST_OPENGL_ALPHA - const bool needAlpha = true; + const bool needAlpha = true; #else - const bool needAlpha = false; + const bool needAlpha = false; #endif #ifdef GHOST_OPENGL_STENCIL - const bool needStencil = true; + const bool needStencil = true; #else - const bool needStencil = false; + const bool needStencil = false; #endif - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags); - SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - if (needAlpha) { - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - } + if (needAlpha) { + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + } - if (needStencil) { - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); - } + if (needStencil) { + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); + } - if (m_stereoVisual) { - SDL_GL_SetAttribute(SDL_GL_STEREO, 1); - } + if (m_stereoVisual) { + SDL_GL_SetAttribute(SDL_GL_STEREO, 1); + } - if (m_numOfAASamples) { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples); - } + if (m_numOfAASamples) { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples); + } - if (m_window == NULL) { - m_hidden_window = SDL_CreateWindow( - "Offscreen Context Windows", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - 1, 1, - SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN - ); + if (m_window == NULL) { + m_hidden_window = SDL_CreateWindow("Offscreen Context Windows", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 1, + 1, + SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | + SDL_WINDOW_HIDDEN); - m_window = m_hidden_window; - } + m_window = m_hidden_window; + } - m_context = SDL_GL_CreateContext(m_window); + m_context = SDL_GL_CreateContext(m_window); - GHOST_TSuccess success; + GHOST_TSuccess success; - if (m_context != NULL) { - if (!s_sharedContext) - s_sharedContext = m_context; + if (m_context != NULL) { + if (!s_sharedContext) + s_sharedContext = m_context; - s_sharedCount++; + s_sharedCount++; - success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? - GHOST_kFailure : GHOST_kSuccess; + success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? GHOST_kFailure : GHOST_kSuccess; - initContextGLEW(); + initContextGLEW(); - initClearGL(); - SDL_GL_SwapWindow(m_window); + initClearGL(); + SDL_GL_SwapWindow(m_window); - success = GHOST_kSuccess; - } - else { - success = GHOST_kFailure; - } + success = GHOST_kSuccess; + } + else { + success = GHOST_kFailure; + } - return success; + return success; } - GHOST_TSuccess GHOST_ContextSDL::releaseNativeHandles() { - m_window = NULL; + m_window = NULL; - return GHOST_kSuccess; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_ContextSDL::setSwapInterval(int interval) { - if (SDL_GL_SetSwapInterval(interval) != -1) { - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (SDL_GL_SetSwapInterval(interval) != -1) { + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextSDL::getSwapInterval(int &intervalOut) { - intervalOut = SDL_GL_GetSwapInterval(); - return GHOST_kSuccess; + intervalOut = SDL_GL_GetSwapInterval(); + return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h index 6c36d1d703e..bbd8dd5ad5e 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.h +++ b/intern/ghost/intern/GHOST_ContextSDL.h @@ -27,104 +27,100 @@ #include "GHOST_Context.h" extern "C" { - #include "SDL.h" +#include "SDL.h" } - #ifndef GHOST_OPENGL_SDL_CONTEXT_FLAGS # ifdef WITH_GPU_DEBUG # define GHOST_OPENGL_SDL_CONTEXT_FLAGS SDL_GL_CONTEXT_DEBUG_FLAG # else # define GHOST_OPENGL_SDL_CONTEXT_FLAGS 0 -# endif +# endif #endif #ifndef GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY -#define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY 0 +# define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY 0 #endif - -class GHOST_ContextSDL : public GHOST_Context -{ -public: - /** - * Constructor. - */ - GHOST_ContextSDL( - bool stereoVisual, - GHOST_TUns16 numOfAASamples, - SDL_Window *window, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy); - - /** - * Destructor. - */ - ~GHOST_ContextSDL(); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - GHOST_TSuccess activateDrawingContext(); - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - GHOST_TSuccess releaseDrawingContext(); - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - GHOST_TSuccess initializeDrawingContext(); - - /** - * Removes references to native handles from this context and then returns - * \return GHOST_kSuccess if it is OK for the parent to release the handles and - * GHOST_kFailure if releasing the handles will interfere with sharing - */ - GHOST_TSuccess releaseNativeHandles(); - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - GHOST_TSuccess getSwapInterval(int &intervalOut); - -private: - SDL_Window *m_window; - SDL_Window *m_hidden_window; - - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const int m_contextResetNotificationStrategy; - - SDL_GLContext m_context; /* m_sdl_glcontext */ - - /** The first created OpenGL context (for sharing display lists) */ - static SDL_GLContext s_sharedContext; - static int s_sharedCount; +class GHOST_ContextSDL : public GHOST_Context { + public: + /** + * Constructor. + */ + GHOST_ContextSDL(bool stereoVisual, + GHOST_TUns16 numOfAASamples, + SDL_Window *window, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy); + + /** + * Destructor. + */ + ~GHOST_ContextSDL(); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + GHOST_TSuccess activateDrawingContext(); + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + GHOST_TSuccess releaseDrawingContext(); + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + GHOST_TSuccess initializeDrawingContext(); + + /** + * Removes references to native handles from this context and then returns + * \return GHOST_kSuccess if it is OK for the parent to release the handles and + * GHOST_kFailure if releasing the handles will interfere with sharing + */ + GHOST_TSuccess releaseNativeHandles(); + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); + + private: + SDL_Window *m_window; + SDL_Window *m_hidden_window; + + const int m_contextProfileMask; + const int m_contextMajorVersion; + const int m_contextMinorVersion; + const int m_contextFlags; + const int m_contextResetNotificationStrategy; + + SDL_GLContext m_context; /* m_sdl_glcontext */ + + /** The first created OpenGL context (for sharing display lists) */ + static SDL_GLContext s_sharedContext; + static int s_sharedCount; }; -#endif // __GHOST_CONTEXTSDL_H__ +#endif // __GHOST_CONTEXTSDL_H__ diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp index 7138db03abc..96d6e0c1600 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.cpp +++ b/intern/ghost/intern/GHOST_ContextWGL.cpp @@ -31,28 +31,25 @@ #include <cassert> #include <vector> - HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL; -int GHOST_ContextWGL::s_sharedCount = 0; +int GHOST_ContextWGL::s_sharedCount = 0; /* Some third-generation Intel video-cards are constantly bring problems */ static bool is_crappy_intel_card() { - return strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL; + return strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL; } - -GHOST_ContextWGL::GHOST_ContextWGL( - bool stereoVisual, - bool alphaBackground, - GHOST_TUns16 numOfAASamples, - HWND hWnd, - HDC hDC, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy) +GHOST_ContextWGL::GHOST_ContextWGL(bool stereoVisual, + bool alphaBackground, + GHOST_TUns16 numOfAASamples, + HWND hWnd, + HDC hDC, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_hWnd(hWnd), m_hDC(hDC), @@ -70,84 +67,78 @@ GHOST_ContextWGL::GHOST_ContextWGL( m_dummyVersion(NULL) #endif { - assert(m_hDC != NULL); + assert(m_hDC != NULL); } - GHOST_ContextWGL::~GHOST_ContextWGL() { - if (m_hGLRC != NULL) { - if (m_hGLRC == ::wglGetCurrentContext()) - WIN32_CHK(::wglMakeCurrent(NULL, NULL)); + if (m_hGLRC != NULL) { + if (m_hGLRC == ::wglGetCurrentContext()) + WIN32_CHK(::wglMakeCurrent(NULL, NULL)); - if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) { - assert(s_sharedCount > 0); + if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) { + assert(s_sharedCount > 0); - s_sharedCount--; + s_sharedCount--; - if (s_sharedCount == 0) - s_sharedHGLRC = NULL; + if (s_sharedCount == 0) + s_sharedHGLRC = NULL; - WIN32_CHK(::wglDeleteContext(m_hGLRC)); - } - } + WIN32_CHK(::wglDeleteContext(m_hGLRC)); + } + } #ifndef NDEBUG - if (m_dummyRenderer) { - free((void*)m_dummyRenderer); - free((void*)m_dummyVendor); - free((void*)m_dummyVersion); - } + if (m_dummyRenderer) { + free((void *)m_dummyRenderer); + free((void *)m_dummyVendor); + free((void *)m_dummyVersion); + } #endif } - GHOST_TSuccess GHOST_ContextWGL::swapBuffers() { - return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure; + return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextWGL::setSwapInterval(int interval) { - if (WGLEW_EXT_swap_control) - return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure; - else - return GHOST_kFailure; + if (WGLEW_EXT_swap_control) + return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure; + else + return GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextWGL::getSwapInterval(int &intervalOut) { - if (WGLEW_EXT_swap_control) { - intervalOut = ::wglGetSwapIntervalEXT(); - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (WGLEW_EXT_swap_control) { + intervalOut = ::wglGetSwapIntervalEXT(); + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextWGL::activateDrawingContext() { - if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) { - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) { + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } - GHOST_TSuccess GHOST_ContextWGL::releaseDrawingContext() { - if (WIN32_CHK(::wglMakeCurrent(NULL, NULL))) { - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (WIN32_CHK(::wglMakeCurrent(NULL, NULL))) { + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } /* Ron Fosner's code for weighting pixel formats and forcing software. @@ -155,99 +146,95 @@ GHOST_TSuccess GHOST_ContextWGL::releaseDrawingContext() */ static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd, PIXELFORMATDESCRIPTOR &preferredPFD) { - int weight = 0; + int weight = 0; - /* assume desktop color depth is 32 bits per pixel */ + /* assume desktop color depth is 32 bits per pixel */ - /* cull unusable pixel formats */ - /* if no formats can be found, can we determine why it was rejected? */ - if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || - !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || - !(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */ - !(pfd.iPixelType == PFD_TYPE_RGBA) || - (pfd.cDepthBits < 16) || - (pfd.cColorBits > 32) || /* 64 bit formats disable aero */ - (pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */ - { - return 0; - } + /* cull unusable pixel formats */ + /* if no formats can be found, can we determine why it was rejected? */ + if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || + !(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */ + !(pfd.iPixelType == PFD_TYPE_RGBA) || (pfd.cDepthBits < 16) || + (pfd.cColorBits > 32) || /* 64 bit formats disable aero */ + (pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */ + { + return 0; + } - weight = 1; /* it's usable */ + weight = 1; /* it's usable */ - /* the bigger the depth buffer the better */ - /* give no weight to a 16-bit depth buffer, because those are crap */ - weight += pfd.cDepthBits - 16; + /* the bigger the depth buffer the better */ + /* give no weight to a 16-bit depth buffer, because those are crap */ + weight += pfd.cDepthBits - 16; - weight += pfd.cColorBits - 8; + weight += pfd.cColorBits - 8; - if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) - weight++; + if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) + weight++; #ifdef WIN32_COMPOSITING - if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) - weight++; + if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) + weight++; #endif #ifdef GHOST_OPENGL_STENCIL - if (pfd.cStencilBits >= 8) - weight++; + if (pfd.cStencilBits >= 8) + weight++; #endif - return weight; + return weight; } - /* * A modification of Ron Fosner's replacement for ChoosePixelFormat * returns 0 on error, else returns the pixel format number to be used */ static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredPFD) { - int iPixelFormat = 0; - int weight = 0; + int iPixelFormat = 0; + int weight = 0; - int iStereoPixelFormat = 0; - int stereoWeight = 0; + int iStereoPixelFormat = 0; + int stereoWeight = 0; - /* choose a pixel format using the useless Windows function in case we come up empty handed */ - int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD); + /* choose a pixel format using the useless Windows function in case we come up empty handed */ + int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD); - WIN32_CHK(iLastResortPixelFormat != 0); + WIN32_CHK(iLastResortPixelFormat != 0); - int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); + int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); - WIN32_CHK(lastPFD != 0); + WIN32_CHK(lastPFD != 0); - for (int i = 1; i <= lastPFD; i++) { - PIXELFORMATDESCRIPTOR pfd; - int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + for (int i = 1; i <= lastPFD; i++) { + PIXELFORMATDESCRIPTOR pfd; + int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - WIN32_CHK(check == lastPFD); + WIN32_CHK(check == lastPFD); - int w = weight_pixel_format(pfd, preferredPFD); + int w = weight_pixel_format(pfd, preferredPFD); - if (w > weight) { - weight = w; - iPixelFormat = i; - } + if (w > weight) { + weight = w; + iPixelFormat = i; + } - if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) { - stereoWeight = w; - iStereoPixelFormat = i; - } - } + if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) { + stereoWeight = w; + iStereoPixelFormat = i; + } + } - /* choose any available stereo format over a non-stereo format */ - if (iStereoPixelFormat != 0) - iPixelFormat = iStereoPixelFormat; + /* choose any available stereo format over a non-stereo format */ + if (iStereoPixelFormat != 0) + iPixelFormat = iStereoPixelFormat; - if (iPixelFormat == 0) { - fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n"); - iPixelFormat = iLastResortPixelFormat; - } + if (iPixelFormat == 0) { + fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n"); + iPixelFormat = iLastResortPixelFormat; + } - return iPixelFormat; + return iPixelFormat; } - /* * Clone a window for the purpose of creating a temporary context to initialize WGL extensions. * There is no generic way to clone the lpParam parameter, so the caller is responsible for cloning it themselves. @@ -255,592 +242,569 @@ static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredP static HWND clone_window(HWND hWnd, LPVOID lpParam) { - int count; + int count; - SetLastError(NO_ERROR); + SetLastError(NO_ERROR); - DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); - WIN32_CHK(GetLastError() == NO_ERROR); + DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); + WIN32_CHK(GetLastError() == NO_ERROR); - WCHAR lpClassName[100] = L""; - count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName)); - WIN32_CHK(count != 0); + WCHAR lpClassName[100] = L""; + count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName)); + WIN32_CHK(count != 0); - WCHAR lpWindowName[100] = L""; - count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName)); - WIN32_CHK(count != 0); + WCHAR lpWindowName[100] = L""; + count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName)); + WIN32_CHK(count != 0); - DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE); - WIN32_CHK(GetLastError() == NO_ERROR); + DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE); + WIN32_CHK(GetLastError() == NO_ERROR); - RECT rect; - GetWindowRect(hWnd, &rect); - WIN32_CHK(GetLastError() == NO_ERROR); + RECT rect; + GetWindowRect(hWnd, &rect); + WIN32_CHK(GetLastError() == NO_ERROR); - HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT); - WIN32_CHK(GetLastError() == NO_ERROR); + HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT); + WIN32_CHK(GetLastError() == NO_ERROR); - HMENU hMenu = GetMenu(hWnd); - WIN32_CHK(GetLastError() == NO_ERROR); + HMENU hMenu = GetMenu(hWnd); + WIN32_CHK(GetLastError() == NO_ERROR); - HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); - WIN32_CHK(GetLastError() == NO_ERROR); + HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); + WIN32_CHK(GetLastError() == NO_ERROR); - HWND hwndCloned = CreateWindowExW( - dwExStyle, - lpClassName, - lpWindowName, - dwStyle, - rect.left, - rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - hWndParent, - hMenu, - hInstance, - lpParam); + HWND hwndCloned = CreateWindowExW(dwExStyle, + lpClassName, + lpWindowName, + dwStyle, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + hWndParent, + hMenu, + hInstance, + lpParam); - WIN32_CHK(hwndCloned != NULL); + WIN32_CHK(hwndCloned != NULL); - return hwndCloned; + return hwndCloned; } - void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD) { - HWND dummyHWND = NULL; + HWND dummyHWND = NULL; - HDC dummyHDC = NULL; - HGLRC dummyHGLRC = NULL; + HDC dummyHDC = NULL; + HGLRC dummyHGLRC = NULL; - HDC prevHDC; - HGLRC prevHGLRC; + HDC prevHDC; + HGLRC prevHGLRC; - int iPixelFormat; + int iPixelFormat; - SetLastError(NO_ERROR); + SetLastError(NO_ERROR); - prevHDC = ::wglGetCurrentDC(); - WIN32_CHK(GetLastError() == NO_ERROR); + prevHDC = ::wglGetCurrentDC(); + WIN32_CHK(GetLastError() == NO_ERROR); - prevHGLRC = ::wglGetCurrentContext(); - WIN32_CHK(GetLastError() == NO_ERROR); + prevHGLRC = ::wglGetCurrentContext(); + WIN32_CHK(GetLastError() == NO_ERROR); - iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); + iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); - if (iPixelFormat == 0) - goto finalize; + if (iPixelFormat == 0) + goto finalize; - PIXELFORMATDESCRIPTOR chosenPFD; - if (!WIN32_CHK(::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD))) - goto finalize; + PIXELFORMATDESCRIPTOR chosenPFD; + if (!WIN32_CHK( + ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD))) + goto finalize; - if (m_hWnd) { - dummyHWND = clone_window(m_hWnd, NULL); + if (m_hWnd) { + dummyHWND = clone_window(m_hWnd, NULL); - if (dummyHWND == NULL) - goto finalize; + if (dummyHWND == NULL) + goto finalize; - dummyHDC = GetDC(dummyHWND); - } + dummyHDC = GetDC(dummyHWND); + } - if (!WIN32_CHK(dummyHDC != NULL)) - goto finalize; + if (!WIN32_CHK(dummyHDC != NULL)) + goto finalize; - if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD))) - goto finalize; + if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD))) + goto finalize; - dummyHGLRC = ::wglCreateContext(dummyHDC); + dummyHGLRC = ::wglCreateContext(dummyHDC); - if (!WIN32_CHK(dummyHGLRC != NULL)) - goto finalize; + if (!WIN32_CHK(dummyHGLRC != NULL)) + goto finalize; - if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) - goto finalize; + if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) + goto finalize; - if (GLEW_CHK(glewInit()) != GLEW_OK) - fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n"); + if (GLEW_CHK(glewInit()) != GLEW_OK) + fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n"); - // the following are not technially WGLEW, but they also require a context to work + // the following are not technially WGLEW, but they also require a context to work #ifndef NDEBUG - free((void*)m_dummyRenderer); - free((void*)m_dummyVendor); - free((void*)m_dummyVersion); + free((void *)m_dummyRenderer); + free((void *)m_dummyVendor); + free((void *)m_dummyVersion); - m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER))); - m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR))); - m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION))); + m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER))); + m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR))); + m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION))); #endif finalize: - WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC)); + WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC)); - if (dummyHGLRC != NULL) - WIN32_CHK(::wglDeleteContext(dummyHGLRC)); + if (dummyHGLRC != NULL) + WIN32_CHK(::wglDeleteContext(dummyHGLRC)); - if (dummyHWND != NULL) { - if (dummyHDC != NULL) - WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC)); + if (dummyHWND != NULL) { + if (dummyHDC != NULL) + WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC)); - WIN32_CHK(::DestroyWindow(dummyHWND)); - } + WIN32_CHK(::DestroyWindow(dummyHWND)); + } } - -static void makeAttribList( - std::vector<int>& out, - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB) +static void makeAttribList(std::vector<int> &out, + bool stereoVisual, + int numOfAASamples, + bool needAlpha, + bool needStencil, + bool sRGB) { - out.clear(); - out.reserve(30); + out.clear(); + out.reserve(30); - out.push_back(WGL_SUPPORT_OPENGL_ARB); - out.push_back(GL_TRUE); + out.push_back(WGL_SUPPORT_OPENGL_ARB); + out.push_back(GL_TRUE); - out.push_back(WGL_DRAW_TO_WINDOW_ARB); - out.push_back(GL_TRUE); + out.push_back(WGL_DRAW_TO_WINDOW_ARB); + out.push_back(GL_TRUE); - out.push_back(WGL_DOUBLE_BUFFER_ARB); - out.push_back(GL_TRUE); + out.push_back(WGL_DOUBLE_BUFFER_ARB); + out.push_back(GL_TRUE); - out.push_back(WGL_ACCELERATION_ARB); - out.push_back(WGL_FULL_ACCELERATION_ARB); + out.push_back(WGL_ACCELERATION_ARB); + out.push_back(WGL_FULL_ACCELERATION_ARB); - if (stereoVisual) { - out.push_back(WGL_STEREO_ARB); - out.push_back(GL_TRUE); - } + if (stereoVisual) { + out.push_back(WGL_STEREO_ARB); + out.push_back(GL_TRUE); + } - out.push_back(WGL_PIXEL_TYPE_ARB); - out.push_back(WGL_TYPE_RGBA_ARB); + out.push_back(WGL_PIXEL_TYPE_ARB); + out.push_back(WGL_TYPE_RGBA_ARB); - out.push_back(WGL_COLOR_BITS_ARB); - out.push_back(24); + out.push_back(WGL_COLOR_BITS_ARB); + out.push_back(24); - out.push_back(WGL_DEPTH_BITS_ARB); - out.push_back(24); + out.push_back(WGL_DEPTH_BITS_ARB); + out.push_back(24); - if (needAlpha) { - out.push_back(WGL_ALPHA_BITS_ARB); - out.push_back(8); - } + if (needAlpha) { + out.push_back(WGL_ALPHA_BITS_ARB); + out.push_back(8); + } - if (needStencil) { - out.push_back(WGL_STENCIL_BITS_ARB); - out.push_back(8); - } + if (needStencil) { + out.push_back(WGL_STENCIL_BITS_ARB); + out.push_back(8); + } - if (numOfAASamples > 0) { - out.push_back(WGL_SAMPLES_ARB); - out.push_back(numOfAASamples); + if (numOfAASamples > 0) { + out.push_back(WGL_SAMPLES_ARB); + out.push_back(numOfAASamples); - out.push_back(WGL_SAMPLE_BUFFERS_ARB); - out.push_back(GL_TRUE); - } + out.push_back(WGL_SAMPLE_BUFFERS_ARB); + out.push_back(GL_TRUE); + } - if (sRGB) { - out.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); - out.push_back(GL_TRUE); - } + if (sRGB) { + out.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); + out.push_back(GL_TRUE); + } - out.push_back(0); + out.push_back(0); } - int GHOST_ContextWGL::_choose_pixel_format_arb_1( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB) + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB) { - std::vector<int> iAttributes; + std::vector<int> iAttributes; #define _MAX_PIXEL_FORMATS 32 - int iPixelFormat = 0; - int iPixelFormats[_MAX_PIXEL_FORMATS]; - - int samples; - - // guard against some insanely high number of samples - if (numOfAASamples > 64) { - fprintf(stderr, "Warning! Clamping number of samples to 64.\n"); - samples = 64; - } - else { - samples = numOfAASamples; - } - - // request a format with as many samples as possible, but not more than requested - while (samples >= 0) { - makeAttribList( - iAttributes, - stereoVisual, - samples, - needAlpha, - needStencil, - sRGB); - - UINT nNumFormats; - WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats)); + int iPixelFormat = 0; + int iPixelFormats[_MAX_PIXEL_FORMATS]; + + int samples; + + // guard against some insanely high number of samples + if (numOfAASamples > 64) { + fprintf(stderr, "Warning! Clamping number of samples to 64.\n"); + samples = 64; + } + else { + samples = numOfAASamples; + } + + // request a format with as many samples as possible, but not more than requested + while (samples >= 0) { + makeAttribList(iAttributes, stereoVisual, samples, needAlpha, needStencil, sRGB); + + UINT nNumFormats; + WIN32_CHK(wglChoosePixelFormatARB( + m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats)); #ifdef WIN32_COMPOSITING - if (needAlpha && nNumFormats) { - // scan through all pixel format to make sure one supports compositing - PIXELFORMATDESCRIPTOR pfd; - int i; - - for (i = 0; i < nNumFormats; i++) { - if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) { - iPixelFormat = iPixelFormats[i]; - break; - } - } - } - if (i == nNumFormats) { - fprintf(stderr, - "Warning! Unable to find a pixel format with compositing capability.\n"); - iPixelFormat = iPixelFormats[0]; - } - } - else + if (needAlpha && nNumFormats) { + // scan through all pixel format to make sure one supports compositing + PIXELFORMATDESCRIPTOR pfd; + int i; + + for (i = 0; i < nNumFormats; i++) { + if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { + if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) { + iPixelFormat = iPixelFormats[i]; + break; + } + } + } + if (i == nNumFormats) { + fprintf(stderr, "Warning! Unable to find a pixel format with compositing capability.\n"); + iPixelFormat = iPixelFormats[0]; + } + } + else #endif - iPixelFormat = iPixelFormats[0]; - /* total number of formats that match (regardless of size of iPixelFormat array) - * see: WGL_ARB_pixel_format extension spec */ - if (nNumFormats > 0) - break; - - /* if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB - * see: WGL_ARB_pixel_format extension spec */ - iPixelFormat = 0; - - samples--; - } - - // check how many samples were actually gotten - if (iPixelFormat != 0) { - int iQuery[] = { WGL_SAMPLES_ARB }; - int actualSamples, alphaBits; - wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples); - - if (actualSamples != numOfAASamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - numOfAASamples, actualSamples); - } - if (needAlpha) { - iQuery[0] = WGL_ALPHA_BITS_ARB; - wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &alphaBits); - if (alphaBits == 0) { - fprintf(stderr, - "Warning! Unable to find a frame buffer with alpha channel.\n"); - } - } - } - return iPixelFormat; + iPixelFormat = iPixelFormats[0]; + /* total number of formats that match (regardless of size of iPixelFormat array) + * see: WGL_ARB_pixel_format extension spec */ + if (nNumFormats > 0) + break; + + /* if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB + * see: WGL_ARB_pixel_format extension spec */ + iPixelFormat = 0; + + samples--; + } + + // check how many samples were actually gotten + if (iPixelFormat != 0) { + int iQuery[] = {WGL_SAMPLES_ARB}; + int actualSamples, alphaBits; + wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples); + + if (actualSamples != numOfAASamples) { + fprintf( + stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, + actualSamples); + } + if (needAlpha) { + iQuery[0] = WGL_ALPHA_BITS_ARB; + wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &alphaBits); + if (alphaBits == 0) { + fprintf(stderr, "Warning! Unable to find a frame buffer with alpha channel.\n"); + } + } + } + return iPixelFormat; } - int GHOST_ContextWGL::choose_pixel_format_arb( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB) + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB) { - int iPixelFormat; + int iPixelFormat; - iPixelFormat = _choose_pixel_format_arb_1( - stereoVisual, - numOfAASamples, - needAlpha, - needStencil, - sRGB); + iPixelFormat = _choose_pixel_format_arb_1( + stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB); - if (iPixelFormat == 0 && stereoVisual) { - fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n"); + if (iPixelFormat == 0 && stereoVisual) { + fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n"); - iPixelFormat = _choose_pixel_format_arb_1( - false, - numOfAASamples, - needAlpha, - needStencil, - sRGB); + iPixelFormat = _choose_pixel_format_arb_1(false, numOfAASamples, needAlpha, needStencil, sRGB); - m_stereoVisual = false; // set context property to actual value - } + m_stereoVisual = false; // set context property to actual value + } - return iPixelFormat; + return iPixelFormat; } - int GHOST_ContextWGL::choose_pixel_format( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB) + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB) { - PIXELFORMATDESCRIPTOR preferredPFD = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - (DWORD) ( - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER | /* support double-buffering */ - (stereoVisual ? PFD_STEREO : 0) |/* support stereo */ - ( + PIXELFORMATDESCRIPTOR preferredPFD = { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + (DWORD)( + PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER | /* support double-buffering */ + (stereoVisual ? PFD_STEREO : 0) | /* support stereo */ + ( #ifdef WIN32_COMPOSITING - needAlpha ? PFD_SUPPORT_COMPOSITION : /* support composition for transparent background */ + needAlpha ? + PFD_SUPPORT_COMPOSITION : /* support composition for transparent background */ #endif - 0 - )), - PFD_TYPE_RGBA, /* color type */ - (BYTE) (needAlpha ? 32 : 24), /* preferred color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - (BYTE) (needAlpha ? 8 : 0), /* alpha buffer */ - 0, /* alpha shift (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 24, /* depth buffer */ - (BYTE) (needStencil ? 8 : 0), /* stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0 /* layer, visible, and damage masks (ignored) */ - }; - - initContextWGLEW(preferredPFD); - - if (numOfAASamples > 0 && !WGLEW_ARB_multisample) { - fprintf(stderr, "Warning! Unable to request a multisample framebuffer.\n"); - numOfAASamples = 0; - } - - if (sRGB && !(WGLEW_ARB_framebuffer_sRGB || WGLEW_EXT_framebuffer_sRGB)) { - fprintf(stderr, "Warning! Unable to request an sRGB framebuffer.\n"); - sRGB = false; - } - - int iPixelFormat = 0; - - if (WGLEW_ARB_pixel_format) - iPixelFormat = choose_pixel_format_arb(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB); - - if (iPixelFormat == 0) - iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); - - return iPixelFormat; + 0)), + PFD_TYPE_RGBA, /* color type */ + (BYTE)(needAlpha ? 32 : 24), /* preferred color depth */ + 0, + 0, + 0, + 0, + 0, + 0, /* color bits (ignored) */ + (BYTE)(needAlpha ? 8 : 0), /* alpha buffer */ + 0, /* alpha shift (ignored) */ + 0, /* no accumulation buffer */ + 0, + 0, + 0, + 0, /* accum bits (ignored) */ + 24, /* depth buffer */ + (BYTE)(needStencil ? 8 : 0), /* stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, + 0, + 0 /* layer, visible, and damage masks (ignored) */ + }; + + initContextWGLEW(preferredPFD); + + if (numOfAASamples > 0 && !WGLEW_ARB_multisample) { + fprintf(stderr, "Warning! Unable to request a multisample framebuffer.\n"); + numOfAASamples = 0; + } + + if (sRGB && !(WGLEW_ARB_framebuffer_sRGB || WGLEW_EXT_framebuffer_sRGB)) { + fprintf(stderr, "Warning! Unable to request an sRGB framebuffer.\n"); + sRGB = false; + } + + int iPixelFormat = 0; + + if (WGLEW_ARB_pixel_format) + iPixelFormat = choose_pixel_format_arb( + stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB); + + if (iPixelFormat == 0) + iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); + + return iPixelFormat; } - #ifndef NDEBUG static void reportContextString(const char *name, const char *dummy, const char *context) { - fprintf(stderr, "%s: %s\n", name, context); + fprintf(stderr, "%s: %s\n", name, context); - if (dummy && strcmp(dummy, context) != 0) - fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy); + if (dummy && strcmp(dummy, context) != 0) + fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy); } #endif - GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() { - SetLastError(NO_ERROR); + SetLastError(NO_ERROR); - HGLRC prevHGLRC = ::wglGetCurrentContext(); - WIN32_CHK(GetLastError() == NO_ERROR); + HGLRC prevHGLRC = ::wglGetCurrentContext(); + WIN32_CHK(GetLastError() == NO_ERROR); - HDC prevHDC = ::wglGetCurrentDC(); - WIN32_CHK(GetLastError() == NO_ERROR); + HDC prevHDC = ::wglGetCurrentDC(); + WIN32_CHK(GetLastError() == NO_ERROR); - if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { - const bool needAlpha = m_alphaBackground; + if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { + const bool needAlpha = m_alphaBackground; #ifdef GHOST_OPENGL_STENCIL - const bool needStencil = true; + const bool needStencil = true; #else - const bool needStencil = false; + const bool needStencil = false; #endif #ifdef GHOST_OPENGL_SRGB - const bool sRGB = true; + const bool sRGB = true; #else - const bool sRGB = false; + const bool sRGB = false; #endif - int iPixelFormat; - int lastPFD; + int iPixelFormat; + int lastPFD; - PIXELFORMATDESCRIPTOR chosenPFD; + PIXELFORMATDESCRIPTOR chosenPFD; - iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); + iPixelFormat = choose_pixel_format( + m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); - if (iPixelFormat == 0) { - goto error; - } + if (iPixelFormat == 0) { + goto error; + } - lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); + lastPFD = ::DescribePixelFormat( + m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); - if (!WIN32_CHK(lastPFD != 0)) { - goto error; - } + if (!WIN32_CHK(lastPFD != 0)) { + goto error; + } - if (needAlpha && chosenPFD.cAlphaBits == 0) - fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); + if (needAlpha && chosenPFD.cAlphaBits == 0) + fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); - if (needStencil && chosenPFD.cStencilBits == 0) - fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); + if (needStencil && chosenPFD.cStencilBits == 0) + fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); - if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { - goto error; - } - } + if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { + goto error; + } + } - if (WGLEW_ARB_create_context) { - int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + if (WGLEW_ARB_create_context) { + int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #ifdef WITH_GLEW_ES - int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; + int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; #endif - if (!WGLEW_ARB_create_context_profile && profileBitCore) - fprintf(stderr, "Warning! OpenGL core profile not available.\n"); + if (!WGLEW_ARB_create_context_profile && profileBitCore) + fprintf(stderr, "Warning! OpenGL core profile not available.\n"); - if (!WGLEW_ARB_create_context_profile && profileBitCompat) - fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); + if (!WGLEW_ARB_create_context_profile && profileBitCompat) + fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); #ifdef WITH_GLEW_ES - if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) - fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); + if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) + fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); - if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) - fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); + if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) + fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); #endif - int profileMask = 0; + int profileMask = 0; - if (WGLEW_ARB_create_context_profile && profileBitCore) - profileMask |= profileBitCore; + if (WGLEW_ARB_create_context_profile && profileBitCore) + profileMask |= profileBitCore; - if (WGLEW_ARB_create_context_profile && profileBitCompat) - profileMask |= profileBitCompat; + if (WGLEW_ARB_create_context_profile && profileBitCompat) + profileMask |= profileBitCompat; #ifdef WITH_GLEW_ES - if (WGLEW_EXT_create_context_es_profile && profileBitES) - profileMask |= profileBitES; + if (WGLEW_EXT_create_context_es_profile && profileBitES) + profileMask |= profileBitES; #endif - if (profileMask != m_contextProfileMask) - fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); - - std::vector<int> iAttributes; - - if (profileMask) { - iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); - iAttributes.push_back(profileMask); - } - - if (m_contextMajorVersion != 0) { - iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); - iAttributes.push_back(m_contextMajorVersion); - } - - if (m_contextMinorVersion != 0) { - iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); - iAttributes.push_back(m_contextMinorVersion); - } - - if (m_contextFlags != 0) { - iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); - iAttributes.push_back(m_contextFlags); - } - - if (m_contextResetNotificationStrategy != 0) { - if (WGLEW_ARB_create_context_robustness) { - iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); - iAttributes.push_back(m_contextResetNotificationStrategy); - } - else { - fprintf(stderr, "Warning! Cannot set the reset notification strategy."); - } - } - - iAttributes.push_back(0); - - m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0])); - } - - /* Silence warnings interpreted as errors by users when trying to get - * a context with version higher than 3.3 Core. */ - const bool silent = m_contextMajorVersion > 3; - if (!WIN32_CHK_SILENT(m_hGLRC != NULL, silent)) { - goto error; - } - - s_sharedCount++; - - if (s_sharedHGLRC == NULL) { - s_sharedHGLRC = m_hGLRC; - } - else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) { - goto error; - } - - if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) { - goto error; - } - - initContextGLEW(); - - if (is_crappy_intel_card()) { - /* Some Intel cards with context 4.1 or 4.2 - * don't have the point sprite enabled by default. - * - * However GL_POINT_SPRITE was removed in 3.2 and is now permanently ON. - * Then use brute force. */ - glEnable(GL_POINT_SPRITE); - } - - initClearGL(); - ::SwapBuffers(m_hDC); + if (profileMask != m_contextProfileMask) + fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); + + std::vector<int> iAttributes; + + if (profileMask) { + iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); + iAttributes.push_back(profileMask); + } + + if (m_contextMajorVersion != 0) { + iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); + iAttributes.push_back(m_contextMajorVersion); + } + + if (m_contextMinorVersion != 0) { + iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); + iAttributes.push_back(m_contextMinorVersion); + } + + if (m_contextFlags != 0) { + iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); + iAttributes.push_back(m_contextFlags); + } + + if (m_contextResetNotificationStrategy != 0) { + if (WGLEW_ARB_create_context_robustness) { + iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); + iAttributes.push_back(m_contextResetNotificationStrategy); + } + else { + fprintf(stderr, "Warning! Cannot set the reset notification strategy."); + } + } + + iAttributes.push_back(0); + + m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0])); + } + + /* Silence warnings interpreted as errors by users when trying to get + * a context with version higher than 3.3 Core. */ + const bool silent = m_contextMajorVersion > 3; + if (!WIN32_CHK_SILENT(m_hGLRC != NULL, silent)) { + goto error; + } + + s_sharedCount++; + + if (s_sharedHGLRC == NULL) { + s_sharedHGLRC = m_hGLRC; + } + else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) { + goto error; + } + + if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) { + goto error; + } + + initContextGLEW(); + + if (is_crappy_intel_card()) { + /* Some Intel cards with context 4.1 or 4.2 + * don't have the point sprite enabled by default. + * + * However GL_POINT_SPRITE was removed in 3.2 and is now permanently ON. + * Then use brute force. */ + glEnable(GL_POINT_SPRITE); + } + + initClearGL(); + ::SwapBuffers(m_hDC); #ifndef NDEBUG - const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); - const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); + const char *vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR)); + const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); + const char *version = reinterpret_cast<const char *>(glGetString(GL_VERSION)); - reportContextString("Vendor", m_dummyVendor, vendor); - reportContextString("Renderer", m_dummyRenderer, renderer); - reportContextString("Version", m_dummyVersion, version); + reportContextString("Vendor", m_dummyVendor, vendor); + reportContextString("Renderer", m_dummyRenderer, renderer); + reportContextString("Version", m_dummyVersion, version); - fprintf(stderr, "Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion); + fprintf(stderr, "Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion); #endif - return GHOST_kSuccess; + return GHOST_kSuccess; error: - ::wglMakeCurrent(prevHDC, prevHGLRC); - return GHOST_kFailure; - + ::wglMakeCurrent(prevHDC, prevHGLRC); + return GHOST_kFailure; } - GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles() { - GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure; + GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : + GHOST_kFailure; - m_hWnd = NULL; - m_hDC = NULL; + m_hWnd = NULL; + m_hDC = NULL; - return success; + return success; } diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h index e96abbf5459..a3fd9de74a1 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -31,122 +31,107 @@ #include <GL/wglew.h> #ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY -#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0 +# define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0 #endif - -class GHOST_ContextWGL : public GHOST_Context -{ -public: - /** - * Constructor. - */ - GHOST_ContextWGL( - bool stereoVisual, - bool alphaBackground, - GHOST_TUns16 numOfAASamples, - HWND hWnd, - HDC hDC, - int contextProfileMask, - int contextMajorVersion, - int contextMinorVersion, - int contextFlags, - int contextResetNotificationStrategy); - - /** - * Destructor. - */ - ~GHOST_ContextWGL(); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - GHOST_TSuccess activateDrawingContext(); - - /** - * Release the drawing context of the calling thread. - * \return A boolean success indicator. - */ - GHOST_TSuccess releaseDrawingContext(); - - /** - * Call immediately after new to initialize. If this fails then immediately delete the object. - * \return Indication as to whether initialization has succeeded. - */ - GHOST_TSuccess initializeDrawingContext(); - - /** - * Removes references to native handles from this context and then returns - * \return GHOST_kSuccess if it is OK for the parent to release the handles and - * GHOST_kFailure if releasing the handles will interfere with sharing - */ - GHOST_TSuccess releaseNativeHandles(); - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. - * \return Whether the swap interval can be read. - */ - GHOST_TSuccess getSwapInterval(int &intervalOut); - -private: - int choose_pixel_format( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB); - - int choose_pixel_format_arb( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB); - - int _choose_pixel_format_arb_1( - bool stereoVisual, - int numOfAASamples, - bool needAlpha, - bool needStencil, - bool sRGB); - - void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD); - - HWND m_hWnd; - HDC m_hDC; - - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const bool m_alphaBackground; - const int m_contextResetNotificationStrategy; - - HGLRC m_hGLRC; +class GHOST_ContextWGL : public GHOST_Context { + public: + /** + * Constructor. + */ + GHOST_ContextWGL(bool stereoVisual, + bool alphaBackground, + GHOST_TUns16 numOfAASamples, + HWND hWnd, + HDC hDC, + int contextProfileMask, + int contextMajorVersion, + int contextMinorVersion, + int contextFlags, + int contextResetNotificationStrategy); + + /** + * Destructor. + */ + ~GHOST_ContextWGL(); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + GHOST_TSuccess activateDrawingContext(); + + /** + * Release the drawing context of the calling thread. + * \return A boolean success indicator. + */ + GHOST_TSuccess releaseDrawingContext(); + + /** + * Call immediately after new to initialize. If this fails then immediately delete the object. + * \return Indication as to whether initialization has succeeded. + */ + GHOST_TSuccess initializeDrawingContext(); + + /** + * Removes references to native handles from this context and then returns + * \return GHOST_kSuccess if it is OK for the parent to release the handles and + * GHOST_kFailure if releasing the handles will interfere with sharing + */ + GHOST_TSuccess releaseNativeHandles(); + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \param intervalOut Variable to store the swap interval if it can be read. + * \return Whether the swap interval can be read. + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); + + private: + int choose_pixel_format( + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB); + + int choose_pixel_format_arb( + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB); + + int _choose_pixel_format_arb_1( + bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB); + + void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD); + + HWND m_hWnd; + HDC m_hDC; + + const int m_contextProfileMask; + const int m_contextMajorVersion; + const int m_contextMinorVersion; + const int m_contextFlags; + const bool m_alphaBackground; + const int m_contextResetNotificationStrategy; + + HGLRC m_hGLRC; #ifndef NDEBUG - const char *m_dummyVendor; - const char *m_dummyRenderer; - const char *m_dummyVersion; + const char *m_dummyVendor; + const char *m_dummyRenderer; + const char *m_dummyVersion; #endif - static HGLRC s_sharedHGLRC; - static int s_sharedCount; + static HGLRC s_sharedHGLRC; + static int s_sharedCount; }; #endif // __GHOST_CONTEXTWGL_H__ diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h index 2351935f16b..0163197e14a 100644 --- a/intern/ghost/intern/GHOST_Debug.h +++ b/intern/ghost/intern/GHOST_Debug.h @@ -27,52 +27,61 @@ #ifdef _MSC_VER # ifdef DEBUG - /* Suppress stl-MSVC debug info warning. */ -# pragma warning (disable:4786) +/* Suppress stl-MSVC debug info warning. */ +# pragma warning(disable : 4786) # endif #endif #ifdef WITH_GHOST_DEBUG -# define GHOST_DEBUG // spit ghost events to stdout -#endif // WITH_GHOST_DEBUG +# define GHOST_DEBUG // spit ghost events to stdout +#endif // WITH_GHOST_DEBUG #ifdef GHOST_DEBUG # include <iostream> -# include <stdio.h> //for printf() -#endif // GHOST_DEBUG - +# include <stdio.h> //for printf() +#endif // GHOST_DEBUG #ifdef GHOST_DEBUG -# define GHOST_PRINT(x) { std::cout << x; } (void)0 -# define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); } (void)0 +# define GHOST_PRINT(x) \ + { \ + std::cout << x; \ + } \ + (void)0 +# define GHOST_PRINTF(x, ...) \ + { \ + printf(x, __VA_ARGS__); \ + } \ + (void)0 #else // GHOST_DEBUG # define GHOST_PRINT(x) # define GHOST_PRINTF(x, ...) -#endif // GHOST_DEBUG +#endif // GHOST_DEBUG #ifdef WITH_ASSERT_ABORT -# include <stdio.h> //for fprintf() -# include <stdlib.h> //for abort() -# define GHOST_ASSERT(x, info) \ - { \ - if (!(x)) { \ - fprintf(stderr, "GHOST_ASSERT failed: "); \ - fprintf(stderr, info); \ - fprintf(stderr, "\n"); \ - abort(); \ - } \ - } (void)0 +# include <stdio.h> //for fprintf() +# include <stdlib.h> //for abort() +# define GHOST_ASSERT(x, info) \ + { \ + if (!(x)) { \ + fprintf(stderr, "GHOST_ASSERT failed: "); \ + fprintf(stderr, info); \ + fprintf(stderr, "\n"); \ + abort(); \ + } \ + } \ + (void)0 #elif defined(GHOST_DEBUG) -# define GHOST_ASSERT(x, info) \ - { \ - if (!(x)) { \ - GHOST_PRINT("GHOST_ASSERT failed: "); \ - GHOST_PRINT(info); \ - GHOST_PRINT("\n"); \ - } \ - } (void)0 +# define GHOST_ASSERT(x, info) \ + { \ + if (!(x)) { \ + GHOST_PRINT("GHOST_ASSERT failed: "); \ + GHOST_PRINT(info); \ + GHOST_PRINT("\n"); \ + } \ + } \ + (void)0 #else // GHOST_DEBUG # define GHOST_ASSERT(x, info) ((void)0) -#endif // GHOST_DEBUG +#endif // GHOST_DEBUG -#endif // __GHOST_DEBUG_H__ +#endif // __GHOST_DEBUG_H__ diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp index 30dc78f063a..d8321bb1732 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.cpp +++ b/intern/ghost/intern/GHOST_DisplayManager.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -29,183 +28,156 @@ #include "GHOST_DisplayManager.h" #include "GHOST_Debug.h" - -GHOST_DisplayManager::GHOST_DisplayManager(void) - : m_settingsInitialized(false) +GHOST_DisplayManager::GHOST_DisplayManager(void) : m_settingsInitialized(false) { } - GHOST_DisplayManager::~GHOST_DisplayManager(void) { } - -GHOST_TSuccess -GHOST_DisplayManager::initialize( - 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 success; + if (!m_settingsInitialized) { + success = initializeSettings(); + m_settingsInitialized = true; + } + else { + success = GHOST_kSuccess; + } + return success; } - -GHOST_TSuccess -GHOST_DisplayManager::getNumDisplays( - GHOST_TUns8& /*numDisplays*/) const +GHOST_TSuccess GHOST_DisplayManager::getNumDisplays(GHOST_TUns8 & /*numDisplays*/) const { - // Don't know if we have a display... - return GHOST_kFailure; + // 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 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 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 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 && ((GHOST_TUns8)index < m_settings[display].size())) { - setting = m_settings[display][index]; - } - else { - success = GHOST_kFailure; - } - } - return success; + 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 && ((GHOST_TUns8)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 +GHOST_TSuccess GHOST_DisplayManager::getCurrentDisplaySetting( + GHOST_TUns8 /*display*/, GHOST_DisplaySetting & /*setting*/) const { - return GHOST_kFailure; + return GHOST_kFailure; } - -GHOST_TSuccess -GHOST_DisplayManager::setCurrentDisplaySetting( - GHOST_TUns8 /*display*/, - const GHOST_DisplaySetting& /*setting*/) +GHOST_TSuccess GHOST_DisplayManager::setCurrentDisplaySetting( + GHOST_TUns8 /*display*/, const GHOST_DisplaySetting & /*setting*/) { - return GHOST_kFailure; + return GHOST_kFailure; } - -GHOST_TSuccess -GHOST_DisplayManager::findMatch( - GHOST_TUns8 display, - const GHOST_DisplaySetting& setting, - GHOST_DisplaySetting& match) const +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] = { - (int)setting.xPixels, - (int)setting.yPixels, - (int)setting.bpp, - (int)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 success = GHOST_kSuccess; + GHOST_ASSERT(m_settingsInitialized, + "GHOST_DisplayManager::findMatch(): m_settingsInitialized=false"); + + int criteria[4] = { + (int)setting.xPixels, (int)setting.yPixels, (int)setting.bpp, (int)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_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; + GHOST_TUns8 numDisplays; + GHOST_TSuccess success = getNumDisplays(numDisplays); + if (success == GHOST_kSuccess) { + for (GHOST_TUns8 display = 0; (display < numDisplays) && (success == GHOST_kSuccess); + display++) { + GHOST_DisplaySettings displaySettings; + m_settings.push_back(displaySettings); + GHOST_TInt32 numSettings; + success = getNumDisplaySettings(display, numSettings); + if (success == GHOST_kSuccess) { + GHOST_TInt32 index; + GHOST_DisplaySetting setting; + for (index = 0; (index < numSettings) && (success == GHOST_kSuccess); index++) { + success = getDisplaySetting(display, index, setting); + m_settings[display].push_back(setting); + } + } + else { + break; + } + } + } + return success; } diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h index 67ab14d2cf9..58b36c0035b 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.h +++ b/intern/ghost/intern/GHOST_DisplayManager.h @@ -32,103 +32,100 @@ /** * 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 numSettings 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 against the available display 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; - +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 numSettings 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 against the available display 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; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DisplayManager") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DisplayManager") #endif }; - -#endif // __GHOST_DISPLAYMANAGER_H__ +#endif // __GHOST_DISPLAYMANAGER_H__ diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h index 5300cd0b50b..cfdc7be357e 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h @@ -26,8 +26,8 @@ #define __GHOST_DISPLAYMANAGERCOCOA_H__ #ifndef __APPLE__ -#error Apple only! -#endif // __APPLE__ +# error Apple only! +#endif // __APPLE__ #include "GHOST_DisplayManager.h" @@ -35,61 +35,63 @@ * Manages system displays (Mac OSX/Cocoa implementation). * \see GHOST_DisplayManager */ -class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager -{ -public: - /** - * Constructor. - */ - GHOST_DisplayManagerCocoa(void); +class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { + public: + /** + * Constructor. + */ + GHOST_DisplayManagerCocoa(void); - /** - * 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 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 numSetting: 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 number of display settings for this display device. + * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param numSetting: 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 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; + /** + * 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); + /** + * 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); -protected: - //Do not cache values as OS X supports screen hot plug - /** Cached number of displays. */ - //CGDisplayCount m_numDisplays; - /** Cached display id's for each display. */ - //CGDirectDisplayID* m_displayIDs; + protected: + //Do not cache values as OS X supports screen hot plug + /** Cached number of displays. */ + //CGDisplayCount m_numDisplays; + /** Cached display id's for each display. */ + //CGDirectDisplayID* m_displayIDs; }; - -#endif // __GHOST_DISPLAYMANAGERCOCOA_H__ +#endif // __GHOST_DISPLAYMANAGERCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm index 74508e1345a..7f44a14f49c 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm @@ -15,7 +15,7 @@ * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. - Damien Plisson 10/2009 + Damien Plisson 10/2009 */ #include <Cocoa/Cocoa.h> @@ -25,130 +25,141 @@ // We do not support multiple monitors at the moment - GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void) { } - -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8 &numDisplays) const { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - numDisplays = (GHOST_TUns8) [[NSScreen screens] count]; + numDisplays = (GHOST_TUns8)[[NSScreen screens] count]; - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32 &numSettings) const { - numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel + numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel - return GHOST_kSuccess; + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting &setting) const { - NSScreen *askedDisplay; + NSScreen *askedDisplay; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (display == kMainDisplay) //Screen #0 may not be the main one - askedDisplay = [NSScreen mainScreen]; - else - askedDisplay = [[NSScreen screens] objectAtIndex:display]; + if (display == kMainDisplay) //Screen #0 may not be the main one + askedDisplay = [NSScreen mainScreen]; + else + askedDisplay = [[NSScreen screens] objectAtIndex:display]; - if (askedDisplay == nil) { - [pool drain]; - return GHOST_kFailure; - } + if (askedDisplay == nil) { + [pool drain]; + return GHOST_kFailure; + } - NSRect frame = [askedDisplay visibleFrame]; - setting.xPixels = frame.size.width; - setting.yPixels = frame.size.height; + NSRect frame = [askedDisplay visibleFrame]; + setting.xPixels = frame.size.width; + setting.yPixels = frame.size.height; - setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); + setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); - setting.frequency = 0; //No more CRT display... + setting.frequency = 0; //No more CRT display... #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 - - [pool drain]; - return GHOST_kSuccess; + printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", + setting.xPixels, + setting.yPixels, + setting.bpp, + setting.frequency); +#endif // GHOST_DEBUG + + [pool drain]; + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting( + GHOST_TUns8 display, GHOST_DisplaySetting &setting) const { - NSScreen *askedDisplay; + NSScreen *askedDisplay; - GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported"); + GHOST_ASSERT( + (display == kMainDisplay), + "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (display == kMainDisplay) //Screen #0 may not be the main one - askedDisplay = [NSScreen mainScreen]; - else - askedDisplay = [[NSScreen screens] objectAtIndex:display]; + if (display == kMainDisplay) //Screen #0 may not be the main one + askedDisplay = [NSScreen mainScreen]; + else + askedDisplay = [[NSScreen screens] objectAtIndex:display]; - if (askedDisplay == nil) { - [pool drain]; - return GHOST_kFailure; - } + if (askedDisplay == nil) { + [pool drain]; + return GHOST_kFailure; + } - NSRect frame = [askedDisplay visibleFrame]; - setting.xPixels = frame.size.width; - setting.yPixels = frame.size.height; + NSRect frame = [askedDisplay visibleFrame]; + setting.xPixels = frame.size.width; + setting.yPixels = frame.size.height; - setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); + setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); - setting.frequency = 0; //No more CRT display... + setting.frequency = 0; //No more CRT display... #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 - - [pool drain]; - return GHOST_kSuccess; + printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", + setting.xPixels, + setting.yPixels, + setting.bpp, + setting.frequency); +#endif // GHOST_DEBUG + + [pool drain]; + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting) +GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting( + GHOST_TUns8 display, const GHOST_DisplaySetting &setting) { - GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported"); + GHOST_ASSERT( + (display == kMainDisplay), + "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported"); #ifdef GHOST_DEBUG - printf("GHOST_DisplayManagerCocoa::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 - - //Display configuration is no more available in 10.6 - -/* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate( - m_displayIDs[display], - (size_t)setting.bpp, - (size_t)setting.xPixels, - (size_t)setting.yPixels, - (CGRefreshRate)setting.frequency, - NULL);*/ + printf("GHOST_DisplayManagerCocoa::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 + + //Display configuration is no more available in 10.6 + + /* 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_DisplayManagerCocoa::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 +/* printf("GHOST_DisplayManagerCocoa::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); + //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues); - return /*err == CGDisplayNoErr ?*/ GHOST_kSuccess /*: GHOST_kFailure*/; + return /*err == CGDisplayNoErr ?*/ GHOST_kSuccess /*: GHOST_kFailure*/; } diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h index 13bd777c2f9..266a3e9a699 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h @@ -27,18 +27,36 @@ class GHOST_SystemNULL; -class GHOST_DisplayManagerNULL : public GHOST_DisplayManager -{ -public: - GHOST_DisplayManagerNULL( GHOST_SystemNULL *system ) : GHOST_DisplayManager(), m_system(system) { /* nop */ } - GHOST_TSuccess getNumDisplays( GHOST_TUns8& numDisplays ) const { return GHOST_kFailure; } - GHOST_TSuccess getNumDisplaySettings( GHOST_TUns8 display, GHOST_TInt32& numSettings ) const{ return GHOST_kFailure; } - GHOST_TSuccess getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting ) const { return GHOST_kFailure; } - GHOST_TSuccess getCurrentDisplaySetting( GHOST_TUns8 display, GHOST_DisplaySetting& setting ) const { return getDisplaySetting(display,GHOST_TInt32(0),setting); } - GHOST_TSuccess setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ) { return GHOST_kSuccess; } +class GHOST_DisplayManagerNULL : public GHOST_DisplayManager { + public: + GHOST_DisplayManagerNULL(GHOST_SystemNULL *system) : GHOST_DisplayManager(), m_system(system) + { /* nop */ + } + GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const + { + return GHOST_kFailure; + } + GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const + { + return GHOST_kFailure; + } + GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting &setting) const + { + return GHOST_kFailure; + } + GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + { + return getDisplaySetting(display, GHOST_TInt32(0), setting); + } + GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting &setting) + { + return GHOST_kSuccess; + } -private: - GHOST_SystemNULL * m_system; + private: + GHOST_SystemNULL *m_system; }; #endif /* __GHOST_DISPLAYMANAGERNULL_H__ */ diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp index 2b2c1e39e95..059f04992fb 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp @@ -28,151 +28,141 @@ #include "GHOST_WindowManager.h" GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) - : GHOST_DisplayManager(), - m_system(system) + : GHOST_DisplayManager(), m_system(system) { - memset(&m_mode, 0, sizeof(m_mode)); + memset(&m_mode, 0, sizeof(m_mode)); } -GHOST_TSuccess -GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8 &numDisplays) const { - numDisplays = SDL_GetNumVideoDisplays(); - return GHOST_kSuccess; + numDisplays = SDL_GetNumVideoDisplays(); + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings) const + GHOST_TInt32 &numSettings) const { - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - numSettings = SDL_GetNumDisplayModes(display - 1); + numSettings = SDL_GetNumDisplayModes(display - 1); - return GHOST_kSuccess; + return GHOST_kSuccess; } -static void ghost_mode_from_sdl(GHOST_DisplaySetting& setting, SDL_DisplayMode *mode) +static void ghost_mode_from_sdl(GHOST_DisplaySetting &setting, SDL_DisplayMode *mode) { - setting.xPixels = mode->w; - setting.yPixels = mode->h; - setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; - /* Just guess the frequency :( */ - setting.frequency = mode->refresh_rate ? mode->refresh_rate : 60; + setting.xPixels = mode->w; + setting.yPixels = mode->h; + setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; + /* Just guess the frequency :( */ + setting.frequency = mode->refresh_rate ? mode->refresh_rate : 60; } -static void ghost_mode_to_sdl(const GHOST_DisplaySetting& setting, SDL_DisplayMode *mode) +static void ghost_mode_to_sdl(const GHOST_DisplaySetting &setting, SDL_DisplayMode *mode) { - mode->w = setting.xPixels; - mode->h = setting.yPixels; - // setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; ??? - mode->refresh_rate = setting.frequency; + mode->w = setting.xPixels; + mode->h = setting.yPixels; + // setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; ??? + mode->refresh_rate = setting.frequency; } -GHOST_TSuccess -GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, - GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerSDL::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(display < 1, "Only single display systems are currently supported.\n"); - SDL_DisplayMode mode; - SDL_GetDisplayMode(display, index, &mode); + SDL_DisplayMode mode; + SDL_GetDisplayMode(display, index, &mode); - ghost_mode_from_sdl(setting, &mode); + ghost_mode_from_sdl(setting, &mode); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting( + GHOST_TUns8 display, GHOST_DisplaySetting &setting) const { - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(display, &mode); + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(display, &mode); - ghost_mode_from_sdl(setting, &mode); + ghost_mode_from_sdl(setting, &mode); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const +GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const { - mode = m_mode; - return GHOST_kSuccess; + mode = m_mode; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting& setting) +GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting( + GHOST_TUns8 display, const GHOST_DisplaySetting &setting) { - /* - * Mode switching code ported from Quake 2 version 3.21 and bzflag version - * 2.4.0: - * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip - * See linux/gl_glx.c:GLimp_SetMode - * http://wiki.bzflag.org/BZFlag_Source - * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow - */ - SDL_DisplayMode mode; - const int num_modes = SDL_GetNumDisplayModes(display); - int best_fit, best_dist, dist, x, y; - - best_dist = 9999999; - best_fit = -1; - - if (num_modes == 0) { - /* Any mode is OK. */ - ghost_mode_to_sdl(setting, &mode); - } - else { - for (int i = 0; i < num_modes; i++) { - - SDL_GetDisplayMode(display, i, &mode); - - if (setting.xPixels > mode.w || - setting.yPixels > mode.h) - { - continue; - } - - x = setting.xPixels - mode.w; - y = setting.yPixels - mode.h; - dist = (x * x) + (y * y); - if (dist < best_dist) { - best_dist = dist; - best_fit = i; - } - } - - if (best_fit == -1) - return GHOST_kFailure; - - SDL_GetDisplayMode(display, best_fit, &mode); - } - - m_mode = mode; - - /* evil, SDL2 needs a window to adjust display modes */ - GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow(); - - if (win) { - SDL_Window *sdl_win = win->getSDLWindow(); - - - SDL_SetWindowDisplayMode(sdl_win, &mode); - SDL_ShowWindow(sdl_win); - SDL_SetWindowFullscreen(sdl_win, SDL_TRUE); - - return GHOST_kSuccess; - } - else { - /* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point. - * we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */ - printf("no windows available, cant fullscreen\n"); - - /* do not fail, we will try again later when the window is created - wander */ - return GHOST_kSuccess; - } + /* + * Mode switching code ported from Quake 2 version 3.21 and bzflag version + * 2.4.0: + * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + * See linux/gl_glx.c:GLimp_SetMode + * http://wiki.bzflag.org/BZFlag_Source + * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow + */ + SDL_DisplayMode mode; + const int num_modes = SDL_GetNumDisplayModes(display); + int best_fit, best_dist, dist, x, y; + + best_dist = 9999999; + best_fit = -1; + + if (num_modes == 0) { + /* Any mode is OK. */ + ghost_mode_to_sdl(setting, &mode); + } + else { + for (int i = 0; i < num_modes; i++) { + + SDL_GetDisplayMode(display, i, &mode); + + if (setting.xPixels > mode.w || setting.yPixels > mode.h) { + continue; + } + + x = setting.xPixels - mode.w; + y = setting.yPixels - mode.h; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit == -1) + return GHOST_kFailure; + + SDL_GetDisplayMode(display, best_fit, &mode); + } + + m_mode = mode; + + /* evil, SDL2 needs a window to adjust display modes */ + GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow(); + + if (win) { + SDL_Window *sdl_win = win->getSDLWindow(); + + SDL_SetWindowDisplayMode(sdl_win, &mode); + SDL_ShowWindow(sdl_win); + SDL_SetWindowFullscreen(sdl_win, SDL_TRUE); + + return GHOST_kSuccess; + } + else { + /* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point. + * we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */ + printf("no windows available, cant fullscreen\n"); + + /* do not fail, we will try again later when the window is created - wander */ + return GHOST_kSuccess; + } } diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h index 913eaf17bb0..f7704d57ab0 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h @@ -25,7 +25,7 @@ #include "GHOST_DisplayManager.h" extern "C" { - #include "SDL.h" +#include "SDL.h" } #if !SDL_VERSION_ATLEAST(2, 0, 0) @@ -34,37 +34,29 @@ extern "C" { class GHOST_SystemSDL; -class GHOST_DisplayManagerSDL : public GHOST_DisplayManager -{ -public: - GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); +class GHOST_DisplayManagerSDL : public GHOST_DisplayManager { + public: + GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); - GHOST_TSuccess - getNumDisplays(GHOST_TUns8& numDisplays) const; + GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; - GHOST_TSuccess - getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings) const; + GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const; - GHOST_TSuccess - getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, - GHOST_DisplaySetting& setting) const; + GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting &setting) const; - GHOST_TSuccess - getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting) const; + GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, + GHOST_DisplaySetting &setting) const; - GHOST_TSuccess - getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const; + GHOST_TSuccess getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const; - GHOST_TSuccess - setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting& setting); + GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, + const GHOST_DisplaySetting &setting); -private: - GHOST_SystemSDL *m_system; - SDL_DisplayMode m_mode; + private: + GHOST_SystemSDL *m_system; + SDL_DisplayMode m_mode; }; #endif /* __GHOST_DISPLAYMANAGERSDL_H__ */ diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp index da47fe9a65c..3b28f055191 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp @@ -25,7 +25,7 @@ #include "GHOST_Debug.h" #undef _WIN32_WINNT -#define _WIN32_WINNT 0x501 // require Windows XP or newer +#define _WIN32_WINNT 0x501 // require Windows XP or newer #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -33,22 +33,20 @@ #define COMPILE_MULTIMON_STUBS #include <multimon.h> - GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void) { } - -GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8 &numDisplays) const { - numDisplays = ::GetSystemMetrics(SM_CMONITORS); - return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure; + numDisplays = ::GetSystemMetrics(SM_CMONITORS); + return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure; } static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd) { - dd->cb = sizeof(DISPLAY_DEVICE); - return ::EnumDisplayDevices(NULL, d, dd, 0); + dd->cb = sizeof(DISPLAY_DEVICE); + return ::EnumDisplayDevices(NULL, d, dd, 0); } /* @@ -58,125 +56,134 @@ static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd) * 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_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32 &numSettings) const { - DISPLAY_DEVICE display_device; - if (!get_dd(display, &display_device)) return GHOST_kFailure; - - numSettings = 0; - DEVMODE dm; - while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) { - numSettings++; - } - return GHOST_kSuccess; + DISPLAY_DEVICE display_device; + if (!get_dd(display, &display_device)) + return GHOST_kFailure; + + numSettings = 0; + DEVMODE dm; + while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) { + numSettings++; + } + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting &setting) const { - DISPLAY_DEVICE display_device; - if (!get_dd(display, &display_device)) return GHOST_kFailure; + DISPLAY_DEVICE display_device; + if (!get_dd(display, &display_device)) + return GHOST_kFailure; - GHOST_TSuccess success; - DEVMODE dm; - if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) { + GHOST_TSuccess success; + DEVMODE dm; + if (::EnumDisplaySettings(display_device.DeviceName, 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; + 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_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting( + GHOST_TUns8 display, GHOST_DisplaySetting &setting) const { - return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting); + return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting); } - -GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting) +GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting( + GHOST_TUns8 display, const GHOST_DisplaySetting &setting) { - DISPLAY_DEVICE display_device; - if (!get_dd(display, &display_device)) return GHOST_kFailure; - - GHOST_DisplaySetting match; - findMatch(display, setting, match); - DEVMODE dm; - int i = 0; - while (::EnumDisplaySettings(display_device.DeviceName, 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; - */ + DISPLAY_DEVICE display_device; + if (!get_dd(display, &display_device)) + return GHOST_kFailure; + + GHOST_DisplaySetting match; + findMatch(display, setting, match); + DEVMODE dm; + int i = 0; + while (::EnumDisplaySettings(display_device.DeviceName, 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); + 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; + switch (status) { + case DISP_CHANGE_SUCCESSFUL: + printf("display change: The settings change was successful.\n"); + break; + case DISP_CHANGE_RESTART: + printf( + "display change: The computer must be restarted in order for the graphics mode to " + "work.\n"); + break; + case DISP_CHANGE_BADFLAGS: + printf("display change: An invalid set of flags was passed in.\n"); + break; + case DISP_CHANGE_BADPARAM: + printf( + "display change: An invalid parameter was passed in. " + "This can include an invalid flag or combination of flags.\n"); + break; + case DISP_CHANGE_FAILED: + printf("display change: The display driver failed the specified graphics mode.\n"); + break; + case DISP_CHANGE_BADMODE: + printf("display change: The graphics mode is not supported.\n"); + break; + case DISP_CHANGE_NOTUPDATED: + printf("display change: Windows NT: Unable to write settings to the registry.\n"); + break; + default: + printf("display change: Return value invalid\n"); + break; + } +#endif // GHOST_DEBUG + return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure; } diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h index 857f96d7cef..c4ad90b1de7 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h @@ -26,65 +26,66 @@ #define __GHOST_DISPLAYMANAGERWIN32_H__ #ifndef WIN32 -#error WIN32 only! -#endif // 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); +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. - */ - GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const; + /** + * 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 numSetting: 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 number of display settings for this display device. + * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param numSetting: 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 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; + /** + * 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); + /** + * 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); -protected: + protected: }; - -#endif // __GHOST_DISPLAYMANAGERWIN32_H__ +#endif // __GHOST_DISPLAYMANAGERWIN32_H__ diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 1500da8028e..4626955ac7f 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -32,238 +32,209 @@ #include "GHOST_DisplayManagerX11.h" #include "GHOST_SystemX11.h" - -GHOST_DisplayManagerX11:: -GHOST_DisplayManagerX11( - GHOST_SystemX11 *system) - : GHOST_DisplayManager(), - m_system(system) +GHOST_DisplayManagerX11::GHOST_DisplayManagerX11(GHOST_SystemX11 *system) + : GHOST_DisplayManager(), m_system(system) { - /* nothing to do. */ + /* nothing to do. */ } -GHOST_TSuccess -GHOST_DisplayManagerX11:: -getNumDisplays(GHOST_TUns8& numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplays(GHOST_TUns8 &numDisplays) const { - numDisplays = m_system->getNumDisplays(); - return GHOST_kSuccess; + numDisplays = m_system->getNumDisplays(); + return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_DisplayManagerX11:: -getNumDisplaySettings( - GHOST_TUns8 display, - GHOST_TInt32& numSettings) const +GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32 &numSettings) const { #ifdef WITH_X11_XF86VMODE - int majorVersion, minorVersion; - XF86VidModeModeInfo **vidmodes; - Display *dpy = m_system->getXDisplay(); + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - if (dpy == NULL) - return GHOST_kFailure; + if (dpy == NULL) + return GHOST_kFailure; - majorVersion = minorVersion = 0; - if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { - fprintf(stderr, "Error: XF86VidMode extension missing!\n"); - return GHOST_kFailure; - } + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } - if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { - XFree(vidmodes); - } + if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { + XFree(vidmodes); + } #else - /* We only have one X11 setting at the moment. */ - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - numSettings = 1; + /* We only have one X11 setting at the moment. */ + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + numSettings = 1; #endif - (void) display; - return GHOST_kSuccess; + (void)display; + return GHOST_kSuccess; } /* from SDL2 */ #ifdef WITH_X11_XF86VMODE -static int -calculate_rate(XF86VidModeModeInfo *info) +static int calculate_rate(XF86VidModeModeInfo *info) { - return (info->htotal - && info->vtotal) ? (1000 * info->dotclock / (info->htotal * - info->vtotal)) : 0; + return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) : + 0; } #endif -GHOST_TSuccess -GHOST_DisplayManagerX11:: -getDisplaySetting( - GHOST_TUns8 display, - GHOST_TInt32 index, - GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting &setting) const { - Display *dpy = m_system->getXDisplay(); + Display *dpy = m_system->getXDisplay(); - if (dpy == NULL) - return GHOST_kFailure; + if (dpy == NULL) + return GHOST_kFailure; - (void)display; + (void)display; #ifdef WITH_X11_XF86VMODE - int majorVersion, minorVersion; - - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - - majorVersion = minorVersion = 0; - if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { - XF86VidModeModeInfo **vidmodes; - int numSettings; - - if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { - GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); - - setting.xPixels = vidmodes[index]->hdisplay; - setting.yPixels = vidmodes[index]->vdisplay; - setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); - setting.frequency = calculate_rate(vidmodes[index]); - XFree(vidmodes); - - return GHOST_kSuccess; - } - } - else { - fprintf(stderr, "Warning: XF86VidMode extension missing!\n"); - /* fallback to non xf86vmode below */ - } -#endif /* WITH_X11_XF86VMODE */ - - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); - (void)index; - - setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); - setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); - setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); - setting.frequency = 60.0f; - - return GHOST_kSuccess; + int majorVersion, minorVersion; + + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + + majorVersion = minorVersion = 0; + if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + XF86VidModeModeInfo **vidmodes; + int numSettings; + + if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { + GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); + + setting.xPixels = vidmodes[index]->hdisplay; + setting.yPixels = vidmodes[index]->vdisplay; + setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); + setting.frequency = calculate_rate(vidmodes[index]); + XFree(vidmodes); + + return GHOST_kSuccess; + } + } + else { + fprintf(stderr, "Warning: XF86VidMode extension missing!\n"); + /* fallback to non xf86vmode below */ + } +#endif /* WITH_X11_XF86VMODE */ + + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); + (void)index; + + setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); + setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); + setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); + setting.frequency = 60.0f; + + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_DisplayManagerX11:: -getCurrentDisplaySetting( - GHOST_TUns8 display, - GHOST_DisplaySetting& setting) const +GHOST_TSuccess GHOST_DisplayManagerX11::getCurrentDisplaySetting( + GHOST_TUns8 display, GHOST_DisplaySetting &setting) const { - /* According to the xf86vidmodegetallmodelines man page, - * "The first element of the array corresponds to the current video mode." - */ - return getDisplaySetting(display, 0, setting); + /* According to the xf86vidmodegetallmodelines man page, + * "The first element of the array corresponds to the current video mode." + */ + return getDisplaySetting(display, 0, setting); } - -GHOST_TSuccess -GHOST_DisplayManagerX11:: -setCurrentDisplaySetting( - GHOST_TUns8 /*display*/, - const GHOST_DisplaySetting& setting) +GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting( + GHOST_TUns8 /*display*/, const GHOST_DisplaySetting &setting) { #ifdef WITH_X11_XF86VMODE - /* Mode switching code ported from SDL: - * See: src/video/x11/SDL_x11modes.c:set_best_resolution - */ - int majorVersion, minorVersion; - XF86VidModeModeInfo **vidmodes; - Display *dpy = m_system->getXDisplay(); - int scrnum, num_vidmodes; - - if (dpy == NULL) - return GHOST_kFailure; - - scrnum = DefaultScreen(dpy); - - /* Get video mode list */ - majorVersion = minorVersion = 0; - if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { - fprintf(stderr, "Error: XF86VidMode extension missing!\n"); - return GHOST_kFailure; - } + /* Mode switching code ported from SDL: + * See: src/video/x11/SDL_x11modes.c:set_best_resolution + */ + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + int scrnum, num_vidmodes; + + if (dpy == NULL) + return GHOST_kFailure; + + scrnum = DefaultScreen(dpy); + + /* Get video mode list */ + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } # ifdef DEBUG - printf("Using XFree86-VidModeExtension Version %d.%d\n", - majorVersion, minorVersion); + printf("Using XFree86-VidModeExtension Version %d.%d\n", majorVersion, minorVersion); # endif - if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) { - int best_fit = -1; - - for (int i = 0; i < num_vidmodes; i++) { - if (vidmodes[i]->hdisplay < setting.xPixels || - vidmodes[i]->vdisplay < setting.yPixels) - { - continue; - } - - if (best_fit == -1 || - (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) || - (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay && - vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) - { - best_fit = i; - continue; - } - - if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) && - (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) - { - if (!setting.frequency) { - /* Higher is better, right? */ - if (calculate_rate(vidmodes[i]) > - calculate_rate(vidmodes[best_fit])) - { - best_fit = i; - } - } - else { - if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) < - abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) - { - best_fit = i; - } - } - } - } - - if (best_fit != -1) { + if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) { + int best_fit = -1; + + for (int i = 0; i < num_vidmodes; i++) { + if (vidmodes[i]->hdisplay < setting.xPixels || vidmodes[i]->vdisplay < setting.yPixels) { + continue; + } + + if (best_fit == -1 || (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) || + (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay && + vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) { + best_fit = i; + continue; + } + + if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) && + (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) { + if (!setting.frequency) { + /* Higher is better, right? */ + if (calculate_rate(vidmodes[i]) > calculate_rate(vidmodes[best_fit])) { + best_fit = i; + } + } + else { + if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) < + abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) { + best_fit = i; + } + } + } + } + + if (best_fit != -1) { # ifdef DEBUG - printf("Switching to video mode %dx%d %dx%d %d\n", - vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay, - vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal, - calculate_rate(vidmodes[best_fit])); + printf("Switching to video mode %dx%d %dx%d %d\n", + vidmodes[best_fit]->hdisplay, + vidmodes[best_fit]->vdisplay, + vidmodes[best_fit]->htotal, + vidmodes[best_fit]->vtotal, + calculate_rate(vidmodes[best_fit])); # endif - /* change to the mode */ - XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + /* change to the mode */ + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); - /* Move the viewport to top left */ - XF86VidModeSetViewPort(dpy, scrnum, 0, 0); - } + /* Move the viewport to top left */ + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } - XFree(vidmodes); - } - else { - return GHOST_kFailure; - } + XFree(vidmodes); + } + else { + return GHOST_kFailure; + } - XFlush(dpy); - return GHOST_kSuccess; + XFlush(dpy); + return GHOST_kSuccess; #else - (void)setting; + (void)setting; - /* Just pretend the request was successful. */ - return GHOST_kSuccess; + /* Just pretend the request was successful. */ + return GHOST_kSuccess; #endif } diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h index 9b28f6cc42e..941152aa034 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.h +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h @@ -27,86 +27,64 @@ #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; +class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { + public: + /** + * Constructor. + */ + GHOST_DisplayManagerX11(GHOST_SystemX11 *system); - /** - * Returns the number of display settings for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param numSetting: 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 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 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 number of display settings for this display device. + * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param numSetting: 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 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; + /** + * 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; - /** - * 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 - ); + /** + * 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; -private: + /** + * 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); - GHOST_SystemX11 *m_system; + private: + GHOST_SystemX11 *m_system; }; - -#endif // +#endif // diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp index 014b8ab13d0..b41a133a069 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - #include "GHOST_Debug.h" #include "GHOST_DropTargetWin32.h" #include <shellapi.h> @@ -32,54 +31,48 @@ #ifdef GHOST_DEBUG // utility void printLastError(void); -#endif // GHOST_DEBUG - +#endif // GHOST_DEBUG -GHOST_DropTargetWin32::GHOST_DropTargetWin32( - GHOST_WindowWin32 *window, - GHOST_SystemWin32 *system) - : m_window(window), - m_system(system) +GHOST_DropTargetWin32::GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system) + : m_window(window), m_system(system) { - m_cRef = 1; - m_hWnd = window->getHWND(); - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + m_cRef = 1; + m_hWnd = window->getHWND(); + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; } GHOST_DropTargetWin32::~GHOST_DropTargetWin32() { } - /* * IUnknown::QueryInterface */ HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface(REFIID riid, void **ppvObj) { - if (!ppvObj) - return E_INVALIDARG; - *ppvObj = NULL; - - if (riid == IID_IUnknown || riid == IID_IDropTarget) { - AddRef(); - *ppvObj = (void *)this; - return S_OK; - } - else { - *ppvObj = NULL; - return E_NOINTERFACE; - } + if (!ppvObj) + return E_INVALIDARG; + *ppvObj = NULL; + + if (riid == IID_IUnknown || riid == IID_IDropTarget) { + AddRef(); + *ppvObj = (void *)this; + return S_OK; + } + else { + *ppvObj = NULL; + return E_NOINTERFACE; + } } - /* * IUnknown::AddRef */ ULONG __stdcall GHOST_DropTargetWin32::AddRef(void) { - return ::InterlockedIncrement(&m_cRef); + return ::InterlockedIncrement(&m_cRef); } /* @@ -87,29 +80,33 @@ ULONG __stdcall GHOST_DropTargetWin32::AddRef(void) */ ULONG __stdcall GHOST_DropTargetWin32::Release(void) { - ULONG refs = ::InterlockedDecrement(&m_cRef); - - if (refs == 0) { - delete this; - return 0; - } - else { - return refs; - } + ULONG refs = ::InterlockedDecrement(&m_cRef); + + if (refs == 0) { + delete this; + return 0; + } + else { + return refs; + } } /* * Implementation of IDropTarget::DragEnter */ -HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) +HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) { - // we accept all drop by default - m_window->setAcceptDragOperation(true); - *pdwEffect = DROPEFFECT_NONE; - - m_draggedObjectType = getGhostType(pDataObject); - m_system->pushDragDropEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, m_window, pt.x, pt.y, NULL); - return S_OK; + // we accept all drop by default + m_window->setAcceptDragOperation(true); + *pdwEffect = DROPEFFECT_NONE; + + m_draggedObjectType = getGhostType(pDataObject); + m_system->pushDragDropEvent( + GHOST_kEventDraggingEntered, m_draggedObjectType, m_window, pt.x, pt.y, NULL); + return S_OK; } /* @@ -117,15 +114,16 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWO */ HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { - if (m_window->canAcceptDragOperation()) { - *pdwEffect = allowedDropEffect(*pdwEffect); - } - else { - *pdwEffect = DROPEFFECT_NONE; - // *pdwEffect = DROPEFFECT_COPY; // XXX Uncomment to test drop. Drop will not be called if pdwEffect == DROPEFFECT_NONE. - } - m_system->pushDragDropEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, m_window, pt.x, pt.y, NULL); - return S_OK; + if (m_window->canAcceptDragOperation()) { + *pdwEffect = allowedDropEffect(*pdwEffect); + } + else { + *pdwEffect = DROPEFFECT_NONE; + // *pdwEffect = DROPEFFECT_COPY; // XXX Uncomment to test drop. Drop will not be called if pdwEffect == DROPEFFECT_NONE. + } + m_system->pushDragDropEvent( + GHOST_kEventDraggingUpdated, m_draggedObjectType, m_window, pt.x, pt.y, NULL); + return S_OK; } /* @@ -133,30 +131,34 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt, */ HRESULT __stdcall GHOST_DropTargetWin32::DragLeave(void) { - m_system->pushDragDropEvent(GHOST_kEventDraggingExited, m_draggedObjectType, m_window, 0, 0, NULL); - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; - return S_OK; + m_system->pushDragDropEvent( + GHOST_kEventDraggingExited, m_draggedObjectType, m_window, 0, 0, NULL); + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + return S_OK; } /* Implementation of IDropTarget::Drop * This function will not be called if pdwEffect is set to DROPEFFECT_NONE in * the implementation of IDropTarget::DragOver */ -HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) +HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) { - void *data = getGhostData(pDataObject); - if (m_window->canAcceptDragOperation()) { - *pdwEffect = allowedDropEffect(*pdwEffect); - - } - else { - *pdwEffect = DROPEFFECT_NONE; - } - if (data) - m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, pt.x, pt.y, data); - - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; - return S_OK; + void *data = getGhostData(pDataObject); + if (m_window->canAcceptDragOperation()) { + *pdwEffect = allowedDropEffect(*pdwEffect); + } + else { + *pdwEffect = DROPEFFECT_NONE; + } + if (data) + m_system->pushDragDropEvent( + GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, pt.x, pt.y, data); + + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + return S_OK; } /* @@ -165,222 +167,214 @@ HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD gr DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dwAllowed) { - DWORD dwEffect = DROPEFFECT_NONE; - if (dwAllowed & DROPEFFECT_COPY) - dwEffect = DROPEFFECT_COPY; + DWORD dwEffect = DROPEFFECT_NONE; + if (dwAllowed & DROPEFFECT_COPY) + dwEffect = DROPEFFECT_COPY; - return dwEffect; + return dwEffect; } GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject *pDataObject) { - /* Text - * Note: Unicode text is available as CF_TEXT too, the system can do the - * conversion, but we do the conversion ourself with WC_NO_BEST_FIT_CHARS. - */ - FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - if (pDataObject->QueryGetData(&fmtetc) == S_OK) { - return GHOST_kDragnDropTypeString; - } - - // Filesnames - fmtetc.cfFormat = CF_HDROP; - if (pDataObject->QueryGetData(&fmtetc) == S_OK) { - return GHOST_kDragnDropTypeFilenames; - } - - return GHOST_kDragnDropTypeUnknown; + /* Text + * Note: Unicode text is available as CF_TEXT too, the system can do the + * conversion, but we do the conversion ourself with WC_NO_BEST_FIT_CHARS. + */ + FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + if (pDataObject->QueryGetData(&fmtetc) == S_OK) { + return GHOST_kDragnDropTypeString; + } + + // Filesnames + fmtetc.cfFormat = CF_HDROP; + if (pDataObject->QueryGetData(&fmtetc) == S_OK) { + return GHOST_kDragnDropTypeFilenames; + } + + return GHOST_kDragnDropTypeUnknown; } void *GHOST_DropTargetWin32::getGhostData(IDataObject *pDataObject) { - GHOST_TDragnDropTypes type = getGhostType(pDataObject); - switch (type) { - case GHOST_kDragnDropTypeFilenames: - return getDropDataAsFilenames(pDataObject); - break; - case GHOST_kDragnDropTypeString: - return getDropDataAsString(pDataObject); - break; - case GHOST_kDragnDropTypeBitmap: - //return getDropDataAsBitmap(pDataObject); - break; - default: + GHOST_TDragnDropTypes type = getGhostType(pDataObject); + switch (type) { + case GHOST_kDragnDropTypeFilenames: + return getDropDataAsFilenames(pDataObject); + break; + case GHOST_kDragnDropTypeString: + return getDropDataAsString(pDataObject); + break; + case GHOST_kDragnDropTypeBitmap: + //return getDropDataAsBitmap(pDataObject); + break; + default: #ifdef GHOST_DEBUG - ::printf("\nGHOST_kDragnDropTypeUnknown"); -#endif // GHOST_DEBUG - return NULL; - break; - } - return NULL; + ::printf("\nGHOST_kDragnDropTypeUnknown"); +#endif // GHOST_DEBUG + return NULL; + break; + } + return NULL; } void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *pDataObject) { - UINT totfiles, nvalid = 0; - WCHAR fpath[MAX_PATH]; - char *temp_path; - GHOST_TStringArray *strArray = NULL; - FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM stgmed; - HDROP hdrop; - - // Check if dataobject supplies the format we want. - // Double checking here, first in getGhostType. - if (pDataObject->QueryGetData(&fmtetc) == S_OK) { - if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { - hdrop = (HDROP) ::GlobalLock(stgmed.hGlobal); - - totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0); - if (!totfiles) { - ::GlobalUnlock(stgmed.hGlobal); - return NULL; - } - - strArray = (GHOST_TStringArray *) ::malloc(sizeof(GHOST_TStringArray)); - strArray->count = 0; - strArray->strings = (GHOST_TUns8 **) ::malloc(totfiles * sizeof(GHOST_TUns8 *)); - - for (UINT nfile = 0; nfile < totfiles; nfile++) { - if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) { - if (!(temp_path = alloc_utf_8_from_16(fpath, 0)) ) { - continue; - } - // Just ignore paths that could not be converted verbatim. - - strArray->strings[nvalid] = (GHOST_TUns8 *) temp_path; - strArray->count = nvalid + 1; - nvalid++; - } - } - // Free up memory. - ::GlobalUnlock(stgmed.hGlobal); - ::ReleaseStgMedium(&stgmed); - - return strArray; - } - } - return NULL; + UINT totfiles, nvalid = 0; + WCHAR fpath[MAX_PATH]; + char *temp_path; + GHOST_TStringArray *strArray = NULL; + FORMATETC fmtetc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + STGMEDIUM stgmed; + HDROP hdrop; + + // Check if dataobject supplies the format we want. + // Double checking here, first in getGhostType. + if (pDataObject->QueryGetData(&fmtetc) == S_OK) { + if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { + hdrop = (HDROP)::GlobalLock(stgmed.hGlobal); + + totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0); + if (!totfiles) { + ::GlobalUnlock(stgmed.hGlobal); + return NULL; + } + + strArray = (GHOST_TStringArray *)::malloc(sizeof(GHOST_TStringArray)); + strArray->count = 0; + strArray->strings = (GHOST_TUns8 **)::malloc(totfiles * sizeof(GHOST_TUns8 *)); + + for (UINT nfile = 0; nfile < totfiles; nfile++) { + if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) { + if (!(temp_path = alloc_utf_8_from_16(fpath, 0))) { + continue; + } + // Just ignore paths that could not be converted verbatim. + + strArray->strings[nvalid] = (GHOST_TUns8 *)temp_path; + strArray->count = nvalid + 1; + nvalid++; + } + } + // Free up memory. + ::GlobalUnlock(stgmed.hGlobal); + ::ReleaseStgMedium(&stgmed); + + return strArray; + } + } + return NULL; } void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *pDataObject) { - char *tmp_string; - FORMATETC fmtetc = { CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM stgmed; - - // Try unicode first. - // Check if dataobject supplies the format we want. - if (pDataObject->QueryGetData(&fmtetc) == S_OK) { - if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { - LPCWSTR wstr = (LPCWSTR) ::GlobalLock(stgmed.hGlobal); - if (!(tmp_string = alloc_utf_8_from_16((wchar_t *)wstr, 0)) ) { - ::GlobalUnlock(stgmed.hGlobal); - return NULL; - } - // Free memory - ::GlobalUnlock(stgmed.hGlobal); - ::ReleaseStgMedium(&stgmed); + char *tmp_string; + FORMATETC fmtetc = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + STGMEDIUM stgmed; + + // Try unicode first. + // Check if dataobject supplies the format we want. + if (pDataObject->QueryGetData(&fmtetc) == S_OK) { + if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { + LPCWSTR wstr = (LPCWSTR)::GlobalLock(stgmed.hGlobal); + if (!(tmp_string = alloc_utf_8_from_16((wchar_t *)wstr, 0))) { + ::GlobalUnlock(stgmed.hGlobal); + return NULL; + } + // Free memory + ::GlobalUnlock(stgmed.hGlobal); + ::ReleaseStgMedium(&stgmed); #ifdef GHOST_DEBUG - ::printf("\n<converted droped unicode string>\n%s\n</droped converted unicode string>\n", tmp_string); -#endif // GHOST_DEBUG - return tmp_string; - } - } - - fmtetc.cfFormat = CF_TEXT; - - if (pDataObject->QueryGetData(&fmtetc) == S_OK) { - if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { - char *str = (char *)::GlobalLock(stgmed.hGlobal); - - tmp_string = (char *)::malloc(::strlen(str) + 1); - if (!tmp_string) { - ::GlobalUnlock(stgmed.hGlobal); - return NULL; - } - - if (!::strcpy(tmp_string, str) ) { - ::free(tmp_string); - ::GlobalUnlock(stgmed.hGlobal); - return NULL; - } - // Free memory - ::GlobalUnlock(stgmed.hGlobal); - ::ReleaseStgMedium(&stgmed); - - return tmp_string; - } - } - - return NULL; + ::printf("\n<converted droped unicode string>\n%s\n</droped converted unicode string>\n", + tmp_string); +#endif // GHOST_DEBUG + return tmp_string; + } + } + + fmtetc.cfFormat = CF_TEXT; + + if (pDataObject->QueryGetData(&fmtetc) == S_OK) { + if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { + char *str = (char *)::GlobalLock(stgmed.hGlobal); + + tmp_string = (char *)::malloc(::strlen(str) + 1); + if (!tmp_string) { + ::GlobalUnlock(stgmed.hGlobal); + return NULL; + } + + if (!::strcpy(tmp_string, str)) { + ::free(tmp_string); + ::GlobalUnlock(stgmed.hGlobal); + return NULL; + } + // Free memory + ::GlobalUnlock(stgmed.hGlobal); + ::ReleaseStgMedium(&stgmed); + + return tmp_string; + } + } + + return NULL; } -int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char * &out) +int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char *&out) { - int size; - out = NULL; //caller should free if != NULL - - // Get the required size. - size = ::WideCharToMultiByte(CP_ACP, //System Default Codepage - 0x00000400, // WC_NO_BEST_FIT_CHARS - in, - -1, //-1 null terminated, makes output null terminated too. - NULL, - 0, - NULL, NULL - ); - - if (!size) { + int size; + out = NULL; //caller should free if != NULL + + // Get the required size. + size = ::WideCharToMultiByte(CP_ACP, //System Default Codepage + 0x00000400, // WC_NO_BEST_FIT_CHARS + in, + -1, //-1 null terminated, makes output null terminated too. + NULL, + 0, + NULL, + NULL); + + if (!size) { #ifdef GHOST_DEBUG - ::printLastError(); -#endif // GHOST_DEBUG - return 0; - } - - out = (char *)::malloc(size); - if (!out) { - ::printf("\nmalloc failed!!!"); - return 0; - } - - size = ::WideCharToMultiByte(CP_ACP, - 0x00000400, - in, - -1, - (LPSTR) out, - size, - NULL, NULL - ); - - if (!size) { + ::printLastError(); +#endif // GHOST_DEBUG + return 0; + } + + out = (char *)::malloc(size); + if (!out) { + ::printf("\nmalloc failed!!!"); + return 0; + } + + size = ::WideCharToMultiByte(CP_ACP, 0x00000400, in, -1, (LPSTR)out, size, NULL, NULL); + + if (!size) { #ifdef GHOST_DEBUG - ::printLastError(); -#endif //GHOST_DEBUG - ::free(out); - out = NULL; - } - return size; + ::printLastError(); +#endif //GHOST_DEBUG + ::free(out); + out = NULL; + } + return size; } #ifdef GHOST_DEBUG void printLastError(void) { - LPTSTR s; - DWORD err; - - err = GetLastError(); - if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - err, - 0, - (LPTSTR)&s, - 0, - NULL)) - { - printf("\nLastError: (%d) %s\n", (int)err, s); - LocalFree(s); - } + LPTSTR s; + DWORD err; + + err = GetLastError(); + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + 0, + (LPTSTR)&s, + 0, + NULL)) { + printf("\nLastError: (%d) %s\n", (int)err, s); + LocalFree(s); + } } -#endif // GHOST_DEBUG +#endif // GHOST_DEBUG diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h index 2d78c384818..e1985f85640 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.h +++ b/intern/ghost/intern/GHOST_DropTargetWin32.h @@ -29,124 +29,125 @@ #include "GHOST_WindowWin32.h" #include "GHOST_SystemWin32.h" -class GHOST_DropTargetWin32 : public IDropTarget -{ -public: - /* IUnknownd implementation. - * Enables clients to get pointers to other interfaces on a given object - * through the QueryInterface method, and manage the existence of the object - * through the AddRef and Release methods. All other COM interfaces are - * inherited, directly or indirectly, from IUnknown. Therefore, the three - * methods in IUnknown are the first entries in the VTable for every interface. - */ - HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj); - ULONG __stdcall AddRef(void); - ULONG __stdcall Release(void); - - /* IDropTarget implementation - * + The IDropTarget interface is one of the interfaces you implement to - * provide drag-and-drop operations in your application. It contains methods - * used in any application that can be a target for data during a - * drag-and-drop operation. A drop-target application is responsible for: - * - * - Determining the effect of the drop on the target application. - * - Incorporating any valid dropped data when the drop occurs. - * - Communicating target feedback to the source so the source application - * can provide appropriate visual feedback such as setting the cursor. - * - Implementing drag scrolling. - * - Registering and revoking its application windows as drop targets. - * - * The IDropTarget interface contains methods that handle all these - * responsibilities except registering and revoking the application window - * as a drop target, for which you must call the RegisterDragDrop and the - * RevokeDragDrop functions. - */ - - HRESULT __stdcall DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT __stdcall DragLeave(void); - HRESULT __stdcall Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - - /** - * Constructor - * 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. - * \param window The window to register as drop target. - * \param system The associated system. - */ - GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system); - - /** - * Destructor - * Do NOT destroy directly. Use Release() instead to make COM happy. - */ - ~GHOST_DropTargetWin32(); - -private: - - /* Internal helper functions */ - - /** - * Base the effect on those allowed by the dropsource. - * \param dwAllowed Drop sources allowed drop effect. - * \return The allowed drop effect. - */ - DWORD allowedDropEffect(DWORD dwAllowed); - - /** - * Query DataObject for the data types it supports. - * \param pDataObject Pointer to the DataObject. - * \return GHOST data type. - */ - GHOST_TDragnDropTypes getGhostType(IDataObject *pDataObject); - - /** - * Get data to pass in event. - * It checks the type and calls specific functions for each type. - * \param pDataObject Pointer to the DataObject. - * \return Pointer to data. - */ - void *getGhostData(IDataObject *pDataObject); - - /** - * Allocate data as file array to pass in event. - * \param pDataObject Pointer to the DataObject. - * \return Pointer to data. - */ - void *getDropDataAsFilenames(IDataObject *pDataObject); - - /** - * Allocate data as string to pass in event. - * \param pDataObject Pointer to the DataObject. - * \return Pointer to data. - */ - void *getDropDataAsString(IDataObject *pDataObject); - - /** - * Convert Unicode to ANSI, replacing unconvertable chars with '?'. - * The ANSI codepage is the system default codepage, - * and can change from system to system. - * \param in LPCWSTR. - * \param out char *. Is set to NULL on failure. - * \return 0 on failure. Else the size of the string including '\0'. - */ - int WideCharToANSI(LPCWSTR in, char * &out); - - /* Private member variables */ - /* COM reference count. */ - LONG m_cRef; - /* Handle of the associated window. */ - HWND m_hWnd; - /* The associated GHOST_WindowWin32. */ - GHOST_WindowWin32 *m_window; - /* The System. */ - GHOST_SystemWin32 *m_system; - /* Data type of the dragged object */ - GHOST_TDragnDropTypes m_draggedObjectType; +class GHOST_DropTargetWin32 : public IDropTarget { + public: + /* IUnknownd implementation. + * Enables clients to get pointers to other interfaces on a given object + * through the QueryInterface method, and manage the existence of the object + * through the AddRef and Release methods. All other COM interfaces are + * inherited, directly or indirectly, from IUnknown. Therefore, the three + * methods in IUnknown are the first entries in the VTable for every interface. + */ + HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj); + ULONG __stdcall AddRef(void); + ULONG __stdcall Release(void); + + /* IDropTarget implementation + * + The IDropTarget interface is one of the interfaces you implement to + * provide drag-and-drop operations in your application. It contains methods + * used in any application that can be a target for data during a + * drag-and-drop operation. A drop-target application is responsible for: + * + * - Determining the effect of the drop on the target application. + * - Incorporating any valid dropped data when the drop occurs. + * - Communicating target feedback to the source so the source application + * can provide appropriate visual feedback such as setting the cursor. + * - Implementing drag scrolling. + * - Registering and revoking its application windows as drop targets. + * + * The IDropTarget interface contains methods that handle all these + * responsibilities except registering and revoking the application window + * as a drop target, for which you must call the RegisterDragDrop and the + * RevokeDragDrop functions. + */ + + HRESULT __stdcall DragEnter(IDataObject *pDataObject, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect); + HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + HRESULT __stdcall DragLeave(void); + HRESULT __stdcall Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + + /** + * Constructor + * 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. + * \param window The window to register as drop target. + * \param system The associated system. + */ + GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system); + + /** + * Destructor + * Do NOT destroy directly. Use Release() instead to make COM happy. + */ + ~GHOST_DropTargetWin32(); + + private: + /* Internal helper functions */ + + /** + * Base the effect on those allowed by the dropsource. + * \param dwAllowed Drop sources allowed drop effect. + * \return The allowed drop effect. + */ + DWORD allowedDropEffect(DWORD dwAllowed); + + /** + * Query DataObject for the data types it supports. + * \param pDataObject Pointer to the DataObject. + * \return GHOST data type. + */ + GHOST_TDragnDropTypes getGhostType(IDataObject *pDataObject); + + /** + * Get data to pass in event. + * It checks the type and calls specific functions for each type. + * \param pDataObject Pointer to the DataObject. + * \return Pointer to data. + */ + void *getGhostData(IDataObject *pDataObject); + + /** + * Allocate data as file array to pass in event. + * \param pDataObject Pointer to the DataObject. + * \return Pointer to data. + */ + void *getDropDataAsFilenames(IDataObject *pDataObject); + + /** + * Allocate data as string to pass in event. + * \param pDataObject Pointer to the DataObject. + * \return Pointer to data. + */ + void *getDropDataAsString(IDataObject *pDataObject); + + /** + * Convert Unicode to ANSI, replacing unconvertable chars with '?'. + * The ANSI codepage is the system default codepage, + * and can change from system to system. + * \param in LPCWSTR. + * \param out char *. Is set to NULL on failure. + * \return 0 on failure. Else the size of the string including '\0'. + */ + int WideCharToANSI(LPCWSTR in, char *&out); + + /* Private member variables */ + /* COM reference count. */ + LONG m_cRef; + /* Handle of the associated window. */ + HWND m_hWnd; + /* The associated GHOST_WindowWin32. */ + GHOST_WindowWin32 *m_window; + /* The System. */ + GHOST_SystemWin32 *m_system; + /* Data type of the dragged object */ + GHOST_TDragnDropTypes m_draggedObjectType; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetWin32") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetWin32") #endif }; diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp index e411772fc32..3d58ed9236e 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.cpp +++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp @@ -31,276 +31,286 @@ bool GHOST_DropTargetX11::m_xdndInitialized = false; DndClass GHOST_DropTargetX11::m_dndClass; Atom *GHOST_DropTargetX11::m_dndTypes = NULL; Atom *GHOST_DropTargetX11::m_dndActions = NULL; -const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {"url/url", "text/uri-list", "text/plain", "application/octet-stream"}; +const char *GHOST_DropTargetX11::m_dndMimeTypes[] = { + "url/url", "text/uri-list", "text/plain", "application/octet-stream"}; int GHOST_DropTargetX11::m_refCounter = 0; -#define dndTypeURLID 0 -#define dndTypeURIListID 1 -#define dndTypePlainTextID 2 -#define dndTypeOctetStreamID 3 +#define dndTypeURLID 0 +#define dndTypeURIListID 1 +#define dndTypePlainTextID 2 +#define dndTypeOctetStreamID 3 -#define dndTypeURL m_dndTypes[dndTypeURLID] -#define dndTypeURIList m_dndTypes[dndTypeURIListID] -#define dndTypePlainText m_dndTypes[dndTypePlainTextID] -#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID] +#define dndTypeURL m_dndTypes[dndTypeURLID] +#define dndTypeURIList m_dndTypes[dndTypeURIListID] +#define dndTypePlainText m_dndTypes[dndTypePlainTextID] +#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID] void GHOST_DropTargetX11::Initialize(void) { - Display *display = m_system->getXDisplay(); - int dndTypesCount = sizeof(m_dndMimeTypes) / sizeof(char *); - int counter; + Display *display = m_system->getXDisplay(); + int dndTypesCount = sizeof(m_dndMimeTypes) / sizeof(char *); + int counter; - xdnd_init(&m_dndClass, display); + xdnd_init(&m_dndClass, display); - m_dndTypes = new Atom[dndTypesCount + 1]; - XInternAtoms(display, (char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes); - m_dndTypes[dndTypesCount] = 0; + m_dndTypes = new Atom[dndTypesCount + 1]; + XInternAtoms(display, (char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes); + m_dndTypes[dndTypesCount] = 0; - m_dndActions = new Atom[8]; - counter = 0; + m_dndActions = new Atom[8]; + counter = 0; - m_dndActions[counter++] = m_dndClass.XdndActionCopy; - m_dndActions[counter++] = m_dndClass.XdndActionMove; + m_dndActions[counter++] = m_dndClass.XdndActionCopy; + m_dndActions[counter++] = m_dndClass.XdndActionMove; #if 0 /* Not supported yet */ - dndActions[counter++] = dnd->XdndActionLink; - dndActions[counter++] = dnd->XdndActionAsk; - dndActions[counter++] = dnd->XdndActionPrivate; - dndActions[counter++] = dnd->XdndActionList; - dndActions[counter++] = dnd->XdndActionDescription; + dndActions[counter++] = dnd->XdndActionLink; + dndActions[counter++] = dnd->XdndActionAsk; + dndActions[counter++] = dnd->XdndActionPrivate; + dndActions[counter++] = dnd->XdndActionList; + dndActions[counter++] = dnd->XdndActionDescription; #endif - m_dndActions[counter++] = 0; + m_dndActions[counter++] = 0; } void GHOST_DropTargetX11::Uninitialize(void) { - xdnd_shut(&m_dndClass); + xdnd_shut(&m_dndClass); - delete[] m_dndActions; - delete[] m_dndTypes; + delete[] m_dndActions; + delete[] m_dndTypes; } GHOST_DropTargetX11::GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system) - : - m_window(window), - m_system(system) + : m_window(window), m_system(system) { - if (!m_xdndInitialized) { - Initialize(); - m_xdndInitialized = true; - GHOST_PRINT("XDND initialized\n"); - } + if (!m_xdndInitialized) { + Initialize(); + m_xdndInitialized = true; + GHOST_PRINT("XDND initialized\n"); + } - Window wnd = window->getXWindow(); + Window wnd = window->getXWindow(); - xdnd_set_dnd_aware(&m_dndClass, wnd, 0); - xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes); + xdnd_set_dnd_aware(&m_dndClass, wnd, 0); + xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes); - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; - m_refCounter++; + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + m_refCounter++; } GHOST_DropTargetX11::~GHOST_DropTargetX11() { - m_refCounter--; - if (m_refCounter == 0) { - Uninitialize(); - m_xdndInitialized = false; - GHOST_PRINT("XDND uninitialized\n"); - } + m_refCounter--; + if (m_refCounter == 0) { + Uninitialize(); + m_xdndInitialized = false; + GHOST_PRINT("XDND uninitialized\n"); + } } /* based on a code from Saul Rennison * http://stackoverflow.com/questions/2673207/c-c-url-decode-library */ typedef enum DecodeState_e { - STATE_SEARCH = 0, ///< searching for an ampersand to convert - STATE_CONVERTING ///< convert the two proceeding characters from hex + STATE_SEARCH = 0, ///< searching for an ampersand to convert + STATE_CONVERTING ///< convert the two proceeding characters from hex } DecodeState_e; void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn) { - unsigned int i; - unsigned int len = strlen(encodedIn); - DecodeState_e state = STATE_SEARCH; - int j; - unsigned int asciiCharacter; - char tempNumBuf[3] = {0}; - bool bothDigits = true; + unsigned int i; + unsigned int len = strlen(encodedIn); + DecodeState_e state = STATE_SEARCH; + int j; + unsigned int asciiCharacter; + char tempNumBuf[3] = {0}; + bool bothDigits = true; - memset(decodedOut, 0, bufferSize); + memset(decodedOut, 0, bufferSize); - for (i = 0; i < len; ++i) { - switch (state) { - case STATE_SEARCH: - if (encodedIn[i] != '%') { - strncat(decodedOut, &encodedIn[i], 1); - assert(strlen(decodedOut) < bufferSize); - break; - } + for (i = 0; i < len; ++i) { + switch (state) { + case STATE_SEARCH: + if (encodedIn[i] != '%') { + strncat(decodedOut, &encodedIn[i], 1); + assert(strlen(decodedOut) < bufferSize); + break; + } - /* We are now converting */ - state = STATE_CONVERTING; - break; + /* We are now converting */ + state = STATE_CONVERTING; + break; - case STATE_CONVERTING: - bothDigits = true; + case STATE_CONVERTING: + bothDigits = true; - /* Create a buffer to hold the hex. For example, if %20, this - * buffer would hold 20 (in ASCII) */ - memset(tempNumBuf, 0, sizeof(tempNumBuf)); + /* Create a buffer to hold the hex. For example, if %20, this + * buffer would hold 20 (in ASCII) */ + memset(tempNumBuf, 0, sizeof(tempNumBuf)); - /* Conversion complete (i.e. don't convert again next iter) */ - state = STATE_SEARCH; + /* Conversion complete (i.e. don't convert again next iter) */ + state = STATE_SEARCH; - strncpy(tempNumBuf, &encodedIn[i], 2); + strncpy(tempNumBuf, &encodedIn[i], 2); - /* Ensure both characters are hexadecimal */ + /* Ensure both characters are hexadecimal */ - for (j = 0; j < 2; ++j) { - if (!isxdigit(tempNumBuf[j])) - bothDigits = false; - } + for (j = 0; j < 2; ++j) { + if (!isxdigit(tempNumBuf[j])) + bothDigits = false; + } - if (!bothDigits) - break; + if (!bothDigits) + break; - /* Convert two hexadecimal characters into one character */ - sscanf(tempNumBuf, "%x", &asciiCharacter); + /* Convert two hexadecimal characters into one character */ + sscanf(tempNumBuf, "%x", &asciiCharacter); - /* Ensure we aren't going to overflow */ - assert(strlen(decodedOut) < bufferSize); + /* Ensure we aren't going to overflow */ + assert(strlen(decodedOut) < bufferSize); - /* Concatenate this character onto the output */ - strncat(decodedOut, (char *)&asciiCharacter, 1); + /* Concatenate this character onto the output */ + strncat(decodedOut, (char *)&asciiCharacter, 1); - /* Skip the next character */ - i++; - break; - } - } + /* Skip the next character */ + i++; + break; + } + } } char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl) { - if (strncmp(fileUrl, "file://", 7) == 0) { - /* assume one character of encoded URL can be expanded to 4 chars max */ - int decodedSize = 4 * strlen(fileUrl) + 1; - char *decodedPath = (char *)malloc(decodedSize); + if (strncmp(fileUrl, "file://", 7) == 0) { + /* assume one character of encoded URL can be expanded to 4 chars max */ + int decodedSize = 4 * strlen(fileUrl) + 1; + char *decodedPath = (char *)malloc(decodedSize); - UrlDecode(decodedPath, decodedSize, fileUrl + 7); + UrlDecode(decodedPath, decodedSize, fileUrl + 7); - return decodedPath; - } + return decodedPath; + } - return NULL; + return NULL; } void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize) { - GHOST_TStringArray *strArray = NULL; - int totPaths = 0, curLength = 0; - - /* count total number of file pathes in buffer */ - for (int i = 0; i <= dropBufferSize; i++) { - if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') { - if (curLength) { - totPaths++; - curLength = 0; - } - } - else curLength++; - } - - strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray)); - strArray->count = 0; - strArray->strings = (GHOST_TUns8 **)malloc(totPaths * sizeof(GHOST_TUns8 *)); - - curLength = 0; - for (int i = 0; i <= dropBufferSize; i++) { - if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') { - if (curLength) { - char *curPath = (char *)malloc(curLength + 1); - char *decodedPath; - - strncpy(curPath, (char *)dropBuffer + i - curLength, curLength); - curPath[curLength] = 0; - - decodedPath = FileUrlDecode(curPath); - if (decodedPath) { - strArray->strings[strArray->count] = (GHOST_TUns8 *)decodedPath; - strArray->count++; - } - - free(curPath); - curLength = 0; - } - } - else curLength++; - } - - return strArray; + GHOST_TStringArray *strArray = NULL; + int totPaths = 0, curLength = 0; + + /* count total number of file pathes in buffer */ + for (int i = 0; i <= dropBufferSize; i++) { + if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') { + if (curLength) { + totPaths++; + curLength = 0; + } + } + else + curLength++; + } + + strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray)); + strArray->count = 0; + strArray->strings = (GHOST_TUns8 **)malloc(totPaths * sizeof(GHOST_TUns8 *)); + + curLength = 0; + for (int i = 0; i <= dropBufferSize; i++) { + if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') { + if (curLength) { + char *curPath = (char *)malloc(curLength + 1); + char *decodedPath; + + strncpy(curPath, (char *)dropBuffer + i - curLength, curLength); + curPath[curLength] = 0; + + decodedPath = FileUrlDecode(curPath); + if (decodedPath) { + strArray->strings[strArray->count] = (GHOST_TUns8 *)decodedPath; + strArray->count++; + } + + free(curPath); + curLength = 0; + } + } + else + curLength++; + } + + return strArray; } -void *GHOST_DropTargetX11::getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize) +void *GHOST_DropTargetX11::getGhostData(Atom dropType, + unsigned char *dropBuffer, + int dropBufferSize) { - void *data = NULL; - unsigned char *tmpBuffer = (unsigned char *)malloc(dropBufferSize + 1); - bool needsFree = true; - - /* ensure NULL-terminator */ - memcpy(tmpBuffer, dropBuffer, dropBufferSize); - tmpBuffer[dropBufferSize] = 0; - - if (dropType == dndTypeURIList) { - m_draggedObjectType = GHOST_kDragnDropTypeFilenames; - data = getURIListGhostData(tmpBuffer, dropBufferSize); - } - else if (dropType == dndTypeURL) { - /* need to be tested */ - char *decodedPath = FileUrlDecode((char *)tmpBuffer); - - if (decodedPath) { - m_draggedObjectType = GHOST_kDragnDropTypeString; - data = decodedPath; - } - } - else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) { - m_draggedObjectType = GHOST_kDragnDropTypeString; - data = tmpBuffer; - needsFree = false; - } - else { - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; - } - - if (needsFree) - free(tmpBuffer); - - return data; + void *data = NULL; + unsigned char *tmpBuffer = (unsigned char *)malloc(dropBufferSize + 1); + bool needsFree = true; + + /* ensure NULL-terminator */ + memcpy(tmpBuffer, dropBuffer, dropBufferSize); + tmpBuffer[dropBufferSize] = 0; + + if (dropType == dndTypeURIList) { + m_draggedObjectType = GHOST_kDragnDropTypeFilenames; + data = getURIListGhostData(tmpBuffer, dropBufferSize); + } + else if (dropType == dndTypeURL) { + /* need to be tested */ + char *decodedPath = FileUrlDecode((char *)tmpBuffer); + + if (decodedPath) { + m_draggedObjectType = GHOST_kDragnDropTypeString; + data = decodedPath; + } + } + else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) { + m_draggedObjectType = GHOST_kDragnDropTypeString; + data = tmpBuffer; + needsFree = false; + } + else { + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + } + + if (needsFree) + free(tmpBuffer); + + return data; } bool GHOST_DropTargetX11::GHOST_HandleClientMessage(XEvent *event) { - Atom dropType; - unsigned char *dropBuffer; - int dropBufferSize, dropX, dropY; + Atom dropType; + unsigned char *dropBuffer; + int dropBufferSize, dropX, dropY; - if (xdnd_get_drop(m_system->getXDisplay(), event, m_dndTypes, m_dndActions, - &dropBuffer, &dropBufferSize, &dropType, &dropX, &dropY)) - { - void *data = getGhostData(dropType, dropBuffer, dropBufferSize); + if (xdnd_get_drop(m_system->getXDisplay(), + event, + m_dndTypes, + m_dndActions, + &dropBuffer, + &dropBufferSize, + &dropType, + &dropX, + &dropY)) { + void *data = getGhostData(dropType, dropBuffer, dropBufferSize); - if (data) - m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, dropX, dropY, data); + if (data) + m_system->pushDragDropEvent( + GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, dropX, dropY, data); - free(dropBuffer); + free(dropBuffer); - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; - return true; - } + return true; + } - return false; + return false; } diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h index 62657b4c0e5..1edb52de5e5 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.h +++ b/intern/ghost/intern/GHOST_DropTargetX11.h @@ -30,101 +30,100 @@ #include "xdnd.h" -class GHOST_DropTargetX11 -{ -public: - /** - * Constructor - * - * \param window The window to register as drop target. - * \param system The associated system. - */ - GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system); - - /** - * Destructor - */ - ~GHOST_DropTargetX11(); - - /** - * Handler of ClientMessage X11 event - */ - bool GHOST_HandleClientMessage(XEvent *event); - - /** - * Get data to pass in event. - * It checks the type and calls specific functions for each type. - * \param dropType - type of dropped entity. - * \param dropBuffer - buffer returned from source application - * \param dropBufferSize - size of returned buffer - * \return Pointer to data. - */ - void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize); - -private: - /* Internal helper functions */ - - /** - * Initialize XDND and all related X atoms - */ - void Initialize(void); - - /** - * Uninitialize XDND and all related X atoms - */ - void Uninitialize(void); - - /** - * Get data to be passed to event from text/uri-list mime type - * \param dropBuffer - buffer returned from source application - * \param dropBufferSize - size of dropped buffer - * \return pointer to newly created GHOST data - */ - void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize); - - /** - * Decode URL (i.e. converts "file:///a%20b/test" to "file:///a b/test") - * \param decodedOut - buffer for decoded URL - * \param bufferSize - size of output buffer - * \param encodedIn - input encoded buffer to be decoded - */ - void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn); - - /** - * Fully decode file URL (i.e. converts "file:///a%20b/test" to "/a b/test") - * \param fileUrl - file path URL to be fully decoded - * \return decoded file path (resutl should be free-d) - */ - char *FileUrlDecode(char *fileUrl); - - /* The associated GHOST_WindowWin32. */ - GHOST_WindowX11 *m_window; - /* The System. */ - GHOST_SystemX11 *m_system; - - /* Data type of the dragged object */ - GHOST_TDragnDropTypes m_draggedObjectType; - - /* is dnd stuff initialzied */ - static bool m_xdndInitialized; - - /* class holding internal stiff of xdnd library */ - static DndClass m_dndClass; - - /* list of supported types to eb draggeg into */ - static Atom *m_dndTypes; - - /* list of supported dran'n'drop actions */ - static Atom *m_dndActions; - - /* List of supported MIME types to be dragged into */ - static const char *m_dndMimeTypes[]; - - /* counter of references to global XDND structures */ - static int m_refCounter; +class GHOST_DropTargetX11 { + public: + /** + * Constructor + * + * \param window The window to register as drop target. + * \param system The associated system. + */ + GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system); + + /** + * Destructor + */ + ~GHOST_DropTargetX11(); + + /** + * Handler of ClientMessage X11 event + */ + bool GHOST_HandleClientMessage(XEvent *event); + + /** + * Get data to pass in event. + * It checks the type and calls specific functions for each type. + * \param dropType - type of dropped entity. + * \param dropBuffer - buffer returned from source application + * \param dropBufferSize - size of returned buffer + * \return Pointer to data. + */ + void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize); + + private: + /* Internal helper functions */ + + /** + * Initialize XDND and all related X atoms + */ + void Initialize(void); + + /** + * Uninitialize XDND and all related X atoms + */ + void Uninitialize(void); + + /** + * Get data to be passed to event from text/uri-list mime type + * \param dropBuffer - buffer returned from source application + * \param dropBufferSize - size of dropped buffer + * \return pointer to newly created GHOST data + */ + void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize); + + /** + * Decode URL (i.e. converts "file:///a%20b/test" to "file:///a b/test") + * \param decodedOut - buffer for decoded URL + * \param bufferSize - size of output buffer + * \param encodedIn - input encoded buffer to be decoded + */ + void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn); + + /** + * Fully decode file URL (i.e. converts "file:///a%20b/test" to "/a b/test") + * \param fileUrl - file path URL to be fully decoded + * \return decoded file path (resutl should be free-d) + */ + char *FileUrlDecode(char *fileUrl); + + /* The associated GHOST_WindowWin32. */ + GHOST_WindowX11 *m_window; + /* The System. */ + GHOST_SystemX11 *m_system; + + /* Data type of the dragged object */ + GHOST_TDragnDropTypes m_draggedObjectType; + + /* is dnd stuff initialzied */ + static bool m_xdndInitialized; + + /* class holding internal stiff of xdnd library */ + static DndClass m_dndClass; + + /* list of supported types to eb draggeg into */ + static Atom *m_dndTypes; + + /* list of supported dran'n'drop actions */ + static Atom *m_dndActions; + + /* List of supported MIME types to be dragged into */ + static const char *m_dndMimeTypes[]; + + /* counter of references to global XDND structures */ + static int m_refCounter; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetX11") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetX11") #endif }; diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h index 49b2c766bb9..2c14df7f243 100644 --- a/intern/ghost/intern/GHOST_Event.h +++ b/intern/ghost/intern/GHOST_Event.h @@ -27,70 +27,68 @@ #include "GHOST_IEvent.h" - /** * Base class for events received the operating system. */ -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(NULL) - { - } +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(NULL) + { + } - /** - * Returns the event type. - * \return The event type. - */ - GHOST_TEventType getType() - { - return m_type; - } + /** + * Returns the event type. + * \return The event type. + */ + GHOST_TEventType getType() + { + return m_type; + } - /** - * Returns the time this event was generated. - * \return The event generation time. - */ - GHOST_TUns64 getTime() - { - return m_time; - } + /** + * Returns the time this event was generated. + * \return The event generation time. + */ + 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. - */ - GHOST_IWindow *getWindow() - { - return m_window; - } + /** + * Returns the window this event was generated on, + * or NULL if it is a 'system' event. + * \return The generating window. + */ + GHOST_IWindow *getWindow() + { + return m_window; + } - /** - * Returns the event data. - * \return The event data. - */ - GHOST_TEventDataPtr getData() - { - return m_data; - } + /** + * Returns the event data. + * \return The event data. + */ + 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; + 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__ +#endif // __GHOST_EVENT_H__ diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h index b7bd27178ac..e33a1c961bc 100644 --- a/intern/ghost/intern/GHOST_EventButton.h +++ b/intern/ghost/intern/GHOST_EventButton.h @@ -30,26 +30,28 @@ /** * Mouse button event. */ -class GHOST_EventButton : public GHOST_Event -{ -public: - /** - * Constructor. - * \param time The time this event was generated. - * \param type The type of this event. - * \param window: The window of this event. - * \param button: The state of the buttons were 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; - } +class GHOST_EventButton : public GHOST_Event { + public: + /** + * Constructor. + * \param time The time this event was generated. + * \param type The type of this event. + * \param window: The window of this event. + * \param button: The state of the buttons were 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; + protected: + /** The button event data. */ + GHOST_TEventButtonData m_buttonEventData; }; -#endif // __GHOST_EVENTBUTTON_H__ +#endif // __GHOST_EVENTBUTTON_H__ diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h index 431c26e2e49..7947b134f4b 100644 --- a/intern/ghost/intern/GHOST_EventCursor.h +++ b/intern/ghost/intern/GHOST_EventCursor.h @@ -30,28 +30,30 @@ /** * Cursor event. */ -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; - } +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; + protected: + /** The x,y-coordinates of the cursor position. */ + GHOST_TEventCursorData m_cursorEventData; }; - -#endif // __GHOST_EVENTCURSOR_H__ +#endif // __GHOST_EVENTCURSOR_H__ diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h index b3572c4ade9..169b0b5d174 100644 --- a/intern/ghost/intern/GHOST_EventDragnDrop.h +++ b/intern/ghost/intern/GHOST_EventDragnDrop.h @@ -21,7 +21,6 @@ * \ingroup GHOST */ - #ifndef __GHOST_EVENTDRAGNDROP_H__ #define __GHOST_EVENTDRAGNDROP_H__ @@ -59,69 +58,66 @@ extern "C" { * <li>array of strings representing filenames (GHOST_TStringArray) * <li>bitmap ImBuf */ -class GHOST_EventDragnDrop : public GHOST_Event -{ -public: - /** - * Constructor. - * \param time The time this event was generated. - * \param type The type of this event. - * \param dataType The type of the drop candidate object - * \param window The window where the event occurred - * \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 data The "content" dropped in the window - */ - GHOST_EventDragnDrop(GHOST_TUns64 time, - GHOST_TEventType type, - GHOST_TDragnDropTypes dataType, - GHOST_IWindow *window, - int x, int y, GHOST_TEventDataPtr data) - : GHOST_Event(time, type, window) - { - m_dragnDropEventData.x = x; - m_dragnDropEventData.y = y; - m_dragnDropEventData.dataType = dataType; - m_dragnDropEventData.data = data; - m_data = &m_dragnDropEventData; - } - - ~GHOST_EventDragnDrop() - { - //Free the dropped object data - if (m_dragnDropEventData.data == NULL) - return; - - switch (m_dragnDropEventData.dataType) { - case GHOST_kDragnDropTypeBitmap: - IMB_freeImBuf((ImBuf *)m_dragnDropEventData.data); - break; - case GHOST_kDragnDropTypeFilenames: - { - GHOST_TStringArray *strArray = (GHOST_TStringArray *)m_dragnDropEventData.data; - int i; +class GHOST_EventDragnDrop : public GHOST_Event { + public: + /** + * Constructor. + * \param time The time this event was generated. + * \param type The type of this event. + * \param dataType The type of the drop candidate object + * \param window The window where the event occurred + * \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 data The "content" dropped in the window + */ + GHOST_EventDragnDrop(GHOST_TUns64 time, + GHOST_TEventType type, + GHOST_TDragnDropTypes dataType, + GHOST_IWindow *window, + int x, + int y, + GHOST_TEventDataPtr data) + : GHOST_Event(time, type, window) + { + m_dragnDropEventData.x = x; + m_dragnDropEventData.y = y; + m_dragnDropEventData.dataType = dataType; + m_dragnDropEventData.data = data; + m_data = &m_dragnDropEventData; + } - for (i = 0; i < strArray->count; i++) - free(strArray->strings[i]); + ~GHOST_EventDragnDrop() + { + //Free the dropped object data + if (m_dragnDropEventData.data == NULL) + return; - free(strArray->strings); - free(strArray); - } - break; - case GHOST_kDragnDropTypeString: - free(m_dragnDropEventData.data); - break; + switch (m_dragnDropEventData.dataType) { + case GHOST_kDragnDropTypeBitmap: + IMB_freeImBuf((ImBuf *)m_dragnDropEventData.data); + break; + case GHOST_kDragnDropTypeFilenames: { + GHOST_TStringArray *strArray = (GHOST_TStringArray *)m_dragnDropEventData.data; + int i; - default: - break; - } - } + for (i = 0; i < strArray->count; i++) + free(strArray->strings[i]); + free(strArray->strings); + free(strArray); + } break; + case GHOST_kDragnDropTypeString: + free(m_dragnDropEventData.data); + break; + default: + break; + } + } -protected: - /** The x,y-coordinates of the cursor position. */ - GHOST_TEventDragnDropData m_dragnDropEventData; + protected: + /** The x,y-coordinates of the cursor position. */ + GHOST_TEventDragnDropData m_dragnDropEventData; }; -#endif // __GHOST_EVENTDRAGNDROP_H__ +#endif // __GHOST_EVENTDRAGNDROP_H__ diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h index d895c3184d0..f42dc99aaa5 100644 --- a/intern/ghost/intern/GHOST_EventKey.h +++ b/intern/ghost/intern/GHOST_EventKey.h @@ -30,52 +30,50 @@ /** * Key event. */ -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_keyEventData.utf8_buf[0] = '\0'; - m_data = &m_keyEventData; - } +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_keyEventData.utf8_buf[0] = '\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, - const char utf8_buf[6]) - : GHOST_Event(msec, type, window) - { - m_keyEventData.key = key; - m_keyEventData.ascii = ascii; - if (utf8_buf) memcpy(m_keyEventData.utf8_buf, utf8_buf, sizeof(m_keyEventData.utf8_buf)); - else m_keyEventData.utf8_buf[0] = '\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, + const char utf8_buf[6]) + : GHOST_Event(msec, type, window) + { + m_keyEventData.key = key; + m_keyEventData.ascii = ascii; + if (utf8_buf) + memcpy(m_keyEventData.utf8_buf, utf8_buf, sizeof(m_keyEventData.utf8_buf)); + else + m_keyEventData.utf8_buf[0] = '\0'; + m_data = &m_keyEventData; + } -protected: - /** The key event data. */ - GHOST_TEventKeyData m_keyEventData; + protected: + /** The key event data. */ + GHOST_TEventKeyData m_keyEventData; }; -#endif // __GHOST_EVENTKEY_H__ +#endif // __GHOST_EVENTKEY_H__ diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp index 094467bb0dd..3c27e2c826a 100644 --- a/intern/ghost/intern/GHOST_EventManager.cpp +++ b/intern/ghost/intern/GHOST_EventManager.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -29,186 +28,176 @@ #include "GHOST_EventManager.h" #include <algorithm> #include "GHOST_Debug.h" -#include <stdio.h> // [mce] temp debug +#include <stdio.h> // [mce] temp debug GHOST_EventManager::GHOST_EventManager() { } - GHOST_EventManager::~GHOST_EventManager() { - disposeEvents(); - - TConsumerVector::iterator iter = m_consumers.begin(); - while (iter != m_consumers.end()) { - GHOST_IEventConsumer *consumer = *iter; - delete consumer; - iter = m_consumers.erase(iter); - } + disposeEvents(); + + TConsumerVector::iterator iter = m_consumers.begin(); + while (iter != m_consumers.end()) { + GHOST_IEventConsumer *consumer = *iter; + delete consumer; + iter = m_consumers.erase(iter); + } } - GHOST_TUns32 GHOST_EventManager::getNumEvents() { - return (GHOST_TUns32) m_events.size(); + return (GHOST_TUns32)m_events.size(); } - GHOST_TUns32 GHOST_EventManager::getNumEvents(GHOST_TEventType type) { - GHOST_TUns32 numEvents = 0; - TEventStack::iterator p; - for (p = m_events.begin(); p != m_events.end(); ++p) { - if ((*p)->getType() == type) { - numEvents++; - } - } - return numEvents; + GHOST_TUns32 numEvents = 0; + TEventStack::iterator p; + for (p = m_events.begin(); p != m_events.end(); ++p) { + if ((*p)->getType() == type) { + numEvents++; + } + } + return numEvents; } - 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; + 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; } - void GHOST_EventManager::dispatchEvent(GHOST_IEvent *event) { - TConsumerVector::iterator iter; + TConsumerVector::iterator iter; - for (iter = m_consumers.begin(); iter != m_consumers.end(); ++iter) { - (*iter)->processEvent(event); - } + for (iter = m_consumers.begin(); iter != m_consumers.end(); ++iter) { + (*iter)->processEvent(event); + } } - void GHOST_EventManager::dispatchEvent() { - GHOST_IEvent *event = m_events.back(); - m_events.pop_back(); - m_handled_events.push_back(event); + GHOST_IEvent *event = m_events.back(); + m_events.pop_back(); + m_handled_events.push_back(event); - dispatchEvent(event); + dispatchEvent(event); } - void GHOST_EventManager::dispatchEvents() { - while (!m_events.empty()) { - dispatchEvent(); - } + while (!m_events.empty()) { + dispatchEvent(); + } - disposeEvents(); + disposeEvents(); } - 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 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_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; } - void GHOST_EventManager::removeWindowEvents(GHOST_IWindow *window) { - TEventStack::iterator iter; - iter = m_events.begin(); - while (iter != m_events.end()) { - GHOST_IEvent *event = *iter; - if (event->getWindow() == window) { - GHOST_PRINT("GHOST_EventManager::removeWindowEvents(): removing event\n"); - /* - * Found an event for this window, remove it. - * The iterator will become invalid. - */ - delete event; - m_events.erase(iter); - iter = m_events.begin(); - } - else { - ++iter; - } - } + TEventStack::iterator iter; + iter = m_events.begin(); + while (iter != m_events.end()) { + GHOST_IEvent *event = *iter; + if (event->getWindow() == window) { + GHOST_PRINT("GHOST_EventManager::removeWindowEvents(): removing event\n"); + /* + * Found an event for this window, remove it. + * The iterator will become invalid. + */ + delete event; + m_events.erase(iter); + iter = m_events.begin(); + } + else { + ++iter; + } + } } void GHOST_EventManager::removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window) { - TEventStack::iterator iter; - iter = m_events.begin(); - while (iter != m_events.end()) { - GHOST_IEvent *event = *iter; - if ((event->getType() == type) && (!window || (event->getWindow() == window))) { - GHOST_PRINT("GHOST_EventManager::removeTypeEvents(): removing event\n"); - /* - * Found an event of this type for the window, remove it. - * The iterator will become invalid. - */ - delete event; - m_events.erase(iter); - iter = m_events.begin(); - } - else { - ++iter; - } - } + TEventStack::iterator iter; + iter = m_events.begin(); + while (iter != m_events.end()) { + GHOST_IEvent *event = *iter; + if ((event->getType() == type) && (!window || (event->getWindow() == window))) { + GHOST_PRINT("GHOST_EventManager::removeTypeEvents(): removing event\n"); + /* + * Found an event of this type for the window, remove it. + * The iterator will become invalid. + */ + delete event; + m_events.erase(iter); + iter = m_events.begin(); + } + else { + ++iter; + } + } } - void GHOST_EventManager::disposeEvents() { - while (m_handled_events.empty() == false) { - GHOST_ASSERT(m_handled_events[0], "invalid event"); - delete m_handled_events[0]; - m_handled_events.pop_front(); - } - - while (m_events.empty() == false) { - GHOST_ASSERT(m_events[0], "invalid event"); - delete m_events[0]; - m_events.pop_front(); - } + while (m_handled_events.empty() == false) { + GHOST_ASSERT(m_handled_events[0], "invalid event"); + delete m_handled_events[0]; + m_handled_events.pop_front(); + } + + while (m_events.empty() == false) { + GHOST_ASSERT(m_events[0], "invalid event"); + delete m_events[0]; + m_events.pop_front(); + } } diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h index 04e71586550..ada5abda89b 100644 --- a/intern/ghost/intern/GHOST_EventManager.h +++ b/intern/ghost/intern/GHOST_EventManager.h @@ -30,7 +30,6 @@ #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. @@ -39,117 +38,107 @@ * 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. - */ - ~GHOST_EventManager(); - - /** - * Returns the number of events currently on the stack. - * \return The number of events on the stack. - */ - 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. - */ - GHOST_TUns32 getNumEvents(GHOST_TEventType type); - - /** - * 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. - */ - GHOST_TSuccess pushEvent(GHOST_IEvent *event); - - /** - * Dispatches the given event directly, bypassing the event stack. - */ - void dispatchEvent(GHOST_IEvent *event); - - /** - * Dispatches the event at the back of the stack. - * The event will be removed from the stack. - */ - void dispatchEvent(); - - /** - * Dispatches all the events on the stack. - * The event stack will be empty afterwards. - */ - void 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. - */ - 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. - */ - GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer); - - /** - * Removes all events for a window from the stack. - * \param window The window to remove events for. - */ - void - removeWindowEvents( - GHOST_IWindow *window - ); - - /** - * Removes all events of a certain type from the stack. - * The window parameter is optional. If non-null, the routine will remove - * events only associated with that window. - * \param type The type of events to be removed. - * \param window The window to remove the events for. - */ - void - removeTypeEvents( - GHOST_TEventType type, - GHOST_IWindow *window = NULL - ); - -protected: - - /** - * Removes all events from the stack. - */ - void disposeEvents(); - - /** A stack with events. */ - typedef std::deque<GHOST_IEvent *> TEventStack; - - /** The event stack. */ - std::deque<GHOST_IEvent *> m_events; - std::deque<GHOST_IEvent *> m_handled_events; - - /** A vector with event consumers. */ - typedef std::vector<GHOST_IEventConsumer *> TConsumerVector; - - /** The list with event consumers. */ - TConsumerVector m_consumers; - +class GHOST_EventManager { + public: + /** + * Constructor. + */ + GHOST_EventManager(); + + /** + * Destructor. + */ + ~GHOST_EventManager(); + + /** + * Returns the number of events currently on the stack. + * \return The number of events on the stack. + */ + 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. + */ + GHOST_TUns32 getNumEvents(GHOST_TEventType type); + + /** + * 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. + */ + GHOST_TSuccess pushEvent(GHOST_IEvent *event); + + /** + * Dispatches the given event directly, bypassing the event stack. + */ + void dispatchEvent(GHOST_IEvent *event); + + /** + * Dispatches the event at the back of the stack. + * The event will be removed from the stack. + */ + void dispatchEvent(); + + /** + * Dispatches all the events on the stack. + * The event stack will be empty afterwards. + */ + void 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. + */ + 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. + */ + GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer); + + /** + * Removes all events for a window from the stack. + * \param window The window to remove events for. + */ + void removeWindowEvents(GHOST_IWindow *window); + + /** + * Removes all events of a certain type from the stack. + * The window parameter is optional. If non-null, the routine will remove + * events only associated with that window. + * \param type The type of events to be removed. + * \param window The window to remove the events for. + */ + void removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window = NULL); + + protected: + /** + * Removes all events from the stack. + */ + void disposeEvents(); + + /** A stack with events. */ + typedef std::deque<GHOST_IEvent *> TEventStack; + + /** The event stack. */ + std::deque<GHOST_IEvent *> m_events; + std::deque<GHOST_IEvent *> m_handled_events; + + /** A vector with event consumers. */ + typedef std::vector<GHOST_IEventConsumer *> TConsumerVector; + + /** The list with event consumers. */ + TConsumerVector m_consumers; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_EventManager") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_EventManager") #endif }; -#endif // __GHOST_EVENTMANAGER_H__ +#endif // __GHOST_EVENTMANAGER_H__ diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h index af4b4cb5f06..196d3868ccd 100644 --- a/intern/ghost/intern/GHOST_EventNDOF.h +++ b/intern/ghost/intern/GHOST_EventNDOF.h @@ -27,31 +27,28 @@ #include "GHOST_Event.h" -class GHOST_EventNDOFMotion : public GHOST_Event -{ -protected: - GHOST_TEventNDOFMotionData m_axisData; - -public: - GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow *window) - : GHOST_Event(time, GHOST_kEventNDOFMotion, window) - { - m_data = &m_axisData; - } +class GHOST_EventNDOFMotion : public GHOST_Event { + protected: + GHOST_TEventNDOFMotionData m_axisData; + + public: + GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow *window) + : GHOST_Event(time, GHOST_kEventNDOFMotion, window) + { + m_data = &m_axisData; + } }; +class GHOST_EventNDOFButton : public GHOST_Event { + protected: + GHOST_TEventNDOFButtonData m_buttonData; -class GHOST_EventNDOFButton : public GHOST_Event -{ -protected: - GHOST_TEventNDOFButtonData m_buttonData; - -public: - GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow *window) - : GHOST_Event(time, GHOST_kEventNDOFButton, window) - { - m_data = &m_buttonData; - } + public: + GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow *window) + : GHOST_Event(time, GHOST_kEventNDOFButton, window) + { + m_data = &m_buttonData; + } }; -#endif // __GHOST_EVENTNDOF_H__ +#endif // __GHOST_EVENTNDOF_H__ diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp index 0ed34cb9fba..3c5f613e11f 100644 --- a/intern/ghost/intern/GHOST_EventPrinter.cpp +++ b/intern/ghost/intern/GHOST_EventPrinter.cpp @@ -32,301 +32,292 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event) { - bool handled = true; + bool handled = true; - GHOST_ASSERT(event, "event==0"); + GHOST_ASSERT(event, "event==0"); - if (event->getType() == GHOST_kEventWindowUpdate) return false; + if (event->getType() == GHOST_kEventWindowUpdate) + return false; - std::cout << "\nGHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime() << ", type: "; - switch (event->getType()) { - case GHOST_kEventUnknown: - std::cout << "GHOST_kEventUnknown"; handled = false; - break; + std::cout << "\nGHOST_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_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_kEventWheel: - { - GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *)((GHOST_IEvent *)event)->getData(); - std::cout << "GHOST_kEventWheel, z: " << wheelData->z; - } - break; + case GHOST_kEventWheel: { + GHOST_TEventWheelData *wheelData = + (GHOST_TEventWheelData *)((GHOST_IEvent *)event)->getData(); + std::cout << "GHOST_kEventWheel, z: " << wheelData->z; + } 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_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(); - char str[32] = {'\0'}; - getKeyString(keyData->key, str); - std::cout << "GHOST_kEventKeyUp, key: " << str; - } - break; - case GHOST_kEventKeyDown: - { - GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData(); - char str[32] = {'\0'}; - getKeyString(keyData->key, str); - std::cout << "GHOST_kEventKeyDown, key: " << str; - } - break; + case GHOST_kEventKeyUp: { + GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData(); + char str[32] = {'\0'}; + getKeyString(keyData->key, str); + std::cout << "GHOST_kEventKeyUp, key: " << str; + } break; + case GHOST_kEventKeyDown: { + GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData(); + char str[32] = {'\0'}; + getKeyString(keyData->key, str); + std::cout << "GHOST_kEventKeyDown, key: " << str; + } break; - case GHOST_kEventDraggingEntered: - { - GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); - std::cout << "GHOST_kEventDraggingEntered, dragged object type : " << dragnDropData->dataType; - std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; - } - break; + case GHOST_kEventDraggingEntered: { + GHOST_TEventDragnDropData *dragnDropData = + (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); + std::cout << "GHOST_kEventDraggingEntered, dragged object type : " + << dragnDropData->dataType; + std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; + } break; - case GHOST_kEventDraggingUpdated: - { - GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); - std::cout << "GHOST_kEventDraggingUpdated, dragged object type : " << dragnDropData->dataType; - std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; - } - break; + case GHOST_kEventDraggingUpdated: { + GHOST_TEventDragnDropData *dragnDropData = + (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); + std::cout << "GHOST_kEventDraggingUpdated, dragged object type : " + << dragnDropData->dataType; + std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; + } break; - case GHOST_kEventDraggingExited: - { - GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); - std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType; - } - break; + case GHOST_kEventDraggingExited: { + GHOST_TEventDragnDropData *dragnDropData = + (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); + std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType; + } break; - case GHOST_kEventDraggingDropDone: - { - GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); - std::cout << "GHOST_kEventDraggingDropDone,"; - std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; - switch (dragnDropData->dataType) { - case GHOST_kDragnDropTypeString: - std::cout << " type : GHOST_kDragnDropTypeString,"; - std::cout << "\n String received = " << (char *)dragnDropData->data; - break; - case GHOST_kDragnDropTypeFilenames: - { - GHOST_TStringArray *strArray = (GHOST_TStringArray *)dragnDropData->data; - int i; - std::cout << " type : GHOST_kDragnDropTypeFilenames,"; - std::cout << "\n Received " << strArray->count << " filename" << (strArray->count > 1 ? "s:" : ":"); - for (i = 0; i < strArray->count; i++) - std::cout << "\n File["<< i << "] : " << strArray->strings[i]; - } - break; - default: - break; - } - } - break; + case GHOST_kEventDraggingDropDone: { + GHOST_TEventDragnDropData *dragnDropData = + (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData(); + std::cout << "GHOST_kEventDraggingDropDone,"; + std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y; + switch (dragnDropData->dataType) { + case GHOST_kDragnDropTypeString: + std::cout << " type : GHOST_kDragnDropTypeString,"; + std::cout << "\n String received = " << (char *)dragnDropData->data; + break; + case GHOST_kDragnDropTypeFilenames: { + GHOST_TStringArray *strArray = (GHOST_TStringArray *)dragnDropData->data; + int i; + std::cout << " type : GHOST_kDragnDropTypeFilenames,"; + std::cout << "\n Received " << strArray->count << " filename" + << (strArray->count > 1 ? "s:" : ":"); + for (i = 0; i < strArray->count; i++) + std::cout << "\n File[" << i << "] : " << strArray->strings[i]; + } break; + default: + break; + } + } break; - case GHOST_kEventOpenMainFile: - { - GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData(); + case GHOST_kEventOpenMainFile: { + GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData(); - if (eventData) - std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData; - else - std::cout << "GHOST_kEventOpenMainFile with no path specified!!"; - } - break; + if (eventData) + std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData; + else + std::cout << "GHOST_kEventOpenMainFile with no path specified!!"; + } 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; + 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; - } + default: + std::cout << "not found"; + handled = false; + break; + } - std::cout.flush(); + std::cout.flush(); - return handled; + return handled; } - void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const { - if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) { - sprintf(str, "%c", (char)key); - } - else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) { - sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0)); - } - else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) { - sprintf(str, "F%d", key - GHOST_kKeyF1 + 1); - } - else { - const char *tstr = NULL; - switch (key) { - case GHOST_kKeyBackSpace: - tstr = "BackSpace"; - break; - case GHOST_kKeyTab: - tstr = "Tab"; - break; - case GHOST_kKeyLinefeed: - tstr = "Linefeed"; - break; - case GHOST_kKeyClear: - tstr = "Clear"; - break; - case GHOST_kKeyEnter: - tstr = "Enter"; - break; - case GHOST_kKeyEsc: - tstr = "Esc"; - break; - case GHOST_kKeySpace: - tstr = "Space"; - break; - case GHOST_kKeyQuote: - tstr = "Quote"; - break; - case GHOST_kKeyBackslash: - tstr = "\\"; - break; - case GHOST_kKeyAccentGrave: - tstr = "`"; - break; - case GHOST_kKeyLeftShift: - tstr = "LeftShift"; - break; - case GHOST_kKeyRightShift: - tstr = "RightShift"; - break; - case GHOST_kKeyLeftControl: - tstr = "LeftControl"; - break; - case GHOST_kKeyRightControl: - tstr = "RightControl"; - break; - case GHOST_kKeyLeftAlt: - tstr = "LeftAlt"; - break; - case GHOST_kKeyRightAlt: - tstr = "RightAlt"; - break; - case GHOST_kKeyOS: - tstr = "OS"; - break; - case GHOST_kKeyGrLess: - // PC german! - tstr = "GrLess"; - break; - case GHOST_kKeyCapsLock: - tstr = "CapsLock"; - break; - case GHOST_kKeyNumLock: - tstr = "NumLock"; - break; - case GHOST_kKeyScrollLock: - tstr = "ScrollLock"; - break; - case GHOST_kKeyLeftArrow: - tstr = "LeftArrow"; - break; - case GHOST_kKeyRightArrow: - tstr = "RightArrow"; - break; - case GHOST_kKeyUpArrow: - tstr = "UpArrow"; - break; - case GHOST_kKeyDownArrow: - tstr = "DownArrow"; - break; - case GHOST_kKeyPrintScreen: - tstr = "PrintScreen"; - break; - case GHOST_kKeyPause: - tstr = "Pause"; - break; - case GHOST_kKeyInsert: - tstr = "Insert"; - break; - case GHOST_kKeyDelete: - tstr = "Delete"; - break; - case GHOST_kKeyHome: - tstr = "Home"; - break; - case GHOST_kKeyEnd: - tstr = "End"; - break; - case GHOST_kKeyUpPage: - tstr = "UpPage"; - break; - case GHOST_kKeyDownPage: - tstr = "DownPage"; - break; - case GHOST_kKeyNumpadPeriod: - tstr = "NumpadPeriod"; - break; - case GHOST_kKeyNumpadEnter: - tstr = "NumpadEnter"; - break; - case GHOST_kKeyNumpadPlus: - tstr = "NumpadPlus"; - break; - case GHOST_kKeyNumpadMinus: - tstr = "NumpadMinus"; - break; - case GHOST_kKeyNumpadAsterisk: - tstr = "NumpadAsterisk"; - break; - case GHOST_kKeyNumpadSlash: - tstr = "NumpadSlash"; - break; - case GHOST_kKeyMediaPlay: - tstr = "MediaPlayPause"; - break; - case GHOST_kKeyMediaStop: - tstr = "MediaStop"; - break; - case GHOST_kKeyMediaFirst: - tstr = "MediaFirst"; - break; - case GHOST_kKeyMediaLast: - tstr = "MediaLast"; - break; - default: - tstr = "unknown"; - break; - } + if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) { + sprintf(str, "%c", (char)key); + } + else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) { + sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0)); + } + else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) { + sprintf(str, "F%d", key - GHOST_kKeyF1 + 1); + } + else { + const char *tstr = NULL; + switch (key) { + case GHOST_kKeyBackSpace: + tstr = "BackSpace"; + break; + case GHOST_kKeyTab: + tstr = "Tab"; + break; + case GHOST_kKeyLinefeed: + tstr = "Linefeed"; + break; + case GHOST_kKeyClear: + tstr = "Clear"; + break; + case GHOST_kKeyEnter: + tstr = "Enter"; + break; + case GHOST_kKeyEsc: + tstr = "Esc"; + break; + case GHOST_kKeySpace: + tstr = "Space"; + break; + case GHOST_kKeyQuote: + tstr = "Quote"; + break; + case GHOST_kKeyBackslash: + tstr = "\\"; + break; + case GHOST_kKeyAccentGrave: + tstr = "`"; + break; + case GHOST_kKeyLeftShift: + tstr = "LeftShift"; + break; + case GHOST_kKeyRightShift: + tstr = "RightShift"; + break; + case GHOST_kKeyLeftControl: + tstr = "LeftControl"; + break; + case GHOST_kKeyRightControl: + tstr = "RightControl"; + break; + case GHOST_kKeyLeftAlt: + tstr = "LeftAlt"; + break; + case GHOST_kKeyRightAlt: + tstr = "RightAlt"; + break; + case GHOST_kKeyOS: + tstr = "OS"; + break; + case GHOST_kKeyGrLess: + // PC german! + tstr = "GrLess"; + break; + case GHOST_kKeyCapsLock: + tstr = "CapsLock"; + break; + case GHOST_kKeyNumLock: + tstr = "NumLock"; + break; + case GHOST_kKeyScrollLock: + tstr = "ScrollLock"; + break; + case GHOST_kKeyLeftArrow: + tstr = "LeftArrow"; + break; + case GHOST_kKeyRightArrow: + tstr = "RightArrow"; + break; + case GHOST_kKeyUpArrow: + tstr = "UpArrow"; + break; + case GHOST_kKeyDownArrow: + tstr = "DownArrow"; + break; + case GHOST_kKeyPrintScreen: + tstr = "PrintScreen"; + break; + case GHOST_kKeyPause: + tstr = "Pause"; + break; + case GHOST_kKeyInsert: + tstr = "Insert"; + break; + case GHOST_kKeyDelete: + tstr = "Delete"; + break; + case GHOST_kKeyHome: + tstr = "Home"; + break; + case GHOST_kKeyEnd: + tstr = "End"; + break; + case GHOST_kKeyUpPage: + tstr = "UpPage"; + break; + case GHOST_kKeyDownPage: + tstr = "DownPage"; + break; + case GHOST_kKeyNumpadPeriod: + tstr = "NumpadPeriod"; + break; + case GHOST_kKeyNumpadEnter: + tstr = "NumpadEnter"; + break; + case GHOST_kKeyNumpadPlus: + tstr = "NumpadPlus"; + break; + case GHOST_kKeyNumpadMinus: + tstr = "NumpadMinus"; + break; + case GHOST_kKeyNumpadAsterisk: + tstr = "NumpadAsterisk"; + break; + case GHOST_kKeyNumpadSlash: + tstr = "NumpadSlash"; + break; + case GHOST_kKeyMediaPlay: + tstr = "MediaPlayPause"; + break; + case GHOST_kKeyMediaStop: + tstr = "MediaStop"; + break; + case GHOST_kKeyMediaFirst: + tstr = "MediaFirst"; + break; + case GHOST_kKeyMediaLast: + tstr = "MediaLast"; + break; + default: + tstr = "unknown"; + break; + } - sprintf(str, "%s", tstr); - } + sprintf(str, "%s", tstr); + } } diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h index 6ac3e1ee68a..fad9ec3cc69 100644 --- a/intern/ghost/intern/GHOST_EventPrinter.h +++ b/intern/ghost/intern/GHOST_EventPrinter.h @@ -33,23 +33,22 @@ * 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. - */ - bool processEvent(GHOST_IEvent *event); +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. + */ + 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, char str[32]) const; + 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, char str[32]) const; }; -#endif // __GHOST_EVENTPRINTER_H__ +#endif // __GHOST_EVENTPRINTER_H__ diff --git a/intern/ghost/intern/GHOST_EventString.h b/intern/ghost/intern/GHOST_EventString.h index 8a1d2169708..f0d3ffb9e91 100644 --- a/intern/ghost/intern/GHOST_EventString.h +++ b/intern/ghost/intern/GHOST_EventString.h @@ -27,30 +27,32 @@ #include "GHOST_Event.h" - /** * Generic class for events with string data */ -class GHOST_EventString : public GHOST_Event -{ -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). - * \param data_ptr Pointer to the (unformatted) data associated with the event - */ - GHOST_EventString(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TEventDataPtr data_ptr) - : GHOST_Event(msec, type, window) - { - m_data = data_ptr; - } +class GHOST_EventString : public GHOST_Event { + 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). + * \param data_ptr Pointer to the (unformatted) data associated with the event + */ + GHOST_EventString(GHOST_TUns64 msec, + GHOST_TEventType type, + GHOST_IWindow *window, + GHOST_TEventDataPtr data_ptr) + : GHOST_Event(msec, type, window) + { + m_data = data_ptr; + } - ~GHOST_EventString() - { - if (m_data) free(m_data); - } + ~GHOST_EventString() + { + if (m_data) + free(m_data); + } }; -#endif // __GHOST_EVENTSTRING_H__ +#endif // __GHOST_EVENTSTRING_H__ diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h index cae80fa85a0..795e969b16d 100644 --- a/intern/ghost/intern/GHOST_EventTrackpad.h +++ b/intern/ghost/intern/GHOST_EventTrackpad.h @@ -30,36 +30,36 @@ /** * Trackpad (scroll, magnify, rotate, ...) event. */ -class GHOST_EventTrackpad : public GHOST_Event -{ -public: - /** - * Constructor. - * \param msec The time this event was generated. - * \param window: The window of this event. - * \param subtype The subtype of the event. - * \param x The x-delta of the pan event. - * \param y The y-delta of the pan event. - */ - GHOST_EventTrackpad(GHOST_TUns64 msec, - GHOST_IWindow *window, - GHOST_TTrackpadEventSubTypes subtype, - GHOST_TInt32 x, GHOST_TInt32 y, - GHOST_TInt32 deltaX, GHOST_TInt32 deltaY) - : GHOST_Event(msec, GHOST_kEventTrackpad, window) - { - m_trackpadEventData.subtype = subtype; - m_trackpadEventData.x = x; - m_trackpadEventData.y = y; - m_trackpadEventData.deltaX = deltaX; - m_trackpadEventData.deltaY = deltaY; - m_data = &m_trackpadEventData; - } +class GHOST_EventTrackpad : public GHOST_Event { + public: + /** + * Constructor. + * \param msec The time this event was generated. + * \param window: The window of this event. + * \param subtype The subtype of the event. + * \param x The x-delta of the pan event. + * \param y The y-delta of the pan event. + */ + GHOST_EventTrackpad(GHOST_TUns64 msec, + GHOST_IWindow *window, + GHOST_TTrackpadEventSubTypes subtype, + GHOST_TInt32 x, + GHOST_TInt32 y, + GHOST_TInt32 deltaX, + GHOST_TInt32 deltaY) + : GHOST_Event(msec, GHOST_kEventTrackpad, window) + { + m_trackpadEventData.subtype = subtype; + m_trackpadEventData.x = x; + m_trackpadEventData.y = y; + m_trackpadEventData.deltaX = deltaX; + m_trackpadEventData.deltaY = deltaY; + m_data = &m_trackpadEventData; + } -protected: - /** The mouse pan data */ - GHOST_TEventTrackpadData m_trackpadEventData; + protected: + /** The mouse pan data */ + GHOST_TEventTrackpadData m_trackpadEventData; }; - -#endif // _GHOST_EVENT_PAN_H_ +#endif // _GHOST_EVENT_PAN_H_ diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h index 02b827d23d0..4d3eeb9cd83 100644 --- a/intern/ghost/intern/GHOST_EventWheel.h +++ b/intern/ghost/intern/GHOST_EventWheel.h @@ -32,26 +32,24 @@ * The displacement of the mouse wheel is counted in ticks. * A positive value means the wheel is turned away from the user. */ -class GHOST_EventWheel : public GHOST_Event -{ -public: - /** - * Constructor. - * \param msec: The time this event was generated. - * \param window: The window of this event. - * \param z: The displacement of the mouse wheel. - */ - GHOST_EventWheel(GHOST_TUns64 msec, GHOST_IWindow *window, GHOST_TInt32 z) - : GHOST_Event(msec, GHOST_kEventWheel, window) - { - m_wheelEventData.z = z; - m_data = &m_wheelEventData; - } +class GHOST_EventWheel : public GHOST_Event { + public: + /** + * Constructor. + * \param msec: The time this event was generated. + * \param window: The window of this event. + * \param z: The displacement of the mouse wheel. + */ + GHOST_EventWheel(GHOST_TUns64 msec, GHOST_IWindow *window, GHOST_TInt32 z) + : GHOST_Event(msec, GHOST_kEventWheel, window) + { + m_wheelEventData.z = z; + m_data = &m_wheelEventData; + } -protected: - /** The z-displacement of the mouse wheel. */ - GHOST_TEventWheelData m_wheelEventData; + protected: + /** The z-displacement of the mouse wheel. */ + GHOST_TEventWheelData m_wheelEventData; }; - -#endif // __GHOST_EVENTWHEEL_H__ +#endif // __GHOST_EVENTWHEEL_H__ diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp index 02e71d1a849..914f6712676 100644 --- a/intern/ghost/intern/GHOST_ISystem.cpp +++ b/intern/ghost/intern/GHOST_ISystem.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -46,52 +45,50 @@ GHOST_ISystem *GHOST_ISystem::m_system = NULL; - GHOST_TSuccess GHOST_ISystem::createSystem() { - GHOST_TSuccess success; - if (!m_system) { + GHOST_TSuccess success; + if (!m_system) { #ifdef WITH_X11 - m_system = new GHOST_SystemX11(); + m_system = new GHOST_SystemX11(); #else # ifdef WITH_HEADLESS - m_system = new GHOST_SystemNULL(); + m_system = new GHOST_SystemNULL(); # elif defined(WITH_GHOST_SDL) - m_system = new GHOST_SystemSDL(); + m_system = new GHOST_SystemSDL(); # elif defined(WIN32) - m_system = new GHOST_SystemWin32(); + m_system = new GHOST_SystemWin32(); # else # ifdef __APPLE__ - m_system = new GHOST_SystemCocoa(); + m_system = new GHOST_SystemCocoa(); # endif # endif #endif - success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure; - } - else { - success = GHOST_kFailure; - } - if (success) { - success = m_system->init(); - } - return success; + success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure; + } + else { + success = GHOST_kFailure; + } + if (success) { + success = m_system->init(); + } + return success; } GHOST_TSuccess GHOST_ISystem::disposeSystem() { - GHOST_TSuccess success = GHOST_kSuccess; - if (m_system) { - delete m_system; - m_system = NULL; - } - else { - success = GHOST_kFailure; - } - return success; + GHOST_TSuccess success = GHOST_kSuccess; + if (m_system) { + delete m_system; + m_system = NULL; + } + else { + success = GHOST_kFailure; + } + return success; } - GHOST_ISystem *GHOST_ISystem::getSystem() { - return m_system; + return m_system; } diff --git a/intern/ghost/intern/GHOST_ISystemPaths.cpp b/intern/ghost/intern/GHOST_ISystemPaths.cpp index e9abe3d2983..f3bcd279211 100644 --- a/intern/ghost/intern/GHOST_ISystemPaths.cpp +++ b/intern/ghost/intern/GHOST_ISystemPaths.cpp @@ -21,12 +21,10 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ - #include <stdio.h> /* just for NULL */ #include "GHOST_ISystemPaths.h" @@ -35,54 +33,52 @@ # include "GHOST_SystemPathsWin32.h" #else # ifdef __APPLE__ -# include "GHOST_SystemPathsCocoa.h" +# include "GHOST_SystemPathsCocoa.h" # else # include "GHOST_SystemPathsUnix.h" # endif #endif - GHOST_ISystemPaths *GHOST_ISystemPaths::m_systemPaths = NULL; - GHOST_TSuccess GHOST_ISystemPaths::create() { - GHOST_TSuccess success; - if (!m_systemPaths) { + GHOST_TSuccess success; + if (!m_systemPaths) { #ifdef WIN32 - m_systemPaths = new GHOST_SystemPathsWin32(); + m_systemPaths = new GHOST_SystemPathsWin32(); #else # ifdef __APPLE__ - m_systemPaths = new GHOST_SystemPathsCocoa(); + m_systemPaths = new GHOST_SystemPathsCocoa(); # else - m_systemPaths = new GHOST_SystemPathsUnix(); + m_systemPaths = new GHOST_SystemPathsUnix(); # endif #endif - success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure; - } - else { - success = GHOST_kFailure; - } - return success; + success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure; + } + else { + success = GHOST_kFailure; + } + return success; } GHOST_TSuccess GHOST_ISystemPaths::dispose() { - GHOST_TSuccess success = GHOST_kSuccess; - if (m_systemPaths) { - delete m_systemPaths; - m_systemPaths = NULL; - } - else { - success = GHOST_kFailure; - } - return success; + GHOST_TSuccess success = GHOST_kSuccess; + if (m_systemPaths) { + delete m_systemPaths; + m_systemPaths = NULL; + } + else { + success = GHOST_kFailure; + } + return success; } GHOST_ISystemPaths *GHOST_ISystemPaths::get() { - if (!m_systemPaths) { - create(); - } - return m_systemPaths; + if (!m_systemPaths) { + create(); + } + return m_systemPaths; } diff --git a/intern/ghost/intern/GHOST_IconX11.h b/intern/ghost/intern/GHOST_IconX11.h index b9951078027..c5bcf4bedeb 100644 --- a/intern/ghost/intern/GHOST_IconX11.h +++ b/intern/ghost/intern/GHOST_IconX11.h @@ -51,550 +51,967 @@ * \note Using 'unsigned' to avoid `-Wnarrowing` warning. */ static const unsigned long BLENDER_ICONS_WM_X11[] = { -16,16, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36f67b2b, 0xa2f6792b, 0x2df47728, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0xebf57a2a, 0xf5f5792a, 0x5ff4792b, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e, 0xccf5792b, 0xfff5792a, 0xa2f6792b, 0xaff8033, 0x0, 0x0, -0x0, 0x0, 0x0, 0x52f6792c, 0xe5f5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xf3f5792a, -0xfff5792a, 0xfff5792a, 0xcdf5792a, 0x22f8782d, 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0x98f5792a, 0x99f57a2a, 0x9cf5792b, -0xf3f5792a, 0xfff5792a, 0xfdf5792a, 0xedf69253, 0xf2f9a36e, 0xf4f78a45, 0xfff5792a, 0xeef5792a, 0x3cf7772b, 0x0, 0x0, -0x0, 0x0, 0x0, 0x15f37924, 0xbbf5792a, 0xfff5792a, 0xf2f67e32, 0xfefde5d5, 0xffd7e3ec, 0xffa9c1d6, 0xffe3eaf1, -0xfffbcaab, 0xfff57a2b, 0xecf5792a, 0x18f4752b, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe3f5792a, 0xfff5792a, 0xfff5792a, -0xf8fcd0b3, 0xffb5cadc, 0xff10548c, 0xff0d528b, 0xff165990, 0xffd2dfea, 0xfff9ab7a, 0xfff5792a, 0x82f57a29, 0x0, -0x1ff0000, 0x70f67929, 0xfaf5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfffef1e9, 0xff6692b6, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff8aacc7, 0xfffbcbac, 0xfff5792a, 0xbef6792a, 0xeed8024, 0xabf5792a, 0xfff5792a, 0xf5f5792a, 0x5cf47a2a, -0xfdf5792a, 0xfff5792a, 0xfffcddca, 0xffb0c7d9, 0xff0f538c, 0xff0d528b, 0xff14578e, 0xffcfdce8, 0xfffab68c, 0xfff5792a, -0xbef6792a, 0xaef57a2b, 0xfff5792a, 0xe2f5792a, 0x32f57a29, 0x0, 0xcef5792a, 0xfff5792a, 0xf7f7904e, 0xfffef6f0, -0xffd1dee9, 0xffa3bdd3, 0xffdde7ef, 0xfffde4d4, 0xfef57d31, 0xfff5792a, 0x84f57a2b, 0x77f4782b, 0xa1f5782b, 0x17f47a2c, -0x0, 0x0, 0x52f6792c, 0xfff5792a, 0xfff5792a, 0xfcf6853d, 0xfffab68b, 0xfffbc5a3, 0xfff9ab7a, 0xfff57c2e, 0xfff5792a, -0xedf5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7af5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xeef5792a, 0x3df7792a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37f6792a, 0xa6f47929, -0xe3f5792a, 0xf2f6792a, 0xd6f57a2a, 0x8bf6792a, 0x17f47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -32,32, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x13f27928, 0x5ff4792b, 0x46f4782c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0xdaf4782a, 0xfff5792a, 0xfff5792a, 0xa9f4792a, -0xdeb7627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2cf37a29, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcff802b, -0xacf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf7f5792a, 0x63f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfdf5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xf0f5792b, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xcef5792a, 0x22f8782d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4ff5772a, 0xcbf57929, -0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, -0xeef5792a, 0xeef5792a, 0xf8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x4cf5792c, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x86f57a2a, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x10ef8030, 0xe6f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0xcff802b, 0x32f57a29, 0x33f57828, 0x33f57828, 0x33f57828, 0x33f57828, 0x3ef77729, 0xcdf5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf68035, 0xfff9b284, 0xfffcd3ba, 0xfffde1cf, 0xfffcdac5, 0xfffac39f, 0xfff79557, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x27f27c27, 0xd3f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef9ac7a, 0xfffef8f3, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd5bc, 0xfff6833a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xb5f5792a, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56f67a2a, 0xf2f6792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b488, 0xffffffff, 0xffffffff, 0xffe4ecf2, 0xff7ba1c0, 0xff4e80aa, 0xff5a89b0, -0xff94b2cc, 0xfff7fafb, 0xffffffff, 0xfffde7d9, 0xfff68036, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ff802b, 0x91f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfaf78e4b, 0xfffffcfb, 0xffffffff, 0xffc0d2e1, 0xff165990, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff326c9d, -0xffecf1f6, 0xffffffff, 0xfffbc8a8, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x1df67b2c, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcaab, -0xffffffff, 0xfff2f5f9, 0xff206094, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5b8ab0, -0xffffffff, 0xfffffbf8, 0xfff68137, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46f4782c, -0xeaf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde9dc, 0xffffffff, -0xffb5cadc, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xfff8fafc, -0xffffffff, 0xfff89c62, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6ff67a29, 0x0, 0x0, 0x0, 0x2ff8000, 0x7ff5782a, -0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffeeee4, -0xffffffff, 0xffb3c9db, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff10548c, -0xfff8fafc, 0xffffffff, 0xfff8a169, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x87f6792a, 0x0, 0x0, 0x14f27326, 0xb8f5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf0f5792b, 0x56f67a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfffcdbc6, 0xffffffff, 0xffeef3f7, 0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff4f81ab, 0xffffffff, 0xffffffff, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8df4792a, 0x0, 0x37f6792a, -0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd9f4792a, 0x28f2792d, 0x4ff8040, 0xf7f5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xffffffff, 0xffffffff, 0xffaac2d6, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff256396, 0xffdce6ee, 0xffffffff, 0xfffde5d6, 0xfff57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6bf57a2b, -0x2ff4772b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb7f5792a, 0x10ef8030, 0x0, 0x0, 0xcbf57929, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57c2e, 0xfffde3d2, 0xffffffff, 0xffffffff, 0xffcedce7, 0xff6390b4, 0xff356e9e, -0xff3d75a2, 0xff7da2c1, 0xffeaf0f5, 0xffffffff, 0xfffffdfc, 0xfff7995d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0x38f67b29, 0x95f57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x3ff5500, 0x0, 0x0, 0x0, -0x6ff67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde4d4, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff8a773, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xd6f57a2a, 0x1ff0000, 0x79f4782a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0xeed8024, -0xecf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfffab68b, 0xfffeede2, 0xffffffff, 0xffffffff, -0xffffffff, 0xfffff9f6, 0xfffbd0b4, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x62f5782a, -0x0, 0x3ff5500, 0x60f47a2b, 0x76f47929, 0x1ff77b29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xfef5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68841, 0xfff79556, 0xfff78f4c, 0xfff57d30, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb5f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xd2f5792b, 0x15f37924, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69f57929, -0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xb6f5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe4f5792b, 0x5ef47a29, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0x77f4782b, 0xbaf5792b, 0xd5f5792a, 0xecf5792a, -0xe1f5792a, 0xc5f57829, 0x98f5792a, 0x45f47a29, 0x4ff8040, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -48,48, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0xdeb7627, 0x1af57627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x7ff6d24, 0xa2f6792b, 0xfdf5792a, 0xfff5792a, 0xd3f5792a, 0x36f67b2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ef6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, -0x6bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59f6782b, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa6f47929, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x29f3762c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x4cf5792c, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x59f6782b, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2df47728, 0xdef5792b, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13f27928, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xccf5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a, -0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a, -0xa2f6792b, 0xcaf5792a, 0xcff5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, -0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, -0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x81f5792a, 0x3ff5500, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xf7f5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x15f37924, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3f57929, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a, -0x39f67928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff5782a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfaf5792a, 0x6df67a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x95f57a2b, -0xd0f5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xd7f6792a, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xd0f5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff68035, 0xfff68c48, 0xfff78d4b, 0xfff68239, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xc0f4792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68c49, 0xfffbc4a1, 0xfffde9dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xfffef0e7, 0xfffbcbad, 0xfff79556, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0x95f57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x3ff77928, 0xe7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f34, 0xfffbc8a8, -0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xfffcd7bf, 0xfff6863f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfbf5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde9dc, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xfffcfdfe, 0xffe0e9f0, 0xffd4e0eb, 0xffedf2f6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xfffef3ed, 0xfff79251, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x2bf3772a, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10ef8030, 0xb1f5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfffdebde, 0xffffffff, 0xffffffff, 0xffffffff, -0xffe6edf3, 0xff7199bb, 0xff1e5e93, 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xff3b73a1, 0xffa5bfd4, 0xfffefeff, 0xffffffff, -0xffffffff, 0xfffef5ef, 0xfff68a45, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32f57a29, 0xddf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffc6d6e4, -0xff1f5f94, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5888af, 0xfff8fafc, -0xffffffff, 0xffffffff, 0xfffddecb, 0xfff57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x36f67b2b, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x65f5792b, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68944, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffe3ebf2, -0xff1b5c92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff6b95b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff89c62, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0x9bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaff8033, 0xa0f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffabc94, 0xffffffff, 0xffffffff, -0xffffffff, 0xff6b95b8, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0e538b, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xe8f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0xd1f57929, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfffcd9c2, 0xffffffff, 0xffffffff, 0xffffffff, 0xff206094, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8bacc7, 0xffffffff, 0xffffffff, -0xfffeece0, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x23f87c2c, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x53f6782b, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde7d9, 0xffffffff, 0xffffffff, 0xfff8fafc, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff7199bb, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5ff6633, 0x8ef47829, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfffde5d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff86a9c5, 0xffffffff, 0xffffffff, 0xfffef7f2, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x1bf67b26, -0xc4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x50f57929, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd2b7, 0xffffffff, 0xffffffff, 0xffffffff, -0xff618eb3, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xffccdae6, 0xffffffff, 0xffffffff, 0xfffde3d2, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0x5df47929, 0x0, 0x0, 0x0, 0x44f47829, 0xe9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x1ef7772b, 0x1af57627, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9af7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd8e3ec, 0xff16588f, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5a89b0, 0xffffffff, -0xffffffff, 0xffffffff, 0xfffac09c, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4cf5792c, -0x0, 0x1ff0000, 0x7cf57929, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xa9f4792a, 0xaff8033, 0x0, 0x5ff6633, 0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff57f33, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffb3c9db, 0xff16588f, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4278a4, 0xfff1f5f8, 0xffffffff, 0xffffffff, 0xfffffcfa, -0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x27f27c27, 0x0, 0x89f6792b, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x7bf57829, 0x1ff0000, -0x0, 0x0, 0x0, 0xc9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b081, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd5e1eb, 0xff5787ae, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff246296, 0xff8cadc8, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09b, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeaf5792b, 0x1ff0000, 0x2af3792b, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf2f6792a, 0x4ef5792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcdaf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xfff0f4f8, 0xffc7d7e4, 0xffbdd0df, 0xffd7e3ec, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xfffcdbc5, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9ff5782a, 0x0, -0x6bf57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdcf5792a, 0x2bf3772a, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x22f8782d, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff57b2d, 0xfffac39f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff57d31, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0x3bf6792b, 0x0, 0x53f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xbcf6792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2f6792b, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89f66, 0xfffde6d7, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece1, 0xfff8a773, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbff67929, 0x0, 0x0, 0x4ff8040, 0xb9f57929, -0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x7df5782b, 0x4ff8040, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e, -0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57a2c, -0xfff7985b, 0xfffabf9a, 0xfffcd8c0, 0xfffde5d6, 0xfffde7d9, 0xfffcd9c2, 0xfffbc3a0, 0xfff89c61, 0xfff57b2d, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x2ef47a2c, 0x0, 0x0, -0x0, 0x1ff0000, 0x27f27c27, 0x3af67b2c, 0xeed8024, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x5df47929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x76f47929, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89f6792b, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8af6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa0f57929, 0x3ff5500, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x62f5782a, 0xf6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfaf5792a, 0x75f47a29, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24f8782b, 0xb8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xc4f5792a, 0x2ef47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3df7792a, 0xabf5792a, 0xf8f5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfcf5792b, 0xb4f5782b, 0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11f0782d, 0x54f6792b, 0x92f5792a, -0xbcf6792a, 0xdbf5792a, 0xeaf5792b, 0xebf57a2a, 0xdcf5792a, 0xbef6792a, 0x97f57a2a, 0x5af47a2b, 0x16f3742e, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -64,64, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xb1f5792a, 0xd3f5792a, 0xbbf5792a, 0x5cf47a2a, 0x1ff0000, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb4f5782b, -0x12f1802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xdff5792a, 0x34f57b2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3f5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x41f37a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xa4f6792a, 0xbff742e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ef47a2c, 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x13f27928, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xf3f5792a, 0x58f67a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x65f5792b, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xcbf57929, 0x20f77828, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a, 0x48f4782b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x1bf67b26, 0xcaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfef5792a, 0x88f67a29, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x79f4782a, 0xaef57a2b, 0xccf5792b, 0xccf5792b, 0xccf5792b, -0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, -0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, -0xccf5792b, 0xd5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xb8f5792a, 0x14f27326, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3bf6792b, 0xeef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe2f5792a, 0x38f67b29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcff802b, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0x6df67a2a, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59f6782b, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xa8f4792b, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x43f47a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2af3792b, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9bf57a2b, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xf1f5792a, 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0x66f5782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, -0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x84f57a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfff89b5f, -0xfff9b284, 0xfffabc95, 0xfffbc3a0, 0xfffabb93, 0xfff9b082, 0xfff79659, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0x5af47a2b, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x2bf3772a, 0xd7f6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b60, 0xfffcd6be, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff9f5, 0xfffbcfb3, 0xfff79455, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0x4ff5772a, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x5cf47a2a, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff78d4b, 0xfffde0ce, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd8c0, 0xfff68741, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x2df47728, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0x97f57a2a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff9ad7d, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef7f2, 0xfff8a26b, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd4f5792a, 0x8ff8020, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828, -0xcbf57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff9b387, 0xfffffefe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff4f7fa, 0xffb7cbdc, -0xff88aac6, 0xff749cbd, 0xff81a5c2, 0xff9fbad1, 0xffdee7ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xfffffcfb, 0xfff8a671, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0x82f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x4bf57a29, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff8a672, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff2f5f9, 0xff7ba1c0, -0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4c7fa9, 0xffcbdae6, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdfc, 0xfff7975a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x1bf67b26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0x80f57a2a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffef5ef, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffd6e2eb, 0xff2c689a, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff11558d, 0xff8fafc9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede3, 0xfff68035, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffe1e9f0, 0xff236295, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff93b2cb, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xfffab98f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xeef5792a, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x3cf7772b, 0xe5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68137, 0xfffff9f6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xff4d7fa9, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff13568e, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef1e8, -0xfff57c2e, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4ff5772a, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x73f47a2a, 0xfbf5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff9ac7b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffcbdae6, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff6893b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79a5f, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0xdeb7627, 0xaaf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc7a6, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff7ea3c1, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff1b5c92, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b589, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd1f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ff4772b, -0xdbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcddca, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xff5888af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffe5edf3, -0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfbf5792a, 0x5ff6633, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5ef47a29, 0xf5f5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffddfcc, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xff5988af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffe8eff4, 0xffffffff, -0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x9df5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcdcc7, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xff759dbd, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff175990, 0xfffafcfd, 0xffffffff, -0xffffffff, 0xffffffff, 0xfffbc8a7, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff77b29, 0xcaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x45f47a29, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc8a7, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffbccfdf, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5888af, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b285, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0x28f2792d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xf0f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xc2f4792a, 0x15f37924, 0x24f8782b, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a773, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xfffefeff, 0xff3d75a2, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffc8d8e5, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79252, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0x1ff77b29, 0x0, 0x0, 0x0, 0x4ff8040, 0x8bf6792a, 0xfef5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, -0x6ff802b, 0x0, 0x1bf67b26, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff68239, 0xfffff9f5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd0dee9, 0xff175990, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff789fbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff57a2c, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x4ff8040, 0x0, 0x0, 0x18f4752b, 0xc2f4792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfaf5792a, 0x6af57829, 0x0, 0x0, 0x0, 0x3ff5500, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffac09c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffbed0e0, 0xff1c5d92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff0d528b, 0xff0d528b, 0xff6c96b8, 0xfffcfdfe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9aa79, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x0, 0x0, 0x18f4752b, -0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xebf57a2a, 0x40f3782c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6843c, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffdee7ef, 0xff5b8ab0, 0xff0e538b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, -0xff2c689a, 0xffaac2d6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde6d8, 0xfff57b2d, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, 0x0, 0xb1f5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xd2f5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x81f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b5f, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffdde7ef, 0xff94b2cc, 0xff6792b6, 0xff5284ac, 0xff5f8cb2, 0xff7ca1c0, 0xffbed1e0, -0xfffafcfd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef6f0, 0xfff68b46, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x56f67a2a, 0x0, 0x1ef7772b, -0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xaef57a2b, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xfffffdfc, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef8f3, 0xfff89b60, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeff5792a, 0x9ff711c, 0x0, 0x4af57929, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x81f5792a, -0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89d64, 0xfffef6f1, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede2, 0xfff78f4d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x92f5792a, 0x0, 0x0, 0x34f57b2c, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x54f6792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x45f47a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68a45, 0xfffbcfb3, 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfffac29e, -0xfff68238, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xf8f5792a, 0x1cf6762e, 0x0, 0x0, 0x1ff0000, 0xc5f57829, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xdef5792b, 0x2ff4772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbaf5792b, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff79150, 0xfffbc8a7, 0xfffeefe5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, -0xffffffff, 0xffffffff, 0xfffde7d9, 0xfffabf99, 0xfff68841, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x0, 0x0, 0x0, 0x0, -0x13f27928, 0xa2f6792b, 0xf6f5792b, 0xfff5792a, 0xe0f5792a, 0x83f5792b, 0xdeb7627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828, 0xf3f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff78f4c, -0xfff8a069, 0xfff9ac7c, 0xfffab68c, 0xfff9aa79, 0xfff89e64, 0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xdaf4782a, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5bf4782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, -0x32f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x59f6782b, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x1ff0000, 0x90f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfef5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x82f57a29, 0xfef5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x58f67a29, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52f6792c, 0xeff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xdbf5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xacf57a2a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x8af6782b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x3bf6792b, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfbf5792a, 0xa1f5782b, 0x23f87c2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2af3792b, 0x8bf6792a, 0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, -0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0xd0f5792a, -0x75f47a29, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x26f87928, 0x67f5792a, 0x93f5792a, 0xbaf5792b, 0xd2f5792b, 0xddf5792a, 0xebf57a2a, 0xddf5792a, -0xcef5792a, 0xb1f5792a, 0x89f6792b, 0x5af47a2b, 0x17f47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 16, 16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36f67b2b, 0xa2f6792b, 0x2df47728, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x31f5782a, 0xebf57a2a, 0xf5f5792a, 0x5ff4792b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1cf6762e, 0xccf5792b, 0xfff5792a, 0xa2f6792b, 0xaff8033, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x52f6792c, 0xe5f5792a, 0xeef5792a, 0xeef5792a, + 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xf3f5792a, 0xfff5792a, 0xfff5792a, 0xcdf5792a, 0x22f8782d, + 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0x98f5792a, 0x99f57a2a, 0x9cf5792b, + 0xf3f5792a, 0xfff5792a, 0xfdf5792a, 0xedf69253, 0xf2f9a36e, 0xf4f78a45, 0xfff5792a, 0xeef5792a, + 0x3cf7772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15f37924, 0xbbf5792a, + 0xfff5792a, 0xf2f67e32, 0xfefde5d5, 0xffd7e3ec, 0xffa9c1d6, 0xffe3eaf1, 0xfffbcaab, 0xfff57a2b, + 0xecf5792a, 0x18f4752b, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe3f5792a, 0xfff5792a, + 0xfff5792a, 0xf8fcd0b3, 0xffb5cadc, 0xff10548c, 0xff0d528b, 0xff165990, 0xffd2dfea, 0xfff9ab7a, + 0xfff5792a, 0x82f57a29, 0x0, 0x1ff0000, 0x70f67929, 0xfaf5792a, 0xfef5792a, 0xfff5792a, + 0xfff5792a, 0xfffef1e9, 0xff6692b6, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8aacc7, 0xfffbcbac, + 0xfff5792a, 0xbef6792a, 0xeed8024, 0xabf5792a, 0xfff5792a, 0xf5f5792a, 0x5cf47a2a, 0xfdf5792a, + 0xfff5792a, 0xfffcddca, 0xffb0c7d9, 0xff0f538c, 0xff0d528b, 0xff14578e, 0xffcfdce8, 0xfffab68c, + 0xfff5792a, 0xbef6792a, 0xaef57a2b, 0xfff5792a, 0xe2f5792a, 0x32f57a29, 0x0, 0xcef5792a, + 0xfff5792a, 0xf7f7904e, 0xfffef6f0, 0xffd1dee9, 0xffa3bdd3, 0xffdde7ef, 0xfffde4d4, 0xfef57d31, + 0xfff5792a, 0x84f57a2b, 0x77f4782b, 0xa1f5782b, 0x17f47a2c, 0x0, 0x0, 0x52f6792c, + 0xfff5792a, 0xfff5792a, 0xfcf6853d, 0xfffab68b, 0xfffbc5a3, 0xfff9ab7a, 0xfff57c2e, 0xfff5792a, + 0xedf5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7af5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, + 0x3df7792a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x37f6792a, 0xa6f47929, 0xe3f5792a, 0xf2f6792a, 0xd6f57a2a, 0x8bf6792a, 0x17f47a2c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 32, 32, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x13f27928, 0x5ff4792b, 0x46f4782c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1ff0000, 0xdaf4782a, 0xfff5792a, 0xfff5792a, 0xa9f4792a, 0xdeb7627, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b, + 0x2cf37a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcff802b, 0xacf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xf7f5792a, 0x63f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfdf5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xf0f5792b, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x22f8782d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4ff5772a, 0xcbf57929, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, + 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xeef5792a, 0xeef5792a, 0xf8f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x4cf5792c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x17f47a2c, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x86f57a2a, 0x3ff5500, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10ef8030, 0xe6f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, + 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcff802b, 0x32f57a29, 0x33f57828, 0x33f57828, 0x33f57828, 0x33f57828, 0x3ef77729, + 0xcdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf68035, 0xfff9b284, 0xfffcd3ba, + 0xfffde1cf, 0xfffcdac5, 0xfffac39f, 0xfff79557, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xcef5792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x27f27c27, 0xd3f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef9ac7a, 0xfffef8f3, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd5bc, 0xfff6833a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xb5f5792a, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x56f67a2a, 0xf2f6792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b488, 0xffffffff, 0xffffffff, 0xffe4ecf2, 0xff7ba1c0, + 0xff4e80aa, 0xff5a89b0, 0xff94b2cc, 0xfff7fafb, 0xffffffff, 0xfffde7d9, 0xfff68036, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6ff802b, 0x91f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfaf78e4b, 0xfffffcfb, 0xffffffff, 0xffc0d2e1, 0xff165990, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff326c9d, 0xffecf1f6, 0xffffffff, 0xfffbc8a8, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1df67b2c, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfffbcaab, 0xffffffff, 0xfff2f5f9, 0xff206094, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5b8ab0, 0xffffffff, 0xfffffbf8, 0xfff68137, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x46f4782c, 0xeaf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfffde9dc, 0xffffffff, 0xffb5cadc, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xfff8fafc, 0xffffffff, 0xfff89c62, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6ff67a29, 0x0, 0x0, 0x0, 0x2ff8000, + 0x7ff5782a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfffeeee4, 0xffffffff, 0xffb3c9db, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff10548c, 0xfff8fafc, 0xffffffff, 0xfff8a169, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x87f6792a, 0x0, 0x0, 0x14f27326, 0xb8f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf0f5792b, 0x56f67a2a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfffcdbc6, 0xffffffff, 0xffeef3f7, 0xff195b91, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4f81ab, 0xffffffff, 0xffffffff, 0xfff78d4b, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8df4792a, 0x0, 0x37f6792a, 0xe1f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd9f4792a, 0x28f2792d, 0x4ff8040, 0xf7f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xffffffff, 0xffffffff, 0xffaac2d6, 0xff11558d, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff256396, 0xffdce6ee, 0xffffffff, 0xfffde5d6, 0xfff57a2b, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6bf57a2b, 0x2ff4772b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xb7f5792a, 0x10ef8030, 0x0, 0x0, 0xcbf57929, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff57c2e, 0xfffde3d2, 0xffffffff, 0xffffffff, 0xffcedce7, 0xff6390b4, + 0xff356e9e, 0xff3d75a2, 0xff7da2c1, 0xffeaf0f5, 0xffffffff, 0xfffffdfc, 0xfff7995d, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x38f67b29, 0x95f57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0x8cf6782a, 0x3ff5500, 0x0, 0x0, 0x0, 0x6ff67a29, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde4d4, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff8a773, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x1ff0000, 0x79f4782a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, + 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0xeed8024, 0xecf5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfffab68b, 0xfffeede2, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffff9f6, 0xfffbd0b4, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x3ff5500, 0x60f47a2b, 0x76f47929, 0x1ff77b29, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, + 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68841, + 0xfff79556, 0xfff78f4c, 0xfff57d30, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xb5f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x80f57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xd2f5792b, 0x15f37924, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x69f57929, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, + 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28f2792d, 0xb6f5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe4f5792b, 0x5ef47a29, 0x1ff0000, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0x77f4782b, 0xbaf5792b, 0xd5f5792a, + 0xecf5792a, 0xe1f5792a, 0xc5f57829, 0x98f5792a, 0x45f47a29, 0x4ff8040, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 48, 48, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdeb7627, 0x1af57627, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0xa2f6792b, 0xfdf5792a, 0xfff5792a, + 0xd3f5792a, 0x36f67b2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6ef6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xf9f5792a, 0x6bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x59f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa6f47929, 0xcff802b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfef5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x29f3762c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4cf5792c, 0xf1f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x59f6782b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2df47728, + 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, + 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13f27928, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xccf5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xecf5792a, 0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0xa2f6792b, + 0xcaf5792a, 0xcff5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, + 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, + 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x81f5792a, 0x3ff5500, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xf7f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x15f37924, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3f57929, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x39f67928, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff5782a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x6df67a2a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x95f57a2b, 0xd0f5792a, + 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xd7f6792a, 0xccf5792b, 0xccf5792b, 0xccf5792b, + 0xd0f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfff68c48, 0xfff78d4b, 0xfff68239, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0x89f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29, + 0xc0f4792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff68c49, 0xfffbc4a1, 0xfffde9dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef0e7, + 0xfffbcbad, 0xfff79556, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0x95f57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xe7f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f34, 0xfffbc8a8, + 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffcd7bf, 0xfff6863f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfbf5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde9dc, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfdfe, 0xffe0e9f0, 0xffd4e0eb, 0xffedf2f6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef3ed, 0xfff79251, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10ef8030, 0xb1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfffdebde, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffe6edf3, 0xff7199bb, 0xff1e5e93, 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xff3b73a1, + 0xffa5bfd4, 0xfffefeff, 0xffffffff, 0xffffffff, 0xfffef5ef, 0xfff68a45, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x32f57a29, 0xddf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffc6d6e4, 0xff1f5f94, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff5888af, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xfffddecb, 0xfff57a2b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x36f67b2b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x65f5792b, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68944, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffe3ebf2, + 0xff1b5c92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff6b95b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff89c62, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9bf57a2b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaff8033, + 0xa0f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffabc94, 0xffffffff, 0xffffffff, 0xffffffff, 0xff6b95b8, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe8f5792a, 0x1ff0000, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0xd1f57929, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd9c2, 0xffffffff, 0xffffffff, 0xffffffff, 0xff206094, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8bacc7, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x23f87c2c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x53f6782b, 0xf1f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde7d9, 0xffffffff, 0xffffffff, 0xfff8fafc, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff7199bb, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4af57929, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5ff6633, 0x8ef47829, 0xfef5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde5d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xff195b91, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff86a9c5, 0xffffffff, 0xffffffff, 0xfffef7f2, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, + 0x0, 0x0, 0x1bf67b26, 0xc4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x50f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd2b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xff618eb3, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffccdae6, 0xffffffff, 0xffffffff, 0xfffde3d2, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5df47929, 0x0, 0x0, + 0x0, 0x44f47829, 0xe9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x1ef7772b, 0x1af57627, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9af7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd8e3ec, + 0xff16588f, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff5a89b0, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09c, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4cf5792c, 0x0, 0x1ff0000, + 0x7cf57929, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xa9f4792a, 0xaff8033, 0x0, 0x5ff6633, 0xfbf5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f33, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffb3c9db, 0xff16588f, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff4278a4, 0xfff1f5f8, 0xffffffff, 0xffffffff, 0xfffffcfa, 0xfff68842, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x27f27c27, 0x0, 0x89f6792b, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, + 0x7bf57829, 0x1ff0000, 0x0, 0x0, 0x0, 0xc9f5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b081, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffd5e1eb, 0xff5787ae, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff246296, + 0xff8cadc8, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09b, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeaf5792b, 0x1ff0000, 0x2af3792b, 0xfef5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf2f6792a, 0x4ef5792b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcdaf, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfff0f4f8, 0xffc7d7e4, 0xffbdd0df, 0xffd7e3ec, 0xfffefeff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcdbc5, 0xfff57b2d, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9ff5782a, 0x0, 0x6bf57a2b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdcf5792a, 0x2bf3772a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x22f8782d, 0xfcf5792b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57b2d, 0xfffac39f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff57d31, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x3bf6792b, 0x0, 0x53f6782b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0x13f27928, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2f6792b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89f66, + 0xfffde6d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffeece1, 0xfff8a773, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbff67929, 0x0, 0x0, 0x4ff8040, 0xb9f57929, + 0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x7df5782b, 0x4ff8040, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e, 0xf1f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff57a2c, 0xfff7985b, 0xfffabf9a, 0xfffcd8c0, 0xfffde5d6, 0xfffde7d9, 0xfffcd9c2, 0xfffbc3a0, + 0xfff89c61, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x2ef47a2c, 0x0, 0x0, 0x0, 0x1ff0000, + 0x27f27c27, 0x3af67b2c, 0xeed8024, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5df47929, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0x76f47929, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x89f6792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xa2f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8af6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xa0f57929, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x62f5782a, 0xf6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x75f47a29, + 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x24f8782b, 0xb8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xc4f5792a, 0x2ef47a2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3df7792a, 0xabf5792a, 0xf8f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0xb4f5782b, 0x49f57a2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11f0782d, + 0x54f6792b, 0x92f5792a, 0xbcf6792a, 0xdbf5792a, 0xeaf5792b, 0xebf57a2a, 0xdcf5792a, 0xbef6792a, + 0x97f57a2a, 0x5af47a2b, 0x16f3742e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64, 64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, + 0xb1f5792a, 0xd3f5792a, 0xbbf5792a, 0x5cf47a2a, 0x1ff0000, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77f4782b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb4f5782b, 0x12f1802b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0xf1f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdff5792a, 0x34f57b2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x69f57929, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41f37a2b, 0xf4f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xa4f6792a, 0xbff742e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ef47a2c, + 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xd7f6792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13f27928, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x58f67a29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x65f5792b, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcbf57929, 0x20f77828, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe7f5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a, 0x48f4782b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1bf67b26, 0xcaf5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, + 0x88f67a29, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x12f1802b, 0x79f4782a, 0xaef57a2b, 0xccf5792b, 0xccf5792b, + 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, + 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, + 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xd5f5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xb8f5792a, 0x14f27326, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3bf6792b, 0xeef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xe2f5792a, 0x38f67b29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcff802b, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0x6df67a2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa8f4792b, 0xcff802b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x43f47a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2af3792b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9bf57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf1f5792a, + 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x31f5782a, 0x66f5782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, + 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, + 0x84f57a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfff89b5f, 0xfff9b284, + 0xfffabc95, 0xfffbc3a0, 0xfffabb93, 0xfff9b082, 0xfff79659, 0xfff57b2d, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfcf5792b, 0x5af47a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2bf3772a, + 0xd7f6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b60, 0xfffcd6be, 0xfffffaf7, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff9f5, 0xfffbcfb3, 0xfff79455, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfcf5792b, 0x4ff5772a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5cf47a2a, 0xf4f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff78d4b, 0xfffde0ce, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfffcd8c0, 0xfff68741, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x2df47728, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0x97f57a2a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff9ad7d, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffef7f2, 0xfff8a26b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd4f5792a, 0x8ff8020, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x20f77828, 0xcbf57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b387, + 0xfffffefe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff4f7fa, 0xffb7cbdc, + 0xff88aac6, 0xff749cbd, 0xff81a5c2, 0xff9fbad1, 0xffdee7ef, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffcfb, 0xfff8a671, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x82f57a29, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4bf57a29, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a672, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff2f5f9, 0xff7ba1c0, 0xff195b91, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4c7fa9, 0xffcbdae6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdfc, 0xfff7975a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x1bf67b26, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3ff5500, 0x80f57a2a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffef5ef, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffd6e2eb, 0xff2c689a, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xff8fafc9, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede3, 0xfff68035, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c, + 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffe1e9f0, 0xff236295, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff93b2cb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffab98f, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x9ff711c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0xe5f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68137, 0xfffff9f6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff4d7fa9, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff13568e, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef1e8, 0xfff57c2e, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4ff5772a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x73f47a2a, 0xfbf5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ac7b, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffcbdae6, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff6893b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79a5f, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xdeb7627, 0xaaf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc7a6, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff7ea3c1, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff1b5c92, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b589, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd1f57929, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2ff4772b, 0xdbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcddca, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff5888af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xffe5edf3, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfbf5792a, 0x5ff6633, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5ef47a29, 0xf5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffddfcc, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff5988af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xffe8eff4, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x19f57a29, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c, + 0x9df5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcdcc7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff759dbd, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff175990, 0xfffafcfd, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbc8a7, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x2bf3772a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff77b29, 0xcaf5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x45f47a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc8a7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffbccfdf, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff5888af, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b285, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x28f2792d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xf0f5792b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xc2f4792a, 0x15f37924, 0x24f8782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a773, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffefeff, 0xff3d75a2, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xffc8d8e5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79252, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x1ff77b29, + 0x0, 0x0, 0x0, 0x4ff8040, 0x8bf6792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0x99f57a2a, 0x6ff802b, 0x0, 0x1bf67b26, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68239, 0xfffff9f5, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffd0dee9, 0xff175990, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff789fbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff57a2c, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x4ff8040, + 0x0, 0x0, 0x18f4752b, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x6af57829, + 0x0, 0x0, 0x0, 0x3ff5500, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffac09c, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffbed0e0, 0xff1c5d92, 0xff0d528b, 0xff0d528b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff6c96b8, + 0xfffcfdfe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9aa79, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x0, + 0x0, 0x18f4752b, 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x40f3782c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6843c, 0xfffef4ed, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffdee7ef, 0xff5b8ab0, 0xff0e538b, 0xff0d528b, + 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff2c689a, 0xffaac2d6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde6d8, 0xfff57b2d, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, + 0x0, 0xb1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd2f5792b, 0x21f77c27, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x81f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b5f, 0xfffffdfc, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffdde7ef, 0xff94b2cc, + 0xff6792b6, 0xff5284ac, 0xff5f8cb2, 0xff7ca1c0, 0xffbed1e0, 0xfffafcfd, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef6f0, 0xfff68b46, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x56f67a2a, 0x0, + 0x1ef7772b, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xaef57a2b, 0xcff802b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ad7d, + 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffef8f3, 0xfff89b60, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeff5792a, 0x9ff711c, 0x0, + 0x4af57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfef5792a, 0x81f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff89d64, 0xfffef6f1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffeede2, 0xfff78f4d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x92f5792a, 0x0, 0x0, + 0x34f57b2c, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xf4f5792a, 0x54f6792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x45f47a29, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff68a45, 0xfffbcfb3, 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, + 0xfffac29e, 0xfff68238, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x1cf6762e, 0x0, 0x0, + 0x1ff0000, 0xc5f57829, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdef5792b, + 0x2ff4772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbaf5792b, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff79150, 0xfffbc8a7, 0xfffeefe5, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde7d9, 0xfffabf99, 0xfff68841, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x0, 0x0, 0x0, + 0x0, 0x13f27928, 0xa2f6792b, 0xf6f5792b, 0xfff5792a, 0xe0f5792a, 0x83f5792b, 0xdeb7627, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828, 0xf3f5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff78f4c, 0xfff8a069, + 0xfff9ac7c, 0xfffab68c, 0xfff9aa79, 0xfff89e64, 0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdaf4782a, 0x9ff711c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5bf4782a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x32f57a29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfdf5792a, 0x59f6782b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1ff0000, 0x90f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfef5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1ff0000, 0x82f57a29, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, + 0x58f67a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x52f6792c, 0xeff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdbf5792a, 0x31f5782a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xacf57a2a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x8af6782b, 0x9ff711c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3bf6792b, 0xbcf6792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfbf5792a, 0xa1f5782b, 0x23f87c2c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2af3792b, 0x8bf6792a, 0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, + 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, + 0xd0f5792a, 0x75f47a29, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x26f87928, 0x67f5792a, 0x93f5792a, 0xbaf5792b, 0xd2f5792b, + 0xddf5792a, 0xebf57a2a, 0xddf5792a, 0xcef5792a, 0xb1f5792a, 0x89f6792b, 0x5af47a2b, 0x17f47a2c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; -#endif // __GHOST_ICONX11_H__ +#endif // __GHOST_ICONX11_H__ diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index 94abf92dae4..531dbe4b444 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -19,18 +19,16 @@ * The Original Code is: some of this file. */ - /** \file * \ingroup GHOST */ #ifdef WITH_INPUT_IME -#include "GHOST_C-api.h" -#include "GHOST_ImeWin32.h" -#include "GHOST_WindowWin32.h" -#include "utfconv.h" - +# include "GHOST_C-api.h" +# include "GHOST_ImeWin32.h" +# include "GHOST_WindowWin32.h" +# include "utfconv.h" GHOST_ImeWin32::GHOST_ImeWin32() : ime_status_(false), @@ -43,472 +41,449 @@ GHOST_ImeWin32::GHOST_ImeWin32() { } - GHOST_ImeWin32::~GHOST_ImeWin32() { } - bool GHOST_ImeWin32::SetInputLanguage() { - /** - * Retrieve the current keyboard layout from Windows and determine whether - * or not the current input context has IMEs. - * Also save its input language for language-specific operations required - * while composing a text. - */ - HKL keyboard_layout = ::GetKeyboardLayout(0); - input_language_id_ = LOWORD(keyboard_layout); - ime_status_ = ::ImmIsIME(keyboard_layout); - return ime_status_; + /** + * Retrieve the current keyboard layout from Windows and determine whether + * or not the current input context has IMEs. + * Also save its input language for language-specific operations required + * while composing a text. + */ + HKL keyboard_layout = ::GetKeyboardLayout(0); + input_language_id_ = LOWORD(keyboard_layout); + ime_status_ = ::ImmIsIME(keyboard_layout); + return ime_status_; } - void GHOST_ImeWin32::CreateImeWindow(HWND window_handle) { - /** - * When a user disables TSF (Text Service Framework) and CUAS (Cicero - * Unaware Application Support), Chinese IMEs somehow ignore function calls - * to ::ImmSetCandidateWindow(), i.e. they do not move their candidate - * window to the position given as its parameters, and use the position - * of the current system caret instead, i.e. it uses ::GetCaretPos() to - * retrieve the position of their IME candidate window. - * Therefore, we create a temporary system caret for Chinese IMEs and use - * it during this input context. - * Since some third-party Japanese IME also uses ::GetCaretPos() to determine - * their window position, we also create a caret for Japanese IMEs. - */ - if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE || - PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) { - if (!system_caret_) { - if (::CreateCaret(window_handle, NULL, 1, 1)) { - system_caret_ = true; - } - } - } - /* Restore the positions of the IME windows. */ - UpdateImeWindow(window_handle); + /** + * When a user disables TSF (Text Service Framework) and CUAS (Cicero + * Unaware Application Support), Chinese IMEs somehow ignore function calls + * to ::ImmSetCandidateWindow(), i.e. they do not move their candidate + * window to the position given as its parameters, and use the position + * of the current system caret instead, i.e. it uses ::GetCaretPos() to + * retrieve the position of their IME candidate window. + * Therefore, we create a temporary system caret for Chinese IMEs and use + * it during this input context. + * Since some third-party Japanese IME also uses ::GetCaretPos() to determine + * their window position, we also create a caret for Japanese IMEs. + */ + if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE || + PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) { + if (!system_caret_) { + if (::CreateCaret(window_handle, NULL, 1, 1)) { + system_caret_ = true; + } + } + } + /* Restore the positions of the IME windows. */ + UpdateImeWindow(window_handle); } - -void GHOST_ImeWin32::SetImeWindowStyle(HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled) +void GHOST_ImeWin32::SetImeWindowStyle( + HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled) { - /** - * To prevent the IMM (Input Method Manager) from displaying the IME - * composition window, Update the styles of the IME windows and EXPLICITLY - * call ::DefWindowProc() here. - * NOTE(hbono): We can NEVER let WTL call ::DefWindowProc() when we update - * the styles of IME windows because the 'lparam' variable is a local one - * and all its updates disappear in returning from this function, i.e. WTL - * does not call ::DefWindowProc() with our updated 'lparam' value but call - * the function with its original value and over-writes our window styles. - */ - *handled = TRUE; - lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW; - ::DefWindowProc(window_handle, message, wparam, lparam); + /** + * To prevent the IMM (Input Method Manager) from displaying the IME + * composition window, Update the styles of the IME windows and EXPLICITLY + * call ::DefWindowProc() here. + * NOTE(hbono): We can NEVER let WTL call ::DefWindowProc() when we update + * the styles of IME windows because the 'lparam' variable is a local one + * and all its updates disappear in returning from this function, i.e. WTL + * does not call ::DefWindowProc() with our updated 'lparam' value but call + * the function with its original value and over-writes our window styles. + */ + *handled = TRUE; + lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW; + ::DefWindowProc(window_handle, message, wparam, lparam); } - void GHOST_ImeWin32::DestroyImeWindow(HWND window_handle) { - /* Destroy the system caret if we have created for this IME input context. */ - if (system_caret_) { - ::DestroyCaret(); - system_caret_ = false; - } + /* Destroy the system caret if we have created for this IME input context. */ + if (system_caret_) { + ::DestroyCaret(); + system_caret_ = false; + } } - void GHOST_ImeWin32::MoveImeWindow(HWND window_handle, HIMC imm_context) { - int x = caret_rect_.m_l; - int y = caret_rect_.m_t; - const int kCaretMargin = 1; - /** - * As written in a comment in GHOST_ImeWin32::CreateImeWindow(), - * Chinese IMEs ignore function calls to ::ImmSetCandidateWindow() - * when a user disables TSF (Text Service Framework) and CUAS (Cicero - * Unaware Application Support). - * On the other hand, when a user enables TSF and CUAS, Chinese IMEs - * ignore the position of the current system caret and uses the - * parameters given to ::ImmSetCandidateWindow() with its 'dwStyle' - * parameter CFS_CANDIDATEPOS. - * Therefore, we do not only call ::ImmSetCandidateWindow() but also - * set the positions of the temporary system caret if it exists. - */ - CANDIDATEFORM candidate_position = { 0, CFS_CANDIDATEPOS, { x, y }, - { 0, 0, 0, 0 } }; - ::ImmSetCandidateWindow(imm_context, &candidate_position); - if (system_caret_) { - switch (PRIMARYLANGID(input_language_id_)) { - case LANG_JAPANESE: - ::SetCaretPos(x, y + caret_rect_.getHeight()); - break; - default: - ::SetCaretPos(x, y); - break; - } - } - if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) { - /** - * Chinese IMEs and Japanese IMEs require the upper-left corner of - * the caret to move the position of their candidate windows. - * On the other hand, Korean IMEs require the lower-left corner of the - * caret to move their candidate windows. - */ - y += kCaretMargin; - } - /** - * Japanese IMEs and Korean IMEs also use the rectangle given to - * ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE - * to move their candidate windows when a user disables TSF and CUAS. - * Therefore, we also set this parameter here. - */ - CANDIDATEFORM exclude_rectangle = { 0, CFS_EXCLUDE, { x, y }, - { x, y, x + caret_rect_.getWidth(), y + caret_rect_.getHeight() } }; - ::ImmSetCandidateWindow(imm_context, &exclude_rectangle); + int x = caret_rect_.m_l; + int y = caret_rect_.m_t; + const int kCaretMargin = 1; + /** + * As written in a comment in GHOST_ImeWin32::CreateImeWindow(), + * Chinese IMEs ignore function calls to ::ImmSetCandidateWindow() + * when a user disables TSF (Text Service Framework) and CUAS (Cicero + * Unaware Application Support). + * On the other hand, when a user enables TSF and CUAS, Chinese IMEs + * ignore the position of the current system caret and uses the + * parameters given to ::ImmSetCandidateWindow() with its 'dwStyle' + * parameter CFS_CANDIDATEPOS. + * Therefore, we do not only call ::ImmSetCandidateWindow() but also + * set the positions of the temporary system caret if it exists. + */ + CANDIDATEFORM candidate_position = {0, CFS_CANDIDATEPOS, {x, y}, {0, 0, 0, 0}}; + ::ImmSetCandidateWindow(imm_context, &candidate_position); + if (system_caret_) { + switch (PRIMARYLANGID(input_language_id_)) { + case LANG_JAPANESE: + ::SetCaretPos(x, y + caret_rect_.getHeight()); + break; + default: + ::SetCaretPos(x, y); + break; + } + } + if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) { + /** + * Chinese IMEs and Japanese IMEs require the upper-left corner of + * the caret to move the position of their candidate windows. + * On the other hand, Korean IMEs require the lower-left corner of the + * caret to move their candidate windows. + */ + y += kCaretMargin; + } + /** + * Japanese IMEs and Korean IMEs also use the rectangle given to + * ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE + * to move their candidate windows when a user disables TSF and CUAS. + * Therefore, we also set this parameter here. + */ + CANDIDATEFORM exclude_rectangle = { + 0, CFS_EXCLUDE, {x, y}, {x, y, x + caret_rect_.getWidth(), y + caret_rect_.getHeight()}}; + ::ImmSetCandidateWindow(imm_context, &exclude_rectangle); } - void GHOST_ImeWin32::UpdateImeWindow(HWND window_handle) { - /* Just move the IME window attached to the given window. */ - if (caret_rect_.m_l >= 0 && caret_rect_.m_t >= 0) { - HIMC imm_context = ::ImmGetContext(window_handle); - if (imm_context) { - MoveImeWindow(window_handle, imm_context); - ::ImmReleaseContext(window_handle, imm_context); - } - } + /* Just move the IME window attached to the given window. */ + if (caret_rect_.m_l >= 0 && caret_rect_.m_t >= 0) { + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + MoveImeWindow(window_handle, imm_context); + ::ImmReleaseContext(window_handle, imm_context); + } + } } - void GHOST_ImeWin32::CleanupComposition(HWND window_handle) { - /** - * Notify the IMM attached to the given window to complete the ongoing - * composition, (this case happens when the given window is de-activated - * while composing a text and re-activated), and reset the omposition status. - */ - if (is_composing_) { - HIMC imm_context = ::ImmGetContext(window_handle); - if (imm_context) { - ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); - ::ImmReleaseContext(window_handle, imm_context); - } - ResetComposition(window_handle); - } + /** + * Notify the IMM attached to the given window to complete the ongoing + * composition, (this case happens when the given window is de-activated + * while composing a text and re-activated), and reset the omposition status. + */ + if (is_composing_) { + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + ::ImmReleaseContext(window_handle, imm_context); + } + ResetComposition(window_handle); + } } - void GHOST_ImeWin32::CheckFirst(HWND window_handle) { - if (is_first) { - this->EndIME(window_handle); - is_first = false; - } + if (is_first) { + this->EndIME(window_handle); + is_first = false; + } } - void GHOST_ImeWin32::ResetComposition(HWND window_handle) { - /* Currently, just reset the composition status. */ - is_composing_ = false; + /* Currently, just reset the composition status. */ + is_composing_ = false; } - void GHOST_ImeWin32::CompleteComposition(HWND window_handle, HIMC imm_context) { - /** - * We have to confirm there is an ongoing composition before completing it. - * This is for preventing some IMEs from getting confused while completing an - * ongoing composition even if they do not have any ongoing compositions.) - */ - if (is_composing_) { - ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); - ResetComposition(window_handle); - } + /** + * We have to confirm there is an ongoing composition before completing it. + * This is for preventing some IMEs from getting confused while completing an + * ongoing composition even if they do not have any ongoing compositions.) + */ + if (is_composing_) { + ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + ResetComposition(window_handle); + } } - void GHOST_ImeWin32::GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *composition) { - /** - * This operation is optional and language-dependent because the caret - * style is depended on the language, e.g.: - * * Korean IMEs: the caret is a blinking block, - * (It contains only one hangul character); - * * Chinese IMEs: the caret is a blinking line, - * (i.e. they do not need to retrieve the target selection); - * * Japanese IMEs: the caret is a selection (or underlined) block, - * (which can contain one or more Japanese characters). - */ - int target_start = -1; - int target_end = -1; - switch (PRIMARYLANGID(input_language_id_)) { - case LANG_KOREAN: - if (lparam & CS_NOMOVECARET) { - target_start = 0; - target_end = 1; - } - break; - case LANG_CHINESE: - { - int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0); - if (clause_size) { - static std::vector<unsigned long> clauses; - clause_size = clause_size / sizeof(clauses[0]); - clauses.resize(clause_size); - ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, &clauses[0], - sizeof(clauses[0]) *clause_size); - if (composition->cursor_position == composition->ime_string.size()) { - target_start = clauses[clause_size - 2]; - target_end = clauses[clause_size - 1]; - } - else { - for (int i = 0; i < clause_size - 1; i++) { - if (clauses[i] == composition->cursor_position) { - target_start = clauses[i]; - target_end = clauses[i + 1]; - break; - } - } - } - } - else { - if (composition->cursor_position != -1) { - target_start = composition->cursor_position; - target_end = composition->ime_string.size(); - } - } - break; - } - case LANG_JAPANESE: - - /** - * For Japanese IMEs, the robustest way to retrieve the caret - * is scanning the attribute of the latest composition string and - * retrieving the begining and the end of the target clause, i.e. - * a clause being converted. - */ - if (lparam & GCS_COMPATTR) { - int attribute_size = ::ImmGetCompositionStringW(imm_context, - GCS_COMPATTR, - NULL, 0); - if (attribute_size > 0) { - char *attribute_data = new char[attribute_size]; - if (attribute_data) { - ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, - attribute_data, attribute_size); - for (target_start = 0; target_start < attribute_size; - ++target_start) { - if (IsTargetAttribute(attribute_data[target_start])) - break; - } - for (target_end = target_start; target_end < attribute_size; - ++target_end) { - if (!IsTargetAttribute(attribute_data[target_end])) - break; - } - if (target_start == attribute_size) { - /** - * This composition clause does not contain any target clauses, - * i.e. this clauses is an input clause. - * We treat whole this clause as a target clause. - */ - target_end = target_start; - target_start = 0; - } - if (target_start != -1 && target_start < attribute_size && - attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED) - { - composition->cursor_position = target_start; - } - } - delete[] attribute_data; - } - } - break; - } - composition->target_start = target_start; - composition->target_end = target_end; + /** + * This operation is optional and language-dependent because the caret + * style is depended on the language, e.g.: + * * Korean IMEs: the caret is a blinking block, + * (It contains only one hangul character); + * * Chinese IMEs: the caret is a blinking line, + * (i.e. they do not need to retrieve the target selection); + * * Japanese IMEs: the caret is a selection (or underlined) block, + * (which can contain one or more Japanese characters). + */ + int target_start = -1; + int target_end = -1; + switch (PRIMARYLANGID(input_language_id_)) { + case LANG_KOREAN: + if (lparam & CS_NOMOVECARET) { + target_start = 0; + target_end = 1; + } + break; + case LANG_CHINESE: { + int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0); + if (clause_size) { + static std::vector<unsigned long> clauses; + clause_size = clause_size / sizeof(clauses[0]); + clauses.resize(clause_size); + ImmGetCompositionStringW( + imm_context, GCS_COMPCLAUSE, &clauses[0], sizeof(clauses[0]) * clause_size); + if (composition->cursor_position == composition->ime_string.size()) { + target_start = clauses[clause_size - 2]; + target_end = clauses[clause_size - 1]; + } + else { + for (int i = 0; i < clause_size - 1; i++) { + if (clauses[i] == composition->cursor_position) { + target_start = clauses[i]; + target_end = clauses[i + 1]; + break; + } + } + } + } + else { + if (composition->cursor_position != -1) { + target_start = composition->cursor_position; + target_end = composition->ime_string.size(); + } + } + break; + } + case LANG_JAPANESE: + + /** + * For Japanese IMEs, the robustest way to retrieve the caret + * is scanning the attribute of the latest composition string and + * retrieving the begining and the end of the target clause, i.e. + * a clause being converted. + */ + if (lparam & GCS_COMPATTR) { + int attribute_size = ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, NULL, 0); + if (attribute_size > 0) { + char *attribute_data = new char[attribute_size]; + if (attribute_data) { + ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, attribute_data, attribute_size); + for (target_start = 0; target_start < attribute_size; ++target_start) { + if (IsTargetAttribute(attribute_data[target_start])) + break; + } + for (target_end = target_start; target_end < attribute_size; ++target_end) { + if (!IsTargetAttribute(attribute_data[target_end])) + break; + } + if (target_start == attribute_size) { + /** + * This composition clause does not contain any target clauses, + * i.e. this clauses is an input clause. + * We treat whole this clause as a target clause. + */ + target_end = target_start; + target_start = 0; + } + if (target_start != -1 && target_start < attribute_size && + attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED) { + composition->cursor_position = target_start; + } + } + delete[] attribute_data; + } + } + break; + } + composition->target_start = target_start; + composition->target_end = target_end; } - -bool GHOST_ImeWin32::GetString(HIMC imm_context, WPARAM lparam, int type, ImeComposition *composition) +bool GHOST_ImeWin32::GetString(HIMC imm_context, + WPARAM lparam, + int type, + ImeComposition *composition) { - bool result = false; - if (lparam & type) { - int string_size = ::ImmGetCompositionStringW(imm_context, type, NULL, 0); - if (string_size > 0) { - int string_length = string_size / sizeof(wchar_t); - wchar_t *string_data = new wchar_t[string_length + 1]; - string_data[string_length] = '\0'; - if (string_data) { - /* Fill the given ImeComposition object. */ - ::ImmGetCompositionStringW(imm_context, type, - string_data, string_size); - composition->string_type = type; - composition->ime_string = string_data; - result = true; - } - delete[] string_data; - } - } - return result; + bool result = false; + if (lparam & type) { + int string_size = ::ImmGetCompositionStringW(imm_context, type, NULL, 0); + if (string_size > 0) { + int string_length = string_size / sizeof(wchar_t); + wchar_t *string_data = new wchar_t[string_length + 1]; + string_data[string_length] = '\0'; + if (string_data) { + /* Fill the given ImeComposition object. */ + ::ImmGetCompositionStringW(imm_context, type, string_data, string_size); + composition->string_type = type; + composition->ime_string = string_data; + result = true; + } + delete[] string_data; + } + } + return result; } - bool GHOST_ImeWin32::GetResult(HWND window_handle, LPARAM lparam, ImeComposition *composition) { - bool result = false; - HIMC imm_context = ::ImmGetContext(window_handle); - if (imm_context) { - /* Copy the result string to the ImeComposition object. */ - result = GetString(imm_context, lparam, GCS_RESULTSTR, composition); - /** - * Reset all the other parameters because a result string does not - * have composition attributes. - */ - composition->cursor_position = -1; - composition->target_start = -1; - composition->target_end = -1; - ::ImmReleaseContext(window_handle, imm_context); - } - return result; + bool result = false; + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + /* Copy the result string to the ImeComposition object. */ + result = GetString(imm_context, lparam, GCS_RESULTSTR, composition); + /** + * Reset all the other parameters because a result string does not + * have composition attributes. + */ + composition->cursor_position = -1; + composition->target_start = -1; + composition->target_end = -1; + ::ImmReleaseContext(window_handle, imm_context); + } + return result; } - bool GHOST_ImeWin32::GetComposition(HWND window_handle, LPARAM lparam, ImeComposition *composition) { - bool result = false; - HIMC imm_context = ::ImmGetContext(window_handle); - if (imm_context) { - /* Copy the composition string to the ImeComposition object. */ - result = GetString(imm_context, lparam, GCS_COMPSTR, composition); - - /* Retrieve the cursor position in the IME composition. */ - int cursor_position = ::ImmGetCompositionStringW(imm_context, GCS_CURSORPOS, NULL, 0); - composition->cursor_position = cursor_position; - composition->target_start = -1; - composition->target_end = -1; - - /* Retrieve the target selection and Update the ImeComposition object. */ - GetCaret(imm_context, lparam, composition); - - /* Mark that there is an ongoing composition. */ - is_composing_ = true; - - ::ImmReleaseContext(window_handle, imm_context); - } - return result; + bool result = false; + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + /* Copy the composition string to the ImeComposition object. */ + result = GetString(imm_context, lparam, GCS_COMPSTR, composition); + + /* Retrieve the cursor position in the IME composition. */ + int cursor_position = ::ImmGetCompositionStringW(imm_context, GCS_CURSORPOS, NULL, 0); + composition->cursor_position = cursor_position; + composition->target_start = -1; + composition->target_end = -1; + + /* Retrieve the target selection and Update the ImeComposition object. */ + GetCaret(imm_context, lparam, composition); + + /* Mark that there is an ongoing composition. */ + is_composing_ = true; + + ::ImmReleaseContext(window_handle, imm_context); + } + return result; } - void GHOST_ImeWin32::EndIME(HWND window_handle) { - /** - * A renderer process have moved its input focus to a password input - * when there is an ongoing composition, e.g. a user has clicked a - * mouse button and selected a password input while composing a text. - * For this case, we have to complete the ongoing composition and - * clean up the resources attached to this object BEFORE DISABLING THE IME. - */ - if (!is_enable) return; - is_enable = false; - CleanupComposition(window_handle); - ::ImmAssociateContextEx(window_handle, NULL, 0); - eventImeData.composite_len = 0; + /** + * A renderer process have moved its input focus to a password input + * when there is an ongoing composition, e.g. a user has clicked a + * mouse button and selected a password input while composing a text. + * For this case, we have to complete the ongoing composition and + * clean up the resources attached to this object BEFORE DISABLING THE IME. + */ + if (!is_enable) + return; + is_enable = false; + CleanupComposition(window_handle); + ::ImmAssociateContextEx(window_handle, NULL, 0); + eventImeData.composite_len = 0; } - void GHOST_ImeWin32::BeginIME(HWND window_handle, const GHOST_Rect &caret_rect, bool complete) { - if (is_enable && complete) return; - is_enable = true; - /** - * Load the default IME context. - * NOTE(hbono) - * IMM ignores this call if the IME context is loaded. Therefore, we do - * not have to check whether or not the IME context is loaded. - */ - ::ImmAssociateContextEx(window_handle, NULL, IACE_DEFAULT); - /* Complete the ongoing composition and move the IME windows. */ - HIMC imm_context = ::ImmGetContext(window_handle); - if (imm_context) { - if (complete) { - /** - * A renderer process have moved its input focus to another edit - * control when there is an ongoing composition, e.g. a user has - * clicked a mouse button and selected another edit control while - * composing a text. - * For this case, we have to complete the ongoing composition and - * hide the IME windows BEFORE MOVING THEM. - */ - CompleteComposition(window_handle, imm_context); - } - /** - * Save the caret position, and Update the position of the IME window. - * This update is used for moving an IME window when a renderer process - * resize/moves the input caret. - */ - if (caret_rect.m_l >= 0 && caret_rect.m_t >= 0) { - caret_rect_ = caret_rect; - MoveImeWindow(window_handle, imm_context); - } - ::ImmReleaseContext(window_handle, imm_context); - } + if (is_enable && complete) + return; + is_enable = true; + /** + * Load the default IME context. + * NOTE(hbono) + * IMM ignores this call if the IME context is loaded. Therefore, we do + * not have to check whether or not the IME context is loaded. + */ + ::ImmAssociateContextEx(window_handle, NULL, IACE_DEFAULT); + /* Complete the ongoing composition and move the IME windows. */ + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + if (complete) { + /** + * A renderer process have moved its input focus to another edit + * control when there is an ongoing composition, e.g. a user has + * clicked a mouse button and selected another edit control while + * composing a text. + * For this case, we have to complete the ongoing composition and + * hide the IME windows BEFORE MOVING THEM. + */ + CompleteComposition(window_handle, imm_context); + } + /** + * Save the caret position, and Update the position of the IME window. + * This update is used for moving an IME window when a renderer process + * resize/moves the input caret. + */ + if (caret_rect.m_l >= 0 && caret_rect.m_t >= 0) { + caret_rect_ = caret_rect; + MoveImeWindow(window_handle, imm_context); + } + ::ImmReleaseContext(window_handle, imm_context); + } } - static void convert_utf16_to_utf8_len(std::wstring s, int &len) { - if (len >= 0 && len <= s.size()) - len = count_utf_8_from_16(s.substr(0, len).c_str()) - 1; - else - len = -1; + if (len >= 0 && len <= s.size()) + len = count_utf_8_from_16(s.substr(0, len).c_str()) - 1; + else + len = -1; } - static size_t updateUtf8Buf(ImeComposition &info) { - size_t len = count_utf_8_from_16(info.ime_string.c_str()); - info.utf8_buf.resize(len); - conv_utf_16_to_8(info.ime_string.c_str(), &info.utf8_buf[0], len); - convert_utf16_to_utf8_len(info.ime_string, info.cursor_position); - convert_utf16_to_utf8_len(info.ime_string, info.target_start); - convert_utf16_to_utf8_len(info.ime_string, info.target_end); - return len - 1; + size_t len = count_utf_8_from_16(info.ime_string.c_str()); + info.utf8_buf.resize(len); + conv_utf_16_to_8(info.ime_string.c_str(), &info.utf8_buf[0], len); + convert_utf16_to_utf8_len(info.ime_string, info.cursor_position); + convert_utf16_to_utf8_len(info.ime_string, info.target_start); + convert_utf16_to_utf8_len(info.ime_string, info.target_end); + return len - 1; } - void GHOST_ImeWin32::UpdateInfo(HWND window_handle) { - int res = this->GetResult(window_handle, GCS_RESULTSTR, &resultInfo); - int comp = this->GetComposition(window_handle, GCS_COMPSTR | GCS_COMPATTR, &compInfo); - /* convert wchar to utf8 */ - if (res) { - eventImeData.result_len = (GHOST_TUserDataPtr)updateUtf8Buf(resultInfo); - eventImeData.result = &resultInfo.utf8_buf[0]; - } - else { - eventImeData.result = 0; - eventImeData.result_len = 0; - } - if (comp) { - eventImeData.composite_len = (GHOST_TUserDataPtr)updateUtf8Buf(compInfo); - eventImeData.composite = &compInfo.utf8_buf[0]; - eventImeData.cursor_position = compInfo.cursor_position; - eventImeData.target_start = compInfo.target_start; - eventImeData.target_end = compInfo.target_end; - } - else { - eventImeData.composite = 0; - eventImeData.composite_len = 0; - eventImeData.cursor_position = -1; - eventImeData.target_start = -1; - eventImeData.target_end = -1; - } + int res = this->GetResult(window_handle, GCS_RESULTSTR, &resultInfo); + int comp = this->GetComposition(window_handle, GCS_COMPSTR | GCS_COMPATTR, &compInfo); + /* convert wchar to utf8 */ + if (res) { + eventImeData.result_len = (GHOST_TUserDataPtr)updateUtf8Buf(resultInfo); + eventImeData.result = &resultInfo.utf8_buf[0]; + } + else { + eventImeData.result = 0; + eventImeData.result_len = 0; + } + if (comp) { + eventImeData.composite_len = (GHOST_TUserDataPtr)updateUtf8Buf(compInfo); + eventImeData.composite = &compInfo.utf8_buf[0]; + eventImeData.cursor_position = compInfo.cursor_position; + eventImeData.target_start = compInfo.target_start; + eventImeData.target_end = compInfo.target_end; + } + else { + eventImeData.composite = 0; + eventImeData.composite_len = 0; + eventImeData.cursor_position = -1; + eventImeData.target_start = -1; + eventImeData.target_end = -1; + } } -#endif // WITH_INPUT_IME +#endif // WITH_INPUT_IME diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index 10f6d1cef55..61fc93a78af 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -28,35 +28,30 @@ #ifdef WITH_INPUT_IME -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -#include <string> - -#include "GHOST_Event.h" -#include "GHOST_Rect.h" -#include <vector> - -class GHOST_EventIME : 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_EventIME(GHOST_TUns64 msec, - GHOST_TEventType type, - GHOST_IWindow *window, void *customdata) - : GHOST_Event(msec, type, window) - { - this->m_data = customdata; - } - +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +# include <string> + +# include "GHOST_Event.h" +# include "GHOST_Rect.h" +# include <vector> + +class GHOST_EventIME : 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_EventIME(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) + : GHOST_Event(msec, type, window) + { + this->m_data = customdata; + } }; - /** * This header file defines a struct and a class used for encapsulating IMM32 * APIs, controls IMEs attached to a window, and enables the 'on-the-spot' @@ -100,29 +95,29 @@ public: /* This struct represents the status of an ongoing composition. */ struct ImeComposition { - /* Represents the cursor position in the IME composition. */ - int cursor_position; - - /* Represents the position of the beginning of the selection */ - int target_start; - - /* Represents the position of the end of the selection */ - int target_end; - - /** - * Represents the type of the string in the 'ime_string' parameter. - * Its possible values and description are listed below: - * Value Description - * 0 The parameter is not used. - * GCS_RESULTSTR The parameter represents a result string. - * GCS_COMPSTR The parameter represents a composition string. - */ - int string_type; - - /* Represents the string retrieved from IME (Input Method Editor) */ - std::wstring ime_string; - std::vector<char> utf8_buf; - std::vector<unsigned char> format; + /* Represents the cursor position in the IME composition. */ + int cursor_position; + + /* Represents the position of the beginning of the selection */ + int target_start; + + /* Represents the position of the end of the selection */ + int target_end; + + /** + * Represents the type of the string in the 'ime_string' parameter. + * Its possible values and description are listed below: + * Value Description + * 0 The parameter is not used. + * GCS_RESULTSTR The parameter represents a result string. + * GCS_COMPSTR The parameter represents a composition string. + */ + int string_type; + + /* Represents the string retrieved from IME (Input Method Editor) */ + std::wstring ime_string; + std::vector<char> utf8_buf; + std::vector<unsigned char> format; }; /** @@ -142,258 +137,255 @@ struct ImeComposition { * LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES. */ class GHOST_ImeWin32 { -public: - GHOST_ImeWin32(); - ~GHOST_ImeWin32(); - - /* Retrieves whether or not there is an ongoing composition. */ - bool is_composing() const {return is_composing_;} - - /** - * Retrieves the input language from Windows and update it. - * Return values - * * true - * The given input language has IMEs. - * * false - * The given input language does not have IMEs. - */ - bool SetInputLanguage(); - - /** - * Create the IME windows, and allocate required resources for them. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void CreateImeWindow(HWND window_handle); - - /** - * Update the style of the IME windows. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - * * message [in] (UINT) - * * wparam [in] (WPARAM) - * * lparam [in] (LPARAM) - * Represent the windows message of the caller. - * These parameters are used for verifying if this function is called - * in a handler function for WM_IME_SETCONTEXT messages because this - * function uses ::DefWindowProc() to update the style. - * A caller just has to pass the input parameters for the handler - * function without modifications. - * * handled [out] (BOOL*) - * Returns ::DefWindowProc() is really called in this function. - * PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE! - * All the window styles set in this function are over-written when - * calling ::DefWindowProc() after returning this function. - */ - void SetImeWindowStyle(HWND window_handle, UINT message, - WPARAM wparam, LPARAM lparam, BOOL* handled); - - /** - * Destroy the IME windows and all the resources attached to them. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void DestroyImeWindow(HWND window_handle); - - /** - * Update the position of the IME windows. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void UpdateImeWindow(HWND window_handle); - - /** - * Clean up the all resources attached to the given GHOST_ImeWin32 object, and - * reset its composition status. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void CleanupComposition(HWND window_handle); - - /** - * Reset the composition status. - * Cancel the ongoing composition if it exists. - * NOTE(hbono): This method does not release the allocated resources. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void ResetComposition(HWND window_handle); - - /** - * Retrieve a composition result of the ongoing composition if it exists. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - * * lparam [in] (LPARAM) - * Specifies the updated members of the ongoing composition, and must be - * the same parameter of a WM_IME_COMPOSITION message handler. - * This parameter is used for checking if the ongoing composition has - * its result string, - * * composition [out] (ImeComposition) - * Represents the struct contains the composition result. - * Return values - * * true - * The ongoing composition has a composition result. - * * false - * The ongoing composition does not have composition results. - * Remarks - * This function is designed for being called from WM_IME_COMPOSITION - * message handlers. - */ - bool GetResult(HWND window_handle, LPARAM lparam, - ImeComposition* composition); - - /** - * Retrieve the current composition status of the ongoing composition. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - * * lparam [in] (LPARAM) - * Specifies the updated members of the ongoing composition, and must be - * the same parameter of a WM_IME_COMPOSITION message handler. - * This parameter is used for checking if the ongoing composition has - * its result string, - * * composition [out] (ImeComposition) - * Represents the struct contains the composition status. - * Return values - * * true - * The status of the ongoing composition is updated. - * * false - * The status of the ongoing composition is not updated. - * Remarks - * This function is designed for being called from WM_IME_COMPOSITION - * message handlers. - */ - bool GetComposition(HWND window_handle, LPARAM lparam, - ImeComposition* composition); - - /** - * Enable the IME attached to the given window, i.e. allows user-input - * events to be dispatched to the IME. - * In Chrome, this function is used when: - * * a renderer process moves its input focus to another edit control, or; - * * a renrerer process moves the position of the focused edit control. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - * * caret_rect [in] (const gfx::Rect&) - * Represent the rectangle of the input caret. - * This rectangle is used for controlling the positions of IME windows. - * * complete [in] (bool) - * Represents whether or not to complete the ongoing composition. - * + true - * After finishing the ongoing composition and close its IME windows, - * start another composition and display its IME windows to the given - * position. - * + false - * Just move the IME windows of the ongoing composition to the given - * position without finishing it. - */ - void BeginIME(HWND window_handle, - const GHOST_Rect& caret_rect, - bool complete); - - /** - * Disable the IME attached to the given window, i.e. prohibits any user-input - * events from being dispatched to the IME. - * In Chrome, this function is used when: - * * a renreder process sets its input focus to a password input. - * Parameters - * * window_handle [in] (HWND) - * Represents the window handle of the caller. - */ - void EndIME(HWND window_handle); - - /* Updatg resultInfo and compInfo */ - void UpdateInfo(HWND window_handle); - - /* disable ime when start up */ - void CheckFirst(HWND window_handle); - - ImeComposition resultInfo, compInfo; - GHOST_TEventImeData eventImeData; - -protected: - /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */ - bool IsTargetAttribute(char attribute) const { - return (attribute == ATTR_TARGET_CONVERTED || - attribute == ATTR_TARGET_NOTCONVERTED); - } - - /* Retrieve the target area. */ - void GetCaret(HIMC imm_context, LPARAM lparam, - ImeComposition* composition); - - /* Update the position of the IME windows. */ - void MoveImeWindow(HWND window_handle, HIMC imm_context); - - /* Complete the ongoing composition if it exists. */ - void CompleteComposition(HWND window_handle, HIMC imm_context); - - /* Retrieve a string from the IMM. */ - bool GetString(HIMC imm_context, WPARAM lparam, int type, - ImeComposition* composition); - -private: - /** - * Represents whether or not there is an ongoing composition in a browser - * process, i.e. whether or not a browser process is composing a text. - */ - bool is_composing_; - - /** - * This value represents whether or not the current input context has IMEs. - * The following table shows the list of IME status: - * Value Description - * false The current input language does not have IMEs. - * true The current input language has IMEs. - */ - bool ime_status_; - - /** - * The current input Language ID retrieved from Windows, which consists of: - * * Primary Language ID (bit 0 to bit 9), which shows a natunal language - * (English, Korean, Chinese, Japanese, etc.) and; - * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region - * the language is spoken (For English, United States, United Kingdom, - * Australia, Canada, etc.) - * The following list enumerates some examples for the Language ID: - * * "en-US" (0x0409) - * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); - * * "ko-KR" (0x0412) - * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN); - * * "zh-TW" (0x0404) - * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL); - * * "zh-CN" (0x0804) - * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED); - * * "ja-JP" (0x0411) - * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc. - * (See <winnt.h> for other available values.) - * This Language ID is used for processing language-specific operations in - * IME functions. - */ - LANGID input_language_id_; - - /** - * Represents whether or not the current input context has created a system - * caret to set the position of its IME candidate window. - * * true: it creates a system caret. - * * false: it does not create a system caret. - */ - bool system_caret_; - - /* The rectangle of the input caret retrieved from a renderer process. */ - GHOST_Rect caret_rect_; - - /* used for disable ime when start up */ - bool is_first, is_enable; + public: + GHOST_ImeWin32(); + ~GHOST_ImeWin32(); + + /* Retrieves whether or not there is an ongoing composition. */ + bool is_composing() const + { + return is_composing_; + } + + /** + * Retrieves the input language from Windows and update it. + * Return values + * * true + * The given input language has IMEs. + * * false + * The given input language does not have IMEs. + */ + bool SetInputLanguage(); + + /** + * Create the IME windows, and allocate required resources for them. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void CreateImeWindow(HWND window_handle); + + /** + * Update the style of the IME windows. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + * * message [in] (UINT) + * * wparam [in] (WPARAM) + * * lparam [in] (LPARAM) + * Represent the windows message of the caller. + * These parameters are used for verifying if this function is called + * in a handler function for WM_IME_SETCONTEXT messages because this + * function uses ::DefWindowProc() to update the style. + * A caller just has to pass the input parameters for the handler + * function without modifications. + * * handled [out] (BOOL*) + * Returns ::DefWindowProc() is really called in this function. + * PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE! + * All the window styles set in this function are over-written when + * calling ::DefWindowProc() after returning this function. + */ + void SetImeWindowStyle( + HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled); + + /** + * Destroy the IME windows and all the resources attached to them. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void DestroyImeWindow(HWND window_handle); + + /** + * Update the position of the IME windows. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void UpdateImeWindow(HWND window_handle); + + /** + * Clean up the all resources attached to the given GHOST_ImeWin32 object, and + * reset its composition status. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void CleanupComposition(HWND window_handle); + + /** + * Reset the composition status. + * Cancel the ongoing composition if it exists. + * NOTE(hbono): This method does not release the allocated resources. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void ResetComposition(HWND window_handle); + + /** + * Retrieve a composition result of the ongoing composition if it exists. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + * * lparam [in] (LPARAM) + * Specifies the updated members of the ongoing composition, and must be + * the same parameter of a WM_IME_COMPOSITION message handler. + * This parameter is used for checking if the ongoing composition has + * its result string, + * * composition [out] (ImeComposition) + * Represents the struct contains the composition result. + * Return values + * * true + * The ongoing composition has a composition result. + * * false + * The ongoing composition does not have composition results. + * Remarks + * This function is designed for being called from WM_IME_COMPOSITION + * message handlers. + */ + bool GetResult(HWND window_handle, LPARAM lparam, ImeComposition *composition); + + /** + * Retrieve the current composition status of the ongoing composition. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + * * lparam [in] (LPARAM) + * Specifies the updated members of the ongoing composition, and must be + * the same parameter of a WM_IME_COMPOSITION message handler. + * This parameter is used for checking if the ongoing composition has + * its result string, + * * composition [out] (ImeComposition) + * Represents the struct contains the composition status. + * Return values + * * true + * The status of the ongoing composition is updated. + * * false + * The status of the ongoing composition is not updated. + * Remarks + * This function is designed for being called from WM_IME_COMPOSITION + * message handlers. + */ + bool GetComposition(HWND window_handle, LPARAM lparam, ImeComposition *composition); + + /** + * Enable the IME attached to the given window, i.e. allows user-input + * events to be dispatched to the IME. + * In Chrome, this function is used when: + * * a renderer process moves its input focus to another edit control, or; + * * a renrerer process moves the position of the focused edit control. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + * * caret_rect [in] (const gfx::Rect&) + * Represent the rectangle of the input caret. + * This rectangle is used for controlling the positions of IME windows. + * * complete [in] (bool) + * Represents whether or not to complete the ongoing composition. + * + true + * After finishing the ongoing composition and close its IME windows, + * start another composition and display its IME windows to the given + * position. + * + false + * Just move the IME windows of the ongoing composition to the given + * position without finishing it. + */ + void BeginIME(HWND window_handle, const GHOST_Rect &caret_rect, bool complete); + + /** + * Disable the IME attached to the given window, i.e. prohibits any user-input + * events from being dispatched to the IME. + * In Chrome, this function is used when: + * * a renreder process sets its input focus to a password input. + * Parameters + * * window_handle [in] (HWND) + * Represents the window handle of the caller. + */ + void EndIME(HWND window_handle); + + /* Updatg resultInfo and compInfo */ + void UpdateInfo(HWND window_handle); + + /* disable ime when start up */ + void CheckFirst(HWND window_handle); + + ImeComposition resultInfo, compInfo; + GHOST_TEventImeData eventImeData; + + protected: + /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */ + bool IsTargetAttribute(char attribute) const + { + return (attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED); + } + + /* Retrieve the target area. */ + void GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *composition); + + /* Update the position of the IME windows. */ + void MoveImeWindow(HWND window_handle, HIMC imm_context); + + /* Complete the ongoing composition if it exists. */ + void CompleteComposition(HWND window_handle, HIMC imm_context); + + /* Retrieve a string from the IMM. */ + bool GetString(HIMC imm_context, WPARAM lparam, int type, ImeComposition *composition); + + private: + /** + * Represents whether or not there is an ongoing composition in a browser + * process, i.e. whether or not a browser process is composing a text. + */ + bool is_composing_; + + /** + * This value represents whether or not the current input context has IMEs. + * The following table shows the list of IME status: + * Value Description + * false The current input language does not have IMEs. + * true The current input language has IMEs. + */ + bool ime_status_; + + /** + * The current input Language ID retrieved from Windows, which consists of: + * * Primary Language ID (bit 0 to bit 9), which shows a natunal language + * (English, Korean, Chinese, Japanese, etc.) and; + * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region + * the language is spoken (For English, United States, United Kingdom, + * Australia, Canada, etc.) + * The following list enumerates some examples for the Language ID: + * * "en-US" (0x0409) + * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + * * "ko-KR" (0x0412) + * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN); + * * "zh-TW" (0x0404) + * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL); + * * "zh-CN" (0x0804) + * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED); + * * "ja-JP" (0x0411) + * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc. + * (See <winnt.h> for other available values.) + * This Language ID is used for processing language-specific operations in + * IME functions. + */ + LANGID input_language_id_; + + /** + * Represents whether or not the current input context has created a system + * caret to set the position of its IME candidate window. + * * true: it creates a system caret. + * * false: it does not create a system caret. + */ + bool system_caret_; + + /* The rectangle of the input caret retrieved from a renderer process. */ + GHOST_Rect caret_rect_; + + /* used for disable ime when start up */ + bool is_first, is_enable; }; -#endif // WITH_INPUT_IME -#endif // __GHOST_IME_H__ +#endif // WITH_INPUT_IME +#endif // __GHOST_IME_H__ diff --git a/intern/ghost/intern/GHOST_ModifierKeys.cpp b/intern/ghost/intern/GHOST_ModifierKeys.cpp index 6dfdb5f5a3d..6b74eab17b8 100644 --- a/intern/ghost/intern/GHOST_ModifierKeys.cpp +++ b/intern/ghost/intern/GHOST_ModifierKeys.cpp @@ -21,107 +21,120 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ #include "GHOST_ModifierKeys.h" - GHOST_ModifierKeys::GHOST_ModifierKeys() { - clear(); + clear(); } -GHOST_ModifierKeys::~GHOST_ModifierKeys() {} - +GHOST_ModifierKeys::~GHOST_ModifierKeys() +{ +} 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_kModifierKeyOS: key = GHOST_kKeyOS; break; - default: - // Should not happen - key = GHOST_kKeyUnknown; - break; - } - return key; + 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_kModifierKeyOS: + key = GHOST_kKeyOS; + 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_kModifierKeyOS: - return m_OS; - default: - return false; - } + 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_kModifierKeyOS: + return m_OS; + 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_kModifierKeyOS: - m_OS = down; break; - default: - break; - } + 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_kModifierKeyOS: + m_OS = 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_OS = false; + m_LeftShift = false; + m_RightShift = false; + m_LeftAlt = false; + m_RightAlt = false; + m_LeftControl = false; + m_RightControl = false; + m_OS = false; } - -bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys& keys) const +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_OS == keys.m_OS); + 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_OS == keys.m_OS); } diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h index 092f38f4d5a..27ad4034068 100644 --- a/intern/ghost/intern/GHOST_ModifierKeys.h +++ b/intern/ghost/intern/GHOST_ModifierKeys.h @@ -32,61 +32,60 @@ * Discriminates between left and right modifier keys. */ struct GHOST_ModifierKeys { - /** - * Constructor. - */ - GHOST_ModifierKeys(); + /** + * Constructor. + */ + GHOST_ModifierKeys(); - ~GHOST_ModifierKeys(); + ~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 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). + */ + bool get(GHOST_TModifierKeyMask mask) const; - /** - * Returns the state of a single modifier key. - * \param mask: Key state to return. - * \return The state of the key (pressed == true). - */ - 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. + */ + void set(GHOST_TModifierKeyMask mask, bool down); - /** - * Updates the state of a single modifier key. - * \param mask: Key state to update. - * \param down: The new state of the key. - */ - void set(GHOST_TModifierKeyMask mask, bool down); + /** + * Sets the state of all modifier keys to up. + */ + void clear(); - /** - * Sets the state of all modifier keys to up. - */ - void clear(); + /** + * Determines whether to modifier key states are equal. + * \param keys: The modifier key state to compare to. + * \return Indication of equality. + */ + bool equals(const GHOST_ModifierKeys &keys) const; - /** - * Determines whether to modifier key states are equal. - * \param keys: The modifier key state to compare to. - * \return Indication of equality. - */ - 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. */ - GHOST_TUns8 m_OS : 1; + /** 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. */ + GHOST_TUns8 m_OS : 1; }; -#endif // __GHOST_MODIFIERKEYS_H__ +#endif // __GHOST_MODIFIERKEYS_H__ diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index d8a81bb5839..b407d120a99 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -19,513 +19,492 @@ #include "GHOST_EventNDOF.h" #include "GHOST_EventKey.h" #include "GHOST_WindowManager.h" -#include <string.h> // for memory functions -#include <stdio.h> // for error/info reporting +#include <string.h> // for memory functions +#include <stdio.h> // for error/info reporting #include <math.h> #ifdef DEBUG_NDOF_MOTION // printable version of each GHOST_TProgress value -static const char *progress_string[] = -{"not started", "starting", "in progress", "finishing", "finished"}; +static const char *progress_string[] = { + "not started", "starting", "in progress", "finishing", "finished"}; #endif #ifdef DEBUG_NDOF_BUTTONS static const char *ndof_button_names[] = { - // used internally, never sent - "NDOF_BUTTON_NONE", - // these two are available from any 3Dconnexion device - "NDOF_BUTTON_MENU", - "NDOF_BUTTON_FIT", - // standard views - "NDOF_BUTTON_TOP", - "NDOF_BUTTON_BOTTOM", - "NDOF_BUTTON_LEFT", - "NDOF_BUTTON_RIGHT", - "NDOF_BUTTON_FRONT", - "NDOF_BUTTON_BACK", - // more views - "NDOF_BUTTON_ISO1", - "NDOF_BUTTON_ISO2", - // 90 degree rotations - "NDOF_BUTTON_ROLL_CW", - "NDOF_BUTTON_ROLL_CCW", - "NDOF_BUTTON_SPIN_CW", - "NDOF_BUTTON_SPIN_CCW", - "NDOF_BUTTON_TILT_CW", - "NDOF_BUTTON_TILT_CCW", - // device control - "NDOF_BUTTON_ROTATE", - "NDOF_BUTTON_PANZOOM", - "NDOF_BUTTON_DOMINANT", - "NDOF_BUTTON_PLUS", - "NDOF_BUTTON_MINUS", - // keyboard emulation - "NDOF_BUTTON_ESC", - "NDOF_BUTTON_ALT", - "NDOF_BUTTON_SHIFT", - "NDOF_BUTTON_CTRL", - // general-purpose buttons - "NDOF_BUTTON_1", - "NDOF_BUTTON_2", - "NDOF_BUTTON_3", - "NDOF_BUTTON_4", - "NDOF_BUTTON_5", - "NDOF_BUTTON_6", - "NDOF_BUTTON_7", - "NDOF_BUTTON_8", - "NDOF_BUTTON_9", - "NDOF_BUTTON_10", - // more general-purpose buttons - "NDOF_BUTTON_A", - "NDOF_BUTTON_B", - "NDOF_BUTTON_C", - // the end - "NDOF_BUTTON_LAST" -}; + // used internally, never sent + "NDOF_BUTTON_NONE", + // these two are available from any 3Dconnexion device + "NDOF_BUTTON_MENU", + "NDOF_BUTTON_FIT", + // standard views + "NDOF_BUTTON_TOP", + "NDOF_BUTTON_BOTTOM", + "NDOF_BUTTON_LEFT", + "NDOF_BUTTON_RIGHT", + "NDOF_BUTTON_FRONT", + "NDOF_BUTTON_BACK", + // more views + "NDOF_BUTTON_ISO1", + "NDOF_BUTTON_ISO2", + // 90 degree rotations + "NDOF_BUTTON_ROLL_CW", + "NDOF_BUTTON_ROLL_CCW", + "NDOF_BUTTON_SPIN_CW", + "NDOF_BUTTON_SPIN_CCW", + "NDOF_BUTTON_TILT_CW", + "NDOF_BUTTON_TILT_CCW", + // device control + "NDOF_BUTTON_ROTATE", + "NDOF_BUTTON_PANZOOM", + "NDOF_BUTTON_DOMINANT", + "NDOF_BUTTON_PLUS", + "NDOF_BUTTON_MINUS", + // keyboard emulation + "NDOF_BUTTON_ESC", + "NDOF_BUTTON_ALT", + "NDOF_BUTTON_SHIFT", + "NDOF_BUTTON_CTRL", + // general-purpose buttons + "NDOF_BUTTON_1", + "NDOF_BUTTON_2", + "NDOF_BUTTON_3", + "NDOF_BUTTON_4", + "NDOF_BUTTON_5", + "NDOF_BUTTON_6", + "NDOF_BUTTON_7", + "NDOF_BUTTON_8", + "NDOF_BUTTON_9", + "NDOF_BUTTON_10", + // more general-purpose buttons + "NDOF_BUTTON_A", + "NDOF_BUTTON_B", + "NDOF_BUTTON_C", + // the end + "NDOF_BUTTON_LAST"}; #endif // shared by the latest 3Dconnexion hardware // SpacePilotPro uses all of these // smaller devices use only some, based on button mask static const NDOF_ButtonT Modern3Dx_HID_map[] = { - NDOF_BUTTON_MENU, - NDOF_BUTTON_FIT, - NDOF_BUTTON_TOP, - NDOF_BUTTON_LEFT, - NDOF_BUTTON_RIGHT, - NDOF_BUTTON_FRONT, - NDOF_BUTTON_BOTTOM, - NDOF_BUTTON_BACK, - NDOF_BUTTON_ROLL_CW, - NDOF_BUTTON_ROLL_CCW, - NDOF_BUTTON_ISO1, - NDOF_BUTTON_ISO2, - NDOF_BUTTON_1, - NDOF_BUTTON_2, - NDOF_BUTTON_3, - NDOF_BUTTON_4, - NDOF_BUTTON_5, - NDOF_BUTTON_6, - NDOF_BUTTON_7, - NDOF_BUTTON_8, - NDOF_BUTTON_9, - NDOF_BUTTON_10, - NDOF_BUTTON_ESC, - NDOF_BUTTON_ALT, - NDOF_BUTTON_SHIFT, - NDOF_BUTTON_CTRL, - NDOF_BUTTON_ROTATE, - NDOF_BUTTON_PANZOOM, - NDOF_BUTTON_DOMINANT, - NDOF_BUTTON_PLUS, - NDOF_BUTTON_MINUS -}; - -static const NDOF_ButtonT SpaceExplorer_HID_map[] = { - NDOF_BUTTON_1, - NDOF_BUTTON_2, - NDOF_BUTTON_TOP, - NDOF_BUTTON_LEFT, - NDOF_BUTTON_RIGHT, - NDOF_BUTTON_FRONT, - NDOF_BUTTON_ESC, - NDOF_BUTTON_ALT, - NDOF_BUTTON_SHIFT, - NDOF_BUTTON_CTRL, - NDOF_BUTTON_FIT, - NDOF_BUTTON_MENU, - NDOF_BUTTON_PLUS, - NDOF_BUTTON_MINUS, - NDOF_BUTTON_ROTATE -}; + NDOF_BUTTON_MENU, NDOF_BUTTON_FIT, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT, + NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_BOTTOM, NDOF_BUTTON_BACK, + NDOF_BUTTON_ROLL_CW, NDOF_BUTTON_ROLL_CCW, NDOF_BUTTON_ISO1, NDOF_BUTTON_ISO2, + NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4, + NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_7, NDOF_BUTTON_8, + NDOF_BUTTON_9, NDOF_BUTTON_10, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_ROTATE, NDOF_BUTTON_PANZOOM, + NDOF_BUTTON_DOMINANT, NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS}; + +static const NDOF_ButtonT SpaceExplorer_HID_map[] = {NDOF_BUTTON_1, + NDOF_BUTTON_2, + NDOF_BUTTON_TOP, + NDOF_BUTTON_LEFT, + NDOF_BUTTON_RIGHT, + NDOF_BUTTON_FRONT, + NDOF_BUTTON_ESC, + NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, + NDOF_BUTTON_CTRL, + NDOF_BUTTON_FIT, + NDOF_BUTTON_MENU, + NDOF_BUTTON_PLUS, + NDOF_BUTTON_MINUS, + NDOF_BUTTON_ROTATE}; // this is the older SpacePilot (sans Pro) // thanks to polosson for info about this device static const NDOF_ButtonT SpacePilot_HID_map[] = { - NDOF_BUTTON_1, - NDOF_BUTTON_2, - NDOF_BUTTON_3, - NDOF_BUTTON_4, - NDOF_BUTTON_5, - NDOF_BUTTON_6, - NDOF_BUTTON_TOP, - NDOF_BUTTON_LEFT, - NDOF_BUTTON_RIGHT, - NDOF_BUTTON_FRONT, - NDOF_BUTTON_ESC, - NDOF_BUTTON_ALT, - NDOF_BUTTON_SHIFT, - NDOF_BUTTON_CTRL, - NDOF_BUTTON_FIT, - NDOF_BUTTON_MENU, - NDOF_BUTTON_PLUS, - NDOF_BUTTON_MINUS, - NDOF_BUTTON_DOMINANT, - NDOF_BUTTON_ROTATE, - NDOF_BUTTON_NONE // the CONFIG button -- what does it do? + NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4, + NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT, + NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_FIT, NDOF_BUTTON_MENU, + NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS, NDOF_BUTTON_DOMINANT, NDOF_BUTTON_ROTATE, + NDOF_BUTTON_NONE // the CONFIG button -- what does it do? }; -static const NDOF_ButtonT Generic_HID_map[] = { - NDOF_BUTTON_1, - NDOF_BUTTON_2, - NDOF_BUTTON_3, - NDOF_BUTTON_4, - NDOF_BUTTON_5, - NDOF_BUTTON_6, - NDOF_BUTTON_7, - NDOF_BUTTON_8, - NDOF_BUTTON_9, - NDOF_BUTTON_A, - NDOF_BUTTON_B, - NDOF_BUTTON_C -}; +static const NDOF_ButtonT Generic_HID_map[] = {NDOF_BUTTON_1, + NDOF_BUTTON_2, + NDOF_BUTTON_3, + NDOF_BUTTON_4, + NDOF_BUTTON_5, + NDOF_BUTTON_6, + NDOF_BUTTON_7, + NDOF_BUTTON_8, + NDOF_BUTTON_9, + NDOF_BUTTON_A, + NDOF_BUTTON_B, + NDOF_BUTTON_C}; static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT); GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys) - : m_system(sys), - m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code - m_buttonCount(genericButtonCount), - m_buttonMask(0), - m_hidMap(Generic_HID_map), - m_buttons(0), - m_motionTime(0), - m_prevMotionTime(0), - m_motionState(GHOST_kNotStarted), - m_motionEventPending(false), - m_deadZone(0.0f) + : m_system(sys), + m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code + m_buttonCount(genericButtonCount), + m_buttonMask(0), + m_hidMap(Generic_HID_map), + m_buttons(0), + m_motionTime(0), + m_prevMotionTime(0), + m_motionState(GHOST_kNotStarted), + m_motionEventPending(false), + m_deadZone(0.0f) { - // to avoid the rare situation where one triple is updated and - // the other is not, initialize them both here: - memset(m_translation, 0, sizeof(m_translation)); - memset(m_rotation, 0, sizeof(m_rotation)); + // to avoid the rare situation where one triple is updated and + // the other is not, initialize them both here: + memset(m_translation, 0, sizeof(m_translation)); + memset(m_rotation, 0, sizeof(m_rotation)); } bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id) { - // call this function until it returns true - // it's a good idea to stop calling it after that, as it will "forget" - // whichever device it already found - - // default to safe generic behavior for "unknown" devices - // unidentified devices will emit motion events like normal - // rogue buttons do nothing by default, but can be customized by the user - - m_deviceType = NDOF_UnknownDevice; - m_hidMap = Generic_HID_map; - m_buttonCount = genericButtonCount; - m_buttonMask = 0; - - // "mystery device" owners can help build a HID_map for their hardware - // A few users have already contributed information about several older devices - // that I don't have access to. Thanks! - - switch (vendor_id) { - case 0x046D: // Logitech (3Dconnexion was a subsidiary) - switch (product_id) { - // -- current devices -- - case 0xC626: // full-size SpaceNavigator - case 0xC628: // the "for Notebooks" one - puts("ndof: using SpaceNavigator"); - m_deviceType = NDOF_SpaceNavigator; - m_buttonCount = 2; - m_hidMap = Modern3Dx_HID_map; - break; - case 0xC627: - puts("ndof: using SpaceExplorer"); - m_deviceType = NDOF_SpaceExplorer; - m_buttonCount = 15; - m_hidMap = SpaceExplorer_HID_map; - break; - case 0xC629: - puts("ndof: using SpacePilot Pro"); - m_deviceType = NDOF_SpacePilotPro; - m_buttonCount = 31; - m_hidMap = Modern3Dx_HID_map; - break; - case 0xC62B: - puts("ndof: using SpaceMouse Pro"); - m_deviceType = NDOF_SpaceMousePro; - m_buttonCount = 27; - // ^^ actually has 15 buttons, but their HID codes range from 0 to 26 - m_buttonMask = 0x07C0F137; - m_hidMap = Modern3Dx_HID_map; - break; - - // -- older devices -- - case 0xC625: - puts("ndof: using SpacePilot"); - m_deviceType = NDOF_SpacePilot; - m_buttonCount = 21; - m_hidMap = SpacePilot_HID_map; - break; - case 0xC621: - puts("ndof: using Spaceball 5000"); - m_deviceType = NDOF_Spaceball5000; - m_buttonCount = 12; - break; - case 0xC623: - puts("ndof: using SpaceTraveler"); - m_deviceType = NDOF_SpaceTraveler; - m_buttonCount = 8; - break; - - default: - printf("ndof: unknown Logitech product %04hx\n", product_id); - } - break; - case 0x256F: // 3Dconnexion - switch (product_id) { - case 0xC62E: // plugged in - case 0xC62F: // wireless - puts("ndof: using SpaceMouse Wireless"); - m_deviceType = NDOF_SpaceMouseWireless; - m_buttonCount = 2; - m_hidMap = Modern3Dx_HID_map; - break; - case 0xC631: // plugged in - case 0xC632: // wireless - puts("ndof: using SpaceMouse Pro Wireless"); - m_deviceType = NDOF_SpaceMouseProWireless; - m_buttonCount = 27; - // ^^ actually has 15 buttons, but their HID codes range from 0 to 26 - m_buttonMask = 0x07C0F137; - m_hidMap = Modern3Dx_HID_map; - break; - case 0xC633: - puts("ndof: using SpaceMouse Enterprise"); - m_deviceType = NDOF_SpaceMouseEnterprise; - m_buttonCount = 31; - m_hidMap = Modern3Dx_HID_map; - break; - - default: - printf("ndof: unknown 3Dconnexion product %04hx\n", product_id); - } - break; - default: - printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id); - } - - if (m_buttonMask == 0) - m_buttonMask = (int) ~(UINT_MAX << m_buttonCount); + // call this function until it returns true + // it's a good idea to stop calling it after that, as it will "forget" + // whichever device it already found + + // default to safe generic behavior for "unknown" devices + // unidentified devices will emit motion events like normal + // rogue buttons do nothing by default, but can be customized by the user + + m_deviceType = NDOF_UnknownDevice; + m_hidMap = Generic_HID_map; + m_buttonCount = genericButtonCount; + m_buttonMask = 0; + + // "mystery device" owners can help build a HID_map for their hardware + // A few users have already contributed information about several older devices + // that I don't have access to. Thanks! + + switch (vendor_id) { + case 0x046D: // Logitech (3Dconnexion was a subsidiary) + switch (product_id) { + // -- current devices -- + case 0xC626: // full-size SpaceNavigator + case 0xC628: // the "for Notebooks" one + puts("ndof: using SpaceNavigator"); + m_deviceType = NDOF_SpaceNavigator; + m_buttonCount = 2; + m_hidMap = Modern3Dx_HID_map; + break; + case 0xC627: + puts("ndof: using SpaceExplorer"); + m_deviceType = NDOF_SpaceExplorer; + m_buttonCount = 15; + m_hidMap = SpaceExplorer_HID_map; + break; + case 0xC629: + puts("ndof: using SpacePilot Pro"); + m_deviceType = NDOF_SpacePilotPro; + m_buttonCount = 31; + m_hidMap = Modern3Dx_HID_map; + break; + case 0xC62B: + puts("ndof: using SpaceMouse Pro"); + m_deviceType = NDOF_SpaceMousePro; + m_buttonCount = 27; + // ^^ actually has 15 buttons, but their HID codes range from 0 to 26 + m_buttonMask = 0x07C0F137; + m_hidMap = Modern3Dx_HID_map; + break; + + // -- older devices -- + case 0xC625: + puts("ndof: using SpacePilot"); + m_deviceType = NDOF_SpacePilot; + m_buttonCount = 21; + m_hidMap = SpacePilot_HID_map; + break; + case 0xC621: + puts("ndof: using Spaceball 5000"); + m_deviceType = NDOF_Spaceball5000; + m_buttonCount = 12; + break; + case 0xC623: + puts("ndof: using SpaceTraveler"); + m_deviceType = NDOF_SpaceTraveler; + m_buttonCount = 8; + break; + + default: + printf("ndof: unknown Logitech product %04hx\n", product_id); + } + break; + case 0x256F: // 3Dconnexion + switch (product_id) { + case 0xC62E: // plugged in + case 0xC62F: // wireless + puts("ndof: using SpaceMouse Wireless"); + m_deviceType = NDOF_SpaceMouseWireless; + m_buttonCount = 2; + m_hidMap = Modern3Dx_HID_map; + break; + case 0xC631: // plugged in + case 0xC632: // wireless + puts("ndof: using SpaceMouse Pro Wireless"); + m_deviceType = NDOF_SpaceMouseProWireless; + m_buttonCount = 27; + // ^^ actually has 15 buttons, but their HID codes range from 0 to 26 + m_buttonMask = 0x07C0F137; + m_hidMap = Modern3Dx_HID_map; + break; + case 0xC633: + puts("ndof: using SpaceMouse Enterprise"); + m_deviceType = NDOF_SpaceMouseEnterprise; + m_buttonCount = 31; + m_hidMap = Modern3Dx_HID_map; + break; + + default: + printf("ndof: unknown 3Dconnexion product %04hx\n", product_id); + } + break; + default: + printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id); + } + + if (m_buttonMask == 0) + m_buttonMask = (int)~(UINT_MAX << m_buttonCount); #ifdef DEBUG_NDOF_BUTTONS - printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask); + printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask); #endif - return m_deviceType != NDOF_UnknownDevice; + return m_deviceType != NDOF_UnknownDevice; } void GHOST_NDOFManager::updateTranslation(const int t[3], GHOST_TUns64 time) { - memcpy(m_translation, t, sizeof(m_translation)); - m_motionTime = time; - m_motionEventPending = true; + memcpy(m_translation, t, sizeof(m_translation)); + m_motionTime = time; + m_motionEventPending = true; } void GHOST_NDOFManager::updateRotation(const int r[3], GHOST_TUns64 time) { - memcpy(m_rotation, r, sizeof(m_rotation)); - m_motionTime = time; - m_motionEventPending = true; + memcpy(m_rotation, r, sizeof(m_rotation)); + m_motionTime = time; + m_motionEventPending = true; } -void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow *window) +void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, + bool press, + GHOST_TUns64 time, + GHOST_IWindow *window) { - GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST, - "rogue button trying to escape NDOF manager"); + GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST, + "rogue button trying to escape NDOF manager"); - GHOST_EventNDOFButton *event = new GHOST_EventNDOFButton(time, window); - GHOST_TEventNDOFButtonData *data = (GHOST_TEventNDOFButtonData *) event->getData(); + GHOST_EventNDOFButton *event = new GHOST_EventNDOFButton(time, window); + GHOST_TEventNDOFButtonData *data = (GHOST_TEventNDOFButtonData *)event->getData(); - data->action = press ? GHOST_kPress : GHOST_kRelease; - data->button = button; + data->action = press ? GHOST_kPress : GHOST_kRelease; + data->button = button; #ifdef DEBUG_NDOF_BUTTONS - printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released"); + printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released"); #endif - m_system.pushEvent(event); + m_system.pushEvent(event); } -void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, bool press, GHOST_TUns64 time, GHOST_IWindow *window) +void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, + bool press, + GHOST_TUns64 time, + GHOST_IWindow *window) { - GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; - GHOST_EventKey *event = new GHOST_EventKey(time, type, window, key); + GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; + GHOST_EventKey *event = new GHOST_EventKey(time, type, window, key); #ifdef DEBUG_NDOF_BUTTONS - printf("keyboard %s\n", press ? "down" : "up"); + printf("keyboard %s\n", press ? "down" : "up"); #endif - m_system.pushEvent(event); + m_system.pushEvent(event); } void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time) { - GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow(); + GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow(); #ifdef DEBUG_NDOF_BUTTONS - printf("ndof: button %d -> ", button_number); + printf("ndof: button %d -> ", button_number); #endif - NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] : NDOF_BUTTON_NONE; + NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] : + NDOF_BUTTON_NONE; - switch (button) { - case NDOF_BUTTON_NONE: + switch (button) { + case NDOF_BUTTON_NONE: #ifdef DEBUG_NDOF_BUTTONS - printf("discarded\n"); + printf("discarded\n"); #endif - break; - case NDOF_BUTTON_ESC: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break; - case NDOF_BUTTON_ALT: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break; - case NDOF_BUTTON_SHIFT: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break; - case NDOF_BUTTON_CTRL: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break; - default: sendButtonEvent(button, press, time, window); - } - - int mask = 1 << button_number; - if (press) { - m_buttons |= mask; // set this button's bit - } - else { - m_buttons &= ~mask; // clear this button's bit - } + break; + case NDOF_BUTTON_ESC: + sendKeyEvent(GHOST_kKeyEsc, press, time, window); + break; + case NDOF_BUTTON_ALT: + sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); + break; + case NDOF_BUTTON_SHIFT: + sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); + break; + case NDOF_BUTTON_CTRL: + sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); + break; + default: + sendButtonEvent(button, press, time, window); + } + + int mask = 1 << button_number; + if (press) { + m_buttons |= mask; // set this button's bit + } + else { + m_buttons &= ~mask; // clear this button's bit + } } void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time) { - button_bits &= m_buttonMask; // discard any "garbage" bits + button_bits &= m_buttonMask; // discard any "garbage" bits - int diff = m_buttons ^ button_bits; + int diff = m_buttons ^ button_bits; - for (int button_number = 0; button_number < m_buttonCount; ++button_number) { - int mask = 1 << button_number; + for (int button_number = 0; button_number < m_buttonCount; ++button_number) { + int mask = 1 << button_number; - if (diff & mask) { - bool press = button_bits & mask; - updateButton(button_number, press, time); - } - } + if (diff & mask) { + bool press = button_bits & mask; + updateButton(button_number, press, time); + } + } } void GHOST_NDOFManager::setDeadZone(float dz) { - if (dz < 0.0f) { - // negative values don't make sense, so clamp at zero - dz = 0.0f; - } - else if (dz > 0.5f) { - // warn the rogue user/developer, but allow it - GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz); - } - m_deadZone = dz; - - GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz); + if (dz < 0.0f) { + // negative values don't make sense, so clamp at zero + dz = 0.0f; + } + else if (dz > 0.5f) { + // warn the rogue user/developer, but allow it + GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz); + } + m_deadZone = dz; + + GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz); } static bool atHomePosition(GHOST_TEventNDOFMotionData *ndof) { #define HOME(foo) (ndof->foo == 0.0f) - return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz); + return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz); #undef HOME } static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold) { - if (threshold == 0.0f) { - return atHomePosition(ndof); - } - else { + if (threshold == 0.0f) { + return atHomePosition(ndof); + } + else { #define HOME(foo) (fabsf(ndof->foo) < threshold) - return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz); + return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz); #undef HOME - } + } } bool GHOST_NDOFManager::sendMotionEvent() { - if (!m_motionEventPending) - return false; + if (!m_motionEventPending) + return false; - m_motionEventPending = false; // any pending motion is handled right now + m_motionEventPending = false; // any pending motion is handled right now - GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow(); + GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow(); - if (window == NULL) { - m_motionState = GHOST_kNotStarted; // avoid large 'dt' times when changing windows - return false; // delivery will fail, so don't bother sending - } + if (window == NULL) { + m_motionState = GHOST_kNotStarted; // avoid large 'dt' times when changing windows + return false; // delivery will fail, so don't bother sending + } - GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window); - GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *) event->getData(); + GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window); + GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *)event->getData(); - // scale axis values here to normalize them to around +/- 1 - // they are scaled again for overall sensitivity in the WM based on user prefs + // scale axis values here to normalize them to around +/- 1 + // they are scaled again for overall sensitivity in the WM based on user prefs - const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually + const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually - data->tx = scale * m_translation[0]; - data->ty = scale * m_translation[1]; - data->tz = scale * m_translation[2]; + data->tx = scale * m_translation[0]; + data->ty = scale * m_translation[1]; + data->tz = scale * m_translation[2]; - data->rx = scale * m_rotation[0]; - data->ry = scale * m_rotation[1]; - data->rz = scale * m_rotation[2]; + data->rx = scale * m_rotation[0]; + data->ry = scale * m_rotation[1]; + data->rz = scale * m_rotation[2]; - data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds - m_prevMotionTime = m_motionTime; + data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds + m_prevMotionTime = m_motionTime; - bool weHaveMotion = !nearHomePosition(data, m_deadZone); + bool weHaveMotion = !nearHomePosition(data, m_deadZone); - // determine what kind of motion event to send (Starting, InProgress, Finishing) - // and where that leaves this NDOF manager (NotStarted, InProgress, Finished) - switch (m_motionState) { - case GHOST_kNotStarted: - case GHOST_kFinished: - if (weHaveMotion) { - data->progress = GHOST_kStarting; - m_motionState = GHOST_kInProgress; - // prev motion time will be ancient, so just make up a reasonable time delta - data->dt = 0.0125f; - } - else { - // send no event and keep current state + // determine what kind of motion event to send (Starting, InProgress, Finishing) + // and where that leaves this NDOF manager (NotStarted, InProgress, Finished) + switch (m_motionState) { + case GHOST_kNotStarted: + case GHOST_kFinished: + if (weHaveMotion) { + data->progress = GHOST_kStarting; + m_motionState = GHOST_kInProgress; + // prev motion time will be ancient, so just make up a reasonable time delta + data->dt = 0.0125f; + } + else { + // send no event and keep current state #ifdef DEBUG_NDOF_MOTION - printf("ndof motion ignored -- %s\n", progress_string[data->progress]); + printf("ndof motion ignored -- %s\n", progress_string[data->progress]); #endif - delete event; - return false; - } - break; - case GHOST_kInProgress: - if (weHaveMotion) { - data->progress = GHOST_kInProgress; - // remain 'InProgress' - } - else { - data->progress = GHOST_kFinishing; - m_motionState = GHOST_kFinished; - } - break; - default: - ; // will always be one of the above - } + delete event; + return false; + } + break; + case GHOST_kInProgress: + if (weHaveMotion) { + data->progress = GHOST_kInProgress; + // remain 'InProgress' + } + else { + data->progress = GHOST_kFinishing; + m_motionState = GHOST_kFinished; + } + break; + default:; // will always be one of the above + } #ifdef DEBUG_NDOF_MOTION - printf("ndof motion sent -- %s\n", progress_string[data->progress]); - - // show details about this motion event - printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n", - m_translation[0], m_translation[1], m_translation[2], - m_rotation[0], m_rotation[1], m_rotation[2]); - printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n", - data->tx, data->ty, data->tz, - data->rx, data->ry, data->rz, - data->dt); + printf("ndof motion sent -- %s\n", progress_string[data->progress]); + + // show details about this motion event + printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n", + m_translation[0], + m_translation[1], + m_translation[2], + m_rotation[0], + m_rotation[1], + m_rotation[2]); + printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n", + data->tx, + data->ty, + data->tz, + data->rx, + data->ry, + data->rz, + data->dt); #endif - m_system.pushEvent(event); + m_system.pushEvent(event); - return true; + return true; } diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h index 5f1069f11a0..a190607ca66 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.h +++ b/intern/ghost/intern/GHOST_NDOFManager.h @@ -27,144 +27,145 @@ // #define DEBUG_NDOF_BUTTONS typedef enum { - NDOF_UnknownDevice, - - // current devices - NDOF_SpaceNavigator, - NDOF_SpaceExplorer, - NDOF_SpacePilotPro, - NDOF_SpaceMousePro, - NDOF_SpaceMouseWireless, - NDOF_SpaceMouseProWireless, - NDOF_SpaceMouseEnterprise, - - // older devices - NDOF_SpacePilot, - NDOF_Spaceball5000, - NDOF_SpaceTraveler + NDOF_UnknownDevice, + + // current devices + NDOF_SpaceNavigator, + NDOF_SpaceExplorer, + NDOF_SpacePilotPro, + NDOF_SpaceMousePro, + NDOF_SpaceMouseWireless, + NDOF_SpaceMouseProWireless, + NDOF_SpaceMouseEnterprise, + + // older devices + NDOF_SpacePilot, + NDOF_Spaceball5000, + NDOF_SpaceTraveler } NDOF_DeviceT; // NDOF device button event types typedef enum { - // used internally, never sent - NDOF_BUTTON_NONE, - // these two are available from any 3Dconnexion device - NDOF_BUTTON_MENU, - NDOF_BUTTON_FIT, - // standard views - NDOF_BUTTON_TOP, - NDOF_BUTTON_BOTTOM, - NDOF_BUTTON_LEFT, - NDOF_BUTTON_RIGHT, - NDOF_BUTTON_FRONT, - NDOF_BUTTON_BACK, - // more views - NDOF_BUTTON_ISO1, - NDOF_BUTTON_ISO2, - // 90 degree rotations - // these don't all correspond to physical buttons - NDOF_BUTTON_ROLL_CW, - NDOF_BUTTON_ROLL_CCW, - NDOF_BUTTON_SPIN_CW, - NDOF_BUTTON_SPIN_CCW, - NDOF_BUTTON_TILT_CW, - NDOF_BUTTON_TILT_CCW, - // device control - NDOF_BUTTON_ROTATE, - NDOF_BUTTON_PANZOOM, - NDOF_BUTTON_DOMINANT, - NDOF_BUTTON_PLUS, - NDOF_BUTTON_MINUS, - // keyboard emulation - NDOF_BUTTON_ESC, - NDOF_BUTTON_ALT, - NDOF_BUTTON_SHIFT, - NDOF_BUTTON_CTRL, - // general-purpose buttons - // users can assign functions via keymap editor - NDOF_BUTTON_1, - NDOF_BUTTON_2, - NDOF_BUTTON_3, - NDOF_BUTTON_4, - NDOF_BUTTON_5, - NDOF_BUTTON_6, - NDOF_BUTTON_7, - NDOF_BUTTON_8, - NDOF_BUTTON_9, - NDOF_BUTTON_10, - // more general-purpose buttons - NDOF_BUTTON_A, - NDOF_BUTTON_B, - NDOF_BUTTON_C, - // the end - NDOF_BUTTON_LAST + // used internally, never sent + NDOF_BUTTON_NONE, + // these two are available from any 3Dconnexion device + NDOF_BUTTON_MENU, + NDOF_BUTTON_FIT, + // standard views + NDOF_BUTTON_TOP, + NDOF_BUTTON_BOTTOM, + NDOF_BUTTON_LEFT, + NDOF_BUTTON_RIGHT, + NDOF_BUTTON_FRONT, + NDOF_BUTTON_BACK, + // more views + NDOF_BUTTON_ISO1, + NDOF_BUTTON_ISO2, + // 90 degree rotations + // these don't all correspond to physical buttons + NDOF_BUTTON_ROLL_CW, + NDOF_BUTTON_ROLL_CCW, + NDOF_BUTTON_SPIN_CW, + NDOF_BUTTON_SPIN_CCW, + NDOF_BUTTON_TILT_CW, + NDOF_BUTTON_TILT_CCW, + // device control + NDOF_BUTTON_ROTATE, + NDOF_BUTTON_PANZOOM, + NDOF_BUTTON_DOMINANT, + NDOF_BUTTON_PLUS, + NDOF_BUTTON_MINUS, + // keyboard emulation + NDOF_BUTTON_ESC, + NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, + NDOF_BUTTON_CTRL, + // general-purpose buttons + // users can assign functions via keymap editor + NDOF_BUTTON_1, + NDOF_BUTTON_2, + NDOF_BUTTON_3, + NDOF_BUTTON_4, + NDOF_BUTTON_5, + NDOF_BUTTON_6, + NDOF_BUTTON_7, + NDOF_BUTTON_8, + NDOF_BUTTON_9, + NDOF_BUTTON_10, + // more general-purpose buttons + NDOF_BUTTON_A, + NDOF_BUTTON_B, + NDOF_BUTTON_C, + // the end + NDOF_BUTTON_LAST } NDOF_ButtonT; -class GHOST_NDOFManager -{ -public: - GHOST_NDOFManager(GHOST_System&); - virtual ~GHOST_NDOFManager() {} - - // whether multi-axis functionality is available (via the OS or driver) - // does not imply that a device is plugged in or being used - virtual bool available() = 0; - - // each platform's device detection should call this - // use standard USB/HID identifiers - bool setDevice(unsigned short vendor_id, unsigned short product_id); - - // filter out small/accidental/uncalibrated motions by - // setting up a "dead zone" around home position - // set to 0 to disable - // 0.1 is a safe and reasonable value - void setDeadZone(float); - - // the latest raw axis data from the device - // NOTE: axis data should be in blender view coordinates - // +X is to the right - // +Y is up - // +Z is out of the screen - // for rotations, look from origin to each +axis - // rotations are + when CCW, - when CW - // each platform is responsible for getting axis data into this form - // these values should not be scaled (just shuffled or flipped) - void updateTranslation(const int t[3], GHOST_TUns64 time); - void updateRotation(const int r[3], GHOST_TUns64 time); - - // the latest raw button data from the device - // use HID button encoding (not NDOF_ButtonT) - void updateButton(int button_number, bool press, GHOST_TUns64 time); - void updateButtons(int button_bits, GHOST_TUns64 time); - // NDOFButton events are sent immediately - - // processes and sends most recent raw data as an NDOFMotion event - // returns whether an event was sent - bool sendMotionEvent(); - -protected: - GHOST_System& m_system; - -private: - void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow *); - void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow *); - - NDOF_DeviceT m_deviceType; - int m_buttonCount; - int m_buttonMask; - const NDOF_ButtonT *m_hidMap; - - int m_translation[3]; - int m_rotation[3]; - int m_buttons; // bit field - - GHOST_TUns64 m_motionTime; // in milliseconds - GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent - - GHOST_TProgress m_motionState; - bool m_motionEventPending; - float m_deadZone; // discard motion with each component < this +class GHOST_NDOFManager { + public: + GHOST_NDOFManager(GHOST_System &); + virtual ~GHOST_NDOFManager() + { + } + + // whether multi-axis functionality is available (via the OS or driver) + // does not imply that a device is plugged in or being used + virtual bool available() = 0; + + // each platform's device detection should call this + // use standard USB/HID identifiers + bool setDevice(unsigned short vendor_id, unsigned short product_id); + + // filter out small/accidental/uncalibrated motions by + // setting up a "dead zone" around home position + // set to 0 to disable + // 0.1 is a safe and reasonable value + void setDeadZone(float); + + // the latest raw axis data from the device + // NOTE: axis data should be in blender view coordinates + // +X is to the right + // +Y is up + // +Z is out of the screen + // for rotations, look from origin to each +axis + // rotations are + when CCW, - when CW + // each platform is responsible for getting axis data into this form + // these values should not be scaled (just shuffled or flipped) + void updateTranslation(const int t[3], GHOST_TUns64 time); + void updateRotation(const int r[3], GHOST_TUns64 time); + + // the latest raw button data from the device + // use HID button encoding (not NDOF_ButtonT) + void updateButton(int button_number, bool press, GHOST_TUns64 time); + void updateButtons(int button_bits, GHOST_TUns64 time); + // NDOFButton events are sent immediately + + // processes and sends most recent raw data as an NDOFMotion event + // returns whether an event was sent + bool sendMotionEvent(); + + protected: + GHOST_System &m_system; + + private: + void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow *); + void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow *); + + NDOF_DeviceT m_deviceType; + int m_buttonCount; + int m_buttonMask; + const NDOF_ButtonT *m_hidMap; + + int m_translation[3]; + int m_rotation[3]; + int m_buttons; // bit field + + GHOST_TUns64 m_motionTime; // in milliseconds + GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent + + GHOST_TProgress m_motionState; + bool m_motionEventPending; + float m_deadZone; // discard motion with each component < this }; #endif diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h index e3c8dd8d985..bd1e6903f94 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h +++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h @@ -22,13 +22,12 @@ // Event capture is handled within the NDOF manager on Macintosh, // so there's no need for SystemCocoa to look for them. -class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager -{ -public: - GHOST_NDOFManagerCocoa(GHOST_System&); - ~GHOST_NDOFManagerCocoa(); +class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager { + public: + GHOST_NDOFManagerCocoa(GHOST_System &); + ~GHOST_NDOFManagerCocoa(); - bool available(); + bool available(); }; -#endif // #include guard +#endif // #include guard diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm index 65d8b965d09..4d07a399002 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm @@ -23,18 +23,20 @@ #include <dlfcn.h> #if DEBUG_NDOF_DRIVER - #include <cstdio> +# include <cstdio> #endif // static callback functions need to talk to these objects: -static GHOST_SystemCocoa* ghost_system = NULL; -static GHOST_NDOFManager* ndof_manager = NULL; +static GHOST_SystemCocoa *ghost_system = NULL; +static GHOST_NDOFManager *ndof_manager = NULL; static uint16_t clientID = 0; static bool driver_loaded = false; -static bool has_old_driver = false; // 3Dconnexion drivers before 10 beta 4 are "old", not all buttons will work -static bool has_new_driver = false; // drivers >= 10.2.2 are "new", and can process events on a separate thread +static bool has_old_driver = + false; // 3Dconnexion drivers before 10 beta 4 are "old", not all buttons will work +static bool has_new_driver = + false; // drivers >= 10.2.2 are "new", and can process events on a separate thread // replicate just enough of the 3Dx API for our uses, not everything the driver provides @@ -47,35 +49,41 @@ static bool has_new_driver = false; // drivers >= 10.2.2 are "new", and can proc #define kConnexionMsgDeviceState '3dSR' #define kConnexionCtlGetDeviceID '3did' -#pragma pack(push,2) // just this struct +#pragma pack(push, 2) // just this struct struct ConnexionDeviceState { - uint16_t version; - uint16_t client; - uint16_t command; - int16_t param; - int32_t value; - uint64_t time; - uint8_t report[8]; - uint16_t buttons8; // obsolete! (pre-10.x drivers) - int16_t axis[6]; // tx, ty, tz, rx, ry, rz - uint16_t address; - uint32_t buttons; + uint16_t version; + uint16_t client; + uint16_t command; + int16_t param; + int32_t value; + uint64_t time; + uint8_t report[8]; + uint16_t buttons8; // obsolete! (pre-10.x drivers) + int16_t axis[6]; // tx, ty, tz, rx, ry, rz + uint16_t address; + uint32_t buttons; }; #pragma pack(pop) // callback functions: typedef void (*AddedHandler)(uint32_t); typedef void (*RemovedHandler)(uint32_t); -typedef void (*MessageHandler)(uint32_t, uint32_t msg_type, void* msg_arg); +typedef void (*MessageHandler)(uint32_t, uint32_t msg_type, void *msg_arg); // driver functions: typedef int16_t (*SetConnexionHandlers_ptr)(MessageHandler, AddedHandler, RemovedHandler, bool); typedef int16_t (*InstallConnexionHandlers_ptr)(MessageHandler, AddedHandler, RemovedHandler); typedef void (*CleanupConnexionHandlers_ptr)(); -typedef uint16_t (*RegisterConnexionClient_ptr)(uint32_t signature, const char* name, uint16_t mode, uint32_t mask); +typedef uint16_t (*RegisterConnexionClient_ptr)(uint32_t signature, + const char *name, + uint16_t mode, + uint32_t mask); typedef void (*SetConnexionClientButtonMask_ptr)(uint16_t clientID, uint32_t buttonMask); typedef void (*UnregisterConnexionClient_ptr)(uint16_t clientID); -typedef int16_t (*ConnexionClientControl_ptr)(uint16_t clientID, uint32_t message, int32_t param, int32_t* result); +typedef int16_t (*ConnexionClientControl_ptr)(uint16_t clientID, + uint32_t message, + int32_t param, + int32_t *result); #define DECLARE_FUNC(name) name##_ptr name = NULL @@ -87,190 +95,187 @@ DECLARE_FUNC(SetConnexionClientButtonMask); DECLARE_FUNC(UnregisterConnexionClient); DECLARE_FUNC(ConnexionClientControl); - -static void* load_func(void* module, const char* func_name) +static void *load_func(void *module, const char *func_name) { - void* func = dlsym(module, func_name); + void *func = dlsym(module, func_name); #if DEBUG_NDOF_DRIVER - if (func) { - printf("'%s' loaded :D\n", func_name); - } - else { - printf("<!> %s\n", dlerror()); - } + if (func) { + printf("'%s' loaded :D\n", func_name); + } + else { + printf("<!> %s\n", dlerror()); + } #endif - return func; + return func; } -#define LOAD_FUNC(name) name = (name##_ptr) load_func(module, #name) +#define LOAD_FUNC(name) name = (name##_ptr)load_func(module, #name) -static void* module; // handle to the whole driver +static void *module; // handle to the whole driver static bool load_driver_functions() { - if (driver_loaded) { - return true; - } - - module = dlopen("3DconnexionClient.framework/3DconnexionClient", RTLD_LAZY | RTLD_LOCAL); - - if (module) { - LOAD_FUNC(SetConnexionHandlers); - - if (SetConnexionHandlers != NULL) { - driver_loaded = true; - has_new_driver = true; - } - else { - LOAD_FUNC(InstallConnexionHandlers); - - driver_loaded = (InstallConnexionHandlers != NULL); - } - - if (driver_loaded) { - LOAD_FUNC(CleanupConnexionHandlers); - LOAD_FUNC(RegisterConnexionClient); - LOAD_FUNC(SetConnexionClientButtonMask); - LOAD_FUNC(UnregisterConnexionClient); - LOAD_FUNC(ConnexionClientControl); - - has_old_driver = (SetConnexionClientButtonMask == NULL); - } - } + if (driver_loaded) { + return true; + } + + module = dlopen("3DconnexionClient.framework/3DconnexionClient", RTLD_LAZY | RTLD_LOCAL); + + if (module) { + LOAD_FUNC(SetConnexionHandlers); + + if (SetConnexionHandlers != NULL) { + driver_loaded = true; + has_new_driver = true; + } + else { + LOAD_FUNC(InstallConnexionHandlers); + + driver_loaded = (InstallConnexionHandlers != NULL); + } + + if (driver_loaded) { + LOAD_FUNC(CleanupConnexionHandlers); + LOAD_FUNC(RegisterConnexionClient); + LOAD_FUNC(SetConnexionClientButtonMask); + LOAD_FUNC(UnregisterConnexionClient); + LOAD_FUNC(ConnexionClientControl); + + has_old_driver = (SetConnexionClientButtonMask == NULL); + } + } #if DEBUG_NDOF_DRIVER - else { - printf("<!> %s\n", dlerror()); - } + else { + printf("<!> %s\n", dlerror()); + } - printf("loaded: %s\n", driver_loaded ? "YES" : "NO"); - printf("old: %s\n", has_old_driver ? "YES" : "NO"); - printf("new: %s\n", has_new_driver ? "YES" : "NO"); + printf("loaded: %s\n", driver_loaded ? "YES" : "NO"); + printf("old: %s\n", has_old_driver ? "YES" : "NO"); + printf("new: %s\n", has_new_driver ? "YES" : "NO"); #endif - return driver_loaded; - } + return driver_loaded; +} static void unload_driver() { - dlclose(module); + dlclose(module); } static void DeviceAdded(uint32_t unused) { #if DEBUG_NDOF_DRIVER - printf("ndof: device added\n"); + printf("ndof: device added\n"); #endif - // determine exactly which device is plugged in - int32_t result; - ConnexionClientControl(clientID, kConnexionCtlGetDeviceID, 0, &result); - int16_t vendorID = result >> 16; - int16_t productID = result & 0xffff; + // determine exactly which device is plugged in + int32_t result; + ConnexionClientControl(clientID, kConnexionCtlGetDeviceID, 0, &result); + int16_t vendorID = result >> 16; + int16_t productID = result & 0xffff; - ndof_manager->setDevice(vendorID, productID); + ndof_manager->setDevice(vendorID, productID); } static void DeviceRemoved(uint32_t unused) { #if DEBUG_NDOF_DRIVER - printf("ndof: device removed\n"); + printf("ndof: device removed\n"); #endif } -static void DeviceEvent(uint32_t unused, uint32_t msg_type, void* msg_arg) +static void DeviceEvent(uint32_t unused, uint32_t msg_type, void *msg_arg) { - if (msg_type == kConnexionMsgDeviceState) { - ConnexionDeviceState* s = (ConnexionDeviceState*)msg_arg; - - // device state is broadcast to all clients; only react if sent to us - if (s->client == clientID) { - // TODO: is s->time compatible with GHOST timestamps? if so use that instead. - GHOST_TUns64 now = ghost_system->getMilliSeconds(); - - switch (s->command) { - case kConnexionCmdHandleAxis: - { - // convert to blender view coordinates - const int t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]}; - const int r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])}; - - ndof_manager->updateTranslation(t, now); - ndof_manager->updateRotation(r, now); - - ghost_system->notifyExternalEventProcessed(); - break; - } - case kConnexionCmdHandleButtons: - { - int button_bits = has_old_driver ? s->buttons8 : s->buttons; + if (msg_type == kConnexionMsgDeviceState) { + ConnexionDeviceState *s = (ConnexionDeviceState *)msg_arg; + + // device state is broadcast to all clients; only react if sent to us + if (s->client == clientID) { + // TODO: is s->time compatible with GHOST timestamps? if so use that instead. + GHOST_TUns64 now = ghost_system->getMilliSeconds(); + + switch (s->command) { + case kConnexionCmdHandleAxis: { + // convert to blender view coordinates + const int t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]}; + const int r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])}; + + ndof_manager->updateTranslation(t, now); + ndof_manager->updateRotation(r, now); + + ghost_system->notifyExternalEventProcessed(); + break; + } + case kConnexionCmdHandleButtons: { + int button_bits = has_old_driver ? s->buttons8 : s->buttons; #ifdef DEBUG_NDOF_BUTTONS - printf("button bits: 0x%08x\n", button_bits); + printf("button bits: 0x%08x\n", button_bits); #endif - ndof_manager->updateButtons(button_bits, now); - ghost_system->notifyExternalEventProcessed(); - break; - } + ndof_manager->updateButtons(button_bits, now); + ghost_system->notifyExternalEventProcessed(); + break; + } #if DEBUG_NDOF_DRIVER - case kConnexionCmdAppSpecific: - printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value); - break; + case kConnexionCmdAppSpecific: + printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value); + break; - default: - printf("ndof: mystery device command %d\n", s->command); + default: + printf("ndof: mystery device command %d\n", s->command); #endif - } - } - } + } + } + } } -GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys) - : GHOST_NDOFManager(sys) +GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System &sys) : GHOST_NDOFManager(sys) { - if (load_driver_functions()) { - // give static functions something to talk to: - ghost_system = dynamic_cast<GHOST_SystemCocoa*>(&sys); - ndof_manager = this; - - uint16_t error; - if (has_new_driver) { - const bool separate_thread = false; // TODO: rework Mac event handler to allow this - error = SetConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved, separate_thread); - } - else { - error = InstallConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved); - } - - if (error) { + if (load_driver_functions()) { + // give static functions something to talk to: + ghost_system = dynamic_cast<GHOST_SystemCocoa *>(&sys); + ndof_manager = this; + + uint16_t error; + if (has_new_driver) { + const bool separate_thread = false; // TODO: rework Mac event handler to allow this + error = SetConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved, separate_thread); + } + else { + error = InstallConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved); + } + + if (error) { #if DEBUG_NDOF_DRIVER - printf("ndof: error %d while setting up handlers\n", error); + printf("ndof: error %d while setting up handlers\n", error); #endif - return; - } + return; + } - // Pascal string *and* a four-letter constant. How old-skool. - clientID = RegisterConnexionClient('blnd', "\007blender", kConnexionClientModeTakeOver, kConnexionMaskAll); + // Pascal string *and* a four-letter constant. How old-skool. + clientID = RegisterConnexionClient( + 'blnd', "\007blender", kConnexionClientModeTakeOver, kConnexionMaskAll); - if (!has_old_driver) { - SetConnexionClientButtonMask(clientID, kConnexionMaskAllButtons); - } - } + if (!has_old_driver) { + SetConnexionClientButtonMask(clientID, kConnexionMaskAllButtons); + } + } } GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa() { - if (driver_loaded) { - UnregisterConnexionClient(clientID); - CleanupConnexionHandlers(); - unload_driver(); - - ghost_system = NULL; - ndof_manager = NULL; - } + if (driver_loaded) { + UnregisterConnexionClient(clientID); + CleanupConnexionHandlers(); + unload_driver(); + + ghost_system = NULL; + ndof_manager = NULL; + } } bool GHOST_NDOFManagerCocoa::available() { - return driver_loaded; + return driver_loaded; } diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp index f8609e5cccb..8ed0af1fc29 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp +++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp @@ -23,49 +23,48 @@ #define SPNAV_SOCK_PATH "/var/run/spnav.sock" -GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System& sys) - : GHOST_NDOFManager(sys), - m_available(false) +GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys) + : GHOST_NDOFManager(sys), m_available(false) { - if (access(SPNAV_SOCK_PATH, F_OK) != 0) { + if (access(SPNAV_SOCK_PATH, F_OK) != 0) { #ifdef DEBUG - /* annoying for official builds, just adds noise and most people don't own these */ - puts("ndof: spacenavd not found"); - /* This isn't a hard error, just means the user doesn't have a 3D mouse. */ + /* annoying for official builds, just adds noise and most people don't own these */ + puts("ndof: spacenavd not found"); + /* This isn't a hard error, just means the user doesn't have a 3D mouse. */ #endif - } - else if (spnav_open() != -1) { - m_available = true; + } + else if (spnav_open() != -1) { + m_available = true; - /* determine exactly which device (if any) is plugged in */ + /* determine exactly which device (if any) is plugged in */ #define MAX_LINE_LENGTH 100 - /* look for USB devices with Logitech or 3Dconnexion's vendor ID */ - FILE *command_output = popen("lsusb | grep '046d:\\|256f:'", "r"); - if (command_output) { - char line[MAX_LINE_LENGTH] = {0}; - while (fgets(line, MAX_LINE_LENGTH, command_output)) { - unsigned short vendor_id = 0, product_id = 0; - if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2) - if (setDevice(vendor_id, product_id)) { - break; /* stop looking once the first 3D mouse is found */ - } - } - pclose(command_output); - } - } + /* look for USB devices with Logitech or 3Dconnexion's vendor ID */ + FILE *command_output = popen("lsusb | grep '046d:\\|256f:'", "r"); + if (command_output) { + char line[MAX_LINE_LENGTH] = {0}; + while (fgets(line, MAX_LINE_LENGTH, command_output)) { + unsigned short vendor_id = 0, product_id = 0; + if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2) + if (setDevice(vendor_id, product_id)) { + break; /* stop looking once the first 3D mouse is found */ + } + } + pclose(command_output); + } + } } GHOST_NDOFManagerUnix::~GHOST_NDOFManagerUnix() { - if (m_available) - spnav_close(); + if (m_available) + spnav_close(); } bool GHOST_NDOFManagerUnix::available() { - return m_available; + return m_available; } /* @@ -85,53 +84,51 @@ static bool motion_test_prev = false; bool GHOST_NDOFManagerUnix::processEvents() { - bool anyProcessed = false; + bool anyProcessed = false; - if (m_available) { - spnav_event e; + if (m_available) { + spnav_event e; #ifdef USE_FINISH_GLITCH_WORKAROUND - bool motion_test = false; + bool motion_test = false; #endif - while (spnav_poll_event(&e)) { - switch (e.type) { - case SPNAV_EVENT_MOTION: - { - /* convert to blender view coords */ - GHOST_TUns64 now = m_system.getMilliSeconds(); - const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z}; - const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz}; - - updateTranslation(t, now); - updateRotation(r, now); + while (spnav_poll_event(&e)) { + switch (e.type) { + case SPNAV_EVENT_MOTION: { + /* convert to blender view coords */ + GHOST_TUns64 now = m_system.getMilliSeconds(); + const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z}; + const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz}; + + updateTranslation(t, now); + updateRotation(r, now); #ifdef USE_FINISH_GLITCH_WORKAROUND - motion_test = true; + motion_test = true; #endif - break; - } - case SPNAV_EVENT_BUTTON: - GHOST_TUns64 now = m_system.getMilliSeconds(); - updateButton(e.button.bnum, e.button.press, now); - break; - } - anyProcessed = true; - } + break; + } + case SPNAV_EVENT_BUTTON: + GHOST_TUns64 now = m_system.getMilliSeconds(); + updateButton(e.button.bnum, e.button.press, now); + break; + } + anyProcessed = true; + } #ifdef USE_FINISH_GLITCH_WORKAROUND - if (motion_test_prev == true && motion_test == false) { - GHOST_TUns64 now = m_system.getMilliSeconds(); - const int v[3] = {0, 0, 0}; + if (motion_test_prev == true && motion_test == false) { + GHOST_TUns64 now = m_system.getMilliSeconds(); + const int v[3] = {0, 0, 0}; - updateTranslation(v, now); - updateRotation(v, now); + updateTranslation(v, now); + updateRotation(v, now); - anyProcessed = true; - } - motion_test_prev = motion_test; + anyProcessed = true; + } + motion_test_prev = motion_test; #endif + } - } - - return anyProcessed; + return anyProcessed; } diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.h b/intern/ghost/intern/GHOST_NDOFManagerUnix.h index e6b3f95124f..75bd022631a 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerUnix.h +++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.h @@ -22,16 +22,15 @@ /* Event capture is handled within the NDOF manager on Linux, * so there's no need for SystemX11 to look for them. */ -class GHOST_NDOFManagerUnix : public GHOST_NDOFManager -{ -public: - GHOST_NDOFManagerUnix(GHOST_System&); - ~GHOST_NDOFManagerUnix(); - bool available(); - bool processEvents(); +class GHOST_NDOFManagerUnix : public GHOST_NDOFManager { + public: + GHOST_NDOFManagerUnix(GHOST_System &); + ~GHOST_NDOFManagerUnix(); + bool available(); + bool processEvents(); -private: - bool m_available; + private: + bool m_available; }; -#endif /* __GHOST_NDOFMANAGERUNIX_H__ */ +#endif /* __GHOST_NDOFMANAGERUNIX_H__ */ diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp index bcbae1c52bd..5bd1bdfb6a1 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp +++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp @@ -16,17 +16,15 @@ #include "GHOST_NDOFManagerWin32.h" - -GHOST_NDOFManagerWin32::GHOST_NDOFManagerWin32(GHOST_System& sys) - : GHOST_NDOFManager(sys) +GHOST_NDOFManagerWin32::GHOST_NDOFManagerWin32(GHOST_System &sys) : GHOST_NDOFManager(sys) { - /* pass */ + /* pass */ } // whether multi-axis functionality is available (via the OS or driver) // does not imply that a device is plugged in or being used bool GHOST_NDOFManagerWin32::available() { - // always available since RawInput is built into Windows - return true; + // always available since RawInput is built into Windows + return true; } diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h index 3a1304ffd71..9ed5e6ab978 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerWin32.h +++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h @@ -14,18 +14,15 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #ifndef __GHOST_NDOFMANAGERWIN32_H__ #define __GHOST_NDOFMANAGERWIN32_H__ #include "GHOST_NDOFManager.h" - -class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager -{ -public: - GHOST_NDOFManagerWin32(GHOST_System&); - bool available(); +class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager { + public: + GHOST_NDOFManagerWin32(GHOST_System &); + bool available(); }; -#endif // #include guard +#endif // #include guard diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp index 645613d17a6..9e4ed1e0eea 100644 --- a/intern/ghost/intern/GHOST_Path-api.cpp +++ b/intern/ghost/intern/GHOST_Path-api.cpp @@ -30,36 +30,36 @@ GHOST_TSuccess GHOST_CreateSystemPaths(void) { - return GHOST_ISystemPaths::create(); + return GHOST_ISystemPaths::create(); } GHOST_TSuccess GHOST_DisposeSystemPaths(void) { - return GHOST_ISystemPaths::dispose(); + return GHOST_ISystemPaths::dispose(); } const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr) { - GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); - return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL; + GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); + return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL; } const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr) { - GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); - return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */ + GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); + return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */ } const GHOST_TUns8 *GHOST_getBinaryDir() { - GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); - return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */ + GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); + return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */ } void GHOST_addToSystemRecentFiles(const char *filename) { - GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); - if (systemPaths) { - systemPaths->addToSystemRecentFiles(filename); - } + GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); + if (systemPaths) { + systemPaths->addToSystemRecentFiles(filename); + } } diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp index 973c3d40ae8..c5b9bc44468 100644 --- a/intern/ghost/intern/GHOST_Rect.cpp +++ b/intern/ghost/intern/GHOST_Rect.cpp @@ -21,112 +21,107 @@ * \ingroup GHOST */ - #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; - } - } + 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 +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; + 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; + 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; + 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; + 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 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; + bool clipped = false; + if (r.m_l < m_l) { + r.m_l = m_l; + clipped = true; + } + if (r.m_t < m_t) { + r.m_t = m_t; + clipped = true; + } + if (r.m_r > m_r) { + r.m_r = m_r; + clipped = true; + } + if (r.m_b > m_b) { + r.m_b = m_b; + clipped = true; + } + return clipped; } diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 27fb08ad014..1530dddd5f1 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -50,352 +50,354 @@ GHOST_System::GHOST_System() { } - GHOST_System::~GHOST_System() { - exit(); + 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_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 = NULL; - } - } - return timer; + 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 = NULL; + } + } + 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 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; - - /* - * Remove all pending events for the window. - */ - if (m_windowManager->getWindowFound(window)) { - m_eventManager->removeWindowEvents(window); - } - 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; + GHOST_TSuccess success; + + /* + * Remove all pending events for the window. + */ + if (m_windowManager->getWindowFound(window)) { + m_eventManager->removeWindowEvents(window); + } + 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); + return m_windowManager->getWindowFound(window); } - -GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window, - const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples) +GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting &setting, + GHOST_IWindow **window, + const bool stereoVisual, + const bool alphaBackground, + const GHOST_TUns16 numOfAASamples) { - 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, setting, stereoVisual, alphaBackground, numOfAASamples); - 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 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, setting, stereoVisual, alphaBackground, numOfAASamples); + 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::updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow ** /*window*/) +GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting &setting, + GHOST_IWindow ** /*window*/) { - GHOST_TSuccess success = GHOST_kFailure; - GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager"); - if (m_displayManager) { - if (m_windowManager->getFullScreen()) { - success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting); - } - } - - return success; + GHOST_TSuccess success = GHOST_kFailure; + GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager"); + if (m_displayManager) { + if (m_windowManager->getFullScreen()) { + success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, + setting); + } + } + + 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; + 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 fullScreen; + if (m_windowManager) { + fullScreen = m_windowManager->getFullScreen(); + } + else { + fullScreen = false; + } + return fullScreen; } - void GHOST_System::dispatchEvents() { #ifdef WITH_INPUT_NDOF - // NDOF Motion event is sent only once per dispatch, so do it now: - if (m_ndofManager) { - m_ndofManager->sendMotionEvent(); - } + // NDOF Motion event is sent only once per dispatch, so do it now: + if (m_ndofManager) { + m_ndofManager->sendMotionEvent(); + } #endif - if (m_eventManager) { - m_eventManager->dispatchEvents(); - } + if (m_eventManager) { + m_eventManager->dispatchEvents(); + } - m_timerManager->fireTimers(getMilliSeconds()); + m_timerManager->fireTimers(getMilliSeconds()); } - 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 success; + if (m_eventManager) { + success = m_eventManager->addConsumer(consumer); + } + else { + success = GHOST_kFailure; + } + return success; } GHOST_TSuccess GHOST_System::removeEventConsumer(GHOST_IEventConsumer *consumer) { - GHOST_TSuccess success; - if (m_eventManager) { - success = m_eventManager->removeConsumer(consumer); - } - else { - success = GHOST_kFailure; - } - return success; + GHOST_TSuccess success; + if (m_eventManager) { + success = m_eventManager->removeConsumer(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 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_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_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_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_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; } void GHOST_System::setTabletAPI(GHOST_TTabletAPI api) { - m_tabletAPI = api; + m_tabletAPI = api; } GHOST_TTabletAPI GHOST_System::getTabletAPI(void) { - return m_tabletAPI; + return m_tabletAPI; } #ifdef WITH_INPUT_NDOF void GHOST_System::setNDOFDeadZone(float deadzone) { - if (this->m_ndofManager) { - this->m_ndofManager->setDeadZone(deadzone); - } + if (this->m_ndofManager) { + this->m_ndofManager->setDeadZone(deadzone); + } } #endif GHOST_TSuccess GHOST_System::init() { - m_timerManager = new GHOST_TimerManager(); - m_windowManager = new GHOST_WindowManager(); - m_eventManager = new GHOST_EventManager(); + m_timerManager = new GHOST_TimerManager(); + m_windowManager = new GHOST_WindowManager(); + m_eventManager = new GHOST_EventManager(); #ifdef GHOST_DEBUG - if (m_eventManager) { - m_eventPrinter = new GHOST_EventPrinter(); - m_eventManager->addConsumer(m_eventPrinter); - } -#endif // GHOST_DEBUG - - if (m_timerManager && m_windowManager && m_eventManager) { - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (m_eventManager) { + m_eventPrinter = new GHOST_EventPrinter(); + 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 (getFullScreen()) { + endFullScreen(); + } - delete m_displayManager; - m_displayManager = NULL; + delete m_displayManager; + m_displayManager = NULL; - delete m_windowManager; - m_windowManager = NULL; + delete m_windowManager; + m_windowManager = NULL; - delete m_timerManager; - m_timerManager = NULL; + delete m_timerManager; + m_timerManager = NULL; - delete m_eventManager; - m_eventManager = NULL; + delete m_eventManager; + m_eventManager = NULL; #ifdef WITH_INPUT_NDOF - delete m_ndofManager; - m_ndofManager = NULL; + delete m_ndofManager; + m_ndofManager = NULL; #endif - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples) +GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, + const GHOST_DisplaySetting &settings, + const bool stereoVisual, + const bool alphaBackground, + const GHOST_TUns16 numOfAASamples) { - GHOST_GLSettings glSettings = {0}; - - if (stereoVisual) - glSettings.flags |= GHOST_glStereoVisual; - if (alphaBackground) - glSettings.flags |= GHOST_glAlphaBackground; - glSettings.numOfAASamples = numOfAASamples; - - /* note: don't use getCurrentDisplaySetting() because on X11 we may - * be zoomed in and the desktop may be bigger then the viewport. */ - GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager"); - //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n"); - *window = (GHOST_Window *)createWindow( - STR_String(""), - 0, 0, settings.xPixels, settings.yPixels, - GHOST_kWindowStateNormal, - GHOST_kDrawingContextTypeOpenGL, - glSettings, - true /* exclusive */); - return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess; + GHOST_GLSettings glSettings = {0}; + + if (stereoVisual) + glSettings.flags |= GHOST_glStereoVisual; + if (alphaBackground) + glSettings.flags |= GHOST_glAlphaBackground; + glSettings.numOfAASamples = numOfAASamples; + + /* note: don't use getCurrentDisplaySetting() because on X11 we may + * be zoomed in and the desktop may be bigger then the viewport. */ + GHOST_ASSERT(m_displayManager, + "GHOST_System::createFullScreenWindow(): invalid display manager"); + //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n"); + *window = (GHOST_Window *)createWindow(STR_String(""), + 0, + 0, + settings.xPixels, + settings.yPixels, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, + glSettings, + true /* exclusive */); + return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess; } - int GHOST_System::confirmQuit(GHOST_IWindow * /*window*/) const { - return 1; + return 1; } bool GHOST_System::supportsNativeDialogs(void) { - return 1; + return 1; } bool GHOST_System::useNativePixel(void) { - m_nativePixel = true; - return 1; + m_nativePixel = true; + return 1; } void GHOST_System::useWindowFocus(const bool use_focus) { - m_windowFocus = use_focus; + m_windowFocus = use_focus; } diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index b9b7fc5658a..2c7025b6036 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -32,8 +32,8 @@ #include "GHOST_ModifierKeys.h" #include "GHOST_EventManager.h" #ifdef GHOST_DEBUG -#include "GHOST_EventPrinter.h" -#endif // GHOST_DEBUG +# include "GHOST_EventPrinter.h" +#endif // GHOST_DEBUG class GHOST_DisplayManager; class GHOST_Event; @@ -51,356 +51,357 @@ class GHOST_NDOFManager; * are implemented. * \see GHOST_ISystem. */ -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). - */ - GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, - GHOST_TUns64 interval, - GHOST_TimerProcPtr timerProc, - GHOST_TUserDataPtr userData = NULL); - - /** - * Removes a timer. - * \param timerTask Timer task to be removed. - * \return Indication of success. - */ - 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. - */ - 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. - */ - 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. - */ - GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window, - const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples = 0); - - /** - * Updates the resolution while in fullscreen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. - * - * \return Indication of success. - */ - GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window); - - /** - * Ends full screen mode. - * \return Indication of success. - */ - GHOST_TSuccess endFullScreen(void); - - /** - * Returns current full screen mode status. - * \return The current status. - */ - bool getFullScreen(void); - - - /** - * Native pixel size support (MacBook 'retina'). - * \return The pixel size in float. - */ - bool useNativePixel(void); - bool m_nativePixel; - - /** - * Focus window after opening, or put them in the background. - */ - void useWindowFocus(const bool use_focus); - bool m_windowFocus; - - /*************************************************************************************** - * 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. - */ - void dispatchEvents(); - - /** - * Adds the given event consumer to our list. - * \param consumer The event consumer to add. - * \return Indication of success. - */ - GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer); - - /** - * Remove the given event consumer to our list. - * \param consumer The event consumer to remove. - * \return Indication of success. - */ - GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer); - - /*************************************************************************************** - * Cursor management functionality - ***************************************************************************************/ - - /** - * Inherited from GHOST_ISystem but left pure virtual - * <pre> - * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0; - * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) - * </pre> - */ - - /*************************************************************************************** - * 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. - */ - 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. - */ - GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const; - - /** - * Set which tablet API to use. Only affects Windows, other platforms have a single API. - * \param api Enum indicating which API to use. - */ - void setTabletAPI(GHOST_TTabletAPI api); - GHOST_TTabletAPI getTabletAPI(void); +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). + */ + GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData = NULL); + + /** + * Removes a timer. + * \param timerTask Timer task to be removed. + * \return Indication of success. + */ + 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. + */ + 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. + */ + 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. + */ + GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, + GHOST_IWindow **window, + const bool stereoVisual, + const bool alphaBackground, + const GHOST_TUns16 numOfAASamples = 0); + + /** + * Updates the resolution while in fullscreen mode. + * \param setting The new setting of the display. + * \param window Window displayed in full screen. + * + * \return Indication of success. + */ + GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window); + + /** + * Ends full screen mode. + * \return Indication of success. + */ + GHOST_TSuccess endFullScreen(void); + + /** + * Returns current full screen mode status. + * \return The current status. + */ + bool getFullScreen(void); + + /** + * Native pixel size support (MacBook 'retina'). + * \return The pixel size in float. + */ + bool useNativePixel(void); + bool m_nativePixel; + + /** + * Focus window after opening, or put them in the background. + */ + void useWindowFocus(const bool use_focus); + bool m_windowFocus; + + /*************************************************************************************** + * 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. + */ + void dispatchEvents(); + + /** + * Adds the given event consumer to our list. + * \param consumer The event consumer to add. + * \return Indication of success. + */ + GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer); + + /** + * Remove the given event consumer to our list. + * \param consumer The event consumer to remove. + * \return Indication of success. + */ + GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer); + + /*************************************************************************************** + * Cursor management functionality + ***************************************************************************************/ + + /** + * Inherited from GHOST_ISystem but left pure virtual + * <pre> + * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0; + * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) + * </pre> + */ + + /*************************************************************************************** + * 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. + */ + 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. + */ + GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const; + + /** + * Set which tablet API to use. Only affects Windows, other platforms have a single API. + * \param api Enum indicating which API to use. + */ + void setTabletAPI(GHOST_TTabletAPI api); + GHOST_TTabletAPI getTabletAPI(void); #ifdef WITH_INPUT_NDOF - /*************************************************************************************** - * Access to 3D mouse. - ***************************************************************************************/ - - /** - * Sets 3D mouse deadzone - * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range - */ - void setNDOFDeadZone(float deadzone); + /*************************************************************************************** + * Access to 3D mouse. + ***************************************************************************************/ + + /** + * Sets 3D mouse deadzone + * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range + */ + void setNDOFDeadZone(float deadzone); #endif - /*************************************************************************************** - * 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. - */ - GHOST_TSuccess pushEvent(GHOST_IEvent *event); - - /** - * \return The timer manager. - */ - inline GHOST_TimerManager *getTimerManager() const; - - /** - * \return A pointer to our event manager. - */ - inline GHOST_EventManager *getEventManager() const; - - /** - * \return A pointer to our window manager. - */ - inline GHOST_WindowManager *getWindowManager() 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. + */ + GHOST_TSuccess pushEvent(GHOST_IEvent *event); + + /** + * \return The timer manager. + */ + inline GHOST_TimerManager *getTimerManager() const; + + /** + * \return A pointer to our event manager. + */ + inline GHOST_EventManager *getEventManager() const; + + /** + * \return A pointer to our window manager. + */ + inline GHOST_WindowManager *getWindowManager() const; #ifdef WITH_INPUT_NDOF - /** - * \return A pointer to our n-degree of freedom manager. - */ - inline GHOST_NDOFManager *getNDOFManager() const; + /** + * \return A pointer to our n-degree of freedom manager. + */ + inline GHOST_NDOFManager *getNDOFManager() const; #endif - /** - * 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; - - /** - * Returns the selection buffer - * \param selection Only used on X11 - * \return Returns the clipboard data - * - */ - virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; - - /** - * Put data to the Clipboard - * \param buffer The buffer to copy to the clipboard - * \param selection The clipboard to copy too only used on X11 - */ - virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; - - /** - * Confirms quitting he program when there is just one window left open - * in the application - */ - virtual int confirmQuit(GHOST_IWindow *window) const; - - /** - * Informs if the system provides native dialogs (eg. confirm quit) - */ - virtual bool supportsNativeDialogs(void); - - -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. - */ - GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0); - - /** The display manager (platform dependent). */ - 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; + /** + * 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; + + /** + * Returns the selection buffer + * \param selection Only used on X11 + * \return Returns the clipboard data + * + */ + virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; + + /** + * Put data to the Clipboard + * \param buffer The buffer to copy to the clipboard + * \param selection The clipboard to copy too only used on X11 + */ + virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; + + /** + * Confirms quitting he program when there is just one window left open + * in the application + */ + virtual int confirmQuit(GHOST_IWindow *window) const; + + /** + * Informs if the system provides native dialogs (eg. confirm quit) + */ + virtual bool supportsNativeDialogs(void); + + 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. + */ + GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, + const GHOST_DisplaySetting &settings, + const bool stereoVisual, + const bool alphaBackground = 0, + const GHOST_TUns16 numOfAASamples = 0); + + /** The display manager (platform dependent). */ + 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; #ifdef WITH_INPUT_NDOF - /** The N-degree of freedom device manager */ - GHOST_NDOFManager *m_ndofManager; + /** The N-degree of freedom device manager */ + GHOST_NDOFManager *m_ndofManager; #endif - /** Prints all the events. */ + /** Prints all the events. */ #ifdef GHOST_DEBUG - GHOST_EventPrinter *m_eventPrinter; -#endif // GHOST_DEBUG + GHOST_EventPrinter *m_eventPrinter; +#endif // GHOST_DEBUG - /** Settings of the display before the display went fullscreen. */ - GHOST_DisplaySetting m_preFullScreenSetting; + /** Settings of the display before the display went fullscreen. */ + GHOST_DisplaySetting m_preFullScreenSetting; - /** Which tablet API to use. */ - GHOST_TTabletAPI m_tabletAPI; + /** Which tablet API to use. */ + GHOST_TTabletAPI m_tabletAPI; }; inline GHOST_TimerManager *GHOST_System::getTimerManager() const { - return m_timerManager; + return m_timerManager; } inline GHOST_EventManager *GHOST_System::getEventManager() const { - return m_eventManager; + return m_eventManager; } inline GHOST_WindowManager *GHOST_System::getWindowManager() const { - return m_windowManager; + return m_windowManager; } #ifdef WITH_INPUT_NDOF inline GHOST_NDOFManager *GHOST_System::getNDOFManager() const { - return m_ndofManager; + return m_ndofManager; } #endif -#endif // __GHOST_SYSTEM_H__ +#endif // __GHOST_SYSTEM_H__ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 289b084cc71..9206ef90ee7 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -26,12 +26,11 @@ #define __GHOST_SYSTEMCOCOA_H__ #ifndef __APPLE__ -#error Apple OSX only! -#endif // __APPLE__ +# error Apple OSX only! +#endif // __APPLE__ //#define __CARBONSOUND__ - #include "GHOST_System.h" class GHOST_EventCursor; @@ -39,278 +38,275 @@ class GHOST_EventKey; class GHOST_EventWindow; class GHOST_WindowCocoa; - class GHOST_SystemCocoa : public GHOST_System { -public: - /** - * Constructor. - */ - GHOST_SystemCocoa(); - - /** - * Destructor. - */ - ~GHOST_SystemCocoa(); - - /*************************************************************************************** - * 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. - */ - GHOST_TUns64 getMilliSeconds() const; - - /*************************************************************************************** - * Display/window management functionality - ***************************************************************************************/ - - /** - * 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; - - /** Returns the combine dimensions of all monitors. - * \return The dimension of the workspace. - */ - void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. - * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent (embedder) window - * \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, - GHOST_GLSettings glSettings, - const bool exclusive = false, - const GHOST_TEmbedderWindowID parentWindow = 0 - ); - - /** - * Create a new offscreen context. - * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). - */ - GHOST_IContext * - createOffscreenContext( - ); - - /** - * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. - */ - GHOST_TSuccess - disposeContext( - GHOST_IContext *context - ); - - /*************************************************************************************** - * 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. - */ - bool processEvents(bool waitForEvent); - - /** - * Handle User request to quit, from Menu bar Quit, and Cmd+Q - * Display alert panel if changes performed since last save - */ - GHOST_TUns8 handleQuitRequest(); - - /** - * Handle Cocoa openFile event - * Display confirmation request panel if changes performed since last save - */ - bool handleOpenDocumentRequest(void *filepathStr); - - /** - * Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass - * \param eventType The type of drag'n'drop event - * \param draggedObjectType The type object concerned (currently array of file names, string, TIFF image) - * \param mouseX x mouse coordinate (in cocoa base window coordinates) - * \param mouseY y mouse coordinate - * \param window The window on which the event occurred - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, - GHOST_WindowCocoa *window, int mouseX, int mouseY, void *data); - - /*************************************************************************************** - * 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. - */ - 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. - */ - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); - - /*************************************************************************************** - * 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. - */ - 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; - - /** - * Returns Clipboard data - * \param selection Indicate which buffer to return - * \return Returns the selected buffer - */ - GHOST_TUns8 *getClipboard(bool selection) const; - - /** - * Puts buffer to system clipboard - * \param buffer The buffer to be copied - * \param selection Indicates which buffer to copy too, only used on X11 - */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; - - /** - * Handles a window event. Called by GHOST_WindowCocoa window delegate - * \param eventType The type of window event - * \param window The window on which the event occurred - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window); - - /** - * Handles the Cocoa event telling the application has become active (again) - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleApplicationBecomeActiveEvent(); - - /** - * External objects should call this when they send an event outside processEvents. - */ - void notifyExternalEventProcessed(); - - /** - * \see GHOST_ISystem - */ - int toggleConsole(int action) { - return 0; - } - - /** - * Handles a tablet event. - * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * \param eventType The type of the event. - * It needs to be passed separately as it can be either directly in the event type, - * or as a subtype if combined with a mouse button event. - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType); - bool handleTabletEvent(void *eventPtr); - - /** - * Handles a mouse event. - * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleMouseEvent(void *eventPtr); - - /** - * Handles a key event. - * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * \return Indication whether the event was handled. - */ - GHOST_TSuccess handleKeyEvent(void *eventPtr); - - /** - * Informs if the system provides native dialogs (eg. confirm quit) - */ - virtual bool supportsNativeDialogs(void); - -protected: - /** - * Initializes the system. - * For now, it just registers the window class (WNDCLASS). - * \return A success value. - */ - GHOST_TSuccess init(); - - /** - * Performs the actual cursor position update (location in screen coordinates). - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. - */ - GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); - - /** Start time at initialization. */ - GHOST_TUns64 m_start_time; - - /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */ - bool m_outsideLoopEventProcessed; - - /** Raised window is not yet known by the window manager, so delay application become active event handling */ - bool m_needDelayedApplicationBecomeActiveEventProcessing; - - /** State of the modifiers. */ - GHOST_TUns32 m_modifierMask; - - /** Ignores window size messages (when window is dragged). */ - bool m_ignoreWindowSizedMessages; - - /** Temporarily ignore momentum scroll events */ - bool m_ignoreMomentumScroll; - /** Is the scroll wheel event generated by a multitouch trackpad or mouse? */ - bool m_multiTouchScroll; + public: + /** + * Constructor. + */ + GHOST_SystemCocoa(); + + /** + * Destructor. + */ + ~GHOST_SystemCocoa(); + + /*************************************************************************************** + * 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. + */ + GHOST_TUns64 getMilliSeconds() const; + + /*************************************************************************************** + * Display/window management functionality + ***************************************************************************************/ + + /** + * 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; + + /** Returns the combine dimensions of all monitors. + * \return The dimension of the workspace. + */ + void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. + * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). + * \param parentWindow Parent (embedder) window + * \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, + GHOST_GLSettings glSettings, + const bool exclusive = false, + const GHOST_TEmbedderWindowID parentWindow = 0); + + /** + * Create a new offscreen context. + * Never explicitly delete the context, use disposeContext() instead. + * \return The new context (or 0 if creation failed). + */ + GHOST_IContext *createOffscreenContext(); + + /** + * Dispose of a context. + * \param context Pointer to the context to be disposed. + * \return Indication of success. + */ + GHOST_TSuccess disposeContext(GHOST_IContext *context); + + /*************************************************************************************** + * 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. + */ + bool processEvents(bool waitForEvent); + + /** + * Handle User request to quit, from Menu bar Quit, and Cmd+Q + * Display alert panel if changes performed since last save + */ + GHOST_TUns8 handleQuitRequest(); + + /** + * Handle Cocoa openFile event + * Display confirmation request panel if changes performed since last save + */ + bool handleOpenDocumentRequest(void *filepathStr); + + /** + * Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass + * \param eventType The type of drag'n'drop event + * \param draggedObjectType The type object concerned (currently array of file names, string, TIFF image) + * \param mouseX x mouse coordinate (in cocoa base window coordinates) + * \param mouseY y mouse coordinate + * \param window The window on which the event occurred + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, + GHOST_TDragnDropTypes draggedObjectType, + GHOST_WindowCocoa *window, + int mouseX, + int mouseY, + void *data); + + /*************************************************************************************** + * 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. + */ + 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. + */ + GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + + /*************************************************************************************** + * 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. + */ + 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; + + /** + * Returns Clipboard data + * \param selection Indicate which buffer to return + * \return Returns the selected buffer + */ + GHOST_TUns8 *getClipboard(bool selection) const; + + /** + * Puts buffer to system clipboard + * \param buffer The buffer to be copied + * \param selection Indicates which buffer to copy too, only used on X11 + */ + void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + + /** + * Handles a window event. Called by GHOST_WindowCocoa window delegate + * \param eventType The type of window event + * \param window The window on which the event occurred + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window); + + /** + * Handles the Cocoa event telling the application has become active (again) + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleApplicationBecomeActiveEvent(); + + /** + * External objects should call this when they send an event outside processEvents. + */ + void notifyExternalEventProcessed(); + + /** + * \see GHOST_ISystem + */ + int toggleConsole(int action) + { + return 0; + } + + /** + * Handles a tablet event. + * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * \param eventType The type of the event. + * It needs to be passed separately as it can be either directly in the event type, + * or as a subtype if combined with a mouse button event. + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType); + bool handleTabletEvent(void *eventPtr); + + /** + * Handles a mouse event. + * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleMouseEvent(void *eventPtr); + + /** + * Handles a key event. + * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * \return Indication whether the event was handled. + */ + GHOST_TSuccess handleKeyEvent(void *eventPtr); + + /** + * Informs if the system provides native dialogs (eg. confirm quit) + */ + virtual bool supportsNativeDialogs(void); + + protected: + /** + * Initializes the system. + * For now, it just registers the window class (WNDCLASS). + * \return A success value. + */ + GHOST_TSuccess init(); + + /** + * Performs the actual cursor position update (location in screen coordinates). + * \param x The x-coordinate of the cursor. + * \param y The y-coordinate of the cursor. + * \return Indication of success. + */ + GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + + /** Start time at initialization. */ + GHOST_TUns64 m_start_time; + + /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */ + bool m_outsideLoopEventProcessed; + + /** Raised window is not yet known by the window manager, so delay application become active event handling */ + bool m_needDelayedApplicationBecomeActiveEventProcessing; + + /** State of the modifiers. */ + GHOST_TUns32 m_modifierMask; + + /** Ignores window size messages (when window is dragged). */ + bool m_ignoreWindowSizedMessages; + + /** Temporarily ignore momentum scroll events */ + bool m_ignoreMomentumScroll; + /** Is the scroll wheel event generated by a multitouch trackpad or mouse? */ + bool m_multiTouchScroll; }; -#endif // __GHOST_SYSTEMCOCOA_H__ +#endif // __GHOST_SYSTEMCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 8b270c1d972..4c9c7453f43 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -39,7 +39,7 @@ #endif #ifdef WITH_INPUT_NDOF - #include "GHOST_NDOFManagerCocoa.h" +# include "GHOST_NDOFManagerCocoa.h" #endif #include "AssertMacros.h" @@ -57,24 +57,24 @@ static GHOST_TButtonMask convertButton(int button) { - switch (button) { - case 0: - return GHOST_kButtonMaskLeft; - case 1: - return GHOST_kButtonMaskRight; - case 2: - return GHOST_kButtonMaskMiddle; - case 3: - return GHOST_kButtonMaskButton4; - case 4: - return GHOST_kButtonMaskButton5; - case 5: - return GHOST_kButtonMaskButton6; - case 6: - return GHOST_kButtonMaskButton7; - default: - return GHOST_kButtonMaskLeft; - } + switch (button) { + case 0: + return GHOST_kButtonMaskLeft; + case 1: + return GHOST_kButtonMaskRight; + case 2: + return GHOST_kButtonMaskMiddle; + case 3: + return GHOST_kButtonMaskButton4; + case 4: + return GHOST_kButtonMaskButton5; + case 5: + return GHOST_kButtonMaskButton6; + case 6: + return GHOST_kButtonMaskButton7; + default: + return GHOST_kButtonMaskLeft; + } } /** @@ -86,171 +86,253 @@ static GHOST_TButtonMask convertButton(int button) */ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction) { - //printf("\nrecvchar %c 0x%x",recvChar,recvChar); - switch (rawCode) { - /*Physical keycodes not used due to map changes in int'l keyboards - case kVK_ANSI_A: return GHOST_kKeyA; - case kVK_ANSI_B: return GHOST_kKeyB; - case kVK_ANSI_C: return GHOST_kKeyC; - case kVK_ANSI_D: return GHOST_kKeyD; - case kVK_ANSI_E: return GHOST_kKeyE; - case kVK_ANSI_F: return GHOST_kKeyF; - case kVK_ANSI_G: return GHOST_kKeyG; - case kVK_ANSI_H: return GHOST_kKeyH; - case kVK_ANSI_I: return GHOST_kKeyI; - case kVK_ANSI_J: return GHOST_kKeyJ; - case kVK_ANSI_K: return GHOST_kKeyK; - case kVK_ANSI_L: return GHOST_kKeyL; - case kVK_ANSI_M: return GHOST_kKeyM; - case kVK_ANSI_N: return GHOST_kKeyN; - case kVK_ANSI_O: return GHOST_kKeyO; - case kVK_ANSI_P: return GHOST_kKeyP; - case kVK_ANSI_Q: return GHOST_kKeyQ; - case kVK_ANSI_R: return GHOST_kKeyR; - case kVK_ANSI_S: return GHOST_kKeyS; - case kVK_ANSI_T: return GHOST_kKeyT; - case kVK_ANSI_U: return GHOST_kKeyU; - case kVK_ANSI_V: return GHOST_kKeyV; - case kVK_ANSI_W: return GHOST_kKeyW; - case kVK_ANSI_X: return GHOST_kKeyX; - case kVK_ANSI_Y: return GHOST_kKeyY; - case kVK_ANSI_Z: return GHOST_kKeyZ;*/ - - /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/ - case kVK_ISO_Section: return GHOST_kKeyUnknown; - case kVK_ANSI_1: return GHOST_kKey1; - case kVK_ANSI_2: return GHOST_kKey2; - case kVK_ANSI_3: return GHOST_kKey3; - case kVK_ANSI_4: return GHOST_kKey4; - case kVK_ANSI_5: return GHOST_kKey5; - case kVK_ANSI_6: return GHOST_kKey6; - case kVK_ANSI_7: return GHOST_kKey7; - case kVK_ANSI_8: return GHOST_kKey8; - case kVK_ANSI_9: return GHOST_kKey9; - case kVK_ANSI_0: return GHOST_kKey0; - - case kVK_ANSI_Keypad0: return GHOST_kKeyNumpad0; - case kVK_ANSI_Keypad1: return GHOST_kKeyNumpad1; - case kVK_ANSI_Keypad2: return GHOST_kKeyNumpad2; - case kVK_ANSI_Keypad3: return GHOST_kKeyNumpad3; - case kVK_ANSI_Keypad4: return GHOST_kKeyNumpad4; - case kVK_ANSI_Keypad5: return GHOST_kKeyNumpad5; - case kVK_ANSI_Keypad6: return GHOST_kKeyNumpad6; - case kVK_ANSI_Keypad7: return GHOST_kKeyNumpad7; - case kVK_ANSI_Keypad8: return GHOST_kKeyNumpad8; - case kVK_ANSI_Keypad9: return GHOST_kKeyNumpad9; - case kVK_ANSI_KeypadDecimal: return GHOST_kKeyNumpadPeriod; - case kVK_ANSI_KeypadEnter: return GHOST_kKeyNumpadEnter; - case kVK_ANSI_KeypadPlus: return GHOST_kKeyNumpadPlus; - case kVK_ANSI_KeypadMinus: return GHOST_kKeyNumpadMinus; - case kVK_ANSI_KeypadMultiply: return GHOST_kKeyNumpadAsterisk; - case kVK_ANSI_KeypadDivide: return GHOST_kKeyNumpadSlash; - case kVK_ANSI_KeypadClear: return GHOST_kKeyUnknown; - - case kVK_F1: return GHOST_kKeyF1; - case kVK_F2: return GHOST_kKeyF2; - case kVK_F3: return GHOST_kKeyF3; - case kVK_F4: return GHOST_kKeyF4; - case kVK_F5: return GHOST_kKeyF5; - case kVK_F6: return GHOST_kKeyF6; - case kVK_F7: return GHOST_kKeyF7; - case kVK_F8: return GHOST_kKeyF8; - case kVK_F9: return GHOST_kKeyF9; - case kVK_F10: return GHOST_kKeyF10; - case kVK_F11: return GHOST_kKeyF11; - case kVK_F12: return GHOST_kKeyF12; - case kVK_F13: return GHOST_kKeyF13; - case kVK_F14: return GHOST_kKeyF14; - case kVK_F15: return GHOST_kKeyF15; - case kVK_F16: return GHOST_kKeyF16; - case kVK_F17: return GHOST_kKeyF17; - case kVK_F18: return GHOST_kKeyF18; - case kVK_F19: return GHOST_kKeyF19; - case kVK_F20: return GHOST_kKeyF20; - - case kVK_UpArrow: return GHOST_kKeyUpArrow; - case kVK_DownArrow: return GHOST_kKeyDownArrow; - case kVK_LeftArrow: return GHOST_kKeyLeftArrow; - case kVK_RightArrow: return GHOST_kKeyRightArrow; - - case kVK_Return: return GHOST_kKeyEnter; - case kVK_Delete: return GHOST_kKeyBackSpace; - case kVK_ForwardDelete: return GHOST_kKeyDelete; - case kVK_Escape: return GHOST_kKeyEsc; - case kVK_Tab: return GHOST_kKeyTab; - case kVK_Space: return GHOST_kKeySpace; - - case kVK_Home: return GHOST_kKeyHome; - case kVK_End: return GHOST_kKeyEnd; - case kVK_PageUp: return GHOST_kKeyUpPage; - case kVK_PageDown: return GHOST_kKeyDownPage; - - /*case kVK_ANSI_Minus: return GHOST_kKeyMinus; - case kVK_ANSI_Equal: return GHOST_kKeyEqual; - case kVK_ANSI_Comma: return GHOST_kKeyComma; - case kVK_ANSI_Period: return GHOST_kKeyPeriod; - case kVK_ANSI_Slash: return GHOST_kKeySlash; - case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon; - case kVK_ANSI_Quote: return GHOST_kKeyQuote; - case kVK_ANSI_Backslash: return GHOST_kKeyBackslash; - case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket; - case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket; - case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/ - - case kVK_VolumeUp: - case kVK_VolumeDown: - case kVK_Mute: - return GHOST_kKeyUnknown; - - default: - { - /* alphanumerical or punctuation key that is remappable in int'l keyboards */ - if ((recvChar >= 'A') && (recvChar <= 'Z')) { - return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA); - } - else if ((recvChar >= 'a') && (recvChar <= 'z')) { - return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA); - } - else { - /* Leopard and Snow Leopard 64bit compatible API*/ - CFDataRef uchrHandle; /*the keyboard layout*/ - TISInputSourceRef kbdTISHandle; - - kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource(); - uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,kTISPropertyUnicodeKeyLayoutData); - CFRelease(kbdTISHandle); - - /*get actual character value of the "remappable" keys in int'l keyboards, - if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger), - then fallback on using the received charactersIgnoringModifiers */ - if (uchrHandle) { - UInt32 deadKeyState=0; - UniCharCount actualStrLength=0; - - UCKeyTranslate((UCKeyboardLayout*)CFDataGetBytePtr(uchrHandle), rawCode, keyAction, 0, - LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar); - } - - switch (recvChar) { - case '-': return GHOST_kKeyMinus; - case '+': return GHOST_kKeyPlus; - 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; - default: - return GHOST_kKeyUnknown; - } - } - } - } - return GHOST_kKeyUnknown; + //printf("\nrecvchar %c 0x%x",recvChar,recvChar); + switch (rawCode) { + /*Physical keycodes not used due to map changes in int'l keyboards + case kVK_ANSI_A: return GHOST_kKeyA; + case kVK_ANSI_B: return GHOST_kKeyB; + case kVK_ANSI_C: return GHOST_kKeyC; + case kVK_ANSI_D: return GHOST_kKeyD; + case kVK_ANSI_E: return GHOST_kKeyE; + case kVK_ANSI_F: return GHOST_kKeyF; + case kVK_ANSI_G: return GHOST_kKeyG; + case kVK_ANSI_H: return GHOST_kKeyH; + case kVK_ANSI_I: return GHOST_kKeyI; + case kVK_ANSI_J: return GHOST_kKeyJ; + case kVK_ANSI_K: return GHOST_kKeyK; + case kVK_ANSI_L: return GHOST_kKeyL; + case kVK_ANSI_M: return GHOST_kKeyM; + case kVK_ANSI_N: return GHOST_kKeyN; + case kVK_ANSI_O: return GHOST_kKeyO; + case kVK_ANSI_P: return GHOST_kKeyP; + case kVK_ANSI_Q: return GHOST_kKeyQ; + case kVK_ANSI_R: return GHOST_kKeyR; + case kVK_ANSI_S: return GHOST_kKeyS; + case kVK_ANSI_T: return GHOST_kKeyT; + case kVK_ANSI_U: return GHOST_kKeyU; + case kVK_ANSI_V: return GHOST_kKeyV; + case kVK_ANSI_W: return GHOST_kKeyW; + case kVK_ANSI_X: return GHOST_kKeyX; + case kVK_ANSI_Y: return GHOST_kKeyY; + case kVK_ANSI_Z: return GHOST_kKeyZ;*/ + + /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/ + case kVK_ISO_Section: + return GHOST_kKeyUnknown; + case kVK_ANSI_1: + return GHOST_kKey1; + case kVK_ANSI_2: + return GHOST_kKey2; + case kVK_ANSI_3: + return GHOST_kKey3; + case kVK_ANSI_4: + return GHOST_kKey4; + case kVK_ANSI_5: + return GHOST_kKey5; + case kVK_ANSI_6: + return GHOST_kKey6; + case kVK_ANSI_7: + return GHOST_kKey7; + case kVK_ANSI_8: + return GHOST_kKey8; + case kVK_ANSI_9: + return GHOST_kKey9; + case kVK_ANSI_0: + return GHOST_kKey0; + + case kVK_ANSI_Keypad0: + return GHOST_kKeyNumpad0; + case kVK_ANSI_Keypad1: + return GHOST_kKeyNumpad1; + case kVK_ANSI_Keypad2: + return GHOST_kKeyNumpad2; + case kVK_ANSI_Keypad3: + return GHOST_kKeyNumpad3; + case kVK_ANSI_Keypad4: + return GHOST_kKeyNumpad4; + case kVK_ANSI_Keypad5: + return GHOST_kKeyNumpad5; + case kVK_ANSI_Keypad6: + return GHOST_kKeyNumpad6; + case kVK_ANSI_Keypad7: + return GHOST_kKeyNumpad7; + case kVK_ANSI_Keypad8: + return GHOST_kKeyNumpad8; + case kVK_ANSI_Keypad9: + return GHOST_kKeyNumpad9; + case kVK_ANSI_KeypadDecimal: + return GHOST_kKeyNumpadPeriod; + case kVK_ANSI_KeypadEnter: + return GHOST_kKeyNumpadEnter; + case kVK_ANSI_KeypadPlus: + return GHOST_kKeyNumpadPlus; + case kVK_ANSI_KeypadMinus: + return GHOST_kKeyNumpadMinus; + case kVK_ANSI_KeypadMultiply: + return GHOST_kKeyNumpadAsterisk; + case kVK_ANSI_KeypadDivide: + return GHOST_kKeyNumpadSlash; + case kVK_ANSI_KeypadClear: + return GHOST_kKeyUnknown; + + case kVK_F1: + return GHOST_kKeyF1; + case kVK_F2: + return GHOST_kKeyF2; + case kVK_F3: + return GHOST_kKeyF3; + case kVK_F4: + return GHOST_kKeyF4; + case kVK_F5: + return GHOST_kKeyF5; + case kVK_F6: + return GHOST_kKeyF6; + case kVK_F7: + return GHOST_kKeyF7; + case kVK_F8: + return GHOST_kKeyF8; + case kVK_F9: + return GHOST_kKeyF9; + case kVK_F10: + return GHOST_kKeyF10; + case kVK_F11: + return GHOST_kKeyF11; + case kVK_F12: + return GHOST_kKeyF12; + case kVK_F13: + return GHOST_kKeyF13; + case kVK_F14: + return GHOST_kKeyF14; + case kVK_F15: + return GHOST_kKeyF15; + case kVK_F16: + return GHOST_kKeyF16; + case kVK_F17: + return GHOST_kKeyF17; + case kVK_F18: + return GHOST_kKeyF18; + case kVK_F19: + return GHOST_kKeyF19; + case kVK_F20: + return GHOST_kKeyF20; + + case kVK_UpArrow: + return GHOST_kKeyUpArrow; + case kVK_DownArrow: + return GHOST_kKeyDownArrow; + case kVK_LeftArrow: + return GHOST_kKeyLeftArrow; + case kVK_RightArrow: + return GHOST_kKeyRightArrow; + + case kVK_Return: + return GHOST_kKeyEnter; + case kVK_Delete: + return GHOST_kKeyBackSpace; + case kVK_ForwardDelete: + return GHOST_kKeyDelete; + case kVK_Escape: + return GHOST_kKeyEsc; + case kVK_Tab: + return GHOST_kKeyTab; + case kVK_Space: + return GHOST_kKeySpace; + + case kVK_Home: + return GHOST_kKeyHome; + case kVK_End: + return GHOST_kKeyEnd; + case kVK_PageUp: + return GHOST_kKeyUpPage; + case kVK_PageDown: + return GHOST_kKeyDownPage; + + /*case kVK_ANSI_Minus: return GHOST_kKeyMinus; + case kVK_ANSI_Equal: return GHOST_kKeyEqual; + case kVK_ANSI_Comma: return GHOST_kKeyComma; + case kVK_ANSI_Period: return GHOST_kKeyPeriod; + case kVK_ANSI_Slash: return GHOST_kKeySlash; + case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon; + case kVK_ANSI_Quote: return GHOST_kKeyQuote; + case kVK_ANSI_Backslash: return GHOST_kKeyBackslash; + case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket; + case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket; + case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/ + + case kVK_VolumeUp: + case kVK_VolumeDown: + case kVK_Mute: + return GHOST_kKeyUnknown; + + default: { + /* alphanumerical or punctuation key that is remappable in int'l keyboards */ + if ((recvChar >= 'A') && (recvChar <= 'Z')) { + return (GHOST_TKey)(recvChar - 'A' + GHOST_kKeyA); + } + else if ((recvChar >= 'a') && (recvChar <= 'z')) { + return (GHOST_TKey)(recvChar - 'a' + GHOST_kKeyA); + } + else { + /* Leopard and Snow Leopard 64bit compatible API*/ + CFDataRef uchrHandle; /*the keyboard layout*/ + TISInputSourceRef kbdTISHandle; + + kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource(); + uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle, + kTISPropertyUnicodeKeyLayoutData); + CFRelease(kbdTISHandle); + + /*get actual character value of the "remappable" keys in int'l keyboards, + if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger), + then fallback on using the received charactersIgnoringModifiers */ + if (uchrHandle) { + UInt32 deadKeyState = 0; + UniCharCount actualStrLength = 0; + + UCKeyTranslate((UCKeyboardLayout *)CFDataGetBytePtr(uchrHandle), + rawCode, + keyAction, + 0, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &deadKeyState, + 1, + &actualStrLength, + &recvChar); + } + + switch (recvChar) { + case '-': + return GHOST_kKeyMinus; + case '+': + return GHOST_kKeyPlus; + 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; + default: + return GHOST_kKeyUnknown; + } + } + } + } + return GHOST_kKeyUnknown; } #pragma mark Utility functions @@ -262,14 +344,14 @@ static char g_firstFileBuf[512]; //TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { - if (g_hasFirstFile) { - strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1); - buf[FIRSTFILEBUFLG - 1] = '\0'; - return 1; - } - else { - return 0; - } + if (g_hasFirstFile) { + strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1); + buf[FIRSTFILEBUFLG - 1] = '\0'; + return 1; + } + else { + return 0; + } } #pragma mark Cocoa objects @@ -278,9 +360,10 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) * CocoaAppDelegate * ObjC object to capture applicationShouldTerminate, and send quit event */ -@interface CocoaAppDelegate : NSObject <NSApplicationDelegate> { +@interface CocoaAppDelegate : NSObject <NSApplicationDelegate> +{ - GHOST_SystemCocoa *systemCocoa; + GHOST_SystemCocoa *systemCocoa; } - (id)init; @@ -292,57 +375,59 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) - (void)applicationWillTerminate:(NSNotification *)aNotification; - (void)applicationWillBecomeActive:(NSNotification *)aNotification; - (void)toggleFullScreen:(NSNotification *)notification; -- (void)windowWillClose:(NSNotification*)notification; +- (void)windowWillClose:(NSNotification *)notification; @end @implementation CocoaAppDelegate : NSObject -- (id)init { - self = [super init]; - if (self) { - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(windowWillClose:) - name:NSWindowWillCloseNotification - object:nil]; - } - return self; +- (id)init +{ + self = [super init]; + if (self) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:nil]; + } + return self; } -- (void)dealloc { - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center removeObserver:self name:NSWindowWillCloseNotification object:nil]; - [super dealloc]; +- (void)dealloc +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self name:NSWindowWillCloseNotification object:nil]; + [super dealloc]; } --(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa +- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa { - systemCocoa = sysCocoa; + systemCocoa = sysCocoa; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - if (systemCocoa->m_windowFocus) { - // Raise application to front, convenient when starting from the terminal - // and important for launching the animation player. we call this after the - // application finishes launching, as doing it earlier can make us end up - // with a frontmost window but an inactive application. - [NSApp activateIgnoringOtherApps:YES]; - } + if (systemCocoa->m_windowFocus) { + // Raise application to front, convenient when starting from the terminal + // and important for launching the animation player. we call this after the + // application finishes launching, as doing it earlier can make us end up + // with a frontmost window but an inactive application. + [NSApp activateIgnoringOtherApps:YES]; + } } - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { - return systemCocoa->handleOpenDocumentRequest(filename); + return systemCocoa->handleOpenDocumentRequest(filename); } - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be canceled - //Note that Cmd+Q is already handled by keyhandler - if (systemCocoa->handleQuitRequest() == GHOST_kExitNow) - return NSTerminateCancel;//NSTerminateNow; - else - return NSTerminateCancel; + //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be canceled + //Note that Cmd+Q is already handled by keyhandler + if (systemCocoa->handleQuitRequest() == GHOST_kExitNow) + return NSTerminateCancel; //NSTerminateNow; + else + return NSTerminateCancel; } // To avoid canceling a log off process, we must use Cocoa termination process @@ -350,13 +435,13 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) // So WM_exit needs to be called directly, as the event loop will never run before termination - (void)applicationWillTerminate:(NSNotification *)aNotification { - /*G.is_break = FALSE; //Let Cocoa perform the termination at the end - WM_exit(C);*/ + /*G.is_break = FALSE; //Let Cocoa perform the termination at the end + WM_exit(C);*/ } - (void)applicationWillBecomeActive:(NSNotification *)aNotification { - systemCocoa->handleApplicationBecomeActiveEvent(); + systemCocoa->handleApplicationBecomeActiveEvent(); } - (void)toggleFullScreen:(NSNotification *)notification @@ -377,273 +462,294 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) // key window from here if the closing one is not in the orderedWindows. This // saves lack of key windows when closing "About", but does not interfere with // Blender's window manager when closing Blender's windows. -- (void)windowWillClose:(NSNotification*)notification { - NSWindow* closing_window = (NSWindow*)[notification object]; - NSInteger index = [[NSApp orderedWindows] indexOfObject:closing_window]; - if (index != NSNotFound) { - return; - } - // Find first suitable window from the current space. - for (NSWindow* current_window in [NSApp orderedWindows]) { - if (current_window == closing_window) { - continue; - } - if ([current_window isOnActiveSpace] && - [current_window canBecomeKeyWindow]) - { - [current_window makeKeyAndOrderFront:nil]; - return; - } - } - // If that didn't find any windows, we try to find any suitable window of - // the application. - for (NSNumber* window_number in [NSWindow windowNumbersWithOptions:0]) { - NSWindow* current_window = - [NSApp windowWithWindowNumber:[window_number integerValue]]; - if (current_window == closing_window) { - continue; - } - if ([current_window canBecomeKeyWindow]) { - [current_window makeKeyAndOrderFront:nil]; - return; - } - } +- (void)windowWillClose:(NSNotification *)notification +{ + NSWindow *closing_window = (NSWindow *)[notification object]; + NSInteger index = [[NSApp orderedWindows] indexOfObject:closing_window]; + if (index != NSNotFound) { + return; + } + // Find first suitable window from the current space. + for (NSWindow *current_window in [NSApp orderedWindows]) { + if (current_window == closing_window) { + continue; + } + if ([current_window isOnActiveSpace] && [current_window canBecomeKeyWindow]) { + [current_window makeKeyAndOrderFront:nil]; + return; + } + } + // If that didn't find any windows, we try to find any suitable window of + // the application. + for (NSNumber *window_number in [NSWindow windowNumbersWithOptions:0]) { + NSWindow *current_window = [NSApp windowWithWindowNumber:[window_number integerValue]]; + if (current_window == closing_window) { + continue; + } + if ([current_window canBecomeKeyWindow]) { + [current_window makeKeyAndOrderFront:nil]; + return; + } + } } @end - #pragma mark initialization/finalization GHOST_SystemCocoa::GHOST_SystemCocoa() { - int mib[2]; - struct timeval boottime; - size_t len; - char *rstring = NULL; - - m_modifierMask =0; - m_outsideLoopEventProcessed = false; - m_needDelayedApplicationBecomeActiveEventProcessing = false; - m_displayManager = new GHOST_DisplayManagerCocoa (); - GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n"); - m_displayManager->initialize(); - - //NSEvent timeStamp is given in system uptime, state start date is boot time - mib[0] = CTL_KERN; - mib[1] = KERN_BOOTTIME; - len = sizeof(struct timeval); - - sysctl(mib, 2, &boottime, &len, NULL, 0); - m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000)); - - //Detect multitouch trackpad - mib[0] = CTL_HW; - mib[1] = HW_MODEL; - sysctl( mib, 2, NULL, &len, NULL, 0 ); - rstring = (char*)malloc( len ); - sysctl( mib, 2, rstring, &len, NULL, 0 ); - - free( rstring ); - rstring = NULL; - - m_ignoreWindowSizedMessages = false; - m_ignoreMomentumScroll = false; - m_multiTouchScroll = false; + int mib[2]; + struct timeval boottime; + size_t len; + char *rstring = NULL; + + m_modifierMask = 0; + m_outsideLoopEventProcessed = false; + m_needDelayedApplicationBecomeActiveEventProcessing = false; + m_displayManager = new GHOST_DisplayManagerCocoa(); + GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n"); + m_displayManager->initialize(); + + //NSEvent timeStamp is given in system uptime, state start date is boot time + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + len = sizeof(struct timeval); + + sysctl(mib, 2, &boottime, &len, NULL, 0); + m_start_time = ((boottime.tv_sec * 1000) + (boottime.tv_usec / 1000)); + + //Detect multitouch trackpad + mib[0] = CTL_HW; + mib[1] = HW_MODEL; + sysctl(mib, 2, NULL, &len, NULL, 0); + rstring = (char *)malloc(len); + sysctl(mib, 2, rstring, &len, NULL, 0); + + free(rstring); + rstring = NULL; + + m_ignoreWindowSizedMessages = false; + m_ignoreMomentumScroll = false; + m_multiTouchScroll = false; } GHOST_SystemCocoa::~GHOST_SystemCocoa() { } - GHOST_TSuccess GHOST_SystemCocoa::init() { - GHOST_TSuccess success = GHOST_System::init(); - if (success) { + GHOST_TSuccess success = GHOST_System::init(); + if (success) { #ifdef WITH_INPUT_NDOF - m_ndofManager = new GHOST_NDOFManagerCocoa(*this); + m_ndofManager = new GHOST_NDOFManagerCocoa(*this); #endif - //ProcessSerialNumber psn; + //ProcessSerialNumber psn; - //Carbon stuff to move window & menu to foreground - /*if (!GetCurrentProcess(&psn)) { - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); - }*/ + //Carbon stuff to move window & menu to foreground + /*if (!GetCurrentProcess(&psn)) { + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + SetFrontProcess(&psn); + }*/ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSApplication sharedApplication]; // initializes NSApp + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [NSApplication sharedApplication]; // initializes NSApp - if ([NSApp mainMenu] == nil) { - NSMenu *mainMenubar = [[NSMenu alloc] init]; - NSMenuItem *menuItem; - NSMenu *windowMenu; - NSMenu *appMenu; + if ([NSApp mainMenu] == nil) { + NSMenu *mainMenubar = [[NSMenu alloc] init]; + NSMenuItem *menuItem; + NSMenu *windowMenu; + NSMenu *appMenu; - //Create the application menu - appMenu = [[NSMenu alloc] initWithTitle:@"Blender"]; + //Create the application menu + appMenu = [[NSMenu alloc] initWithTitle:@"Blender"]; - [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:@"About Blender" + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; - menuItem = [appMenu addItemWithTitle:@"Hide Blender" action:@selector(hide:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + menuItem = [appMenu addItemWithTitle:@"Hide Blender" + action:@selector(hide:) + keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; - menuItem = [appMenu addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; + menuItem = [appMenu addItemWithTitle:@"Hide others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; - [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + [appMenu addItemWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; - menuItem = [appMenu addItemWithTitle:@"Quit Blender" action:@selector(terminate:) keyEquivalent:@"q"]; - [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + menuItem = [appMenu addItemWithTitle:@"Quit Blender" + action:@selector(terminate:) + keyEquivalent:@"q"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; - menuItem = [[NSMenuItem alloc] init]; - [menuItem setSubmenu:appMenu]; + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:appMenu]; - [mainMenubar addItem:menuItem]; - [menuItem release]; - [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5 - [appMenu release]; + [mainMenubar addItem:menuItem]; + [menuItem release]; + [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5 + [appMenu release]; - //Create the window menu - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + //Create the window menu + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + menuItem = [windowMenu addItemWithTitle:@"Minimize" + action:@selector(performMiniaturize:) + keyEquivalent:@"m"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; - [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; + [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; - menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f" ]; - [menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask]; + menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen" + action:@selector(toggleFullScreen:) + keyEquivalent:@"f"]; + [menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask]; - menuItem = [windowMenu addItemWithTitle:@"Close" action:@selector(performClose:) keyEquivalent:@"w"]; - [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + menuItem = [windowMenu addItemWithTitle:@"Close" + action:@selector(performClose:) + keyEquivalent:@"w"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; - menuItem = [[NSMenuItem alloc] init]; - [menuItem setSubmenu:windowMenu]; + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:windowMenu]; - [mainMenubar addItem:menuItem]; - [menuItem release]; + [mainMenubar addItem:menuItem]; + [menuItem release]; - [NSApp setMainMenu:mainMenubar]; - [NSApp setWindowsMenu:windowMenu]; - [windowMenu release]; - } + [NSApp setMainMenu:mainMenubar]; + [NSApp setWindowsMenu:windowMenu]; + [windowMenu release]; + } - if ([NSApp delegate] == nil) { - CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init]; - [appDelegate setSystemCocoa:this]; - [NSApp setDelegate:appDelegate]; - } + if ([NSApp delegate] == nil) { + CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init]; + [appDelegate setSystemCocoa:this]; + [NSApp setDelegate:appDelegate]; + } - [NSApp finishLaunching]; + [NSApp finishLaunching]; - [pool drain]; - } - return success; + [pool drain]; + } + return success; } - #pragma mark window management GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const { - //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime]) - struct timeval currentTime; + //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime]) + struct timeval currentTime; - gettimeofday(¤tTime, NULL); + gettimeofday(¤tTime, NULL); - //Return timestamp of system uptime + //Return timestamp of system uptime - return ((currentTime.tv_sec*1000)+(currentTime.tv_usec/1000)-m_start_time); + return ((currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000) - m_start_time); } - GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const { - //Note that OS X supports monitor hot plug - // We do not support multiple monitors at the moment - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + //Note that OS X supports monitor hot plug + // We do not support multiple monitors at the moment + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_TUns8 count = [[NSScreen screens] count]; + GHOST_TUns8 count = [[NSScreen screens] count]; - [pool drain]; - return count; + [pool drain]; + return count; } - -void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const +void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //Get visible frame, that is frame excluding dock and top menu bar - NSRect frame = [[NSScreen mainScreen] visibleFrame]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + //Get visible frame, that is frame excluding dock and top menu bar + NSRect frame = [[NSScreen mainScreen] visibleFrame]; - //Returns max window contents (excluding title bar...) - NSRect contentRect = [NSWindow contentRectForFrameRect:frame - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + //Returns max window contents (excluding title bar...) + NSRect contentRect = [NSWindow + contentRectForFrameRect:frame + styleMask:(NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask)]; - width = contentRect.size.width; - height = contentRect.size.height; + width = contentRect.size.width; + height = contentRect.size.height; - [pool drain]; + [pool drain]; } -void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const +void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - /* TODO! */ - getMainDisplayDimensions(width, height); + /* TODO! */ + getMainDisplayDimensions(width, height); } -GHOST_IWindow* GHOST_SystemCocoa::createWindow( - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - GHOST_GLSettings glSettings, - const bool exclusive, - const GHOST_TEmbedderWindowID parentWindow -) +GHOST_IWindow *GHOST_SystemCocoa::createWindow(const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + GHOST_GLSettings glSettings, + const bool exclusive, + const GHOST_TEmbedderWindowID parentWindow) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_IWindow* window = NULL; - - //Get the available rect for including window contents - NSRect frame = [[NSScreen mainScreen] visibleFrame]; - NSRect contentRect = [NSWindow contentRectForFrameRect:frame - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; - - GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top; - - //Ensures window top left is inside this available rect - left = left > contentRect.origin.x ? left : contentRect.origin.x; - // Add contentRect.origin.y to respect docksize - bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y; - - window = new GHOST_WindowCocoa(this, title, left, bottom, width, height, state, type, glSettings.flags & GHOST_glStereoVisual, glSettings.numOfAASamples, glSettings.flags & GHOST_glDebugContext); - - 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); - //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation) - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window)); - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); - } - else { - GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n"); - delete window; - window = NULL; - } - - [pool drain]; - return window; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_IWindow *window = NULL; + + //Get the available rect for including window contents + NSRect frame = [[NSScreen mainScreen] visibleFrame]; + NSRect contentRect = [NSWindow + contentRectForFrameRect:frame + styleMask:(NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask)]; + + GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top; + + //Ensures window top left is inside this available rect + left = left > contentRect.origin.x ? left : contentRect.origin.x; + // Add contentRect.origin.y to respect docksize + bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y; + + window = new GHOST_WindowCocoa(this, + title, + left, + bottom, + width, + height, + state, + type, + glSettings.flags & GHOST_glStereoVisual, + glSettings.numOfAASamples, + glSettings.flags & GHOST_glDebugContext); + + 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); + //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation) + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window)); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + } + else { + GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n"); + delete window; + window = NULL; + } + + [pool drain]; + return window; } /** @@ -651,32 +757,31 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( * Never explicitly delete the context, use #disposeContext() instead. * \return The new context (or 0 if creation failed). */ -GHOST_IContext * -GHOST_SystemCocoa:: -createOffscreenContext() +GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext() { - GHOST_Context *context = new GHOST_ContextCGL( - false, - 0, - NULL, - NULL, + GHOST_Context *context = new GHOST_ContextCGL(false, + 0, + NULL, + NULL, #if defined(WITH_GL_PROFILE_CORE) - GL_CONTEXT_CORE_PROFILE_BIT, - 3, 3, + GL_CONTEXT_CORE_PROFILE_BIT, + 3, + 3, #else - 0, // no profile bit - 2, 1, + 0, // no profile bit + 2, + 1, #endif - GHOST_OPENGL_CGL_CONTEXT_FLAGS, - GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); + GHOST_OPENGL_CGL_CONTEXT_FLAGS, + GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); - if (context->initializeDrawingContext()) - return context; - else - delete context; + if (context->initializeDrawingContext()) + return context; + else + delete context; - return NULL; + return NULL; } /** @@ -684,26 +789,24 @@ createOffscreenContext() * \param context Pointer to the context to be disposed. * \return Indication of success. */ -GHOST_TSuccess -GHOST_SystemCocoa:: -disposeContext(GHOST_IContext *context) +GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context) { - delete context; + delete context; - return GHOST_kSuccess; + return GHOST_kSuccess; } /** * \note : returns coordinates in Cocoa screen coordinates */ -GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const +GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - NSPoint mouseLoc = [NSEvent mouseLocation]; + NSPoint mouseLoc = [NSEvent mouseLocation]; - // Returns the mouse location in screen coordinates - x = (GHOST_TInt32)mouseLoc.x; - y = (GHOST_TInt32)mouseLoc.y; - return GHOST_kSuccess; + // Returns the mouse location in screen coordinates + x = (GHOST_TInt32)mouseLoc.x; + y = (GHOST_TInt32)mouseLoc.y; + return GHOST_kSuccess; } /** @@ -711,77 +814,79 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3 */ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { - GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow(); - if (!window) return GHOST_kFailure; + GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow(); + if (!window) + return GHOST_kFailure; - //Cursor and mouse dissociation placed here not to interfere with continuous grab - // (in cont. grab setMouseCursorPosition is directly called) - CGAssociateMouseAndMouseCursorPosition(false); - setMouseCursorPosition(x, y); - CGAssociateMouseAndMouseCursorPosition(true); + //Cursor and mouse dissociation placed here not to interfere with continuous grab + // (in cont. grab setMouseCursorPosition is directly called) + CGAssociateMouseAndMouseCursorPosition(false); + setMouseCursorPosition(x, y); + CGAssociateMouseAndMouseCursorPosition(true); - //Force mouse move event (not pushed by Cocoa) - pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y)); - m_outsideLoopEventProcessed = true; + //Force mouse move event (not pushed by Cocoa) + pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y)); + m_outsideLoopEventProcessed = true; - return GHOST_kSuccess; + return GHOST_kSuccess; } GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { - float xf=(float)x, yf=(float)y; - GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow(); - if (!window) return GHOST_kFailure; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSScreen *windowScreen = window->getScreen(); - NSRect screenRect = [windowScreen frame]; - - //Set position relative to current screen - xf -= screenRect.origin.x; - yf -= screenRect.origin.y; - - //Quartz Display Services uses the old coordinates (top left origin) - yf = screenRect.size.height -yf; - - CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf)); - - // See https://stackoverflow.com/a/17559012. By default, hardware events - // will be suppressed for 500ms after a synthetic mouse event. For unknown - // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work, - // however calling CGAssociateMouseAndMouseCursorPosition also removes the - // delay, even if this is undocumented. - CGAssociateMouseAndMouseCursorPosition(true); - - [pool drain]; - return GHOST_kSuccess; + float xf = (float)x, yf = (float)y; + GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow(); + if (!window) + return GHOST_kFailure; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSScreen *windowScreen = window->getScreen(); + NSRect screenRect = [windowScreen frame]; + + //Set position relative to current screen + xf -= screenRect.origin.x; + yf -= screenRect.origin.y; + + //Quartz Display Services uses the old coordinates (top left origin) + yf = screenRect.size.height - yf; + + CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] + objectForKey:@"NSScreenNumber"] unsignedIntValue], + CGPointMake(xf, yf)); + + // See https://stackoverflow.com/a/17559012. By default, hardware events + // will be suppressed for 500ms after a synthetic mouse event. For unknown + // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work, + // however calling CGAssociateMouseAndMouseCursorPosition also removes the + // delay, even if this is undocumented. + CGAssociateMouseAndMouseCursorPosition(true); + + [pool drain]; + return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const +GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys &keys) const { - keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSCommandKeyMask) ? true : false); - keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSAlternateKeyMask) ? true : false); - keys.set(GHOST_kModifierKeyLeftShift, (m_modifierMask & NSShiftKeyMask) ? true : false); - keys.set(GHOST_kModifierKeyLeftControl, (m_modifierMask & NSControlKeyMask) ? true : false); + keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSCommandKeyMask) ? true : false); + keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSAlternateKeyMask) ? true : false); + keys.set(GHOST_kModifierKeyLeftShift, (m_modifierMask & NSShiftKeyMask) ? true : false); + keys.set(GHOST_kModifierKeyLeftControl, (m_modifierMask & NSControlKeyMask) ? true : false); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const +GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const { - UInt32 button_state = GetCurrentEventButtonState(); - - buttons.clear(); - buttons.set(GHOST_kButtonMaskLeft, button_state & (1 << 0)); - buttons.set(GHOST_kButtonMaskRight, button_state & (1 << 1)); - buttons.set(GHOST_kButtonMaskMiddle, button_state & (1 << 2)); - buttons.set(GHOST_kButtonMaskButton4, button_state & (1 << 3)); - buttons.set(GHOST_kButtonMaskButton5, button_state & (1 << 4)); - return GHOST_kSuccess; + UInt32 button_state = GetCurrentEventButtonState(); + + buttons.clear(); + buttons.set(GHOST_kButtonMaskLeft, button_state & (1 << 0)); + buttons.set(GHOST_kButtonMaskRight, button_state & (1 << 1)); + buttons.set(GHOST_kButtonMaskMiddle, button_state & (1 << 2)); + buttons.set(GHOST_kButtonMaskButton4, button_state & (1 << 3)); + buttons.set(GHOST_kButtonMaskButton5, button_state & (1 << 4)); + return GHOST_kSuccess; } - #pragma mark Event handlers /** @@ -789,991 +894,1074 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const */ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) { - bool anyProcessed = false; - NSEvent *event; + bool anyProcessed = false; + NSEvent *event; - // SetMouseCoalescingEnabled(false, NULL); - //TODO : implement timer ?? + // SetMouseCoalescingEnabled(false, NULL); + //TODO : implement timer ?? #if 0 - do { - GHOST_TimerManager* timerMgr = getTimerManager(); - - if (waitForEvent) { - GHOST_TUns64 next = timerMgr->nextFireTime(); - double timeOut; - - if (next == GHOST_kFireTimeNever) { - timeOut = kEventDurationForever; - } - else { - timeOut = (double)(next - getMilliSeconds())/1000.0; - if (timeOut < 0.0) - timeOut = 0.0; - } - - ::ReceiveNextEvent(0, NULL, timeOut, false, &event); - } - - if (timerMgr->fireTimers(getMilliSeconds())) { - anyProcessed = true; - } + do { + GHOST_TimerManager* timerMgr = getTimerManager(); + + if (waitForEvent) { + GHOST_TUns64 next = timerMgr->nextFireTime(); + double timeOut; + + if (next == GHOST_kFireTimeNever) { + timeOut = kEventDurationForever; + } + else { + timeOut = (double)(next - getMilliSeconds())/1000.0; + if (timeOut < 0.0) + timeOut = 0.0; + } + + ::ReceiveNextEvent(0, NULL, timeOut, false, &event); + } + + if (timerMgr->fireTimers(getMilliSeconds())) { + anyProcessed = true; + } #endif - do { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (event==nil) { - [pool drain]; - break; - } - - anyProcessed = true; - - // Send event to NSApp to ensure Mac wide events are handled, - // this will send events to CocoaWindow which will call back - // to handleKeyEvent, handleMouseEvent and handleTabletEvent - - // There is on special exception for ctrl+(shift)+tab. We do not - // get keyDown events delivered to the view because they are - // special hotkeys to switch between views, so override directly - - if ([event type] == NSKeyDown && - [event keyCode] == kVK_Tab && - ([event modifierFlags] & NSControlKeyMask)) { - handleKeyEvent(event); - } - else { - // For some reason NSApp is swallowing the key up events when modifier - // key is pressed, even if there seems to be no apparent reason to do - // so, as a workaround we always handle these up events. - if ([event type] == NSKeyUp && ([event modifierFlags] & (NSCommandKeyMask | NSAlternateKeyMask))) - handleKeyEvent(event); - - [NSApp sendEvent:event]; - } - - [pool drain]; - } while (event != nil); + do { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event == nil) { + [pool drain]; + break; + } + + anyProcessed = true; + + // Send event to NSApp to ensure Mac wide events are handled, + // this will send events to CocoaWindow which will call back + // to handleKeyEvent, handleMouseEvent and handleTabletEvent + + // There is on special exception for ctrl+(shift)+tab. We do not + // get keyDown events delivered to the view because they are + // special hotkeys to switch between views, so override directly + + if ([event type] == NSKeyDown && [event keyCode] == kVK_Tab && + ([event modifierFlags] & NSControlKeyMask)) { + handleKeyEvent(event); + } + else { + // For some reason NSApp is swallowing the key up events when modifier + // key is pressed, even if there seems to be no apparent reason to do + // so, as a workaround we always handle these up events. + if ([event type] == NSKeyUp && + ([event modifierFlags] & (NSCommandKeyMask | NSAlternateKeyMask))) + handleKeyEvent(event); + + [NSApp sendEvent:event]; + } + + [pool drain]; + } while (event != nil); #if 0 - } while (waitForEvent && !anyProcessed); // Needed only for timer implementation + } while (waitForEvent && !anyProcessed); // Needed only for timer implementation #endif - if (m_needDelayedApplicationBecomeActiveEventProcessing) handleApplicationBecomeActiveEvent(); + if (m_needDelayedApplicationBecomeActiveEventProcessing) + handleApplicationBecomeActiveEvent(); - if (m_outsideLoopEventProcessed) { - m_outsideLoopEventProcessed = false; - return true; - } + if (m_outsideLoopEventProcessed) { + m_outsideLoopEventProcessed = false; + return true; + } - m_ignoreWindowSizedMessages = false; + m_ignoreWindowSizedMessages = false; - return anyProcessed; + return anyProcessed; } //Note: called from NSApplication delegate GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent() { - //Update the modifiers key mask, as its status may have changed when the application was not active - //(that is when update events are sent to another application) - unsigned int modifiers; - GHOST_IWindow* window = m_windowManager->getActiveWindow(); - - if (!window) { - m_needDelayedApplicationBecomeActiveEventProcessing = true; - return GHOST_kFailure; - } - else m_needDelayedApplicationBecomeActiveEventProcessing = false; - - modifiers = [[[NSApplication sharedApplication] currentEvent] modifierFlags]; - - if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift)); - } - if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl)); - } - if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt)); - } - if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS)); - } - - m_modifierMask = modifiers; - - m_outsideLoopEventProcessed = true; - return GHOST_kSuccess; + //Update the modifiers key mask, as its status may have changed when the application was not active + //(that is when update events are sent to another application) + unsigned int modifiers; + GHOST_IWindow *window = m_windowManager->getActiveWindow(); + + if (!window) { + m_needDelayedApplicationBecomeActiveEventProcessing = true; + return GHOST_kFailure; + } + else + m_needDelayedApplicationBecomeActiveEventProcessing = false; + + modifiers = [[[NSApplication sharedApplication] currentEvent] modifierFlags]; + + if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { + pushEvent( + new GHOST_EventKey(getMilliSeconds(), + (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftShift)); + } + if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) { + pushEvent(new GHOST_EventKey(getMilliSeconds(), + (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftControl)); + } + if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) { + pushEvent(new GHOST_EventKey(getMilliSeconds(), + (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftAlt)); + } + if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) { + pushEvent(new GHOST_EventKey(getMilliSeconds(), + (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyOS)); + } + + m_modifierMask = modifiers; + + m_outsideLoopEventProcessed = true; + return GHOST_kSuccess; } void GHOST_SystemCocoa::notifyExternalEventProcessed() { - m_outsideLoopEventProcessed = true; + m_outsideLoopEventProcessed = true; } //Note: called from NSWindow delegate -GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window) +GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, + GHOST_WindowCocoa *window) { - NSArray *windowsList; - windowsList = [NSApp orderedWindows]; - if (!validWindow(window)) { - return GHOST_kFailure; - } - switch (eventType) { - case GHOST_kEventWindowClose: - // check for index of mainwindow as it would quit blender without dialog and discard - if ([windowsList count] > 1 && window->getCocoaWindow() != [windowsList objectAtIndex:[windowsList count] - 1]) { - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) ); - } - else { - handleQuitRequest(); // -> quit dialog - } - break; - case GHOST_kEventWindowActivate: - m_windowManager->setActiveWindow(window); - window->loadCursor(window->getCursorVisibility(), window->getCursorShape()); - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) ); - break; - case GHOST_kEventWindowDeactivate: - m_windowManager->setWindowInactive(window); - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) ); - break; - case GHOST_kEventWindowUpdate: - if (m_nativePixel) { - window->setNativePixelSize(); - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) ); - } - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) ); - break; - case GHOST_kEventWindowMove: - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window) ); - break; - case GHOST_kEventWindowSize: - if (!m_ignoreWindowSizedMessages) { - //Enforce only one resize message per event loop (coalescing all the live resize messages) - window->updateDrawingContext(); - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) ); - //Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager - pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft)); - //m_ignoreWindowSizedMessages = true; - } - break; - case GHOST_kEventNativeResolutionChange: - - if (m_nativePixel) { - window->setNativePixelSize(); - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) ); - } - - default: - return GHOST_kFailure; - break; - } - - m_outsideLoopEventProcessed = true; - return GHOST_kSuccess; + NSArray *windowsList; + windowsList = [NSApp orderedWindows]; + if (!validWindow(window)) { + return GHOST_kFailure; + } + switch (eventType) { + case GHOST_kEventWindowClose: + // check for index of mainwindow as it would quit blender without dialog and discard + if ([windowsList count] > 1 && + window->getCocoaWindow() != [windowsList objectAtIndex:[windowsList count] - 1]) { + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window)); + } + else { + handleQuitRequest(); // -> quit dialog + } + break; + case GHOST_kEventWindowActivate: + m_windowManager->setActiveWindow(window); + window->loadCursor(window->getCursorVisibility(), window->getCursorShape()); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window)); + break; + case GHOST_kEventWindowDeactivate: + m_windowManager->setWindowInactive(window); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window)); + break; + case GHOST_kEventWindowUpdate: + if (m_nativePixel) { + window->setNativePixelSize(); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window)); + } + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window)); + break; + case GHOST_kEventWindowMove: + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window)); + break; + case GHOST_kEventWindowSize: + if (!m_ignoreWindowSizedMessages) { + //Enforce only one resize message per event loop (coalescing all the live resize messages) + window->updateDrawingContext(); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + //Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager + pushEvent(new GHOST_EventButton( + getMilliSeconds(), GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft)); + //m_ignoreWindowSizedMessages = true; + } + break; + case GHOST_kEventNativeResolutionChange: + + if (m_nativePixel) { + window->setNativePixelSize(); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window)); + } + + default: + return GHOST_kFailure; + break; + } + + m_outsideLoopEventProcessed = true; + return GHOST_kSuccess; } //Note: called from NSWindow subclass -GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, - GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data) +GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType, + GHOST_TDragnDropTypes draggedObjectType, + GHOST_WindowCocoa *window, + int mouseX, + int mouseY, + void *data) { - if (!validWindow(window)) { - return GHOST_kFailure; - } - switch (eventType) { - case GHOST_kEventDraggingEntered: - case GHOST_kEventDraggingUpdated: - case GHOST_kEventDraggingExited: - pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,NULL)); - break; - - case GHOST_kEventDraggingDropDone: - { - GHOST_TUns8 * temp_buff; - GHOST_TStringArray *strArray; - NSArray *droppedArray; - size_t pastedTextSize; - NSString *droppedStr; - GHOST_TEventDataPtr eventData; - int i; - - if (!data) return GHOST_kFailure; - - switch (draggedObjectType) { - case GHOST_kDragnDropTypeFilenames: - droppedArray = (NSArray*)data; - - strArray = (GHOST_TStringArray*)malloc(sizeof(GHOST_TStringArray)); - if (!strArray) return GHOST_kFailure; - - strArray->count = [droppedArray count]; - if (strArray->count == 0) { - free(strArray); - return GHOST_kFailure; - } - - strArray->strings = (GHOST_TUns8**) malloc(strArray->count*sizeof(GHOST_TUns8*)); - - for (i=0;i<strArray->count;i++) - { - droppedStr = [droppedArray objectAtIndex:i]; - - pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); - - if (!temp_buff) { - strArray->count = i; - break; - } - - strncpy((char*)temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); - temp_buff[pastedTextSize] = '\0'; - - strArray->strings[i] = temp_buff; - } - - eventData = (GHOST_TEventDataPtr) strArray; - break; - - case GHOST_kDragnDropTypeString: - droppedStr = (NSString*)data; - pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - - temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); - - if (temp_buff == NULL) { - return GHOST_kFailure; - } - - strncpy((char*)temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); - - temp_buff[pastedTextSize] = '\0'; - - eventData = (GHOST_TEventDataPtr) temp_buff; - break; - - case GHOST_kDragnDropTypeBitmap: - { - NSImage *droppedImg = (NSImage*)data; - NSSize imgSize = [droppedImg size]; - ImBuf *ibuf = NULL; - GHOST_TUns8 *rasterRGB = NULL; - GHOST_TUns8 *rasterRGBA = NULL; - GHOST_TUns8 *toIBuf = NULL; - int x, y, to_i, from_i; - NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA,*bitmapImage=nil; - NSEnumerator *enumerator; - NSImageRep *representation; - - ibuf = IMB_allocImBuf (imgSize.width, imgSize.height, 32, IB_rect); - if (!ibuf) { - [droppedImg release]; - return GHOST_kFailure; - } - - /*Get the bitmap of the image*/ - enumerator = [[droppedImg representations] objectEnumerator]; - while ((representation = [enumerator nextObject])) { - if ([representation isKindOfClass:[NSBitmapImageRep class]]) { - bitmapImage = (NSBitmapImageRep *)representation; - break; - } - } - if (bitmapImage == nil) return GHOST_kFailure; - - if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) - && ![bitmapImage isPlanar]) { - /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/ - toIBuf = (GHOST_TUns8*)ibuf->rect; - rasterRGB = (GHOST_TUns8*)[bitmapImage bitmapData]; - for (y = 0; y < imgSize.height; y++) { - to_i = (imgSize.height-y-1)*imgSize.width; - from_i = y*imgSize.width; - memcpy(toIBuf+4*to_i, rasterRGB+4*from_i, 4*imgSize.width); - } - } - else { - /* Tell cocoa image resolution is same as current system one */ - [bitmapImage setSize:imgSize]; - - /* Convert the image in a RGBA 32bit format */ - /* As Core Graphics does not support contextes with non premutliplied alpha, - we need to get alpha key values in a separate batch */ - - /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */ - blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:imgSize.width - pixelsHigh:imgSize.height - bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bitmapFormat:(NSBitmapFormat)0 - bytesPerRow:4*imgSize.width - bitsPerPixel:32/*RGB format padded to 32bits*/]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]]; - [bitmapImage draw]; - [NSGraphicsContext restoreGraphicsState]; - - rasterRGB = (GHOST_TUns8*)[blBitmapFormatImageRGB bitmapData]; - if (rasterRGB == NULL) { - [bitmapImage release]; - [blBitmapFormatImageRGB release]; - [droppedImg release]; - return GHOST_kFailure; - } - - /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */ - blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:imgSize.width - pixelsHigh:imgSize.height - bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bitmapFormat:(NSBitmapFormat)0 - bytesPerRow:4*imgSize.width - bitsPerPixel:32/* RGBA */]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]]; - [bitmapImage draw]; - [NSGraphicsContext restoreGraphicsState]; - - rasterRGBA = (GHOST_TUns8*)[blBitmapFormatImageRGBA bitmapData]; - if (rasterRGBA == NULL) { - [bitmapImage release]; - [blBitmapFormatImageRGB release]; - [blBitmapFormatImageRGBA release]; - [droppedImg release]; - return GHOST_kFailure; - } - - /*Copy the image to ibuf, flipping it vertically*/ - toIBuf = (GHOST_TUns8*)ibuf->rect; - for (y = 0; y < imgSize.height; y++) { - for (x = 0; x < imgSize.width; x++) { - to_i = (imgSize.height-y-1)*imgSize.width + x; - from_i = y*imgSize.width + x; - - toIBuf[4*to_i] = rasterRGB[4*from_i]; /* R */ - toIBuf[4*to_i+1] = rasterRGB[4*from_i+1]; /* G */ - toIBuf[4*to_i+2] = rasterRGB[4*from_i+2]; /* B */ - toIBuf[4*to_i+3] = rasterRGBA[4*from_i+3]; /* A */ - } - } - - [blBitmapFormatImageRGB release]; - [blBitmapFormatImageRGBA release]; - [droppedImg release]; - } - - eventData = (GHOST_TEventDataPtr) ibuf; - - break; - } - default: - return GHOST_kFailure; - break; - } - pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,eventData)); - - break; - } - default: - return GHOST_kFailure; - } - m_outsideLoopEventProcessed = true; - return GHOST_kSuccess; + if (!validWindow(window)) { + return GHOST_kFailure; + } + switch (eventType) { + case GHOST_kEventDraggingEntered: + case GHOST_kEventDraggingUpdated: + case GHOST_kEventDraggingExited: + pushEvent(new GHOST_EventDragnDrop( + getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, NULL)); + break; + + case GHOST_kEventDraggingDropDone: { + GHOST_TUns8 *temp_buff; + GHOST_TStringArray *strArray; + NSArray *droppedArray; + size_t pastedTextSize; + NSString *droppedStr; + GHOST_TEventDataPtr eventData; + int i; + + if (!data) + return GHOST_kFailure; + + switch (draggedObjectType) { + case GHOST_kDragnDropTypeFilenames: + droppedArray = (NSArray *)data; + + strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray)); + if (!strArray) + return GHOST_kFailure; + + strArray->count = [droppedArray count]; + if (strArray->count == 0) { + free(strArray); + return GHOST_kFailure; + } + + strArray->strings = (GHOST_TUns8 **)malloc(strArray->count * sizeof(GHOST_TUns8 *)); + + for (i = 0; i < strArray->count; i++) { + droppedStr = [droppedArray objectAtIndex:i]; + + pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); + + if (!temp_buff) { + strArray->count = i; + break; + } + + strncpy((char *)temp_buff, + [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], + pastedTextSize); + temp_buff[pastedTextSize] = '\0'; + + strArray->strings[i] = temp_buff; + } + + eventData = (GHOST_TEventDataPtr)strArray; + break; + + case GHOST_kDragnDropTypeString: + droppedStr = (NSString *)data; + pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); + + if (temp_buff == NULL) { + return GHOST_kFailure; + } + + strncpy((char *)temp_buff, + [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], + pastedTextSize); + + temp_buff[pastedTextSize] = '\0'; + + eventData = (GHOST_TEventDataPtr)temp_buff; + break; + + case GHOST_kDragnDropTypeBitmap: { + NSImage *droppedImg = (NSImage *)data; + NSSize imgSize = [droppedImg size]; + ImBuf *ibuf = NULL; + GHOST_TUns8 *rasterRGB = NULL; + GHOST_TUns8 *rasterRGBA = NULL; + GHOST_TUns8 *toIBuf = NULL; + int x, y, to_i, from_i; + NSBitmapImageRep *blBitmapFormatImageRGB, *blBitmapFormatImageRGBA, *bitmapImage = nil; + NSEnumerator *enumerator; + NSImageRep *representation; + + ibuf = IMB_allocImBuf(imgSize.width, imgSize.height, 32, IB_rect); + if (!ibuf) { + [droppedImg release]; + return GHOST_kFailure; + } + + /*Get the bitmap of the image*/ + enumerator = [[droppedImg representations] objectEnumerator]; + while ((representation = [enumerator nextObject])) { + if ([representation isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImage = (NSBitmapImageRep *)representation; + break; + } + } + if (bitmapImage == nil) + return GHOST_kFailure; + + if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) && + ![bitmapImage isPlanar]) { + /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/ + toIBuf = (GHOST_TUns8 *)ibuf->rect; + rasterRGB = (GHOST_TUns8 *)[bitmapImage bitmapData]; + for (y = 0; y < imgSize.height; y++) { + to_i = (imgSize.height - y - 1) * imgSize.width; + from_i = y * imgSize.width; + memcpy(toIBuf + 4 * to_i, rasterRGB + 4 * from_i, 4 * imgSize.width); + } + } + else { + /* Tell cocoa image resolution is same as current system one */ + [bitmapImage setSize:imgSize]; + + /* Convert the image in a RGBA 32bit format */ + /* As Core Graphics does not support contextes with non premutliplied alpha, + we need to get alpha key values in a separate batch */ + + /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */ + blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:imgSize.width + pixelsHigh:imgSize.height + bitsPerSample:8 + samplesPerPixel:3 + hasAlpha:NO + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:(NSBitmapFormat)0 + bytesPerRow:4 * imgSize.width + bitsPerPixel:32 /*RGB format padded to 32bits*/]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext + setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]]; + [bitmapImage draw]; + [NSGraphicsContext restoreGraphicsState]; + + rasterRGB = (GHOST_TUns8 *)[blBitmapFormatImageRGB bitmapData]; + if (rasterRGB == NULL) { + [bitmapImage release]; + [blBitmapFormatImageRGB release]; + [droppedImg release]; + return GHOST_kFailure; + } + + /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */ + blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:imgSize.width + pixelsHigh:imgSize.height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:(NSBitmapFormat)0 + bytesPerRow:4 * imgSize.width + bitsPerPixel:32 /* RGBA */]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext + setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]]; + [bitmapImage draw]; + [NSGraphicsContext restoreGraphicsState]; + + rasterRGBA = (GHOST_TUns8 *)[blBitmapFormatImageRGBA bitmapData]; + if (rasterRGBA == NULL) { + [bitmapImage release]; + [blBitmapFormatImageRGB release]; + [blBitmapFormatImageRGBA release]; + [droppedImg release]; + return GHOST_kFailure; + } + + /*Copy the image to ibuf, flipping it vertically*/ + toIBuf = (GHOST_TUns8 *)ibuf->rect; + for (y = 0; y < imgSize.height; y++) { + for (x = 0; x < imgSize.width; x++) { + to_i = (imgSize.height - y - 1) * imgSize.width + x; + from_i = y * imgSize.width + x; + + toIBuf[4 * to_i] = rasterRGB[4 * from_i]; /* R */ + toIBuf[4 * to_i + 1] = rasterRGB[4 * from_i + 1]; /* G */ + toIBuf[4 * to_i + 2] = rasterRGB[4 * from_i + 2]; /* B */ + toIBuf[4 * to_i + 3] = rasterRGBA[4 * from_i + 3]; /* A */ + } + } + + [blBitmapFormatImageRGB release]; + [blBitmapFormatImageRGBA release]; + [droppedImg release]; + } + + eventData = (GHOST_TEventDataPtr)ibuf; + + break; + } + default: + return GHOST_kFailure; + break; + } + pushEvent(new GHOST_EventDragnDrop( + getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, eventData)); + + break; + } + default: + return GHOST_kFailure; + } + m_outsideLoopEventProcessed = true; + return GHOST_kSuccess; } - GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() { - GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow(); - - //Discard quit event if we are in cursor grab sequence - if (window && window->getCursorGrabModeIsWarp()) - return GHOST_kExitCancel; - - //Check open windows if some changes are not saved - if (m_windowManager->getAnyModifiedState()) - { - int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved.\nDo you really want to quit?", - @"Cancel", @"Quit Anyway", nil); - if (shouldQuit == NSAlertAlternateReturn) - { - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) ); - return GHOST_kExitNow; - } - else { - //Give back focus to the blender window if user selected cancel quit - NSArray *windowsList = [NSApp orderedWindows]; - if ([windowsList count]) { - [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; - //Handle the modifiers keyes changed state issue - //as recovering from the quit dialog is like application - //gaining focus back. - //Main issue fixed is Cmd modifier not being cleared - handleApplicationBecomeActiveEvent(); - } - } - } - else { - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) ); - m_outsideLoopEventProcessed = true; - return GHOST_kExitNow; - } - - return GHOST_kExitCancel; + GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow(); + + //Discard quit event if we are in cursor grab sequence + if (window && window->getCursorGrabModeIsWarp()) + return GHOST_kExitCancel; + + //Check open windows if some changes are not saved + if (m_windowManager->getAnyModifiedState()) { + int shouldQuit = NSRunAlertPanel( + @"Exit Blender", + @"Some changes have not been saved.\nDo you really want to quit?", + @"Cancel", + @"Quit Anyway", + nil); + if (shouldQuit == NSAlertAlternateReturn) { + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL)); + return GHOST_kExitNow; + } + else { + //Give back focus to the blender window if user selected cancel quit + NSArray *windowsList = [NSApp orderedWindows]; + if ([windowsList count]) { + [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + //Handle the modifiers keyes changed state issue + //as recovering from the quit dialog is like application + //gaining focus back. + //Main issue fixed is Cmd modifier not being cleared + handleApplicationBecomeActiveEvent(); + } + } + } + else { + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL)); + m_outsideLoopEventProcessed = true; + return GHOST_kExitNow; + } + + return GHOST_kExitCancel; } bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr) { - NSString *filepath = (NSString*)filepathStr; - int confirmOpen = NSAlertAlternateReturn; - NSArray *windowsList; - char * temp_buff; - size_t filenameTextSize; - GHOST_Window* window= (GHOST_Window*)m_windowManager->getActiveWindow(); - - if (!window) { - return NO; - } - - //Discard event if we are in cursor grab sequence, it'll lead to "stuck cursor" situation if the alert panel is raised - if (window && window->getCursorGrabModeIsWarp()) - return GHOST_kExitCancel; - - //Check open windows if some changes are not saved - if (m_windowManager->getAnyModifiedState()) - { - confirmOpen = NSRunAlertPanel([NSString stringWithFormat:@"Opening %@",[filepath lastPathComponent]], - @"Current document has not been saved.\nDo you really want to proceed?", - @"Cancel", @"Open", nil); - } - - //Give back focus to the blender window - windowsList = [NSApp orderedWindows]; - if ([windowsList count]) { - [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; - } - - if (confirmOpen == NSAlertAlternateReturn) - { - filenameTextSize = [filepath lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - - temp_buff = (char*) malloc(filenameTextSize+1); - - if (temp_buff == NULL) { - return GHOST_kFailure; - } - - strncpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize); - - temp_buff[filenameTextSize] = '\0'; - - pushEvent(new GHOST_EventString(getMilliSeconds(),GHOST_kEventOpenMainFile,window,(GHOST_TEventDataPtr) temp_buff)); - - return YES; - } - else return NO; + NSString *filepath = (NSString *)filepathStr; + int confirmOpen = NSAlertAlternateReturn; + NSArray *windowsList; + char *temp_buff; + size_t filenameTextSize; + GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow(); + + if (!window) { + return NO; + } + + //Discard event if we are in cursor grab sequence, it'll lead to "stuck cursor" situation if the alert panel is raised + if (window && window->getCursorGrabModeIsWarp()) + return GHOST_kExitCancel; + + //Check open windows if some changes are not saved + if (m_windowManager->getAnyModifiedState()) { + confirmOpen = NSRunAlertPanel( + [NSString stringWithFormat:@"Opening %@", [filepath lastPathComponent]], + @"Current document has not been saved.\nDo you really want to proceed?", + @"Cancel", + @"Open", + nil); + } + + //Give back focus to the blender window + windowsList = [NSApp orderedWindows]; + if ([windowsList count]) { + [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + } + + if (confirmOpen == NSAlertAlternateReturn) { + filenameTextSize = [filepath lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + temp_buff = (char *)malloc(filenameTextSize + 1); + + if (temp_buff == NULL) { + return GHOST_kFailure; + } + + strncpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize); + + temp_buff[filenameTextSize] = '\0'; + + pushEvent(new GHOST_EventString( + getMilliSeconds(), GHOST_kEventOpenMainFile, window, (GHOST_TEventDataPtr)temp_buff)); + + return YES; + } + else + return NO; } GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType) { - NSEvent *event = (NSEvent *)eventPtr; - GHOST_IWindow* window; - - window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); - if (!window) { - //printf("\nW failure for event 0x%x",[event type]); - return GHOST_kFailure; - } - - GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); - - switch (eventType) { - case NSTabletPoint: - // workaround 2 cornercases: - // 1. if [event isEnteringProximity] was not triggered since program-start - // 2. device is not sending [event pointingDeviceType], due no eraser - if (ct.Active == GHOST_kTabletModeNone) - ct.Active = GHOST_kTabletModeStylus; - - ct.Pressure = [event pressure]; - ct.Xtilt = [event tilt].x; - ct.Ytilt = [event tilt].y; - break; - - case NSTabletProximity: - ct.Pressure = 0; - ct.Xtilt = 0; - ct.Ytilt = 0; - if ([event isEnteringProximity]) - { - //pointer is entering tablet area proximity - switch ([event pointingDeviceType]) { - case NSPenPointingDevice: - ct.Active = GHOST_kTabletModeStylus; - break; - case NSEraserPointingDevice: - ct.Active = GHOST_kTabletModeEraser; - break; - case NSCursorPointingDevice: - case NSUnknownPointingDevice: - default: - ct.Active = GHOST_kTabletModeNone; - break; - } - } - else { - // pointer is leaving - return to mouse - ct.Active = GHOST_kTabletModeNone; - } - break; - - default: - GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received"); - return GHOST_kFailure; - break; - } - return GHOST_kSuccess; + NSEvent *event = (NSEvent *)eventPtr; + GHOST_IWindow *window; + + window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } + + GHOST_TabletData &ct = ((GHOST_WindowCocoa *)window)->GetCocoaTabletData(); + + switch (eventType) { + case NSTabletPoint: + // workaround 2 cornercases: + // 1. if [event isEnteringProximity] was not triggered since program-start + // 2. device is not sending [event pointingDeviceType], due no eraser + if (ct.Active == GHOST_kTabletModeNone) + ct.Active = GHOST_kTabletModeStylus; + + ct.Pressure = [event pressure]; + ct.Xtilt = [event tilt].x; + ct.Ytilt = [event tilt].y; + break; + + case NSTabletProximity: + ct.Pressure = 0; + ct.Xtilt = 0; + ct.Ytilt = 0; + if ([event isEnteringProximity]) { + //pointer is entering tablet area proximity + switch ([event pointingDeviceType]) { + case NSPenPointingDevice: + ct.Active = GHOST_kTabletModeStylus; + break; + case NSEraserPointingDevice: + ct.Active = GHOST_kTabletModeEraser; + break; + case NSCursorPointingDevice: + case NSUnknownPointingDevice: + default: + ct.Active = GHOST_kTabletModeNone; + break; + } + } + else { + // pointer is leaving - return to mouse + ct.Active = GHOST_kTabletModeNone; + } + break; + + default: + GHOST_ASSERT(FALSE, "GHOST_SystemCocoa::handleTabletEvent : unknown event received"); + return GHOST_kFailure; + break; + } + return GHOST_kSuccess; } bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) { - NSEvent *event = (NSEvent *)eventPtr; - - switch ([event subtype]) { - case NSTabletPointEventSubtype: - handleTabletEvent(eventPtr, NSTabletPoint); - return true; - case NSTabletProximityEventSubtype: - handleTabletEvent(eventPtr, NSTabletProximity); - return true; - default: - //No tablet event included : do nothing - return false; - } + NSEvent *event = (NSEvent *)eventPtr; + + switch ([event subtype]) { + case NSTabletPointEventSubtype: + handleTabletEvent(eventPtr, NSTabletPoint); + return true; + case NSTabletProximityEventSubtype: + handleTabletEvent(eventPtr, NSTabletProximity); + return true; + default: + //No tablet event included : do nothing + return false; + } } GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { - NSEvent *event = (NSEvent *)eventPtr; - GHOST_WindowCocoa* window; - CocoaWindow *cocoawindow; - - /* [event window] returns other windows if mouse-over, that's OSX input standard - however, if mouse exits window(s), the windows become inactive, until you click. - We then fall back to the active window from ghost */ - window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); - if (!window) { - window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow(); - if (!window) { - //printf("\nW failure for event 0x%x",[event type]); - return GHOST_kFailure; - } - } - - cocoawindow = (CocoaWindow *)window->getOSWindow(); - - switch ([event type]) { - case NSLeftMouseDown: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft)); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - case NSRightMouseDown: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight)); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - case NSOtherMouseDown: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - - case NSLeftMouseUp: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft)); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - case NSRightMouseUp: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight)); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - case NSOtherMouseUp: - pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); - handleTabletEvent(event); //Handle tablet events combined with mouse events - break; - - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - //Handle tablet events combined with mouse events - handleTabletEvent(event); - - case NSMouseMoved: - { - GHOST_TGrabCursorMode grab_mode = window->getCursorGrabMode(); - - /* TODO: CHECK IF THIS IS A TABLET EVENT */ - bool is_tablet = false; - - if (is_tablet && window->getCursorGrabModeIsWarp()) { - grab_mode = GHOST_kGrabDisable; - } - - switch (grab_mode) { - case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move - { - GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; - - window->getCursorGrabInitPos(x_warp, y_warp); - window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); - - window->getCursorGrabAccum(x_accum, y_accum); - x_accum += [event deltaX]; - y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ... - window->setCursorGrabAccum(x_accum, y_accum); - - window->clientToScreenIntern(x_warp+x_accum, y_warp+y_accum, x, y); - pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); - break; - } - case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries - { - NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; - GHOST_TInt32 x_mouse = mousePos.x; - GHOST_TInt32 y_mouse = mousePos.y; - GHOST_Rect bounds, windowBounds, correctedBounds; - - /* fallback to window bounds */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) - window->getClientBounds(bounds); - - //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates - window->getClientBounds(windowBounds); - window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_t); - window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b); - correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b; - correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t; - - //Get accumulation from previous mouse warps - GHOST_TInt32 x_accum, y_accum; - window->getCursorGrabAccum(x_accum, y_accum); - - //Warp mouse cursor if needed - GHOST_TInt32 warped_x_mouse = x_mouse; - GHOST_TInt32 warped_y_mouse = y_mouse; - correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4); - - //Set new cursor position - if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) { - GHOST_TInt32 warped_x, warped_y; - window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y); - setMouseCursorPosition(warped_x, warped_y); /* wrap */ - window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), y_accum + (y_mouse - warped_y_mouse)); - } - - //Generate event - GHOST_TInt32 x, y; - window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y); - pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); - break; - } - default: - { - //Normal cursor operation: send mouse position in window - NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; - GHOST_TInt32 x, y; - - window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); - pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); - break; - } - } - } - break; - - case NSScrollWheel: - { - NSEventPhase momentumPhase = NSEventPhaseNone; - NSEventPhase phase = NSEventPhaseNone; - - if ([event respondsToSelector:@selector(momentumPhase)]) - momentumPhase = [event momentumPhase]; - if ([event respondsToSelector:@selector(phase)]) - phase = [event phase]; - - /* when pressing a key while momentum scrolling continues after - * lifting fingers off the trackpad, the action can unexpectedly - * change from e.g. scrolling to zooming. this works around the - * issue by ignoring momentum scroll after a key press */ - if (momentumPhase) { - if (m_ignoreMomentumScroll) - break; - } - else { - m_ignoreMomentumScroll = false; - } - - /* we assume phases are only set for gestures from trackpad or magic - * mouse events. note that using tablet at the same time may not work - * since this is a static variable */ - if (phase == NSEventPhaseBegan) - m_multiTouchScroll = true; - else if (phase == NSEventPhaseEnded) - m_multiTouchScroll = false; - - /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ - if (!m_multiTouchScroll && momentumPhase == NSEventPhaseNone) { - GHOST_TInt32 delta; - - double deltaF = [event deltaY]; - - if (deltaF == 0.0) deltaF = [event deltaX]; // make blender decide if it's horizontal scroll - if (deltaF == 0.0) break; //discard trackpad delta=0 events - - delta = deltaF > 0.0 ? 1 : -1; - pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta)); - } - else { - NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; - GHOST_TInt32 x, y; - double dx; - double dy; - - /* with 10.7 nice scrolling deltas are supported */ - dx = [event scrollingDeltaX]; - dy = [event scrollingDeltaY]; - - /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */ - if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { - dx = [event deltaX]; - dy = [event deltaY]; - } - window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); - - pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy)); - } - } - break; - - case NSEventTypeMagnify: - { - NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; - GHOST_TInt32 x, y; - window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); - pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y, - [event magnification] * 125.0 + 0.1, 0)); - } - break; - - case NSEventTypeRotate: - { - NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; - GHOST_TInt32 x, y; - window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); - pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y, - [event rotation] * -5.0, 0)); - } - default: - return GHOST_kFailure; - break; - } - - return GHOST_kSuccess; + NSEvent *event = (NSEvent *)eventPtr; + GHOST_WindowCocoa *window; + CocoaWindow *cocoawindow; + + /* [event window] returns other windows if mouse-over, that's OSX input standard + however, if mouse exits window(s), the windows become inactive, until you click. + We then fall back to the active window from ghost */ + window = (GHOST_WindowCocoa *)m_windowManager->getWindowAssociatedWithOSWindow( + (void *)[event window]); + if (!window) { + window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow(); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } + } + + cocoawindow = (CocoaWindow *)window->getOSWindow(); + + switch ([event type]) { + case NSLeftMouseDown: + pushEvent(new GHOST_EventButton( + [event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft)); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + case NSRightMouseDown: + pushEvent(new GHOST_EventButton( + [event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight)); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + case NSOtherMouseDown: + pushEvent(new GHOST_EventButton([event timestamp] * 1000, + GHOST_kEventButtonDown, + window, + convertButton([event buttonNumber]))); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + + case NSLeftMouseUp: + pushEvent(new GHOST_EventButton( + [event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft)); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + case NSRightMouseUp: + pushEvent(new GHOST_EventButton( + [event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight)); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + case NSOtherMouseUp: + pushEvent(new GHOST_EventButton([event timestamp] * 1000, + GHOST_kEventButtonUp, + window, + convertButton([event buttonNumber]))); + handleTabletEvent(event); //Handle tablet events combined with mouse events + break; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + //Handle tablet events combined with mouse events + handleTabletEvent(event); + + case NSMouseMoved: { + GHOST_TGrabCursorMode grab_mode = window->getCursorGrabMode(); + + /* TODO: CHECK IF THIS IS A TABLET EVENT */ + bool is_tablet = false; + + if (is_tablet && window->getCursorGrabModeIsWarp()) { + grab_mode = GHOST_kGrabDisable; + } + + switch (grab_mode) { + case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move + { + GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; + + window->getCursorGrabInitPos(x_warp, y_warp); + window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); + + window->getCursorGrabAccum(x_accum, y_accum); + x_accum += [event deltaX]; + y_accum += -[event + deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ... + window->setCursorGrabAccum(x_accum, y_accum); + + window->clientToScreenIntern(x_warp + x_accum, y_warp + y_accum, x, y); + pushEvent(new GHOST_EventCursor( + [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); + break; + } + case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries + { + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; + GHOST_TInt32 x_mouse = mousePos.x; + GHOST_TInt32 y_mouse = mousePos.y; + GHOST_Rect bounds, windowBounds, correctedBounds; + + /* fallback to window bounds */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) + window->getClientBounds(bounds); + + //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates + window->getClientBounds(windowBounds); + window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_t); + window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b); + correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b; + correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t; + + //Get accumulation from previous mouse warps + GHOST_TInt32 x_accum, y_accum; + window->getCursorGrabAccum(x_accum, y_accum); + + //Warp mouse cursor if needed + GHOST_TInt32 warped_x_mouse = x_mouse; + GHOST_TInt32 warped_y_mouse = y_mouse; + correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4); + + //Set new cursor position + if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) { + GHOST_TInt32 warped_x, warped_y; + window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y); + setMouseCursorPosition(warped_x, warped_y); /* wrap */ + window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), + y_accum + (y_mouse - warped_y_mouse)); + } + + //Generate event + GHOST_TInt32 x, y; + window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y); + pushEvent(new GHOST_EventCursor( + [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); + break; + } + default: { + //Normal cursor operation: send mouse position in window + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; + GHOST_TInt32 x, y; + + window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); + pushEvent(new GHOST_EventCursor( + [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); + break; + } + } + } break; + + case NSScrollWheel: { + NSEventPhase momentumPhase = NSEventPhaseNone; + NSEventPhase phase = NSEventPhaseNone; + + if ([event respondsToSelector:@selector(momentumPhase)]) + momentumPhase = [event momentumPhase]; + if ([event respondsToSelector:@selector(phase)]) + phase = [event phase]; + + /* when pressing a key while momentum scrolling continues after + * lifting fingers off the trackpad, the action can unexpectedly + * change from e.g. scrolling to zooming. this works around the + * issue by ignoring momentum scroll after a key press */ + if (momentumPhase) { + if (m_ignoreMomentumScroll) + break; + } + else { + m_ignoreMomentumScroll = false; + } + + /* we assume phases are only set for gestures from trackpad or magic + * mouse events. note that using tablet at the same time may not work + * since this is a static variable */ + if (phase == NSEventPhaseBegan) + m_multiTouchScroll = true; + else if (phase == NSEventPhaseEnded) + m_multiTouchScroll = false; + + /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ + if (!m_multiTouchScroll && momentumPhase == NSEventPhaseNone) { + GHOST_TInt32 delta; + + double deltaF = [event deltaY]; + + if (deltaF == 0.0) + deltaF = [event deltaX]; // make blender decide if it's horizontal scroll + if (deltaF == 0.0) + break; //discard trackpad delta=0 events + + delta = deltaF > 0.0 ? 1 : -1; + pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta)); + } + else { + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; + GHOST_TInt32 x, y; + double dx; + double dy; + + /* with 10.7 nice scrolling deltas are supported */ + dx = [event scrollingDeltaX]; + dy = [event scrollingDeltaY]; + + /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */ + if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { + dx = [event deltaX]; + dy = [event deltaY]; + } + window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); + + pushEvent(new GHOST_EventTrackpad( + [event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy)); + } + } break; + + case NSEventTypeMagnify: { + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; + GHOST_TInt32 x, y; + window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); + pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, + window, + GHOST_kTrackpadEventMagnify, + x, + y, + [event magnification] * 125.0 + 0.1, + 0)); + } break; + + case NSEventTypeRotate: { + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; + GHOST_TInt32 x, y; + window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); + pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, + window, + GHOST_kTrackpadEventRotate, + x, + y, + [event rotation] * -5.0, + 0)); + } + default: + return GHOST_kFailure; + break; + } + + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) { - NSEvent *event = (NSEvent *)eventPtr; - GHOST_IWindow* window; - unsigned int modifiers; - NSString *characters; - NSData *convertedCharacters; - GHOST_TKey keyCode; - unsigned char ascii; - NSString* charsIgnoringModifiers; - - window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); - if (!window) { - //printf("\nW failure for event 0x%x",[event type]); - return GHOST_kFailure; - } - - char utf8_buf[6]= {'\0'}; - ascii = 0; - - switch ([event type]) { - - case NSKeyDown: - case NSKeyUp: - charsIgnoringModifiers = [event charactersIgnoringModifiers]; - if ([charsIgnoringModifiers length] > 0) { - keyCode = convertKey([event keyCode], - [charsIgnoringModifiers characterAtIndex:0], - [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp); - } - else { - keyCode = convertKey([event keyCode],0, - [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp); - } - - /* handling both unicode or ascii */ - characters = [event characters]; - if ([characters length] > 0) { - convertedCharacters = [characters dataUsingEncoding:NSUTF8StringEncoding]; - - for (int x = 0; x < [convertedCharacters length]; x++) { - utf8_buf[x] = ((char*)[convertedCharacters bytes])[x]; - } - } - - /* arrow keys should not have utf8 */ - if ((keyCode > 266) && (keyCode < 271)) - utf8_buf[0] = '\0'; - - /* F keys should not have utf8 */ - if ((keyCode >= GHOST_kKeyF1) && (keyCode <= GHOST_kKeyF20)) - utf8_buf[0] = '\0'; - - /* no text with command key pressed */ - if (m_modifierMask & NSCommandKeyMask) - utf8_buf[0] = '\0'; - - if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) - break; //Cmd-Q is directly handled by Cocoa - - /* ascii is a subset of unicode */ - if (utf8_buf[0] && !utf8_buf[1]) { - ascii = utf8_buf[0]; - } - - if ([event type] == NSKeyDown) { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf)); - //printf("Key down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); - } - else { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL)); - //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); - } - m_ignoreMomentumScroll = true; - break; - - case NSFlagsChanged: - modifiers = [event modifierFlags]; - - if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift)); - } - if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl)); - } - if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt)); - } - if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) { - pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS)); - } - - m_modifierMask = modifiers; - m_ignoreMomentumScroll = true; - break; - - default: - return GHOST_kFailure; - break; - } - - return GHOST_kSuccess; + NSEvent *event = (NSEvent *)eventPtr; + GHOST_IWindow *window; + unsigned int modifiers; + NSString *characters; + NSData *convertedCharacters; + GHOST_TKey keyCode; + unsigned char ascii; + NSString *charsIgnoringModifiers; + + window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } + + char utf8_buf[6] = {'\0'}; + ascii = 0; + + switch ([event type]) { + + case NSKeyDown: + case NSKeyUp: + charsIgnoringModifiers = [event charactersIgnoringModifiers]; + if ([charsIgnoringModifiers length] > 0) { + keyCode = convertKey([event keyCode], + [charsIgnoringModifiers characterAtIndex:0], + [event type] == NSKeyDown ? kUCKeyActionDown : kUCKeyActionUp); + } + else { + keyCode = convertKey( + [event keyCode], 0, [event type] == NSKeyDown ? kUCKeyActionDown : kUCKeyActionUp); + } + + /* handling both unicode or ascii */ + characters = [event characters]; + if ([characters length] > 0) { + convertedCharacters = [characters dataUsingEncoding:NSUTF8StringEncoding]; + + for (int x = 0; x < [convertedCharacters length]; x++) { + utf8_buf[x] = ((char *)[convertedCharacters bytes])[x]; + } + } + + /* arrow keys should not have utf8 */ + if ((keyCode > 266) && (keyCode < 271)) + utf8_buf[0] = '\0'; + + /* F keys should not have utf8 */ + if ((keyCode >= GHOST_kKeyF1) && (keyCode <= GHOST_kKeyF20)) + utf8_buf[0] = '\0'; + + /* no text with command key pressed */ + if (m_modifierMask & NSCommandKeyMask) + utf8_buf[0] = '\0'; + + if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) + break; //Cmd-Q is directly handled by Cocoa + + /* ascii is a subset of unicode */ + if (utf8_buf[0] && !utf8_buf[1]) { + ascii = utf8_buf[0]; + } + + if ([event type] == NSKeyDown) { + pushEvent(new GHOST_EventKey( + [event timestamp] * 1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf)); + //printf("Key down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); + } + else { + pushEvent(new GHOST_EventKey( + [event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL)); + //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); + } + m_ignoreMomentumScroll = true; + break; + + case NSFlagsChanged: + modifiers = [event modifierFlags]; + + if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { + pushEvent(new GHOST_EventKey([event timestamp] * 1000, + (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftShift)); + } + if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) { + pushEvent(new GHOST_EventKey([event timestamp] * 1000, + (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftControl)); + } + if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) { + pushEvent(new GHOST_EventKey([event timestamp] * 1000, + (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyLeftAlt)); + } + if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) { + pushEvent(new GHOST_EventKey([event timestamp] * 1000, + (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp, + window, + GHOST_kKeyOS)); + } + + m_modifierMask = modifiers; + m_ignoreMomentumScroll = true; + break; + + default: + return GHOST_kFailure; + break; + } + + return GHOST_kSuccess; } - #pragma mark Clipboard get/set -GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const +GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const { - GHOST_TUns8 * temp_buff; - size_t pastedTextSize; + GHOST_TUns8 *temp_buff; + size_t pastedTextSize; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; - if (pasteBoard == nil) { - [pool drain]; - return NULL; - } + if (pasteBoard == nil) { + [pool drain]; + return NULL; + } - NSArray *supportedTypes = - [NSArray arrayWithObjects: NSStringPboardType, nil]; + NSArray *supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil]; - NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes]; + NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes]; - if (bestType == nil) { - [pool drain]; - return NULL; - } + if (bestType == nil) { + [pool drain]; + return NULL; + } - NSString *textPasted = [pasteBoard stringForType:NSStringPboardType]; + NSString *textPasted = [pasteBoard stringForType:NSStringPboardType]; - if (textPasted == nil) { - [pool drain]; - return NULL; - } + if (textPasted == nil) { + [pool drain]; + return NULL; + } - pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); + temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); - if (temp_buff == NULL) { - [pool drain]; - return NULL; - } + if (temp_buff == NULL) { + [pool drain]; + return NULL; + } - strncpy((char*)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); + strncpy( + (char *)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); - temp_buff[pastedTextSize] = '\0'; + temp_buff[pastedTextSize] = '\0'; - [pool drain]; + [pool drain]; - if (temp_buff) { - return temp_buff; - } - else { - return NULL; - } + if (temp_buff) { + return temp_buff; + } + else { + return NULL; + } } void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const { - NSString *textToCopy; + NSString *textToCopy; - if (selection) return; // for copying the selection, used on X11 + if (selection) + return; // for copying the selection, used on X11 - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; - if (pasteBoard == nil) { - [pool drain]; - return; - } + if (pasteBoard == nil) { + [pool drain]; + return; + } - NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType]; + NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType]; - [pasteBoard declareTypes:supportedTypes owner:nil]; + [pasteBoard declareTypes:supportedTypes owner:nil]; - textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - [pasteBoard setString:textToCopy forType:NSStringPboardType]; + [pasteBoard setString:textToCopy forType:NSStringPboardType]; - [pool drain]; + [pool drain]; } -bool -GHOST_SystemCocoa::supportsNativeDialogs(void) +bool GHOST_SystemCocoa::supportsNativeDialogs(void) { - return false; + return false; } diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h index 19e87bffd78..7f68c801a70 100644 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ b/intern/ghost/intern/GHOST_SystemNULL.h @@ -30,55 +30,109 @@ class GHOST_WindowNULL; class GHOST_SystemNULL : public GHOST_System { -public: + public: + GHOST_SystemNULL() : GHOST_System() + { /* nop */ + } + ~GHOST_SystemNULL() + { /* nop */ + } + bool processEvents(bool waitForEvent) + { + return false; + } + int toggleConsole(int action) + { + return 0; + } + GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const + { + return GHOST_kSuccess; + } + GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const + { + return GHOST_kSuccess; + } + GHOST_TUns8 *getClipboard(bool selection) const + { + return NULL; + } + void putClipboard(GHOST_TInt8 *buffer, bool selection) const + { /* nop */ + } + GHOST_TUns64 getMilliSeconds() const + { + return 0; + } + GHOST_TUns8 getNumDisplays() const + { + return GHOST_TUns8(1); + } + GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const + { + return GHOST_kFailure; + } + GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) + { + return GHOST_kFailure; + } + void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const + { /* nop */ + } + void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const + { /* nop */ + } + bool supportsNativeDialogs(void) + { + return false; + } + GHOST_IContext *createOffscreenContext() + { + return NULL; + } + GHOST_TSuccess disposeContext(GHOST_IContext *context) + { + return GHOST_kFailure; + } - GHOST_SystemNULL() : GHOST_System() { /* nop */ } - ~GHOST_SystemNULL() { /* nop */ } - bool processEvents(bool waitForEvent) { return false; } - int toggleConsole(int action) { return 0; } - GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const { return GHOST_kSuccess; } - GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const { return GHOST_kSuccess; } - GHOST_TUns8 *getClipboard(bool selection) const { return NULL; } - void putClipboard(GHOST_TInt8 *buffer, bool selection) const { /* nop */ } - GHOST_TUns64 getMilliSeconds() const { return 0; } - GHOST_TUns8 getNumDisplays() const { return GHOST_TUns8(1); } - GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const { return GHOST_kFailure; } - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { return GHOST_kFailure; } - void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ } - void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ } - bool supportsNativeDialogs(void) { return false;} - GHOST_IContext *createOffscreenContext() { return NULL; } - GHOST_TSuccess disposeContext(GHOST_IContext *context) { return GHOST_kFailure; } + GHOST_TSuccess init() + { + GHOST_TSuccess success = GHOST_System::init(); - GHOST_TSuccess init() { - GHOST_TSuccess success = GHOST_System::init(); + if (success) { + m_displayManager = new GHOST_DisplayManagerNULL(this); - if (success) { - m_displayManager = new GHOST_DisplayManagerNULL(this); + if (m_displayManager) { + return GHOST_kSuccess; + } + } - if (m_displayManager) { - return GHOST_kSuccess; - } - } + return GHOST_kFailure; + } - return GHOST_kFailure; - } - - 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, - GHOST_GLSettings glSettings, - bool exclusive, - const GHOST_TEmbedderWindowID parentWindow) - { - return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type, - ((glSettings.flags & GHOST_glStereoVisual) != 0), 1); - } + 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, + GHOST_GLSettings glSettings, + bool exclusive, + const GHOST_TEmbedderWindowID parentWindow) + { + return new GHOST_WindowNULL(this, + title, + left, + top, + width, + height, + state, + parentWindow, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0), + 1); + } }; -#endif /* __GHOST_SYSTEMNULL_H__ */ +#endif /* __GHOST_SYSTEMNULL_H__ */ diff --git a/intern/ghost/intern/GHOST_SystemPaths.h b/intern/ghost/intern/GHOST_SystemPaths.h index d8bcc3de99a..04180a143cb 100644 --- a/intern/ghost/intern/GHOST_SystemPaths.h +++ b/intern/ghost/intern/GHOST_SystemPaths.h @@ -26,47 +26,49 @@ #include "GHOST_ISystemPaths.h" -class GHOST_SystemPaths : public GHOST_ISystemPaths -{ -protected: - /** - * Constructor. - * Protected default constructor to force use of static createSystem member. - */ - GHOST_SystemPaths() {} +class GHOST_SystemPaths : public GHOST_ISystemPaths { + protected: + /** + * Constructor. + * Protected default constructor to force use of static createSystem member. + */ + GHOST_SystemPaths() + { + } - /** - * Destructor. - * Protected default constructor to force use of static dispose member. - */ - virtual ~GHOST_SystemPaths() {} + /** + * Destructor. + * Protected default constructor to force use of static dispose member. + */ + virtual ~GHOST_SystemPaths() + { + } -public: + public: + /** + * Determine the base dir in which shared resources are located. It will first try to use + * "unpack and run" path, then look for properly installed path, including versioning. + * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). + */ + virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; - /** - * Determine the base dir in which shared resources are located. It will first try to use - * "unpack and run" path, then look for properly installed path, including versioning. - * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). - */ - virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; + /** + * Determine the base dir in which user configuration is stored, including versioning. + * If needed, it will create the base directory. + * \return Unsigned char string pointing to user dir (eg ~/.blender/). + */ + virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; - /** - * Determine the base dir in which user configuration is stored, including versioning. - * If needed, it will create the base directory. - * \return Unsigned char string pointing to user dir (eg ~/.blender/). - */ - virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; + /** + * Determine the directory of the current binary + * \return Unsigned char string pointing to the binary dir + */ + virtual const GHOST_TUns8 *getBinaryDir() const = 0; - /** - * Determine the directory of the current binary - * \return Unsigned char string pointing to the binary dir - */ - virtual const GHOST_TUns8 *getBinaryDir() const = 0; - - /** - * Add the file to the operating system most recently used files - */ - virtual void addToSystemRecentFiles(const char *filename) const = 0; + /** + * Add the file to the operating system most recently used files + */ + virtual void addToSystemRecentFiles(const char *filename) const = 0; }; #endif diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h index 746f4933012..b66379649e7 100644 --- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h +++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h @@ -21,54 +21,51 @@ * \ingroup GHOST */ - #ifndef __GHOST_SYSTEMPATHSCOCOA_H__ #define __GHOST_SYSTEMPATHSCOCOA_H__ #ifndef __APPLE__ -#error Apple OSX only! -#endif // __APPLE__ - +# error Apple OSX only! +#endif // __APPLE__ #include "GHOST_SystemPaths.h" - class GHOST_SystemPathsCocoa : public GHOST_SystemPaths { -public: - /** - * Constructor. - */ - GHOST_SystemPathsCocoa(); + public: + /** + * Constructor. + */ + GHOST_SystemPathsCocoa(); - /** - * Destructor. - */ - ~GHOST_SystemPathsCocoa(); + /** + * Destructor. + */ + ~GHOST_SystemPathsCocoa(); - /** - * Determine the base dir in which shared resources are located. It will first try to use - * "unpack and run" path, then look for properly installed path, including versioning. - * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). - */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which shared resources are located. It will first try to use + * "unpack and run" path, then look for properly installed path, including versioning. + * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). + */ + const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; - /** - * Determine the base dir in which user configuration is stored, including versioning. - * If needed, it will create the base directory. - * \return Unsigned char string pointing to user dir (eg ~/.blender/). - */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which user configuration is stored, including versioning. + * If needed, it will create the base directory. + * \return Unsigned char string pointing to user dir (eg ~/.blender/). + */ + const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; - /** - * Determine the directory of the current binary - * \return Unsigned char string pointing to the binary dir - */ - const GHOST_TUns8 *getBinaryDir() const; + /** + * Determine the directory of the current binary + * \return Unsigned char string pointing to the binary dir + */ + const GHOST_TUns8 *getBinaryDir() const; - /** - * Add the file to the operating system most recently used files - */ - void addToSystemRecentFiles(const char *filename) const; + /** + * Add the file to the operating system most recently used files + */ + void addToSystemRecentFiles(const char *filename) const; }; -#endif // __GHOST_SYSTEMPATHSCOCOA_H__ +#endif // __GHOST_SYSTEMPATHSCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm index fd6a66f3db3..232ef048351 100644 --- a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm @@ -23,10 +23,8 @@ #include "GHOST_SystemPathsCocoa.h" - #pragma mark initialization/finalization - GHOST_SystemPathsCocoa::GHOST_SystemPathsCocoa() { } @@ -35,73 +33,82 @@ GHOST_SystemPathsCocoa::~GHOST_SystemPathsCocoa() { } - #pragma mark Base directories retrieval -const GHOST_TUns8* GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const +const GHOST_TUns8 *GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const { - static char tempPath[512] = ""; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *basePath; - NSArray *paths; - - paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSLocalDomainMask, YES); - - if ([paths count] > 0) - basePath = [paths objectAtIndex:0]; - else { - [pool drain]; - return NULL; - } - - snprintf(tempPath, sizeof(tempPath), "%s/Blender/%s", [basePath cStringUsingEncoding:NSASCIIStringEncoding], versionstr); - - [pool drain]; - return (GHOST_TUns8*)tempPath; + static char tempPath[512] = ""; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSString *basePath; + NSArray *paths; + + paths = NSSearchPathForDirectoriesInDomains( + NSApplicationSupportDirectory, NSLocalDomainMask, YES); + + if ([paths count] > 0) + basePath = [paths objectAtIndex:0]; + else { + [pool drain]; + return NULL; + } + + snprintf(tempPath, + sizeof(tempPath), + "%s/Blender/%s", + [basePath cStringUsingEncoding:NSASCIIStringEncoding], + versionstr); + + [pool drain]; + return (GHOST_TUns8 *)tempPath; } -const GHOST_TUns8* GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const +const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const { - static char tempPath[512] = ""; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *basePath; - NSArray *paths; - - paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - - if ([paths count] > 0) - basePath = [paths objectAtIndex:0]; - else { - [pool drain]; - return NULL; - } - - snprintf(tempPath, sizeof(tempPath), "%s/Blender/%s", [basePath cStringUsingEncoding:NSASCIIStringEncoding], versionstr); - - [pool drain]; - return (GHOST_TUns8*)tempPath; + static char tempPath[512] = ""; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSString *basePath; + NSArray *paths; + + paths = NSSearchPathForDirectoriesInDomains( + NSApplicationSupportDirectory, NSUserDomainMask, YES); + + if ([paths count] > 0) + basePath = [paths objectAtIndex:0]; + else { + [pool drain]; + return NULL; + } + + snprintf(tempPath, + sizeof(tempPath), + "%s/Blender/%s", + [basePath cStringUsingEncoding:NSASCIIStringEncoding], + versionstr); + + [pool drain]; + return (GHOST_TUns8 *)tempPath; } -const GHOST_TUns8* GHOST_SystemPathsCocoa::getBinaryDir() const +const GHOST_TUns8 *GHOST_SystemPathsCocoa::getBinaryDir() const { - static GHOST_TUns8 tempPath[512] = ""; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *basePath; + static GHOST_TUns8 tempPath[512] = ""; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSString *basePath; - basePath = [[NSBundle mainBundle] bundlePath]; + basePath = [[NSBundle mainBundle] bundlePath]; - if (basePath == nil) { - [pool drain]; - return NULL; - } + if (basePath == nil) { + [pool drain]; + return NULL; + } - strcpy((char*)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding]); + strcpy((char *)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding]); - [pool drain]; - return tempPath; + [pool drain]; + return tempPath; } -void GHOST_SystemPathsCocoa::addToSystemRecentFiles(const char* filename) const +void GHOST_SystemPathsCocoa::addToSystemRecentFiles(const char *filename) const { - /* XXXXX TODO: Implementation for X11 if possible */ + /* XXXXX TODO: Implementation for X11 if possible */ } diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp index 94e058f3dac..94e48f98510 100644 --- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp @@ -30,10 +30,10 @@ #include <sys/time.h> #include <unistd.h> -#include <stdio.h> /* for fprintf only */ -#include <cstdlib> /* for exit */ +#include <stdio.h> /* for fprintf only */ +#include <cstdlib> /* for exit */ -#include <pwd.h> /* for get home without use getenv() */ +#include <pwd.h> /* for get home without use getenv() */ #include <string> using std::string; @@ -54,67 +54,66 @@ GHOST_SystemPathsUnix::~GHOST_SystemPathsUnix() const GHOST_TUns8 *GHOST_SystemPathsUnix::getSystemDir(int, const char *versionstr) const { - /* no prefix assumes a portable build which only uses bundled scripts */ - if (static_path) { - static string system_path = string(static_path) + "/blender/" + versionstr; - return (GHOST_TUns8 *)system_path.c_str(); - } + /* no prefix assumes a portable build which only uses bundled scripts */ + if (static_path) { + static string system_path = string(static_path) + "/blender/" + versionstr; + return (GHOST_TUns8 *)system_path.c_str(); + } - return NULL; + return NULL; } const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *versionstr) const { - static string user_path = ""; - static int last_version = 0; - - /* in blender 2.64, we migrate to XDG. to ensure the copy previous settings - * operator works we give a different path depending on the requested version */ - if (version < 264) { - if (user_path.empty() || last_version != version) { - const char *home = getenv("HOME"); - - last_version = version; - - if (home) { - user_path = string(home) + "/.blender/" + versionstr; - } - else { - return NULL; - } - } - return (GHOST_TUns8 *)user_path.c_str(); - } - else { - if (user_path.empty() || last_version != version) { - const char *home = getenv("XDG_CONFIG_HOME"); - - last_version = version; - - if (home) { - user_path = string(home) + "/blender/" + versionstr; - } - else { - home = getenv("HOME"); - - if (home == NULL) - home = getpwuid(getuid())->pw_dir; - - user_path = string(home) + "/.config/blender/" + versionstr; - } - } - - return (const GHOST_TUns8 *)user_path.c_str(); - } + static string user_path = ""; + static int last_version = 0; + + /* in blender 2.64, we migrate to XDG. to ensure the copy previous settings + * operator works we give a different path depending on the requested version */ + if (version < 264) { + if (user_path.empty() || last_version != version) { + const char *home = getenv("HOME"); + + last_version = version; + + if (home) { + user_path = string(home) + "/.blender/" + versionstr; + } + else { + return NULL; + } + } + return (GHOST_TUns8 *)user_path.c_str(); + } + else { + if (user_path.empty() || last_version != version) { + const char *home = getenv("XDG_CONFIG_HOME"); + + last_version = version; + + if (home) { + user_path = string(home) + "/blender/" + versionstr; + } + else { + home = getenv("HOME"); + + if (home == NULL) + home = getpwuid(getuid())->pw_dir; + + user_path = string(home) + "/.config/blender/" + versionstr; + } + } + + return (const GHOST_TUns8 *)user_path.c_str(); + } } const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const { - return NULL; + return NULL; } void GHOST_SystemPathsUnix::addToSystemRecentFiles(const char * /*filename*/) const { - /* XXXXX TODO: Implementation for X11 if possible */ - + /* XXXXX TODO: Implementation for X11 if possible */ } diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h index 0bd5690fb1a..bcbe24b0d31 100644 --- a/intern/ghost/intern/GHOST_SystemPathsUnix.h +++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h @@ -21,52 +21,49 @@ * \ingroup GHOST */ - #ifndef __GHOST_SYSTEMPATHSUNIX_H__ #define __GHOST_SYSTEMPATHSUNIX_H__ #include "GHOST_SystemPaths.h" #include "../GHOST_Types.h" - class GHOST_SystemPathsUnix : public GHOST_SystemPaths { -public: - - /** - * Constructor - * this class should only be instanciated by GHOST_ISystem. - */ - GHOST_SystemPathsUnix(); + public: + /** + * Constructor + * this class should only be instanciated by GHOST_ISystem. + */ + GHOST_SystemPathsUnix(); - /** - * Destructor. - */ - ~GHOST_SystemPathsUnix(); + /** + * Destructor. + */ + ~GHOST_SystemPathsUnix(); - /** - * Determine the base dir in which shared resources are located. It will first try to use - * "unpack and run" path, then look for properly installed path, including versioning. - * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`). - */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which shared resources are located. It will first try to use + * "unpack and run" path, then look for properly installed path, including versioning. + * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`). + */ + const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; - /** - * Determine the base dir in which user configuration is stored, including versioning. - * If needed, it will create the base directory. - * \return Unsigned char string pointing to user dir (eg `~/.config/.blender/`). - */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which user configuration is stored, including versioning. + * If needed, it will create the base directory. + * \return Unsigned char string pointing to user dir (eg `~/.config/.blender/`). + */ + const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; - /** - * Determine the directory of the current binary - * \return Unsigned char string pointing to the binary dir - */ - const GHOST_TUns8 *getBinaryDir() const; + /** + * Determine the directory of the current binary + * \return Unsigned char string pointing to the binary dir + */ + const GHOST_TUns8 *getBinaryDir() const; - /** - * Add the file to the operating system most recently used files - */ - void addToSystemRecentFiles(const char *filename) const; + /** + * Add the file to the operating system most recently used files + */ + void addToSystemRecentFiles(const char *filename) const; }; -#endif /* __GHOST_SYSTEMPATHSUNIX_H__ */ +#endif /* __GHOST_SYSTEMPATHSUNIX_H__ */ diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp index a403ef294a2..bdc403b947e 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp @@ -21,11 +21,10 @@ * \ingroup GHOST */ - #include "GHOST_SystemPathsWin32.h" #ifndef _WIN32_IE -#define _WIN32_IE 0x0501 +# define _WIN32_IE 0x0501 #endif #include <shlobj.h> #include "utfconv.h" @@ -40,55 +39,57 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32() const GHOST_TUns8 *GHOST_SystemPathsWin32::getSystemDir(int, const char *versionstr) const { - static char knownpath[MAX_PATH * 3 + 128] = {0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/ - wchar_t knownpath_16[MAX_PATH]; + static char knownpath[MAX_PATH * 3 + 128] = { + 0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/ + wchar_t knownpath_16[MAX_PATH]; - HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); + HRESULT hResult = SHGetFolderPathW( + NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); - if (hResult == S_OK) { - conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3); - strcat(knownpath, "\\Blender Foundation\\Blender\\"); - strcat(knownpath, versionstr); - return (GHOST_TUns8*)knownpath; - } + if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3); + strcat(knownpath, "\\Blender Foundation\\Blender\\"); + strcat(knownpath, versionstr); + return (GHOST_TUns8 *)knownpath; + } - return NULL; + return NULL; } const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserDir(int, const char *versionstr) const { - static char knownpath[MAX_PATH * 3 + 128] = {0}; - wchar_t knownpath_16[MAX_PATH]; + static char knownpath[MAX_PATH * 3 + 128] = {0}; + wchar_t knownpath_16[MAX_PATH]; - HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); + HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); - if (hResult == S_OK) { - conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3); - strcat(knownpath, "\\Blender Foundation\\Blender\\"); - strcat(knownpath, versionstr); - return (GHOST_TUns8*)knownpath; - } + if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3); + strcat(knownpath, "\\Blender Foundation\\Blender\\"); + strcat(knownpath, versionstr); + return (GHOST_TUns8 *)knownpath; + } - return NULL; + return NULL; } const GHOST_TUns8 *GHOST_SystemPathsWin32::getBinaryDir() const { - static char fullname[MAX_PATH * 3] = {0}; - wchar_t fullname_16[MAX_PATH * 3]; + static char fullname[MAX_PATH * 3] = {0}; + wchar_t fullname_16[MAX_PATH * 3]; - if (GetModuleFileNameW(0, fullname_16, MAX_PATH)) { - conv_utf_16_to_8(fullname_16, fullname, MAX_PATH * 3); - return (GHOST_TUns8 *)fullname; - } + if (GetModuleFileNameW(0, fullname_16, MAX_PATH)) { + conv_utf_16_to_8(fullname_16, fullname, MAX_PATH * 3); + return (GHOST_TUns8 *)fullname; + } - return NULL; + return NULL; } void GHOST_SystemPathsWin32::addToSystemRecentFiles(const char *filename) const { - /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */ - UTF16_ENCODE(filename); - SHAddToRecentDocs(SHARD_PATHW, filename_16); - UTF16_UN_ENCODE(filename); + /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */ + UTF16_ENCODE(filename); + SHAddToRecentDocs(SHARD_PATHW, filename_16); + UTF16_UN_ENCODE(filename); } diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h index bfb4ef33a68..49d241df633 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.h +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h @@ -21,62 +21,60 @@ * \ingroup GHOST */ - #ifndef __GHOST_SYSTEMPATHSWIN32_H__ #define __GHOST_SYSTEMPATHSWIN32_H__ #ifndef WIN32 -#error WIN32 only! -#endif // WIN32 +# error WIN32 only! +#endif // WIN32 #undef _WIN32_WINNT -#define _WIN32_WINNT 0x501 // require Windows XP or newer +#define _WIN32_WINNT 0x501 // require Windows XP or newer #define WIN32_LEAN_AND_MEAN #include <windows.h> #include "GHOST_SystemPaths.h" - /** * WIN32 Implementation of GHOST_SystemPaths class. * \see GHOST_SystemPaths. */ class GHOST_SystemPathsWin32 : public GHOST_SystemPaths { -public: - /** - * Constructor. - */ - GHOST_SystemPathsWin32(); + public: + /** + * Constructor. + */ + GHOST_SystemPathsWin32(); - /** - * Destructor. - */ - ~GHOST_SystemPathsWin32(); + /** + * Destructor. + */ + ~GHOST_SystemPathsWin32(); - /** - * Determine the base dir in which shared resources are located. It will first try to use - * "unpack and run" path, then look for properly installed path, including versioning. - * \return Unsigned char string pointing to system dir (eg /usr/share/). - */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which shared resources are located. It will first try to use + * "unpack and run" path, then look for properly installed path, including versioning. + * \return Unsigned char string pointing to system dir (eg /usr/share/). + */ + const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; - /** - * Determine the base dir in which user configuration is stored, including versioning. - * If needed, it will create the base directory. - * \return Unsigned char string pointing to user dir (eg ~/). - */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + /** + * Determine the base dir in which user configuration is stored, including versioning. + * If needed, it will create the base directory. + * \return Unsigned char string pointing to user dir (eg ~/). + */ + const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; - /** - * Determine the directory of the current binary - * \return Unsigned char string pointing to the binary dir - */ - const GHOST_TUns8 *getBinaryDir() const; + /** + * Determine the directory of the current binary + * \return Unsigned char string pointing to the binary dir + */ + const GHOST_TUns8 *getBinaryDir() const; - /** - * Add the file to the operating system most recently used files - */ - void addToSystemRecentFiles(const char *filename) const; + /** + * Add the file to the operating system most recently used files + */ + void addToSystemRecentFiles(const char *filename) const; }; -#endif // __GHOST_SYSTEMPATHSWIN32_H__ +#endif // __GHOST_SYSTEMPATHSWIN32_H__ diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 362d78c6dbd..044695c115c 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -31,270 +31,268 @@ #include "GHOST_EventButton.h" #include "GHOST_EventWheel.h" -GHOST_SystemSDL::GHOST_SystemSDL() - : - GHOST_System() +GHOST_SystemSDL::GHOST_SystemSDL() : GHOST_System() { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { - printf("Error initializing SDL: %s\n", SDL_GetError()); - } - - /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */ - /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */ - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { + printf("Error initializing SDL: %s\n", SDL_GetError()); + } + + /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */ + /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */ + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); } GHOST_SystemSDL::~GHOST_SystemSDL() { - SDL_Quit(); + SDL_Quit(); } -GHOST_IWindow * -GHOST_SystemSDL::createWindow(const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - GHOST_GLSettings glSettings, - const bool exclusive, - const GHOST_TEmbedderWindowID parentWindow - ) +GHOST_IWindow *GHOST_SystemSDL::createWindow(const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + GHOST_GLSettings glSettings, + const bool exclusive, + const GHOST_TEmbedderWindowID parentWindow) { - GHOST_WindowSDL *window = NULL; - - window = new GHOST_WindowSDL(this, title, - left, top, width, height, - state, parentWindow, type, - ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive, - glSettings.numOfAASamples); - - if (window) { - if (GHOST_kWindowStateFullScreen == state) { - SDL_Window *sdl_win = window->getSDLWindow(); - SDL_DisplayMode mode; - - static_cast<GHOST_DisplayManagerSDL *> (m_displayManager)->getCurrentDisplayModeSDL(mode); - - SDL_SetWindowDisplayMode(sdl_win, &mode); - SDL_ShowWindow(sdl_win); - SDL_SetWindowFullscreen(sdl_win, SDL_TRUE); - } - - if (window->getValid()) { - m_windowManager->addWindow(window); - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); - } - else { - delete window; - window = NULL; - } - } - return window; + GHOST_WindowSDL *window = NULL; + + window = new GHOST_WindowSDL(this, + title, + left, + top, + width, + height, + state, + parentWindow, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0), + exclusive, + glSettings.numOfAASamples); + + if (window) { + if (GHOST_kWindowStateFullScreen == state) { + SDL_Window *sdl_win = window->getSDLWindow(); + SDL_DisplayMode mode; + + static_cast<GHOST_DisplayManagerSDL *>(m_displayManager)->getCurrentDisplayModeSDL(mode); + + SDL_SetWindowDisplayMode(sdl_win, &mode); + SDL_ShowWindow(sdl_win); + SDL_SetWindowFullscreen(sdl_win, SDL_TRUE); + } + + if (window->getValid()) { + m_windowManager->addWindow(window); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + } + else { + delete window; + window = NULL; + } + } + return window; } -GHOST_TSuccess -GHOST_SystemSDL::init() { - GHOST_TSuccess success = GHOST_System::init(); +GHOST_TSuccess GHOST_SystemSDL::init() +{ + GHOST_TSuccess success = GHOST_System::init(); - if (success) { - m_displayManager = new GHOST_DisplayManagerSDL(this); + if (success) { + m_displayManager = new GHOST_DisplayManagerSDL(this); - if (m_displayManager) { - return GHOST_kSuccess; - } - } + if (m_displayManager) { + return GHOST_kSuccess; + } + } - return GHOST_kFailure; + return GHOST_kFailure; } /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ -void -GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32& width, - GHOST_TUns32& height) const +void GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - SDL_DisplayMode mode; - SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */ - width = mode.w; - height = mode.h; + SDL_DisplayMode mode; + SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */ + width = mode.w; + height = mode.h; } -void -GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width, - GHOST_TUns32& height) const +void GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */ - width = mode.w; - height = mode.h; + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */ + width = mode.w; + height = mode.h; } -GHOST_TUns8 -GHOST_SystemSDL::getNumDisplays() const +GHOST_TUns8 GHOST_SystemSDL::getNumDisplays() const { - return SDL_GetNumVideoDisplays(); + return SDL_GetNumVideoDisplays(); } -GHOST_IContext * -GHOST_SystemSDL::createOffscreenContext() +GHOST_IContext *GHOST_SystemSDL::createOffscreenContext() { - GHOST_Context *context = new GHOST_ContextSDL( - 0, - 0, - NULL, - 0, // profile bit - 3, 3, - GHOST_OPENGL_SDL_CONTEXT_FLAGS, - GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - - return NULL; + GHOST_Context *context = new GHOST_ContextSDL(0, + 0, + NULL, + 0, // profile bit + 3, + 3, + GHOST_OPENGL_SDL_CONTEXT_FLAGS, + GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + + return NULL; } -GHOST_TSuccess -GHOST_SystemSDL::disposeContext(GHOST_IContext *context) +GHOST_TSuccess GHOST_SystemSDL::disposeContext(GHOST_IContext *context) { - delete context; + delete context; - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const +GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys &keys) const { - SDL_Keymod mod = SDL_GetModState(); + SDL_Keymod mod = SDL_GetModState(); - keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0); - keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0); - keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0); - keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0); - keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0); - keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0); - keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0); + keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0); + keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0); + keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0); + keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0); + keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0); + keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0); + keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0); - return GHOST_kSuccess; + return GHOST_kSuccess; } -#define GXMAP(k, x, y) case x: k = y; break +#define GXMAP(k, x, y) \ + case x: \ + k = y; \ + break -static GHOST_TKey -convertSDLKey(SDL_Scancode key) +static GHOST_TKey convertSDLKey(SDL_Scancode key) { - GHOST_TKey type; - - if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) { - type = GHOST_TKey(key - SDL_SCANCODE_A + int(GHOST_kKeyA)); - } - else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) { - type = (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1)); - } - else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) { - type = GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1)); - } - else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) { - type = GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13)); - } - else { - switch (key) { - /* TODO SDL_SCANCODE_NONUSBACKSLASH */ - - GXMAP(type, SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace); - GXMAP(type, SDL_SCANCODE_TAB, GHOST_kKeyTab); - GXMAP(type, SDL_SCANCODE_RETURN, GHOST_kKeyEnter); - GXMAP(type, SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc); - GXMAP(type, SDL_SCANCODE_SPACE, GHOST_kKeySpace); - - GXMAP(type, SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon); - GXMAP(type, SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod); - GXMAP(type, SDL_SCANCODE_COMMA, GHOST_kKeyComma); - GXMAP(type, SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote); - GXMAP(type, SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave); - GXMAP(type, SDL_SCANCODE_MINUS, GHOST_kKeyMinus); - GXMAP(type, SDL_SCANCODE_EQUALS, GHOST_kKeyEqual); - - GXMAP(type, SDL_SCANCODE_SLASH, GHOST_kKeySlash); - GXMAP(type, SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash); - GXMAP(type, SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual); - GXMAP(type, SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket); - GXMAP(type, SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket); - GXMAP(type, SDL_SCANCODE_PAUSE, GHOST_kKeyPause); - - GXMAP(type, SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift); - GXMAP(type, SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift); - GXMAP(type, SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl); - GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl); - GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt); - GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt); - GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS); - GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS); - - GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert); - GXMAP(type, SDL_SCANCODE_DELETE, GHOST_kKeyDelete); - GXMAP(type, SDL_SCANCODE_HOME, GHOST_kKeyHome); - GXMAP(type, SDL_SCANCODE_END, GHOST_kKeyEnd); - GXMAP(type, SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage); - GXMAP(type, SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage); - - GXMAP(type, SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow); - GXMAP(type, SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow); - GXMAP(type, SDL_SCANCODE_UP, GHOST_kKeyUpArrow); - GXMAP(type, SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow); - - GXMAP(type, SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock); - GXMAP(type, SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock); - GXMAP(type, SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock); - GXMAP(type, SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen); - - /* keypad events */ - - /* note, sdl defines a bunch of kp defines I never saw before like - * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */ - GXMAP(type, SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0); - GXMAP(type, SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1); - GXMAP(type, SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2); - GXMAP(type, SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3); - GXMAP(type, SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4); - GXMAP(type, SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5); - GXMAP(type, SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6); - GXMAP(type, SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7); - GXMAP(type, SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8); - GXMAP(type, SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9); - GXMAP(type, SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod); - - GXMAP(type, SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter); - GXMAP(type, SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus); - GXMAP(type, SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus); - GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk); - GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash); - - /* Media keys in some keyboards and laptops with XFree86/Xorg */ - GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay); - GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop); - GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst); - // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst); - GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast); - - default: - printf("Unknown\n"); - type = GHOST_kKeyUnknown; - break; - } - } - - return type; + GHOST_TKey type; + + if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) { + type = GHOST_TKey(key - SDL_SCANCODE_A + int(GHOST_kKeyA)); + } + else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) { + type = (key == SDL_SCANCODE_0) ? GHOST_kKey0 : + GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1)); + } + else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) { + type = GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1)); + } + else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) { + type = GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13)); + } + else { + switch (key) { + /* TODO SDL_SCANCODE_NONUSBACKSLASH */ + + GXMAP(type, SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace); + GXMAP(type, SDL_SCANCODE_TAB, GHOST_kKeyTab); + GXMAP(type, SDL_SCANCODE_RETURN, GHOST_kKeyEnter); + GXMAP(type, SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc); + GXMAP(type, SDL_SCANCODE_SPACE, GHOST_kKeySpace); + + GXMAP(type, SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon); + GXMAP(type, SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod); + GXMAP(type, SDL_SCANCODE_COMMA, GHOST_kKeyComma); + GXMAP(type, SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote); + GXMAP(type, SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave); + GXMAP(type, SDL_SCANCODE_MINUS, GHOST_kKeyMinus); + GXMAP(type, SDL_SCANCODE_EQUALS, GHOST_kKeyEqual); + + GXMAP(type, SDL_SCANCODE_SLASH, GHOST_kKeySlash); + GXMAP(type, SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash); + GXMAP(type, SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual); + GXMAP(type, SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket); + GXMAP(type, SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket); + GXMAP(type, SDL_SCANCODE_PAUSE, GHOST_kKeyPause); + + GXMAP(type, SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift); + GXMAP(type, SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift); + GXMAP(type, SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl); + GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl); + GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt); + GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt); + GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS); + GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS); + + GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert); + GXMAP(type, SDL_SCANCODE_DELETE, GHOST_kKeyDelete); + GXMAP(type, SDL_SCANCODE_HOME, GHOST_kKeyHome); + GXMAP(type, SDL_SCANCODE_END, GHOST_kKeyEnd); + GXMAP(type, SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage); + GXMAP(type, SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage); + + GXMAP(type, SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow); + GXMAP(type, SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow); + GXMAP(type, SDL_SCANCODE_UP, GHOST_kKeyUpArrow); + GXMAP(type, SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow); + + GXMAP(type, SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock); + GXMAP(type, SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock); + GXMAP(type, SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock); + GXMAP(type, SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen); + + /* keypad events */ + + /* note, sdl defines a bunch of kp defines I never saw before like + * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */ + GXMAP(type, SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0); + GXMAP(type, SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1); + GXMAP(type, SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2); + GXMAP(type, SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3); + GXMAP(type, SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4); + GXMAP(type, SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5); + GXMAP(type, SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6); + GXMAP(type, SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7); + GXMAP(type, SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8); + GXMAP(type, SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9); + GXMAP(type, SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod); + + GXMAP(type, SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter); + GXMAP(type, SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus); + GXMAP(type, SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus); + GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk); + GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash); + + /* Media keys in some keyboards and laptops with XFree86/Xorg */ + GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay); + GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop); + GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst); + // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst); + GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast); + + default: + printf("Unknown\n"); + type = GHOST_kKeyUnknown; + break; + } + } + + return type; } #undef GXMAP @@ -304,390 +302,447 @@ convertSDLKey(SDL_Scancode key) */ static SDL_Window *SDL_GetWindowFromID_fallback(Uint32 id) { - SDL_Window *sdl_win = SDL_GetWindowFromID(id); - if (sdl_win == NULL) { - sdl_win = SDL_GL_GetCurrentWindow(); - } - return sdl_win; + SDL_Window *sdl_win = SDL_GetWindowFromID(id); + if (sdl_win == NULL) { + sdl_win = SDL_GL_GetCurrentWindow(); + } + return sdl_win; } -void -GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) +void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) { - GHOST_Event *g_event = NULL; - - switch (sdl_event->type) { - case SDL_WINDOWEVENT: - { - SDL_WindowEvent &sdl_sub_evt = sdl_event->window; - GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); - //assert(window != NULL); // can be NULL on close window. - - switch (sdl_sub_evt.event) { - case SDL_WINDOWEVENT_EXPOSED: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window); - break; - case SDL_WINDOWEVENT_RESIZED: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window); - break; - case SDL_WINDOWEVENT_MOVED: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window); - break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window); - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window); - break; - case SDL_WINDOWEVENT_CLOSE: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window); - break; - } - - break; - } - case SDL_QUIT: - g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL); - break; - - case SDL_MOUSEMOTION: - { - SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion; - SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID); - GHOST_WindowSDL *window = findGhostWindow(sdl_win); - assert(window != NULL); - - int x_win, y_win; - SDL_GetWindowPosition(sdl_win, &x_win, &y_win); - - GHOST_TInt32 x_root = sdl_sub_evt.x + x_win; - GHOST_TInt32 y_root = sdl_sub_evt.y + y_win; + GHOST_Event *g_event = NULL; + + switch (sdl_event->type) { + case SDL_WINDOWEVENT: { + SDL_WindowEvent &sdl_sub_evt = sdl_event->window; + GHOST_WindowSDL *window = findGhostWindow( + SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); + //assert(window != NULL); // can be NULL on close window. + + switch (sdl_sub_evt.event) { + case SDL_WINDOWEVENT_EXPOSED: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window); + break; + case SDL_WINDOWEVENT_RESIZED: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window); + break; + case SDL_WINDOWEVENT_MOVED: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window); + break; + case SDL_WINDOWEVENT_CLOSE: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window); + break; + } + + break; + } + case SDL_QUIT: + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL); + break; + + case SDL_MOUSEMOTION: { + SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion; + SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID); + GHOST_WindowSDL *window = findGhostWindow(sdl_win); + assert(window != NULL); + + int x_win, y_win; + SDL_GetWindowPosition(sdl_win, &x_win, &y_win); + + GHOST_TInt32 x_root = sdl_sub_evt.x + x_win; + GHOST_TInt32 y_root = sdl_sub_evt.y + y_win; #if 0 - if (window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) - { - GHOST_TInt32 x_new = x_root; - GHOST_TInt32 y_new = y_root; - GHOST_TInt32 x_accum, y_accum; - GHOST_Rect bounds; - - /* fallback to window bounds */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) - window->getClientBounds(bounds); - - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ - window->getCursorGrabAccum(x_accum, y_accum); - - // cant use setCursorPosition because the mouse may have no focus! - if (x_new != x_root || y_new != y_root) { - if (1) { //xme.time > m_last_warp) { - /* when wrapping we don't need to add an event because the - * setCursorPosition call will cause a new event after */ - SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */ - window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new)); - // m_last_warp= lastEventTime(xme.time); - } - else { - // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ - SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); - } - - g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new); - } - else { - g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum); - } - } - else + if (window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) + { + GHOST_TInt32 x_new = x_root; + GHOST_TInt32 y_new = y_root; + GHOST_TInt32 x_accum, y_accum; + GHOST_Rect bounds; + + /* fallback to window bounds */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) + window->getClientBounds(bounds); + + /* could also clamp to screen bounds + * wrap with a window outside the view will fail atm */ + bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ + window->getCursorGrabAccum(x_accum, y_accum); + + // cant use setCursorPosition because the mouse may have no focus! + if (x_new != x_root || y_new != y_root) { + if (1) { //xme.time > m_last_warp) { + /* when wrapping we don't need to add an event because the + * setCursorPosition call will cause a new event after */ + SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */ + window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new)); + // m_last_warp= lastEventTime(xme.time); + } + else { + // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ + SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); + } + + g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new); + } + else { + g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum); + } + } + else #endif - { - g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root); - } - break; - } - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEBUTTONDOWN: - { - SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button; - GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft; - GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp; - - GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); - assert(window != NULL); - - /* process rest of normal mouse buttons */ - if (sdl_sub_evt.button == SDL_BUTTON_LEFT) - gbmask = GHOST_kButtonMaskLeft; - else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE) - gbmask = GHOST_kButtonMaskMiddle; - else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT) - gbmask = GHOST_kButtonMaskRight; - /* these buttons are untested! */ - else if (sdl_sub_evt.button == SDL_BUTTON_X1) - gbmask = GHOST_kButtonMaskButton4; - else if (sdl_sub_evt.button == SDL_BUTTON_X2) - gbmask = GHOST_kButtonMaskButton5; - else - break; - - g_event = new GHOST_EventButton(getMilliSeconds(), type, window, gbmask); - break; - } - case SDL_MOUSEWHEEL: - { - SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel; - GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); - assert(window != NULL); - g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y); - break; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key; - SDL_Keycode sym = sdl_sub_evt.keysym.sym; - GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; - - GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); - assert(window != NULL); - - GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode); - /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */ - /* printf("%d\n", sym); */ - if (sym > 127) { - switch (sym) { - case SDLK_KP_DIVIDE: sym = '/'; break; - case SDLK_KP_MULTIPLY: sym = '*'; break; - case SDLK_KP_MINUS: sym = '-'; break; - case SDLK_KP_PLUS: sym = '+'; break; - case SDLK_KP_1: sym = '1'; break; - case SDLK_KP_2: sym = '2'; break; - case SDLK_KP_3: sym = '3'; break; - case SDLK_KP_4: sym = '4'; break; - case SDLK_KP_5: sym = '5'; break; - case SDLK_KP_6: sym = '6'; break; - case SDLK_KP_7: sym = '7'; break; - case SDLK_KP_8: sym = '8'; break; - case SDLK_KP_9: sym = '9'; break; - case SDLK_KP_0: sym = '0'; break; - case SDLK_KP_PERIOD: sym = '.'; break; - default: sym = 0; break; - } - } - else { - if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) { - /* lame US keyboard assumptions */ - if (sym >= 'a' && sym <= ('a' + 32)) { - sym -= 32; - } - else { - switch (sym) { - case '`': sym = '~'; break; - case '1': sym = '!'; break; - case '2': sym = '@'; break; - case '3': sym = '#'; break; - case '4': sym = '$'; break; - case '5': sym = '%'; break; - case '6': sym = '^'; break; - case '7': sym = '&'; break; - case '8': sym = '*'; break; - case '9': sym = '('; break; - case '0': sym = ')'; break; - case '-': sym = '_'; break; - case '=': sym = '+'; break; - case '[': sym = '{'; break; - case ']': sym = '}'; break; - case '\\': sym = '|'; break; - case ';': sym = ':'; break; - case '\'': sym = '"'; break; - case ',': sym = '<'; break; - case '.': sym = '>'; break; - case '/': sym = '?'; break; - default: break; - } - } - } - } - - g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL); - break; - } - } - - if (g_event) { - pushEvent(g_event); - } + { + g_event = new GHOST_EventCursor( + getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root); + } + break; + } + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEBUTTONDOWN: { + SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button; + GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft; + GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown : + GHOST_kEventButtonUp; + + GHOST_WindowSDL *window = findGhostWindow( + SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); + assert(window != NULL); + + /* process rest of normal mouse buttons */ + if (sdl_sub_evt.button == SDL_BUTTON_LEFT) + gbmask = GHOST_kButtonMaskLeft; + else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE) + gbmask = GHOST_kButtonMaskMiddle; + else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT) + gbmask = GHOST_kButtonMaskRight; + /* these buttons are untested! */ + else if (sdl_sub_evt.button == SDL_BUTTON_X1) + gbmask = GHOST_kButtonMaskButton4; + else if (sdl_sub_evt.button == SDL_BUTTON_X2) + gbmask = GHOST_kButtonMaskButton5; + else + break; + + g_event = new GHOST_EventButton(getMilliSeconds(), type, window, gbmask); + break; + } + case SDL_MOUSEWHEEL: { + SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel; + GHOST_WindowSDL *window = findGhostWindow( + SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); + assert(window != NULL); + g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y); + break; + } + case SDL_KEYDOWN: + case SDL_KEYUP: { + SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key; + SDL_Keycode sym = sdl_sub_evt.keysym.sym; + GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : + GHOST_kEventKeyUp; + + GHOST_WindowSDL *window = findGhostWindow( + SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID)); + assert(window != NULL); + + GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode); + /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */ + /* printf("%d\n", sym); */ + if (sym > 127) { + switch (sym) { + case SDLK_KP_DIVIDE: + sym = '/'; + break; + case SDLK_KP_MULTIPLY: + sym = '*'; + break; + case SDLK_KP_MINUS: + sym = '-'; + break; + case SDLK_KP_PLUS: + sym = '+'; + break; + case SDLK_KP_1: + sym = '1'; + break; + case SDLK_KP_2: + sym = '2'; + break; + case SDLK_KP_3: + sym = '3'; + break; + case SDLK_KP_4: + sym = '4'; + break; + case SDLK_KP_5: + sym = '5'; + break; + case SDLK_KP_6: + sym = '6'; + break; + case SDLK_KP_7: + sym = '7'; + break; + case SDLK_KP_8: + sym = '8'; + break; + case SDLK_KP_9: + sym = '9'; + break; + case SDLK_KP_0: + sym = '0'; + break; + case SDLK_KP_PERIOD: + sym = '.'; + break; + default: + sym = 0; + break; + } + } + else { + if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) { + /* lame US keyboard assumptions */ + if (sym >= 'a' && sym <= ('a' + 32)) { + sym -= 32; + } + else { + switch (sym) { + case '`': + sym = '~'; + break; + case '1': + sym = '!'; + break; + case '2': + sym = '@'; + break; + case '3': + sym = '#'; + break; + case '4': + sym = '$'; + break; + case '5': + sym = '%'; + break; + case '6': + sym = '^'; + break; + case '7': + sym = '&'; + break; + case '8': + sym = '*'; + break; + case '9': + sym = '('; + break; + case '0': + sym = ')'; + break; + case '-': + sym = '_'; + break; + case '=': + sym = '+'; + break; + case '[': + sym = '{'; + break; + case ']': + sym = '}'; + break; + case '\\': + sym = '|'; + break; + case ';': + sym = ':'; + break; + case '\'': + sym = '"'; + break; + case ',': + sym = '<'; + break; + case '.': + sym = '>'; + break; + case '/': + sym = '?'; + break; + default: + break; + } + } + } + } + + g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL); + break; + } + } + + if (g_event) { + pushEvent(g_event); + } } -GHOST_TSuccess -GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x, - GHOST_TInt32& y) const +GHOST_TSuccess GHOST_SystemSDL::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - int x_win, y_win; - SDL_Window *win = SDL_GetMouseFocus(); - SDL_GetWindowPosition(win, &x_win, &y_win); + int x_win, y_win; + SDL_Window *win = SDL_GetMouseFocus(); + SDL_GetWindowPosition(win, &x_win, &y_win); - int xi, yi; - SDL_GetMouseState(&xi, &yi); - x = xi + x_win; - y = yi + x_win; + int xi, yi; + SDL_GetMouseState(&xi, &yi); + x = xi + x_win; + y = yi + x_win; - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, - GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { - int x_win, y_win; - SDL_Window *win = SDL_GetMouseFocus(); - SDL_GetWindowPosition(win, &x_win, &y_win); - - SDL_WarpMouseInWindow(win, x - x_win, y - y_win); - return GHOST_kSuccess; -} + int x_win, y_win; + SDL_Window *win = SDL_GetMouseFocus(); + SDL_GetWindowPosition(win, &x_win, &y_win); -bool -GHOST_SystemSDL::generateWindowExposeEvents() -{ - std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin(); - std::vector<GHOST_WindowSDL *>::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) { - //printf("Expose events pushed\n"); - pushEvent(g_event); - anyProcessed = true; - } - } - - m_dirty_windows.clear(); - return anyProcessed; + SDL_WarpMouseInWindow(win, x - x_win, y - y_win); + return GHOST_kSuccess; } - -bool -GHOST_SystemSDL::processEvents(bool waitForEvent) +bool GHOST_SystemSDL::generateWindowExposeEvents() { - // 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() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) { - GHOST_TUns64 next = timerMgr->nextFireTime(); - - if (next == GHOST_kFireTimeNever) { - SDL_WaitEventTimeout(NULL, -1); - //SleepTillEvent(m_display, -1); - } - else { - GHOST_TInt64 maxSleep = next - getMilliSeconds(); - - if (maxSleep >= 0) { - SDL_WaitEventTimeout(NULL, next - getMilliSeconds()); - // SleepTillEvent(m_display, next - getMilliSeconds()); // X11 - } - } - } - - if (timerMgr->fireTimers(getMilliSeconds())) { - anyProcessed = true; - } - - SDL_Event sdl_event; - while (SDL_PollEvent(&sdl_event)) { - processEvent(&sdl_event); - anyProcessed = true; - } - - if (generateWindowExposeEvents()) { - anyProcessed = true; - } - } while (waitForEvent && !anyProcessed); - - return anyProcessed; -} + std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin(); + std::vector<GHOST_WindowSDL *>::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); -GHOST_WindowSDL * -GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win) -{ - if (sdl_win == NULL) 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. + (*w_start)->validate(); - std::vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); + if (g_event) { + //printf("Expose events pushed\n"); + pushEvent(g_event); + anyProcessed = true; + } + } - std::vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); - std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end(); + m_dirty_windows.clear(); + return anyProcessed; +} - for (; win_it != win_end; ++win_it) { - GHOST_WindowSDL *window = static_cast<GHOST_WindowSDL *>(*win_it); - if (window->getSDLWindow() == sdl_win) { - return window; - } - } - return NULL; +bool GHOST_SystemSDL::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() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) { + GHOST_TUns64 next = timerMgr->nextFireTime(); + + if (next == GHOST_kFireTimeNever) { + SDL_WaitEventTimeout(NULL, -1); + //SleepTillEvent(m_display, -1); + } + else { + GHOST_TInt64 maxSleep = next - getMilliSeconds(); + + if (maxSleep >= 0) { + SDL_WaitEventTimeout(NULL, next - getMilliSeconds()); + // SleepTillEvent(m_display, next - getMilliSeconds()); // X11 + } + } + } + + if (timerMgr->fireTimers(getMilliSeconds())) { + anyProcessed = true; + } + + SDL_Event sdl_event; + while (SDL_PollEvent(&sdl_event)) { + processEvent(&sdl_event); + anyProcessed = true; + } + + if (generateWindowExposeEvents()) { + anyProcessed = true; + } + } while (waitForEvent && !anyProcessed); + + return anyProcessed; } +GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win) +{ + if (sdl_win == NULL) + 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. + + std::vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows(); + + std::vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); + std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end(); + + for (; win_it != win_end; ++win_it) { + GHOST_WindowSDL *window = static_cast<GHOST_WindowSDL *>(*win_it); + if (window->getSDLWindow() == sdl_win) { + return window; + } + } + return NULL; +} -void -GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind) +void GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind) { - GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)"); + GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)"); - m_dirty_windows.push_back(bad_wind); + m_dirty_windows.push_back(bad_wind); } -bool -GHOST_SystemSDL::supportsNativeDialogs(void) +bool GHOST_SystemSDL::supportsNativeDialogs(void) { - return false; + return false; } -GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const +GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const { - Uint8 state = SDL_GetMouseState(NULL, NULL); - buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0); - buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0); - buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0); + Uint8 state = SDL_GetMouseState(NULL, NULL); + buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0); + buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0); + buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TUns8 * -GHOST_SystemSDL::getClipboard(bool selection) const +GHOST_TUns8 *GHOST_SystemSDL::getClipboard(bool selection) const { - return (GHOST_TUns8 *)SDL_GetClipboardText(); + return (GHOST_TUns8 *)SDL_GetClipboardText(); } -void -GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const +void GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const { - SDL_SetClipboardText(buffer); + SDL_SetClipboardText(buffer); } -GHOST_TUns64 -GHOST_SystemSDL::getMilliSeconds() +GHOST_TUns64 GHOST_SystemSDL::getMilliSeconds() { - return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */ + return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */ } diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h index fabd15d3164..e51cc3d5b5d 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.h +++ b/intern/ghost/intern/GHOST_SystemSDL.h @@ -30,104 +30,81 @@ #include "GHOST_Event.h" extern "C" { - #include "SDL.h" +#include "SDL.h" } #if !SDL_VERSION_ATLEAST(2, 0, 0) # error "SDL 2.0 or newer is needed to build with Ghost" #endif - class GHOST_WindowSDL; - class GHOST_SystemSDL : public GHOST_System { -public: - - void addDirtyWindow(GHOST_WindowSDL *bad_wind); + public: + void addDirtyWindow(GHOST_WindowSDL *bad_wind); - GHOST_SystemSDL(); - ~GHOST_SystemSDL(); + GHOST_SystemSDL(); + ~GHOST_SystemSDL(); - bool - processEvents(bool waitForEvent); + bool processEvents(bool waitForEvent); - int - toggleConsole(int action) { return 0; } + int toggleConsole(int action) + { + return 0; + } - GHOST_TSuccess - getModifierKeys(GHOST_ModifierKeys& keys) const; + GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const; - GHOST_TSuccess - getButtons(GHOST_Buttons& buttons) const; + GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; - GHOST_TUns8 * - getClipboard(bool selection) const; + GHOST_TUns8 *getClipboard(bool selection) const; - void - putClipboard(GHOST_TInt8 *buffer, bool selection) const; + void putClipboard(GHOST_TInt8 *buffer, bool selection) const; - GHOST_TUns64 - getMilliSeconds(); + GHOST_TUns64 getMilliSeconds(); - GHOST_TUns8 - getNumDisplays() const; + GHOST_TUns8 getNumDisplays() const; - GHOST_TSuccess - getCursorPosition(GHOST_TInt32& x, - GHOST_TInt32& y) const; + GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - GHOST_TSuccess - setCursorPosition(GHOST_TInt32 x, - GHOST_TInt32 y); + GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); - void - getAllDisplayDimensions(GHOST_TUns32& width, - GHOST_TUns32& height) const; + void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; - void - getMainDisplayDimensions(GHOST_TUns32& width, - GHOST_TUns32& height) const; + void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; - GHOST_IContext * - createOffscreenContext(); + GHOST_IContext *createOffscreenContext(); - GHOST_TSuccess - disposeContext(GHOST_IContext *context); + GHOST_TSuccess disposeContext(GHOST_IContext *context); - /** - * Informs if the system provides native dialogs (eg. confirm quit) - */ - virtual bool supportsNativeDialogs(void); -private: + /** + * Informs if the system provides native dialogs (eg. confirm quit) + */ + virtual bool supportsNativeDialogs(void); - GHOST_TSuccess - init(); + private: + GHOST_TSuccess init(); - 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, - GHOST_GLSettings glSettings, - const bool exclusive = false, - const GHOST_TEmbedderWindowID parentWindow = 0 - ); + 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, + GHOST_GLSettings glSettings, + const bool exclusive = false, + const GHOST_TEmbedderWindowID parentWindow = 0); - /* SDL specific */ - GHOST_WindowSDL *findGhostWindow(SDL_Window *sdl_win); + /* SDL specific */ + GHOST_WindowSDL *findGhostWindow(SDL_Window *sdl_win); - bool - generateWindowExposeEvents(); + bool generateWindowExposeEvents(); - void - processEvent(SDL_Event *sdl_event); + void processEvent(SDL_Event *sdl_event); - /// The vector of windows that need to be updated. - std::vector<GHOST_WindowSDL *> m_dirty_windows; + /// The vector of windows that need to be updated. + std::vector<GHOST_WindowSDL *> m_dirty_windows; }; #endif diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 35a9cfac817..95f969bcb67 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - #include "GHOST_SystemWin32.h" #include "GHOST_EventDragnDrop.h" @@ -53,71 +52,71 @@ #endif #ifdef WITH_INPUT_NDOF - #include "GHOST_NDOFManagerWin32.h" +# include "GHOST_NDOFManagerWin32.h" #endif // Key code values not found in winuser.h #ifndef VK_MINUS -#define VK_MINUS 0xBD -#endif // VK_MINUS +# define VK_MINUS 0xBD +#endif // VK_MINUS #ifndef VK_SEMICOLON -#define VK_SEMICOLON 0xBA -#endif // VK_SEMICOLON +# define VK_SEMICOLON 0xBA +#endif // VK_SEMICOLON #ifndef VK_PERIOD -#define VK_PERIOD 0xBE -#endif // VK_PERIOD +# define VK_PERIOD 0xBE +#endif // VK_PERIOD #ifndef VK_COMMA -#define VK_COMMA 0xBC -#endif // VK_COMMA +# define VK_COMMA 0xBC +#endif // VK_COMMA #ifndef VK_QUOTE -#define VK_QUOTE 0xDE -#endif // VK_QUOTE +# define VK_QUOTE 0xDE +#endif // VK_QUOTE #ifndef VK_BACK_QUOTE -#define VK_BACK_QUOTE 0xC0 -#endif // VK_BACK_QUOTE +# define VK_BACK_QUOTE 0xC0 +#endif // VK_BACK_QUOTE #ifndef VK_SLASH -#define VK_SLASH 0xBF -#endif // VK_SLASH +# define VK_SLASH 0xBF +#endif // VK_SLASH #ifndef VK_BACK_SLASH -#define VK_BACK_SLASH 0xDC -#endif // VK_BACK_SLASH +# define VK_BACK_SLASH 0xDC +#endif // VK_BACK_SLASH #ifndef VK_EQUALS -#define VK_EQUALS 0xBB -#endif // VK_EQUALS +# define VK_EQUALS 0xBB +#endif // VK_EQUALS #ifndef VK_OPEN_BRACKET -#define VK_OPEN_BRACKET 0xDB -#endif // 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 +# define VK_CLOSE_BRACKET 0xDD +#endif // VK_CLOSE_BRACKET #ifndef VK_GR_LESS -#define VK_GR_LESS 0xE2 -#endif // VK_GR_LESS +# define VK_GR_LESS 0xE2 +#endif // VK_GR_LESS #ifndef VK_MEDIA_NEXT_TRACK -#define VK_MEDIA_NEXT_TRACK 0xB0 -#endif // VK_MEDIA_NEXT_TRACK +# define VK_MEDIA_NEXT_TRACK 0xB0 +#endif // VK_MEDIA_NEXT_TRACK #ifndef VK_MEDIA_PREV_TRACK -#define VK_MEDIA_PREV_TRACK 0xB1 -#endif // VK_MEDIA_PREV_TRACK +# define VK_MEDIA_PREV_TRACK 0xB1 +#endif // VK_MEDIA_PREV_TRACK #ifndef VK_MEDIA_STOP -#define VK_MEDIA_STOP 0xB2 -#endif // VK_MEDIA_STOP +# define VK_MEDIA_STOP 0xB2 +#endif // VK_MEDIA_STOP #ifndef VK_MEDIA_PLAY_PAUSE -#define VK_MEDIA_PLAY_PAUSE 0xB3 -#endif // VK_MEDIA_PLAY_PAUSE +# define VK_MEDIA_PLAY_PAUSE 0xB3 +#endif // VK_MEDIA_PLAY_PAUSE // Window message newer than Windows 7 #ifndef WM_DPICHANGED -#define WM_DPICHANGED 0x02E0 -#endif // WM_DPICHANGED +# define WM_DPICHANGED 0x02E0 +#endif // WM_DPICHANGED #ifndef WM_POINTERUPDATE -#define WM_POINTERUPDATE 0x0245 -#endif // WM_POINTERUPDATE +# define WM_POINTERUPDATE 0x0245 +#endif // WM_POINTERUPDATE -#define WM_POINTERDOWN 0x0246 -#define WM_POINTERUP 0x0247 +#define WM_POINTERDOWN 0x0246 +#define WM_POINTERUP 0x0247 /* Workaround for some laptop touchpads, some of which seems to * have driver issues which makes it so window function receives @@ -133,175 +132,171 @@ static void initRawInput() { #ifdef WITH_INPUT_NDOF - #define DEVICE_COUNT 2 +# define DEVICE_COUNT 2 #else - #define DEVICE_COUNT 1 +# define DEVICE_COUNT 1 #endif - RAWINPUTDEVICE devices[DEVICE_COUNT]; - memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE)); + RAWINPUTDEVICE devices[DEVICE_COUNT]; + memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE)); - // Initiates WM_INPUT messages from keyboard - // That way GHOST can retrieve true keys - devices[0].usUsagePage = 0x01; - devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ + // Initiates WM_INPUT messages from keyboard + // That way GHOST can retrieve true keys + devices[0].usUsagePage = 0x01; + devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ #ifdef WITH_INPUT_NDOF - // multi-axis mouse (SpaceNavigator, etc.) - devices[1].usUsagePage = 0x01; - devices[1].usUsage = 0x08; + // multi-axis mouse (SpaceNavigator, etc.) + devices[1].usUsagePage = 0x01; + devices[1].usUsage = 0x08; #endif - if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE))) - ; // yay! - else - GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError()); + if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE))) + ; // yay! + else + GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError()); #undef DEVICE_COUNT } #ifndef DPI_ENUMS_DECLARED typedef enum PROCESS_DPI_AWARENESS { - PROCESS_DPI_UNAWARE = 0, - PROCESS_SYSTEM_DPI_AWARE = 1, - PROCESS_PER_MONITOR_DPI_AWARE = 2 + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; typedef enum MONITOR_DPI_TYPE { - MDT_EFFECTIVE_DPI = 0, - MDT_ANGULAR_DPI = 1, - MDT_RAW_DPI = 2, - MDT_DEFAULT = MDT_EFFECTIVE_DPI + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; -#define USER_DEFAULT_SCREEN_DPI 96 +# define USER_DEFAULT_SCREEN_DPI 96 -#define DPI_ENUMS_DECLARED +# define DPI_ENUMS_DECLARED #endif -typedef HRESULT(API * GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); -typedef BOOL(API * GHOST_WIN32_EnableNonClientDpiScaling)(HWND); +typedef HRESULT(API *GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); +typedef BOOL(API *GHOST_WIN32_EnableNonClientDpiScaling)(HWND); -GHOST_SystemWin32::GHOST_SystemWin32() - : m_hasPerformanceCounter(false), m_freq(0), m_start(0) +GHOST_SystemWin32::GHOST_SystemWin32() : m_hasPerformanceCounter(false), m_freq(0), m_start(0) { - m_displayManager = new GHOST_DisplayManagerWin32(); - GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n"); - m_displayManager->initialize(); - - m_consoleStatus = 1; - - // Tell Windows we are per monitor DPI aware. This disables the default - // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI. - HMODULE m_shcore = ::LoadLibrary("Shcore.dll"); - if (m_shcore) { - GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness = - (GHOST_WIN32_SetProcessDpiAwareness) ::GetProcAddress(m_shcore, "SetProcessDpiAwareness"); - - if (fpSetProcessDpiAwareness) { - fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); - } - } - - // Check if current keyboard layout uses AltGr and save keylayout ID for - // specialized handling if keys like VK_OEM_*. I.e. french keylayout - // generates VK_OEM_8 for their exclamation key (key left of right shift) - this->handleKeyboardChange(); - // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. - OleInitialize(0); + m_displayManager = new GHOST_DisplayManagerWin32(); + GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n"); + m_displayManager->initialize(); + + m_consoleStatus = 1; + + // Tell Windows we are per monitor DPI aware. This disables the default + // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI. + HMODULE m_shcore = ::LoadLibrary("Shcore.dll"); + if (m_shcore) { + GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness = + (GHOST_WIN32_SetProcessDpiAwareness)::GetProcAddress(m_shcore, "SetProcessDpiAwareness"); + + if (fpSetProcessDpiAwareness) { + fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); + } + } + + // Check if current keyboard layout uses AltGr and save keylayout ID for + // specialized handling if keys like VK_OEM_*. I.e. french keylayout + // generates VK_OEM_8 for their exclamation key (key left of right shift) + this->handleKeyboardChange(); + // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. + OleInitialize(0); #ifdef WITH_INPUT_NDOF - m_ndofManager = new GHOST_NDOFManagerWin32(*this); + m_ndofManager = new GHOST_NDOFManagerWin32(*this); #endif } GHOST_SystemWin32::~GHOST_SystemWin32() { - // Shutdown COM - OleUninitialize(); - toggleConsole(1); + // Shutdown COM + OleUninitialize(); + toggleConsole(1); } - GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const { - // Hardware does not support high resolution timers. We will use GetTickCount instead then. - if (!m_hasPerformanceCounter) { - return ::GetTickCount(); - } + // 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); + // Retrieve current count + __int64 count = 0; + ::QueryPerformanceCounter((LARGE_INTEGER *)&count); - // Calculate the time passed since system initialization. - __int64 delta = 1000 * (count - m_start); + // Calculate the time passed since system initialization. + __int64 delta = 1000 * (count - m_start); - GHOST_TUns64 t = (GHOST_TUns64)(delta / m_freq); - return t; + 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; + 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); + width = ::GetSystemMetrics(SM_CXSCREEN); + height = ::GetSystemMetrics(SM_CYSCREEN); } void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN); - height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN); + width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN); + height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN); } -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, - GHOST_GLSettings glSettings, - const bool exclusive, - const GHOST_TEmbedderWindowID parentWindow) +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, + GHOST_GLSettings glSettings, + const bool exclusive, + const GHOST_TEmbedderWindowID parentWindow) { - GHOST_WindowWin32 *window = - new GHOST_WindowWin32( - this, - title, - left, - top, - width, - height, - state, - type, - ((glSettings.flags & GHOST_glStereoVisual) != 0), - ((glSettings.flags & GHOST_glAlphaBackground) != 0), - glSettings.numOfAASamples, - parentWindow, - ((glSettings.flags & GHOST_glDebugContext) != 0)); - - if (window->getValid()) { - // Store the pointer to the window - m_windowManager->addWindow(window); - m_windowManager->setActiveWindow(window); - } - else { - GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n"); - delete window; - window = NULL; - } - - return window; + GHOST_WindowWin32 *window = new GHOST_WindowWin32( + this, + title, + left, + top, + width, + height, + state, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0), + ((glSettings.flags & GHOST_glAlphaBackground) != 0), + glSettings.numOfAASamples, + parentWindow, + ((glSettings.flags & GHOST_glDebugContext) != 0)); + + if (window->getValid()) { + // Store the pointer to the window + m_windowManager->addWindow(window); + m_windowManager->setActiveWindow(window); + } + else { + GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n"); + delete window; + window = NULL; + } + + return window; } - /** * Create a new offscreen context. * Never explicitly delete the window, use #disposeContext() instead. @@ -309,85 +304,97 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow( */ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext() { - bool debug_context = false; /* TODO: inform as a parameter */ - - GHOST_Context *context; - - HWND wnd = CreateWindowA("STATIC", - "BlenderGLEW", - WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - 0, 0, 64, 64, - NULL, NULL, - GetModuleHandle(NULL), NULL - ); - - HDC mHDC = GetDC(wnd); - HDC prev_hdc = wglGetCurrentDC(); - HGLRC prev_context = wglGetCurrentContext(); + bool debug_context = false; /* TODO: inform as a parameter */ + + GHOST_Context *context; + + HWND wnd = CreateWindowA("STATIC", + "BlenderGLEW", + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, + 0, + 64, + 64, + NULL, + NULL, + GetModuleHandle(NULL), + NULL); + + HDC mHDC = GetDC(wnd); + HDC prev_hdc = wglGetCurrentDC(); + HGLRC prev_context = wglGetCurrentContext(); #if defined(WITH_GL_PROFILE_CORE) - for (int minor = 5; minor >= 0; --minor) { - context = new GHOST_ContextWGL( - false, true, 0, - wnd, mHDC, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 4, minor, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - goto finished; - } - else { - delete context; - } - } - - context = new GHOST_ContextWGL( - false, true, 0, - wnd, mHDC, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 3, 3, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - goto finished; - } - else { - MessageBox( - NULL, - "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n" - "Installing the latest driver for your graphics card may resolve the issue.\n\n" - "The program will now close.", - "Blender - Unsupported Graphics Card or Driver", - MB_OK | MB_ICONERROR); - delete context; - exit(); - } + for (int minor = 5; minor >= 0; --minor) { + context = new GHOST_ContextWGL(false, + true, + 0, + wnd, + mHDC, + WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 4, + minor, + (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + goto finished; + } + else { + delete context; + } + } + + context = new GHOST_ContextWGL(false, + true, + 0, + wnd, + mHDC, + WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 3, + 3, + (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + goto finished; + } + else { + MessageBox(NULL, + "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n" + "Installing the latest driver for your graphics card may resolve the issue.\n\n" + "The program will now close.", + "Blender - Unsupported Graphics Card or Driver", + MB_OK | MB_ICONERROR); + delete context; + exit(); + } #elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL( - false, true, 0, - NULL, NULL, - 0, // no profile bit - 2, 1, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } + // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile) + // 2.1 ignores the profile bit & is incompatible with core profile + context = new GHOST_ContextWGL(false, + true, + 0, + NULL, + NULL, + 0, // no profile bit + 2, + 1, + (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + else { + delete context; + } #else -# error // must specify either core or compat at build time +# error // must specify either core or compat at build time #endif finished: - wglMakeCurrent(prev_hdc, prev_context); - return context; + wglMakeCurrent(prev_hdc, prev_context); + return context; } /** @@ -397,255 +404,244 @@ finished: */ GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context) { - delete context; + delete context; - return GHOST_kSuccess; + return GHOST_kSuccess; } - bool GHOST_SystemWin32::processEvents(bool waitForEvent) { - MSG msg; - bool hasEventHandled = false; + MSG msg; + bool hasEventHandled = false; - do { - GHOST_TimerManager *timerMgr = getTimerManager(); + do { + GHOST_TimerManager *timerMgr = getTimerManager(); - if (waitForEvent && !::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if (waitForEvent && !::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { #if 1 - ::Sleep(1); + ::Sleep(1); #else - GHOST_TUns64 next = timerMgr->nextFireTime(); - GHOST_TInt64 maxSleep = next - getMilliSeconds(); - - if (next == GHOST_kFireTimeNever) { - ::WaitMessage(); - } - else if (maxSleep >= 0.0) { - ::SetTimer(NULL, 0, maxSleep, NULL); - ::WaitMessage(); - ::KillTimer(NULL, 0); - } + GHOST_TUns64 next = timerMgr->nextFireTime(); + GHOST_TInt64 maxSleep = next - getMilliSeconds(); + + if (next == GHOST_kFireTimeNever) { + ::WaitMessage(); + } + else if (maxSleep >= 0.0) { + ::SetTimer(NULL, 0, maxSleep, NULL); + ::WaitMessage(); + ::KillTimer(NULL, 0); + } #endif - } - - if (timerMgr->fireTimers(getMilliSeconds())) { - hasEventHandled = true; - } - - // Process all the events waiting for us - while (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) != 0) { - // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data. - // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar. - ::TranslateMessage(&msg); - ::DispatchMessageW(&msg); - hasEventHandled = true; - } - } while (waitForEvent && !hasEventHandled); - - return hasEventHandled; + } + + if (timerMgr->fireTimers(getMilliSeconds())) { + hasEventHandled = true; + } + + // Process all the events waiting for us + while (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) != 0) { + // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data. + // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar. + ::TranslateMessage(&msg); + ::DispatchMessageW(&msg); + hasEventHandled = true; + } + } while (waitForEvent && !hasEventHandled); + + return hasEventHandled; } - GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - POINT point; - if (::GetCursorPos(&point)) { - x = point.x; - y = point.y; - return GHOST_kSuccess; - } - return GHOST_kFailure; + POINT point; + if (::GetCursorPos(&point)) { + x = point.x; + y = point.y; + return GHOST_kSuccess; + } + return GHOST_kFailure; } - GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { - if (!::GetActiveWindow()) - return GHOST_kFailure; - return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure; + if (!::GetActiveWindow()) + return GHOST_kFailure; + return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure; } - GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const { - 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); - - bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0; - bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0; - if (lwindown || rwindown) - keys.set(GHOST_kModifierKeyOS, true); - else - keys.set(GHOST_kModifierKeyOS, false); - return GHOST_kSuccess; + 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); + + bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0; + bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0; + if (lwindown || rwindown) + keys.set(GHOST_kModifierKeyOS, true); + else + keys.set(GHOST_kModifierKeyOS, false); + 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; + /* 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); + 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_MBUTTON)) != 0; + buttons.set(GHOST_kButtonMaskMiddle, down); - down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0; - buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down); - return GHOST_kSuccess; + 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(); - - /* Disable scaling on high DPI displays on Vista */ - HMODULE - user32 = ::LoadLibraryA("user32.dll"); - typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)(); - LPFNSETPROCESSDPIAWARE SetProcessDPIAware = - (LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware"); - if (SetProcessDPIAware) - SetProcessDPIAware(); - FreeLibrary(user32); - initRawInput(); - - // 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) { - WNDCLASSW wc = {0}; - 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 = + GHOST_TSuccess success = GHOST_System::init(); + + /* Disable scaling on high DPI displays on Vista */ + HMODULE + user32 = ::LoadLibraryA("user32.dll"); + typedef BOOL(WINAPI * LPFNSETPROCESSDPIAWARE)(); + LPFNSETPROCESSDPIAWARE SetProcessDPIAware = (LPFNSETPROCESSDPIAWARE)GetProcAddress( + user32, "SetProcessDPIAware"); + if (SetProcessDPIAware) + SetProcessDPIAware(); + FreeLibrary(user32); + initRawInput(); + + // 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) { + WNDCLASSW wc = {0}; + 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 = #ifdef INW32_COMPISITING - (HBRUSH)CreateSolidBrush + (HBRUSH)CreateSolidBrush #endif - (0x00000000); - wc.lpszMenuName = 0; - wc.lpszClassName = L"GHOST_WindowClass"; + (0x00000000); + wc.lpszMenuName = 0; + wc.lpszClassName = L"GHOST_WindowClass"; - // Use RegisterClassEx for setting small icon - if (::RegisterClassW(&wc) == 0) { - success = GHOST_kFailure; - } - } + // Use RegisterClassEx for setting small icon + if (::RegisterClassW(&wc) == 0) { + success = GHOST_kFailure; + } + } - return success; + return success; } - GHOST_TSuccess GHOST_SystemWin32::exit() { - return GHOST_System::exit(); + return GHOST_System::exit(); } GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *vk) { - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_TKey key = GHOST_kKeyUnknown; - GHOST_ModifierKeys modifiers; - system->retrieveModifierKeys(modifiers); - - // RI_KEY_BREAK doesn't work for sticky keys release, so we also - // check for the up message - unsigned int msg = raw.data.keyboard.Message; - *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP; - - key = this->convertKey(raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0))); - - // extra handling of modifier keys: don't send repeats out from GHOST - if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) { - bool changed = false; - GHOST_TModifierKeyMask modifier; - switch (key) { - case GHOST_kKeyLeftShift: - { - changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown); - modifier = GHOST_kModifierKeyLeftShift; - break; - } - case GHOST_kKeyRightShift: - { - changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown); - modifier = GHOST_kModifierKeyRightShift; - break; - } - case GHOST_kKeyLeftControl: - { - changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown); - modifier = GHOST_kModifierKeyLeftControl; - break; - } - case GHOST_kKeyRightControl: - { - changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown); - modifier = GHOST_kModifierKeyRightControl; - break; - } - case GHOST_kKeyLeftAlt: - { - changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown); - modifier = GHOST_kModifierKeyLeftAlt; - break; - } - case GHOST_kKeyRightAlt: - { - changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown); - modifier = GHOST_kModifierKeyRightAlt; - break; - } - default: - break; - } - - if (changed) { - modifiers.set(modifier, (bool)*keyDown); - system->storeModifierKeys(modifiers); - } - else { - key = GHOST_kKeyUnknown; - } - } - - - if (vk) *vk = raw.data.keyboard.VKey; - - return key; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + GHOST_TKey key = GHOST_kKeyUnknown; + GHOST_ModifierKeys modifiers; + system->retrieveModifierKeys(modifiers); + + // RI_KEY_BREAK doesn't work for sticky keys release, so we also + // check for the up message + unsigned int msg = raw.data.keyboard.Message; + *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP; + + key = this->convertKey(raw.data.keyboard.VKey, + raw.data.keyboard.MakeCode, + (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0))); + + // extra handling of modifier keys: don't send repeats out from GHOST + if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) { + bool changed = false; + GHOST_TModifierKeyMask modifier; + switch (key) { + case GHOST_kKeyLeftShift: { + changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown); + modifier = GHOST_kModifierKeyLeftShift; + break; + } + case GHOST_kKeyRightShift: { + changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown); + modifier = GHOST_kModifierKeyRightShift; + break; + } + case GHOST_kKeyLeftControl: { + changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown); + modifier = GHOST_kModifierKeyLeftControl; + break; + } + case GHOST_kKeyRightControl: { + changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown); + modifier = GHOST_kModifierKeyRightControl; + break; + } + case GHOST_kKeyLeftAlt: { + changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown); + modifier = GHOST_kModifierKeyLeftAlt; + break; + } + case GHOST_kKeyRightAlt: { + changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown); + modifier = GHOST_kModifierKeyRightAlt; + break; + } + default: + break; + } + + if (changed) { + modifiers.set(modifier, (bool)*keyDown); + system->storeModifierKeys(modifiers); + } + else { + key = GHOST_kKeyUnknown; + } + } + + if (vk) + *vk = raw.data.keyboard.VKey; + + return key; } //! note: this function can be extended to include other exotic cases as they arise. @@ -653,1167 +649,1229 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *v // This is going to be a long list [T42426] GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const { - GHOST_TKey key = GHOST_kKeyUnknown; - switch (PRIMARYLANGID(m_langId)) { - case LANG_FRENCH: - if (vKey == VK_OEM_8) key = GHOST_kKeyF13; // oem key; used purely for shortcuts . - break; - case LANG_ENGLISH: - if (SUBLANGID(m_langId) == SUBLANG_ENGLISH_UK && vKey == VK_OEM_8) // "`¬" - key = GHOST_kKeyAccentGrave; - break; - } - - return key; + GHOST_TKey key = GHOST_kKeyUnknown; + switch (PRIMARYLANGID(m_langId)) { + case LANG_FRENCH: + if (vKey == VK_OEM_8) + key = GHOST_kKeyF13; // oem key; used purely for shortcuts . + break; + case LANG_ENGLISH: + if (SUBLANGID(m_langId) == SUBLANG_ENGLISH_UK && vKey == VK_OEM_8) // "`¬" + key = GHOST_kKeyAccentGrave; + break; + } + + return key; } GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short extend) const { - GHOST_TKey key; - - if ((vKey >= '0') && (vKey <= '9')) { - // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) - key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0); - } - else if ((vKey >= 'A') && (vKey <= 'Z')) { - // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) - key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA); - } - else if ((vKey >= VK_F1) && (vKey <= VK_F24)) { - key = (GHOST_TKey)(vKey - VK_F1 + GHOST_kKeyF1); - } - else { - switch (vKey) { - case VK_RETURN: - key = (extend) ? 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_INSERT: - case VK_NUMPAD0: - key = (extend) ? GHOST_kKeyInsert : GHOST_kKeyNumpad0; break; - case VK_END: - case VK_NUMPAD1: - key = (extend) ? GHOST_kKeyEnd : GHOST_kKeyNumpad1; break; - case VK_DOWN: - case VK_NUMPAD2: - key = (extend) ? GHOST_kKeyDownArrow : GHOST_kKeyNumpad2; break; - case VK_NEXT: - case VK_NUMPAD3: - key = (extend) ? GHOST_kKeyDownPage : GHOST_kKeyNumpad3; break; - case VK_LEFT: - case VK_NUMPAD4: - key = (extend) ? GHOST_kKeyLeftArrow : GHOST_kKeyNumpad4; break; - case VK_CLEAR: - case VK_NUMPAD5: - key = (extend) ? GHOST_kKeyUnknown : GHOST_kKeyNumpad5; break; - case VK_RIGHT: - case VK_NUMPAD6: - key = (extend) ? GHOST_kKeyRightArrow : GHOST_kKeyNumpad6; break; - case VK_HOME: - case VK_NUMPAD7: - key = (extend) ? GHOST_kKeyHome : GHOST_kKeyNumpad7; break; - case VK_UP: - case VK_NUMPAD8: - key = (extend) ? GHOST_kKeyUpArrow : GHOST_kKeyNumpad8; break; - case VK_PRIOR: - case VK_NUMPAD9: - key = (extend) ? GHOST_kKeyUpPage : GHOST_kKeyNumpad9; break; - case VK_DECIMAL: - case VK_DELETE: - key = (extend) ? GHOST_kKeyDelete : GHOST_kKeyNumpadPeriod; 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_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; - case VK_GR_LESS: key = GHOST_kKeyGrLess; break; - - case VK_SHIFT: - /* Check single shift presses */ - if (scanCode == 0x36) { - key = GHOST_kKeyRightShift; - } - else if (scanCode == 0x2a) { - key = GHOST_kKeyLeftShift; - } - else { - /* Must be a combination SHIFT (Left or Right) + a Key - * Ignore this as the next message will contain - * the desired "Key" */ - key = GHOST_kKeyUnknown; - } - break; - case VK_CONTROL: - key = (extend) ? GHOST_kKeyRightControl : GHOST_kKeyLeftControl; - break; - case VK_MENU: - key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt; - break; - case VK_LWIN: - case VK_RWIN: - key = GHOST_kKeyOS; - break; - case VK_NUMLOCK: key = GHOST_kKeyNumLock; break; - case VK_SCROLL: key = GHOST_kKeyScrollLock; break; - case VK_CAPITAL: key = GHOST_kKeyCapsLock; break; - case VK_OEM_8: - key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(vKey, scanCode); - break; - case VK_MEDIA_PLAY_PAUSE: key = GHOST_kKeyMediaPlay; break; - case VK_MEDIA_STOP: key = GHOST_kKeyMediaStop; break; - case VK_MEDIA_PREV_TRACK: key = GHOST_kKeyMediaFirst; break; - case VK_MEDIA_NEXT_TRACK: key = GHOST_kKeyMediaLast; break; - default: - key = GHOST_kKeyUnknown; - break; - } - } - - return key; + GHOST_TKey key; + + if ((vKey >= '0') && (vKey <= '9')) { + // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) + key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0); + } + else if ((vKey >= 'A') && (vKey <= 'Z')) { + // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) + key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA); + } + else if ((vKey >= VK_F1) && (vKey <= VK_F24)) { + key = (GHOST_TKey)(vKey - VK_F1 + GHOST_kKeyF1); + } + else { + switch (vKey) { + case VK_RETURN: + key = (extend) ? 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_INSERT: + case VK_NUMPAD0: + key = (extend) ? GHOST_kKeyInsert : GHOST_kKeyNumpad0; + break; + case VK_END: + case VK_NUMPAD1: + key = (extend) ? GHOST_kKeyEnd : GHOST_kKeyNumpad1; + break; + case VK_DOWN: + case VK_NUMPAD2: + key = (extend) ? GHOST_kKeyDownArrow : GHOST_kKeyNumpad2; + break; + case VK_NEXT: + case VK_NUMPAD3: + key = (extend) ? GHOST_kKeyDownPage : GHOST_kKeyNumpad3; + break; + case VK_LEFT: + case VK_NUMPAD4: + key = (extend) ? GHOST_kKeyLeftArrow : GHOST_kKeyNumpad4; + break; + case VK_CLEAR: + case VK_NUMPAD5: + key = (extend) ? GHOST_kKeyUnknown : GHOST_kKeyNumpad5; + break; + case VK_RIGHT: + case VK_NUMPAD6: + key = (extend) ? GHOST_kKeyRightArrow : GHOST_kKeyNumpad6; + break; + case VK_HOME: + case VK_NUMPAD7: + key = (extend) ? GHOST_kKeyHome : GHOST_kKeyNumpad7; + break; + case VK_UP: + case VK_NUMPAD8: + key = (extend) ? GHOST_kKeyUpArrow : GHOST_kKeyNumpad8; + break; + case VK_PRIOR: + case VK_NUMPAD9: + key = (extend) ? GHOST_kKeyUpPage : GHOST_kKeyNumpad9; + break; + case VK_DECIMAL: + case VK_DELETE: + key = (extend) ? GHOST_kKeyDelete : GHOST_kKeyNumpadPeriod; + 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_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; + case VK_GR_LESS: + key = GHOST_kKeyGrLess; + break; + + case VK_SHIFT: + /* Check single shift presses */ + if (scanCode == 0x36) { + key = GHOST_kKeyRightShift; + } + else if (scanCode == 0x2a) { + key = GHOST_kKeyLeftShift; + } + else { + /* Must be a combination SHIFT (Left or Right) + a Key + * Ignore this as the next message will contain + * the desired "Key" */ + key = GHOST_kKeyUnknown; + } + break; + case VK_CONTROL: + key = (extend) ? GHOST_kKeyRightControl : GHOST_kKeyLeftControl; + break; + case VK_MENU: + key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt; + break; + case VK_LWIN: + case VK_RWIN: + key = GHOST_kKeyOS; + break; + case VK_NUMLOCK: + key = GHOST_kKeyNumLock; + break; + case VK_SCROLL: + key = GHOST_kKeyScrollLock; + break; + case VK_CAPITAL: + key = GHOST_kKeyCapsLock; + break; + case VK_OEM_8: + key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(vKey, scanCode); + break; + case VK_MEDIA_PLAY_PAUSE: + key = GHOST_kKeyMediaPlay; + break; + case VK_MEDIA_STOP: + key = GHOST_kKeyMediaStop; + break; + case VK_MEDIA_PREV_TRACK: + key = GHOST_kKeyMediaFirst; + break; + case VK_MEDIA_NEXT_TRACK: + key = GHOST_kKeyMediaLast; + break; + default: + key = GHOST_kKeyUnknown; + break; + } + } + + return key; } -GHOST_EventButton *GHOST_SystemWin32::processButtonEvent( - GHOST_TEventType type, - GHOST_WindowWin32 *window, - GHOST_TButtonMask mask) +GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TButtonMask mask) { - GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem(); - if (window->useTabletAPI(GHOST_kTabletNative)) { - window->setTabletData(NULL); - } - return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask); + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + if (window->useTabletAPI(GHOST_kTabletNative)) { + window->setTabletData(NULL); + } + return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask); } -GHOST_Event *GHOST_SystemWin32::processPointerEvent( - GHOST_TEventType type, - GHOST_WindowWin32 *window, - WPARAM wParam, - LPARAM lParam, - bool& eventHandled) +GHOST_Event *GHOST_SystemWin32::processPointerEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + WPARAM wParam, + LPARAM lParam, + bool &eventHandled) { - GHOST_PointerInfoWin32 pointerInfo; - GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem(); - - if (!window->useTabletAPI(GHOST_kTabletNative)) { - return NULL; - } - - if (window->getPointerInfo(&pointerInfo, wParam, lParam) != GHOST_kSuccess) { - return NULL; - } - - if (!pointerInfo.isPrimary) { - eventHandled = true; - return NULL; // For multi-touch displays we ignore these events - } - - system->setCursorPosition(pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y); - - switch (type) { - case GHOST_kEventButtonDown: - window->setTabletData(&pointerInfo.tabletData); - eventHandled = true; - return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonDown, window, pointerInfo.buttonMask); - case GHOST_kEventButtonUp: - eventHandled = true; - return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonUp, window, pointerInfo.buttonMask); - case GHOST_kEventCursorMove: - window->setTabletData(&pointerInfo.tabletData); - eventHandled = true; - return new GHOST_EventCursor(system->getMilliSeconds(), GHOST_kEventCursorMove, window, - pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y); - default: - return NULL; - } + GHOST_PointerInfoWin32 pointerInfo; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + + if (!window->useTabletAPI(GHOST_kTabletNative)) { + return NULL; + } + + if (window->getPointerInfo(&pointerInfo, wParam, lParam) != GHOST_kSuccess) { + return NULL; + } + + if (!pointerInfo.isPrimary) { + eventHandled = true; + return NULL; // For multi-touch displays we ignore these events + } + + system->setCursorPosition(pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y); + + switch (type) { + case GHOST_kEventButtonDown: + window->setTabletData(&pointerInfo.tabletData); + eventHandled = true; + return new GHOST_EventButton( + system->getMilliSeconds(), GHOST_kEventButtonDown, window, pointerInfo.buttonMask); + case GHOST_kEventButtonUp: + eventHandled = true; + return new GHOST_EventButton( + system->getMilliSeconds(), GHOST_kEventButtonUp, window, pointerInfo.buttonMask); + case GHOST_kEventCursorMove: + window->setTabletData(&pointerInfo.tabletData); + eventHandled = true; + return new GHOST_EventCursor(system->getMilliSeconds(), + GHOST_kEventCursorMove, + window, + pointerInfo.pixelLocation.x, + pointerInfo.pixelLocation.y); + default: + return NULL; + } } -GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window) +GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window) { - GHOST_TInt32 x_screen, y_screen; - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *) getSystem(); - - system->getCursorPosition(x_screen, y_screen); - - /* TODO: CHECK IF THIS IS A TABLET EVENT */ - bool is_tablet = false; - - if (is_tablet == false && window->getCursorGrabModeIsWarp()) { - GHOST_TInt32 x_new = x_screen; - GHOST_TInt32 y_new = y_screen; - GHOST_TInt32 x_accum, y_accum; - GHOST_Rect bounds; - - /* fallback to window bounds */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { - window->getClientBounds(bounds); - } - - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - - bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */ - - window->getCursorGrabAccum(x_accum, y_accum); - if (x_new != x_screen || y_new != y_screen) { - /* when wrapping we don't need to add an event because the - * setCursorPosition call will cause a new event after */ - system->setCursorPosition(x_new, y_new); /* wrap */ - window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new)); - } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen + x_accum, - y_screen + y_accum - ); - } - - } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen, - y_screen - ); - } - return NULL; + GHOST_TInt32 x_screen, y_screen; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + + system->getCursorPosition(x_screen, y_screen); + + /* TODO: CHECK IF THIS IS A TABLET EVENT */ + bool is_tablet = false; + + if (is_tablet == false && window->getCursorGrabModeIsWarp()) { + GHOST_TInt32 x_new = x_screen; + GHOST_TInt32 y_new = y_screen; + GHOST_TInt32 x_accum, y_accum; + GHOST_Rect bounds; + + /* fallback to window bounds */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { + window->getClientBounds(bounds); + } + + /* could also clamp to screen bounds + * wrap with a window outside the view will fail atm */ + + bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */ + + window->getCursorGrabAccum(x_accum, y_accum); + if (x_new != x_screen || y_new != y_screen) { + /* when wrapping we don't need to add an event because the + * setCursorPosition call will cause a new event after */ + system->setCursorPosition(x_new, y_new); /* wrap */ + window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new)); + } + else { + return new GHOST_EventCursor(system->getMilliSeconds(), + GHOST_kEventCursorMove, + window, + x_screen + x_accum, + y_screen + y_accum); + } + } + else { + return new GHOST_EventCursor( + system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen); + } + return NULL; } - void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam) { - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - - int acc = system->m_wheelDeltaAccum; - int delta = GET_WHEEL_DELTA_WPARAM(wParam); - - if (acc * delta < 0) { - // scroll direction reversed. - acc = 0; - } - acc += delta; - int direction = (acc >= 0) ? 1 : -1; - acc = abs(acc); - - while (acc >= WHEEL_DELTA) { - system->pushEvent(new GHOST_EventWheel(system->getMilliSeconds(), window, direction)); - acc -= WHEEL_DELTA; - } - system->m_wheelDeltaAccum = acc * direction; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + + int acc = system->m_wheelDeltaAccum; + int delta = GET_WHEEL_DELTA_WPARAM(wParam); + + if (acc * delta < 0) { + // scroll direction reversed. + acc = 0; + } + acc += delta; + int direction = (acc >= 0) ? 1 : -1; + acc = abs(acc); + + while (acc >= WHEEL_DELTA) { + system->pushEvent(new GHOST_EventWheel(system->getMilliSeconds(), window, direction)); + acc -= WHEEL_DELTA; + } + system->m_wheelDeltaAccum = acc * direction; } - GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw) { - int keyDown = 0; - char vk; - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_TKey key = system->hardKey(raw, &keyDown, &vk); - GHOST_EventKey *event; - - if (key != GHOST_kKeyUnknown) { - char utf8_char[6] = {0}; - char ascii = 0; - - wchar_t utf16[3] = {0}; - BYTE state[256] = {0}; - int r; - GetKeyboardState((PBYTE)state); - - // don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition. - if (MapVirtualKeyW(vk, 2) != 0) { - // todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes. - if ((r = ToUnicodeEx(vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) { - if ((r > 0 && r < 3)) { - utf16[r] = 0; - conv_utf_16_to_8(utf16, utf8_char, 6); - } - else if (r == -1) { - utf8_char[0] = '\0'; - } - } - } - - if (!keyDown) { - utf8_char[0] = '\0'; - ascii = '\0'; - } - else { - ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0]; - } - - event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, ascii, utf8_char); - - // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter - } - else { - event = NULL; - } - return event; + int keyDown = 0; + char vk; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + GHOST_TKey key = system->hardKey(raw, &keyDown, &vk); + GHOST_EventKey *event; + + if (key != GHOST_kKeyUnknown) { + char utf8_char[6] = {0}; + char ascii = 0; + + wchar_t utf16[3] = {0}; + BYTE state[256] = {0}; + int r; + GetKeyboardState((PBYTE)state); + + // don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition. + if (MapVirtualKeyW(vk, 2) != 0) { + // todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes. + if ((r = ToUnicodeEx( + vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) { + if ((r > 0 && r < 3)) { + utf16[r] = 0; + conv_utf_16_to_8(utf16, utf8_char, 6); + } + else if (r == -1) { + utf8_char[0] = '\0'; + } + } + } + + if (!keyDown) { + utf8_char[0] = '\0'; + ascii = '\0'; + } + else { + ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0]; + } + + event = new GHOST_EventKey(system->getMilliSeconds(), + keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, + window, + key, + ascii, + utf8_char); + + // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter + } + else { + event = NULL; + } + return event; } - -GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window) +GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window) { - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - if (type == GHOST_kEventWindowActivate) { - system->getWindowManager()->setActiveWindow(window); - window->bringTabletContextToFront(); - } + if (type == GHOST_kEventWindowActivate) { + system->getWindowManager()->setActiveWindow(window); + window->bringTabletContextToFront(); + } - return new GHOST_Event(system->getMilliSeconds(), type, window); + return new GHOST_Event(system->getMilliSeconds(), type, window); } #ifdef WITH_INPUT_IME -GHOST_Event *GHOST_SystemWin32::processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data) +GHOST_Event *GHOST_SystemWin32::processImeEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TEventImeData *data) { - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - return new GHOST_EventIME(system->getMilliSeconds(), type, window, data); + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + return new GHOST_EventIME(system->getMilliSeconds(), type, window, data); } #endif - -GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent( - GHOST_TEventType eventType, - GHOST_TDragnDropTypes draggedObjectType, - GHOST_WindowWin32 *window, - int mouseX, int mouseY, - void *data) +GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType, + GHOST_TDragnDropTypes draggedObjectType, + GHOST_WindowWin32 *window, + int mouseX, + int mouseY, + void *data) { - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(), - eventType, - draggedObjectType, - window, mouseX, mouseY, data) - ); + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + return system->pushEvent(new GHOST_EventDragnDrop( + system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data)); } void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax) { - minmax->ptMinTrackSize.x = 320; - minmax->ptMinTrackSize.y = 240; + minmax->ptMinTrackSize.x = 320; + minmax->ptMinTrackSize.y = 240; } #ifdef WITH_INPUT_NDOF bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) { - bool eventSent = false; - GHOST_TUns64 now = getMilliSeconds(); - - static bool firstEvent = true; - if (firstEvent) { // determine exactly which device is plugged in - RID_DEVICE_INFO info; - unsigned infoSize = sizeof(RID_DEVICE_INFO); - info.cbSize = infoSize; - - GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize); - if (info.dwType == RIM_TYPEHID) - m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId); - else - GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n"); - - firstEvent = false; - } - - // The NDOF manager sends button changes immediately, and *pretends* to - // send motion. Mark as 'sent' so motion will always get dispatched. - eventSent = true; - - BYTE const *data = raw.data.hid.bRawData; - - BYTE packetType = data[0]; - switch (packetType) { - case 1: // translation - { - const short *axis = (short *)(data + 1); - // massage into blender view coords (same goes for rotation) - const int t[3] = {axis[0], -axis[2], axis[1]}; - m_ndofManager->updateTranslation(t, now); - - if (raw.data.hid.dwSizeHid == 13) { - // this report also includes rotation - const int r[3] = {-axis[3], axis[5], -axis[4]}; - m_ndofManager->updateRotation(r, now); - - // I've never gotten one of these, has anyone else? - GHOST_PRINT("ndof: combined T + R\n"); - } - break; - } - case 2: // rotation - { - const short *axis = (short *)(data + 1); - const int r[3] = {-axis[0], axis[2], -axis[1]}; - m_ndofManager->updateRotation(r, now); - break; - } - case 3: // buttons - { - int button_bits; - memcpy(&button_bits, data + 1, sizeof(button_bits)); - m_ndofManager->updateButtons(button_bits, now); - break; - } - } - return eventSent; + bool eventSent = false; + GHOST_TUns64 now = getMilliSeconds(); + + static bool firstEvent = true; + if (firstEvent) { // determine exactly which device is plugged in + RID_DEVICE_INFO info; + unsigned infoSize = sizeof(RID_DEVICE_INFO); + info.cbSize = infoSize; + + GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize); + if (info.dwType == RIM_TYPEHID) + m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId); + else + GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n"); + + firstEvent = false; + } + + // The NDOF manager sends button changes immediately, and *pretends* to + // send motion. Mark as 'sent' so motion will always get dispatched. + eventSent = true; + + BYTE const *data = raw.data.hid.bRawData; + + BYTE packetType = data[0]; + switch (packetType) { + case 1: // translation + { + const short *axis = (short *)(data + 1); + // massage into blender view coords (same goes for rotation) + const int t[3] = {axis[0], -axis[2], axis[1]}; + m_ndofManager->updateTranslation(t, now); + + if (raw.data.hid.dwSizeHid == 13) { + // this report also includes rotation + const int r[3] = {-axis[3], axis[5], -axis[4]}; + m_ndofManager->updateRotation(r, now); + + // I've never gotten one of these, has anyone else? + GHOST_PRINT("ndof: combined T + R\n"); + } + break; + } + case 2: // rotation + { + const short *axis = (short *)(data + 1); + const int r[3] = {-axis[0], axis[2], -axis[1]}; + m_ndofManager->updateRotation(r, now); + break; + } + case 3: // buttons + { + int button_bits; + memcpy(&button_bits, data + 1, sizeof(button_bits)); + m_ndofManager->updateButtons(button_bits, now); + break; + } + } + return eventSent; } -#endif // WITH_INPUT_NDOF +#endif // WITH_INPUT_NDOF LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - GHOST_Event *event = NULL; - bool eventHandled = false; + GHOST_Event *event = NULL; + bool eventHandled = false; - LRESULT lResult = 0; - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_EventManager *eventManager = system->getEventManager(); - GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized"); + LRESULT lResult = 0; + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + GHOST_EventManager *eventManager = system->getEventManager(); + GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized"); - if (hwnd) { + if (hwnd) { #if 0 - // Disabled due to bug in Intel drivers, see T51959 - if(msg == WM_NCCREATE) { - // Tell Windows to automatically handle scaling of non-client areas - // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10 - HMODULE m_user32 = ::LoadLibrary("User32.dll"); - if (m_user32) { - GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling = - (GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling"); - - if (fpEnableNonClientDpiScaling) { - fpEnableNonClientDpiScaling(hwnd); - } - } - } + // Disabled due to bug in Intel drivers, see T51959 + if(msg == WM_NCCREATE) { + // Tell Windows to automatically handle scaling of non-client areas + // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10 + HMODULE m_user32 = ::LoadLibrary("User32.dll"); + if (m_user32) { + GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling = + (GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling"); + + if (fpEnableNonClientDpiScaling) { + fpEnableNonClientDpiScaling(hwnd); + } + } + } #endif - GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (window) { - switch (msg) { - // we need to check if new key layout has AltGr - case WM_INPUTLANGCHANGE: - { - system->handleKeyboardChange(); + GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (window) { + switch (msg) { + // we need to check if new key layout has AltGr + case WM_INPUTLANGCHANGE: { + system->handleKeyboardChange(); #ifdef WITH_INPUT_IME - window->getImeInput()->SetInputLanguage(); + window->getImeInput()->SetInputLanguage(); #endif - break; - } - //////////////////////////////////////////////////////////////////////// - // Keyboard events, processed - //////////////////////////////////////////////////////////////////////// - case WM_INPUT: - { - // check WM_INPUT from input sink when ghost window is not in the foreground - if (wParam == RIM_INPUTSINK) { - if (GetFocus() != hwnd) // WM_INPUT message not for this window - return 0; - } //else wParam == RIM_INPUT - - RAWINPUT raw; - RAWINPUT *raw_ptr = &raw; - UINT rawSize = sizeof(RAWINPUT); - - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER)); - - switch (raw.header.dwType) { - case RIM_TYPEKEYBOARD: - event = processKeyEvent(window, raw); - if (!event) { - GHOST_PRINT("GHOST_SystemWin32::wndProc: key event "); - GHOST_PRINT(msg); - GHOST_PRINT(" key ignored\n"); - } - break; + break; + } + //////////////////////////////////////////////////////////////////////// + // Keyboard events, processed + //////////////////////////////////////////////////////////////////////// + case WM_INPUT: { + // check WM_INPUT from input sink when ghost window is not in the foreground + if (wParam == RIM_INPUTSINK) { + if (GetFocus() != hwnd) // WM_INPUT message not for this window + return 0; + } //else wParam == RIM_INPUT + + RAWINPUT raw; + RAWINPUT *raw_ptr = &raw; + UINT rawSize = sizeof(RAWINPUT); + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER)); + + switch (raw.header.dwType) { + case RIM_TYPEKEYBOARD: + event = processKeyEvent(window, raw); + if (!event) { + GHOST_PRINT("GHOST_SystemWin32::wndProc: key event "); + GHOST_PRINT(msg); + GHOST_PRINT(" key ignored\n"); + } + break; #ifdef WITH_INPUT_NDOF - case RIM_TYPEHID: - if (system->processNDOF(raw)) { - eventHandled = true; - } - break; + case RIM_TYPEHID: + if (system->processNDOF(raw)) { + eventHandled = true; + } + break; #endif - } - break; - } + } + break; + } #ifdef WITH_INPUT_IME - //////////////////////////////////////////////////////////////////////// - // IME events, processed, read more in GHOST_IME.h - //////////////////////////////////////////////////////////////////////// - case WM_IME_SETCONTEXT: - { - GHOST_ImeWin32 *ime = window->getImeInput(); - ime->SetInputLanguage(); - ime->CreateImeWindow(hwnd); - ime->CleanupComposition(hwnd); - ime->CheckFirst(hwnd); - break; - } - case WM_IME_STARTCOMPOSITION: - { - GHOST_ImeWin32 *ime = window->getImeInput(); - eventHandled = true; - /* remove input event before start comp event, avoid redundant input */ - eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); - ime->CreateImeWindow(hwnd); - ime->ResetComposition(hwnd); - event = processImeEvent( - GHOST_kEventImeCompositionStart, - window, - &ime->eventImeData); - break; - } - case WM_IME_COMPOSITION: - { - GHOST_ImeWin32 *ime = window->getImeInput(); - eventHandled = true; - ime->UpdateImeWindow(hwnd); - ime->UpdateInfo(hwnd); - if (ime->eventImeData.result_len) { - /* remove redundant IME event */ - eventManager->removeTypeEvents(GHOST_kEventImeComposition, window); - } - event = processImeEvent( - GHOST_kEventImeComposition, - window, - &ime->eventImeData); - break; - } - case WM_IME_ENDCOMPOSITION: - { - GHOST_ImeWin32 *ime = window->getImeInput(); - eventHandled = true; - /* remove input event after end comp event, avoid redundant input */ - eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); - ime->ResetComposition(hwnd); - ime->DestroyImeWindow(hwnd); - event = processImeEvent( - GHOST_kEventImeCompositionEnd, - window, - &ime->eventImeData); - break; - } + //////////////////////////////////////////////////////////////////////// + // IME events, processed, read more in GHOST_IME.h + //////////////////////////////////////////////////////////////////////// + case WM_IME_SETCONTEXT: { + GHOST_ImeWin32 *ime = window->getImeInput(); + ime->SetInputLanguage(); + ime->CreateImeWindow(hwnd); + ime->CleanupComposition(hwnd); + ime->CheckFirst(hwnd); + break; + } + case WM_IME_STARTCOMPOSITION: { + GHOST_ImeWin32 *ime = window->getImeInput(); + eventHandled = true; + /* remove input event before start comp event, avoid redundant input */ + eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); + ime->CreateImeWindow(hwnd); + ime->ResetComposition(hwnd); + event = processImeEvent(GHOST_kEventImeCompositionStart, window, &ime->eventImeData); + break; + } + case WM_IME_COMPOSITION: { + GHOST_ImeWin32 *ime = window->getImeInput(); + eventHandled = true; + ime->UpdateImeWindow(hwnd); + ime->UpdateInfo(hwnd); + if (ime->eventImeData.result_len) { + /* remove redundant IME event */ + eventManager->removeTypeEvents(GHOST_kEventImeComposition, window); + } + event = processImeEvent(GHOST_kEventImeComposition, window, &ime->eventImeData); + break; + } + case WM_IME_ENDCOMPOSITION: { + GHOST_ImeWin32 *ime = window->getImeInput(); + eventHandled = true; + /* remove input event after end comp event, avoid redundant input */ + eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); + ime->ResetComposition(hwnd); + ime->DestroyImeWindow(hwnd); + event = processImeEvent(GHOST_kEventImeCompositionEnd, window, &ime->eventImeData); + break; + } #endif /* WITH_INPUT_IME */ - //////////////////////////////////////////////////////////////////////// - // Keyboard events, ignored - //////////////////////////////////////////////////////////////////////// - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - /* These functions were replaced by WM_INPUT*/ - case WM_CHAR: - /* The WM_CHAR message is posted to the window with the keyboard focus when - * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR - * contains the character code of the key that was pressed. - */ - case WM_DEADCHAR: - /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a - * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR - * specifies a character code generated by a dead key. A dead key is a key that - * generates a character, such as the umlaut (double-dot), that is combined with - * another character to form a composite character. For example, the umlaut-O - * character (Ö) is generated by typing the dead key for the umlaut character, and - * then typing the O key. - */ - break; - 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. - */ - case WM_SYSCHAR: - /* The WM_SYSCHAR message is sent to the window with the keyboard focus when - * a WM_SYSCHAR message is translated by the TranslateMessage function. - * WM_SYSCHAR specifies the character code of a dead key - that is, - * a dead key that is pressed while holding down the alt key. - * To prevent the sound, DefWindowProc must be avoided by return - */ - break; - case WM_SYSCOMMAND: - /* The WM_SYSCHAR message is sent to the window when system commands such as - * maximize, minimize or close the window are triggered. Also it is sent when ALT - * button is press for menu. To prevent this we must return preventing DefWindowProc. - */ - if (wParam == SC_KEYMENU) { - eventHandled = true; - } - break; - //////////////////////////////////////////////////////////////////////// - // Tablet events, processed - //////////////////////////////////////////////////////////////////////// - case WT_PACKET: - window->processWin32TabletEvent(wParam, lParam); - break; - case WT_CSRCHANGE: - case WT_PROXIMITY: - window->processWin32TabletInitEvent(); - break; - //////////////////////////////////////////////////////////////////////// - // Pointer events, processed - //////////////////////////////////////////////////////////////////////// - case WM_POINTERDOWN: - event = processPointerEvent(GHOST_kEventButtonDown, window, wParam, lParam, eventHandled); - if (event && eventHandled) { - window->registerMouseClickEvent(0); - } - break; - case WM_POINTERUP: - event = processPointerEvent(GHOST_kEventButtonUp, window, wParam, lParam, eventHandled); - if (event && eventHandled) { - window->registerMouseClickEvent(1); - } - break; - case WM_POINTERUPDATE: - event = processPointerEvent(GHOST_kEventCursorMove, window, wParam, lParam, eventHandled); - break; - //////////////////////////////////////////////////////////////////////// - // Mouse events, processed - //////////////////////////////////////////////////////////////////////// - case WM_LBUTTONDOWN: - window->registerMouseClickEvent(0); - event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft); - break; - case WM_MBUTTONDOWN: - window->registerMouseClickEvent(0); - event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle); - break; - case WM_RBUTTONDOWN: - window->registerMouseClickEvent(0); - event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight); - break; - case WM_XBUTTONDOWN: - window->registerMouseClickEvent(0); - if ((short) HIWORD(wParam) == XBUTTON1) { - event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4); - } - else if ((short) HIWORD(wParam) == XBUTTON2) { - event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5); - } - break; - case WM_LBUTTONUP: - window->registerMouseClickEvent(1); - event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft); - break; - case WM_MBUTTONUP: - window->registerMouseClickEvent(1); - event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle); - break; - case WM_RBUTTONUP: - window->registerMouseClickEvent(1); - event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight); - break; - case WM_XBUTTONUP: - window->registerMouseClickEvent(1); - if ((short) HIWORD(wParam) == XBUTTON1) { - event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4); - } - else if ((short) HIWORD(wParam) == XBUTTON2) { - event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5); - } - break; - case WM_MOUSEMOVE: - event = processCursorEvent(GHOST_kEventCursorMove, window); - break; - case WM_MOUSEWHEEL: - { - /* The WM_MOUSEWHEEL message is sent to the focus window - * when the mouse wheel is rotated. The DefWindowProc - * function propagates the message to the window's parent. - * There should be no internal forwarding of the message, - * since DefWindowProc propagates it up the parent chain - * until it finds a window that processes it. - */ - - /* Get the window under the mouse and send event to its queue. */ - POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; - HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos); - GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd, GWLP_USERDATA); - - processWheelEvent(mouse_window ? mouse_window : window , wParam, lParam); - eventHandled = true; + //////////////////////////////////////////////////////////////////////// + // Keyboard events, ignored + //////////////////////////////////////////////////////////////////////// + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + /* These functions were replaced by WM_INPUT*/ + case WM_CHAR: + /* The WM_CHAR message is posted to the window with the keyboard focus when + * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR + * contains the character code of the key that was pressed. + */ + case WM_DEADCHAR: + /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a + * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR + * specifies a character code generated by a dead key. A dead key is a key that + * generates a character, such as the umlaut (double-dot), that is combined with + * another character to form a composite character. For example, the umlaut-O + * character (Ö) is generated by typing the dead key for the umlaut character, and + * then typing the O key. + */ + break; + 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. + */ + case WM_SYSCHAR: + /* The WM_SYSCHAR message is sent to the window with the keyboard focus when + * a WM_SYSCHAR message is translated by the TranslateMessage function. + * WM_SYSCHAR specifies the character code of a dead key - that is, + * a dead key that is pressed while holding down the alt key. + * To prevent the sound, DefWindowProc must be avoided by return + */ + break; + case WM_SYSCOMMAND: + /* The WM_SYSCHAR message is sent to the window when system commands such as + * maximize, minimize or close the window are triggered. Also it is sent when ALT + * button is press for menu. To prevent this we must return preventing DefWindowProc. + */ + if (wParam == SC_KEYMENU) { + eventHandled = true; + } + break; + //////////////////////////////////////////////////////////////////////// + // Tablet events, processed + //////////////////////////////////////////////////////////////////////// + case WT_PACKET: + window->processWin32TabletEvent(wParam, lParam); + break; + case WT_CSRCHANGE: + case WT_PROXIMITY: + window->processWin32TabletInitEvent(); + break; + //////////////////////////////////////////////////////////////////////// + // Pointer events, processed + //////////////////////////////////////////////////////////////////////// + case WM_POINTERDOWN: + event = processPointerEvent( + GHOST_kEventButtonDown, window, wParam, lParam, eventHandled); + if (event && eventHandled) { + window->registerMouseClickEvent(0); + } + break; + case WM_POINTERUP: + event = processPointerEvent(GHOST_kEventButtonUp, window, wParam, lParam, eventHandled); + if (event && eventHandled) { + window->registerMouseClickEvent(1); + } + break; + case WM_POINTERUPDATE: + event = processPointerEvent( + GHOST_kEventCursorMove, window, wParam, lParam, eventHandled); + break; + //////////////////////////////////////////////////////////////////////// + // Mouse events, processed + //////////////////////////////////////////////////////////////////////// + case WM_LBUTTONDOWN: + window->registerMouseClickEvent(0); + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft); + break; + case WM_MBUTTONDOWN: + window->registerMouseClickEvent(0); + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle); + break; + case WM_RBUTTONDOWN: + window->registerMouseClickEvent(0); + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight); + break; + case WM_XBUTTONDOWN: + window->registerMouseClickEvent(0); + if ((short)HIWORD(wParam) == XBUTTON1) { + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4); + } + else if ((short)HIWORD(wParam) == XBUTTON2) { + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5); + } + break; + case WM_LBUTTONUP: + window->registerMouseClickEvent(1); + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft); + break; + case WM_MBUTTONUP: + window->registerMouseClickEvent(1); + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle); + break; + case WM_RBUTTONUP: + window->registerMouseClickEvent(1); + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight); + break; + case WM_XBUTTONUP: + window->registerMouseClickEvent(1); + if ((short)HIWORD(wParam) == XBUTTON1) { + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4); + } + else if ((short)HIWORD(wParam) == XBUTTON2) { + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5); + } + break; + case WM_MOUSEMOVE: + event = processCursorEvent(GHOST_kEventCursorMove, window); + break; + case WM_MOUSEWHEEL: { + /* The WM_MOUSEWHEEL message is sent to the focus window + * when the mouse wheel is rotated. The DefWindowProc + * function propagates the message to the window's parent. + * There should be no internal forwarding of the message, + * since DefWindowProc propagates it up the parent chain + * until it finds a window that processes it. + */ + + /* Get the window under the mouse and send event to its queue. */ + POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; + HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos); + GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd, + GWLP_USERDATA); + + processWheelEvent(mouse_window ? mouse_window : window, wParam, lParam); + eventHandled = true; #ifdef BROKEN_PEEK_TOUCHPAD - PostMessage(hwnd, WM_USER, 0, 0); + PostMessage(hwnd, WM_USER, 0, 0); #endif - 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. - */ - { - GHOST_ModifierKeys modifiers; - modifiers.clear(); - system->storeModifierKeys(modifiers); - system->m_wheelDeltaAccum = 0; - event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window); - /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL - * will not be dispatched to OUR active window if we minimize one of OUR windows. */ - if (LOWORD(wParam) == WA_INACTIVE) - window->lostMouseCapture(); - window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam)); - lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); - break; - } - 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. - */ - window->m_inLiveResize = 1; - break; - case WM_EXITSIZEMOVE: - window->m_inLiveResize = 0; - 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. - */ - if (!window->m_inLiveResize) { - event = processWindowEvent(GHOST_kEventWindowUpdate, window); - ::ValidateRect(hwnd, NULL); - } - else { - eventHandled = true; - } - break; - case WM_GETMINMAXINFO: - /* The WM_GETMINMAXINFO message is sent to a window when the size or - * position of the window is about to change. An application can use - * this message to override the window's default maximized size and - * position, or its default minimum or maximum tracking size. - */ - processMinMaxInfo((MINMAXINFO *) lParam); - /* Let DefWindowProc handle it. */ - break; - case WM_SIZING: - 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. - */ - /* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */ - if (window->m_inLiveResize) { - system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window)); - system->dispatchEvents(); - } - else { - event = processWindowEvent(GHOST_kEventWindowSize, window); - } - break; - case WM_CAPTURECHANGED: - window->lostMouseCapture(); - break; - 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_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. - */ - /* see WM_SIZE comment*/ - if (window->m_inLiveResize) { - system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window)); - system->dispatchEvents(); - } - else { - event = processWindowEvent(GHOST_kEventWindowMove, window); - } - - break; - case WM_DPICHANGED: - /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed. - * The DPI is the scale factor for a window. There are multiple events that can cause the DPI to - * change such as when the window is moved to a monitor with a different DPI. - */ - { - // The suggested new size and position of the window. - RECT* const suggestedWindowRect = (RECT*)lParam; - - // Push DPI change event first - system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window)); - system->dispatchEvents(); - eventHandled = true; - - // Then move and resize window - SetWindowPos(hwnd, - NULL, - suggestedWindowRect->left, - suggestedWindowRect->top, - suggestedWindowRect->right - suggestedWindowRect->left, - suggestedWindowRect->bottom - suggestedWindowRect->top, - SWP_NOZORDER | SWP_NOACTIVATE); - } - 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_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. - */ - break; - case WM_KILLFOCUS: - /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. - * We want to prevent this if a window is still active and it loses focus to nowhere*/ - if (!wParam && hwnd == ::GetActiveWindow()) - ::SetFocus(hwnd); - 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. */ - 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); - eventHandled = true; - } - - if (!eventHandled) - lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam); - - return lResult; + 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. + */ + { + GHOST_ModifierKeys modifiers; + modifiers.clear(); + system->storeModifierKeys(modifiers); + system->m_wheelDeltaAccum = 0; + event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : + GHOST_kEventWindowDeactivate, + window); + /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL + * will not be dispatched to OUR active window if we minimize one of OUR windows. */ + if (LOWORD(wParam) == WA_INACTIVE) + window->lostMouseCapture(); + window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam)); + lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); + break; + } + 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. + */ + window->m_inLiveResize = 1; + break; + case WM_EXITSIZEMOVE: + window->m_inLiveResize = 0; + 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. + */ + if (!window->m_inLiveResize) { + event = processWindowEvent(GHOST_kEventWindowUpdate, window); + ::ValidateRect(hwnd, NULL); + } + else { + eventHandled = true; + } + break; + case WM_GETMINMAXINFO: + /* The WM_GETMINMAXINFO message is sent to a window when the size or + * position of the window is about to change. An application can use + * this message to override the window's default maximized size and + * position, or its default minimum or maximum tracking size. + */ + processMinMaxInfo((MINMAXINFO *)lParam); + /* Let DefWindowProc handle it. */ + break; + case WM_SIZING: + 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. + */ + /* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */ + if (window->m_inLiveResize) { + system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window)); + system->dispatchEvents(); + } + else { + event = processWindowEvent(GHOST_kEventWindowSize, window); + } + break; + case WM_CAPTURECHANGED: + window->lostMouseCapture(); + break; + 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_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. + */ + /* see WM_SIZE comment*/ + if (window->m_inLiveResize) { + system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window)); + system->dispatchEvents(); + } + else { + event = processWindowEvent(GHOST_kEventWindowMove, window); + } + + break; + case WM_DPICHANGED: + /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed. + * The DPI is the scale factor for a window. There are multiple events that can cause the DPI to + * change such as when the window is moved to a monitor with a different DPI. + */ + { + // The suggested new size and position of the window. + RECT *const suggestedWindowRect = (RECT *)lParam; + + // Push DPI change event first + system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window)); + system->dispatchEvents(); + eventHandled = true; + + // Then move and resize window + SetWindowPos(hwnd, + NULL, + suggestedWindowRect->left, + suggestedWindowRect->top, + suggestedWindowRect->right - suggestedWindowRect->left, + suggestedWindowRect->bottom - suggestedWindowRect->top, + SWP_NOZORDER | SWP_NOACTIVATE); + } + 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_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. + */ + break; + case WM_KILLFOCUS: + /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. + * We want to prevent this if a window is still active and it loses focus to nowhere*/ + if (!wParam && hwnd == ::GetActiveWindow()) + ::SetFocus(hwnd); + 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. */ + 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); + eventHandled = true; + } + + if (!eventHandled) + lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam); + + return lResult; } GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const { - char *temp_buff; - - if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) { - wchar_t *buffer; - HANDLE hData = GetClipboardData(CF_UNICODETEXT); - if (hData == NULL) { - CloseClipboard(); - return NULL; - } - buffer = (wchar_t *)GlobalLock(hData); - if (!buffer) { - CloseClipboard(); - return NULL; - } - - temp_buff = alloc_utf_8_from_16(buffer, 0); - - /* Buffer mustn't be accessed after CloseClipboard - * it would like accessing free-d memory */ - GlobalUnlock(hData); - CloseClipboard(); - - return (GHOST_TUns8 *)temp_buff; - } - else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) { - char *buffer; - size_t len = 0; - HANDLE hData = GetClipboardData(CF_TEXT); - if (hData == NULL) { - CloseClipboard(); - return NULL; - } - buffer = (char *)GlobalLock(hData); - if (!buffer) { - CloseClipboard(); - return NULL; - } - - len = strlen(buffer); - temp_buff = (char *) malloc(len + 1); - strncpy(temp_buff, buffer, len); - temp_buff[len] = '\0'; - - /* Buffer mustn't be accessed after CloseClipboard - * it would like accessing free-d memory */ - GlobalUnlock(hData); - CloseClipboard(); - - return (GHOST_TUns8 *)temp_buff; - } - else { - return NULL; - } + char *temp_buff; + + if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) { + wchar_t *buffer; + HANDLE hData = GetClipboardData(CF_UNICODETEXT); + if (hData == NULL) { + CloseClipboard(); + return NULL; + } + buffer = (wchar_t *)GlobalLock(hData); + if (!buffer) { + CloseClipboard(); + return NULL; + } + + temp_buff = alloc_utf_8_from_16(buffer, 0); + + /* Buffer mustn't be accessed after CloseClipboard + * it would like accessing free-d memory */ + GlobalUnlock(hData); + CloseClipboard(); + + return (GHOST_TUns8 *)temp_buff; + } + else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { + char *buffer; + size_t len = 0; + HANDLE hData = GetClipboardData(CF_TEXT); + if (hData == NULL) { + CloseClipboard(); + return NULL; + } + buffer = (char *)GlobalLock(hData); + if (!buffer) { + CloseClipboard(); + return NULL; + } + + len = strlen(buffer); + temp_buff = (char *)malloc(len + 1); + strncpy(temp_buff, buffer, len); + temp_buff[len] = '\0'; + + /* Buffer mustn't be accessed after CloseClipboard + * it would like accessing free-d memory */ + GlobalUnlock(hData); + CloseClipboard(); + + return (GHOST_TUns8 *)temp_buff; + } + else { + return NULL; + } } void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const { - if (selection) {return; } // for copying the selection, used on X11 - - if (OpenClipboard(NULL)) { - HLOCAL clipbuffer; - wchar_t *data; - - if (buffer) { - size_t len = count_utf_16_from_8(buffer); - EmptyClipboard(); - - clipbuffer = LocalAlloc(LMEM_FIXED, sizeof(wchar_t) * len); - data = (wchar_t *)GlobalLock(clipbuffer); - - conv_utf_8_to_16(buffer, data, len); - - LocalUnlock(clipbuffer); - SetClipboardData(CF_UNICODETEXT, clipbuffer); - } - CloseClipboard(); - } - else { - return; - } + if (selection) { + return; + } // for copying the selection, used on X11 + + if (OpenClipboard(NULL)) { + HLOCAL clipbuffer; + wchar_t *data; + + if (buffer) { + size_t len = count_utf_16_from_8(buffer); + EmptyClipboard(); + + clipbuffer = LocalAlloc(LMEM_FIXED, sizeof(wchar_t) * len); + data = (wchar_t *)GlobalLock(clipbuffer); + + conv_utf_8_to_16(buffer, data, len); + + LocalUnlock(clipbuffer); + SetClipboardData(CF_UNICODETEXT, clipbuffer); + } + CloseClipboard(); + } + else { + return; + } } static DWORD GetParentProcessID(void) { - HANDLE snapshot; - PROCESSENTRY32 pe32 = {0}; - DWORD ppid = 0, pid = GetCurrentProcessId(); - snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); - if (snapshot == INVALID_HANDLE_VALUE) { - return -1; - } - pe32.dwSize = sizeof( pe32 ); - if (!Process32First(snapshot, &pe32)) { - CloseHandle(snapshot); - return -1; - } - do { - if (pe32.th32ProcessID == pid) { - ppid = pe32.th32ParentProcessID; - break; - } - } while (Process32Next(snapshot, &pe32)); - CloseHandle(snapshot); - return ppid; + HANDLE snapshot; + PROCESSENTRY32 pe32 = {0}; + DWORD ppid = 0, pid = GetCurrentProcessId(); + snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot == INVALID_HANDLE_VALUE) { + return -1; + } + pe32.dwSize = sizeof(pe32); + if (!Process32First(snapshot, &pe32)) { + CloseHandle(snapshot); + return -1; + } + do { + if (pe32.th32ProcessID == pid) { + ppid = pe32.th32ParentProcessID; + break; + } + } while (Process32Next(snapshot, &pe32)); + CloseHandle(snapshot); + return ppid; } static bool getProcessName(int pid, char *buffer, int max_len) { - bool result = false; - HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, - FALSE, pid); - if (handle) { - GetModuleFileNameEx(handle, 0, buffer, max_len); - result = true; - } - CloseHandle(handle); - return result; + bool result = false; + HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (handle) { + GetModuleFileNameEx(handle, 0, buffer, max_len); + result = true; + } + CloseHandle(handle); + return result; } static bool isStartedFromCommandPrompt() { - HWND hwnd = GetConsoleWindow(); - - if (hwnd) { - DWORD pid = (DWORD)-1; - DWORD ppid = GetParentProcessID(); - char parent_name[MAX_PATH]; - bool start_from_launcher = false; - - GetWindowThreadProcessId(hwnd, &pid); - if (getProcessName(ppid, parent_name, sizeof(parent_name))) { - char *filename = strrchr(parent_name, '\\'); - if (filename != NULL) { - start_from_launcher = strstr(filename, "blender.exe") != NULL; - } - } - - /* When we're starting from a wrapper we need to compare with parent process ID. */ - if (pid != (start_from_launcher ? ppid : GetCurrentProcessId())) - return true; - } - - return false; + HWND hwnd = GetConsoleWindow(); + + if (hwnd) { + DWORD pid = (DWORD)-1; + DWORD ppid = GetParentProcessID(); + char parent_name[MAX_PATH]; + bool start_from_launcher = false; + + GetWindowThreadProcessId(hwnd, &pid); + if (getProcessName(ppid, parent_name, sizeof(parent_name))) { + char *filename = strrchr(parent_name, '\\'); + if (filename != NULL) { + start_from_launcher = strstr(filename, "blender.exe") != NULL; + } + } + + /* When we're starting from a wrapper we need to compare with parent process ID. */ + if (pid != (start_from_launcher ? ppid : GetCurrentProcessId())) + return true; + } + + return false; } int GHOST_SystemWin32::toggleConsole(int action) { - HWND wnd = GetConsoleWindow(); - - switch (action) { - case 3: // startup: hide if not started from command prompt - { - if (!isStartedFromCommandPrompt()) { - ShowWindow(wnd, SW_HIDE); - m_consoleStatus = 0; - } - break; - } - case 0: // hide - ShowWindow(wnd, SW_HIDE); - m_consoleStatus = 0; - break; - case 1: // show - ShowWindow(wnd, SW_SHOW); - if (!isStartedFromCommandPrompt()) { - DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); - } - m_consoleStatus = 1; - break; - case 2: // toggle - ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW); - m_consoleStatus = !m_consoleStatus; - if (m_consoleStatus && !isStartedFromCommandPrompt()) { - DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); - } - break; - } - - return m_consoleStatus; + HWND wnd = GetConsoleWindow(); + + switch (action) { + case 3: // startup: hide if not started from command prompt + { + if (!isStartedFromCommandPrompt()) { + ShowWindow(wnd, SW_HIDE); + m_consoleStatus = 0; + } + break; + } + case 0: // hide + ShowWindow(wnd, SW_HIDE); + m_consoleStatus = 0; + break; + case 1: // show + ShowWindow(wnd, SW_SHOW); + if (!isStartedFromCommandPrompt()) { + DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); + } + m_consoleStatus = 1; + break; + case 2: // toggle + ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW); + m_consoleStatus = !m_consoleStatus; + if (m_consoleStatus && !isStartedFromCommandPrompt()) { + DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); + } + break; + } + + return m_consoleStatus; } int GHOST_SystemWin32::confirmQuit(GHOST_IWindow *window) const { - return (MessageBox(window ? ((GHOST_WindowWin32 *)window)->getHWND() : 0, "Some changes have not been saved.\nDo you really want to quit?", - "Exit Blender", MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST) == IDOK); + return (MessageBox(window ? ((GHOST_WindowWin32 *)window)->getHWND() : 0, + "Some changes have not been saved.\nDo you really want to quit?", + "Exit Blender", + MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST) == IDOK); } diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 62492e8d8b7..0eb91d511b1 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -26,8 +26,8 @@ #define __GHOST_SYSTEMWIN32_H__ #ifndef WIN32 -#error WIN32 only! -#endif // WIN32 +# error WIN32 only! +#endif // WIN32 /* require Windows XP or newer */ #undef _WIN32_WINNT @@ -35,7 +35,7 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> -#include <ole2.h> // for drag-n-drop +#include <ole2.h> // for drag-n-drop #include "GHOST_System.h" @@ -53,378 +53,392 @@ class GHOST_WindowWin32; * \see GHOST_System. */ class GHOST_SystemWin32 : public GHOST_System { -public: - /** - * Constructor. - */ - GHOST_SystemWin32(); - - /** - * Destructor. - */ - ~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. - */ - GHOST_TUns64 getMilliSeconds() const; - - /*************************************************************************************** - ** Display/window management functionality - ***************************************************************************************/ - - /** - * 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; - - /** - * Returns the dimensions of all displays on this system. - * \return The dimension of the main display. - */ - void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. - * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent (embedder) window - * \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, - GHOST_GLSettings glSettings, - const bool exclusive = false, - const GHOST_TEmbedderWindowID parentWindow = 0); - - - /** - * Create a new offscreen context. - * Never explicitly delete the window, use disposeContext() instead. - * \return The new context (or 0 if creation failed). - */ - GHOST_IContext *createOffscreenContext(); - - /** - * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. - */ - GHOST_TSuccess disposeContext(GHOST_IContext *context); - - /*************************************************************************************** - ** 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. - */ - 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. - */ - 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. - */ - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); - - /*************************************************************************************** - ** 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. - */ - 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; - - /** - * Returns unsigned char from CUT_BUFFER0 - * \param selection Used by X11 only - * \return Returns the Clipboard - */ - GHOST_TUns8 *getClipboard(bool selection) const; - - /** - * Puts buffer to system clipboard - * \param selection Used by X11 only - * \return No return - */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; - - /** - * Creates a drag'n'drop event and pushes it immediately onto the event queue. - * Called by GHOST_DropTargetWin32 class. - * \param eventType The type of drag'n'drop event - * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap) - * \param mouseX x mouse coordinate (in window coordinates) - * \param mouseY y mouse coordinate - * \param window The window on which the event occurred - * \return Indication whether the event was handled. - */ - static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data); - - /** - * Confirms quitting he program when there is just one window left open - * in the application - */ - int confirmQuit(GHOST_IWindow *window) const; - -protected: - /** - * Initializes the system. - * For now, it just registers the window class (WNDCLASS). - * \return A success value. - */ - GHOST_TSuccess init(); - - /** - * Closes the system down. - * \return A success value. - */ - GHOST_TSuccess exit(); - - /** - * Converts raw WIN32 key codes from the wndproc to GHOST keys. - * \param vKey The virtual key from hardKey - * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1) - * \param extend Flag if key is not primly (left or right) - * \return The GHOST key (GHOST_kKeyUnknown if no match). - */ - GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const; - - /** - * Catches raw WIN32 key codes from WM_INPUT in the wndproc. - * \param raw RawInput structure with detailed info about the key event - * \param keyDown Pointer flag that specify if a key is down - * \param vk Pointer to virtual key - * \return The GHOST key (GHOST_kKeyUnknown if no match). - */ - GHOST_TKey hardKey(RAWINPUT const& raw, int *keyDown, char *vk); - - /** - * Creates mouse button event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \param mask The button mask of this event. - * \return The event created. - */ - static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButtonMask mask); - - /** - * Creates pointer event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \param wParam The wParam from the wndproc - * \param lParam The lParam from the wndproc - * \param eventhandled true if the method handled the event - * \return The event created. - */ - static GHOST_Event *processPointerEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool & eventhandled); - - /** - * Creates cursor event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \return The event created. - */ - static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window); - - /** - * Handles a mouse wheel event. - * \param window The window receiving the event (the active window). - * \param wParam The wParam from the wndproc - * \param lParam The lParam from the wndproc - */ - static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam); - - /** - * 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. - * \param window The window receiving the event (the active window). - * \param raw RawInput structure with detailed info about the key event - */ - static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const& raw); - - /** - * Process special keys (VK_OEM_*), to see if current key layout - * gives us anything special, like ! on french AZERTY. - * \param vKey The virtual key from hardKey - * \param scanCode The ScanCode of pressed key (simular to PS/2 Set 1) - */ - GHOST_TKey processSpecialKey(short vKey, short scanCode) const; - - /** - * Creates a window event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \return The event created. - */ - static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window); + public: + /** + * Constructor. + */ + GHOST_SystemWin32(); + + /** + * Destructor. + */ + ~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. + */ + GHOST_TUns64 getMilliSeconds() const; + + /*************************************************************************************** + ** Display/window management functionality + ***************************************************************************************/ + + /** + * 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; + + /** + * Returns the dimensions of all displays on this system. + * \return The dimension of the main display. + */ + void getAllDisplayDimensions(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 glSettings: Misc OpenGL settings. + * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). + * \param parentWindow Parent (embedder) window + * \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, + GHOST_GLSettings glSettings, + const bool exclusive = false, + const GHOST_TEmbedderWindowID parentWindow = 0); + + /** + * Create a new offscreen context. + * Never explicitly delete the window, use disposeContext() instead. + * \return The new context (or 0 if creation failed). + */ + GHOST_IContext *createOffscreenContext(); + + /** + * Dispose of a context. + * \param context Pointer to the context to be disposed. + * \return Indication of success. + */ + GHOST_TSuccess disposeContext(GHOST_IContext *context); + + /*************************************************************************************** + ** 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. + */ + 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. + */ + 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. + */ + GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + + /*************************************************************************************** + ** 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. + */ + 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; + + /** + * Returns unsigned char from CUT_BUFFER0 + * \param selection Used by X11 only + * \return Returns the Clipboard + */ + GHOST_TUns8 *getClipboard(bool selection) const; + + /** + * Puts buffer to system clipboard + * \param selection Used by X11 only + * \return No return + */ + void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + + /** + * Creates a drag'n'drop event and pushes it immediately onto the event queue. + * Called by GHOST_DropTargetWin32 class. + * \param eventType The type of drag'n'drop event + * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap) + * \param mouseX x mouse coordinate (in window coordinates) + * \param mouseY y mouse coordinate + * \param window The window on which the event occurred + * \return Indication whether the event was handled. + */ + static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, + GHOST_TDragnDropTypes draggedObjectType, + GHOST_WindowWin32 *window, + int mouseX, + int mouseY, + void *data); + + /** + * Confirms quitting he program when there is just one window left open + * in the application + */ + int confirmQuit(GHOST_IWindow *window) const; + + protected: + /** + * Initializes the system. + * For now, it just registers the window class (WNDCLASS). + * \return A success value. + */ + GHOST_TSuccess init(); + + /** + * Closes the system down. + * \return A success value. + */ + GHOST_TSuccess exit(); + + /** + * Converts raw WIN32 key codes from the wndproc to GHOST keys. + * \param vKey The virtual key from hardKey + * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1) + * \param extend Flag if key is not primly (left or right) + * \return The GHOST key (GHOST_kKeyUnknown if no match). + */ + GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const; + + /** + * Catches raw WIN32 key codes from WM_INPUT in the wndproc. + * \param raw RawInput structure with detailed info about the key event + * \param keyDown Pointer flag that specify if a key is down + * \param vk Pointer to virtual key + * \return The GHOST key (GHOST_kKeyUnknown if no match). + */ + GHOST_TKey hardKey(RAWINPUT const &raw, int *keyDown, char *vk); + + /** + * Creates mouse button event. + * \param type The type of event to create. + * \param window The window receiving the event (the active window). + * \param mask The button mask of this event. + * \return The event created. + */ + static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TButtonMask mask); + + /** + * Creates pointer event. + * \param type The type of event to create. + * \param window The window receiving the event (the active window). + * \param wParam The wParam from the wndproc + * \param lParam The lParam from the wndproc + * \param eventhandled true if the method handled the event + * \return The event created. + */ + static GHOST_Event *processPointerEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + WPARAM wParam, + LPARAM lParam, + bool &eventhandled); + + /** + * Creates cursor event. + * \param type The type of event to create. + * \param window The window receiving the event (the active window). + * \return The event created. + */ + static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window); + + /** + * Handles a mouse wheel event. + * \param window The window receiving the event (the active window). + * \param wParam The wParam from the wndproc + * \param lParam The lParam from the wndproc + */ + static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam); + + /** + * 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. + * \param window The window receiving the event (the active window). + * \param raw RawInput structure with detailed info about the key event + */ + static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw); + + /** + * Process special keys (VK_OEM_*), to see if current key layout + * gives us anything special, like ! on french AZERTY. + * \param vKey The virtual key from hardKey + * \param scanCode The ScanCode of pressed key (simular to PS/2 Set 1) + */ + GHOST_TKey processSpecialKey(short vKey, short scanCode) const; + + /** + * Creates a window event. + * \param type The type of event to create. + * \param window The window receiving the event (the active window). + * \return The event created. + */ + static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window); #ifdef WITH_INPUT_IME - /** - * Creates a IME event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \param data IME data. - * \return The event created. - */ - static GHOST_Event *processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data); -#endif // WITH_INPUT_IME - - /** - * Handles minimum window size. - * \param minmax The MINMAXINFO structure. - */ - static void processMinMaxInfo(MINMAXINFO *minmax); + /** + * Creates a IME event. + * \param type The type of event to create. + * \param window The window receiving the event (the active window). + * \param data IME data. + * \return The event created. + */ + static GHOST_Event *processImeEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TEventImeData *data); +#endif // WITH_INPUT_IME + + /** + * Handles minimum window size. + * \param minmax The MINMAXINFO structure. + */ + static void processMinMaxInfo(MINMAXINFO *minmax); #ifdef WITH_INPUT_NDOF - /** - * Handles Motion and Button events from a SpaceNavigator or related device. - * Instead of returning an event object, this function communicates directly - * with the GHOST_NDOFManager. - * \param raw RawInput structure with detailed info about the NDOF event - * \return Whether an event was generated and sent. - */ - bool processNDOF(RAWINPUT const& raw); + /** + * Handles Motion and Button events from a SpaceNavigator or related device. + * Instead of returning an event object, this function communicates directly + * with the GHOST_NDOFManager. + * \param raw RawInput structure with detailed info about the NDOF event + * \return Whether an event was generated and sent. + */ + bool processNDOF(RAWINPUT const &raw); #endif - /** - * Returns the local state of the modifier keys (from the message queue). - * \param keys The state of the keys. - */ - inline 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 void storeModifierKeys(const GHOST_ModifierKeys& keys); - - /** - * Check current key layout for AltGr - */ - inline void handleKeyboardChange(void); - - /** - * Windows call back routine for our window class. - */ - static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - - /** - * Toggles console - * \param action - * - 0 - Hides - * - 1 - Shows - * - 2 - Toggles - * - 3 - Hides if it runs not from command line - * - * - Does nothing - * \return current status (1 -visible, 0 - hidden) - */ - int toggleConsole(int action); - - /** 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; - /** AltGr on current keyboard layout. */ - bool m_hasAltGr; - /** language identifier. */ - WORD m_langId; - /** stores keyboard layout. */ - HKL m_keylayout; - - /** Console status */ - int m_consoleStatus; - - /** Wheel delta accumulator */ - int m_wheelDeltaAccum; + /** + * Returns the local state of the modifier keys (from the message queue). + * \param keys The state of the keys. + */ + inline 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 void storeModifierKeys(const GHOST_ModifierKeys &keys); + + /** + * Check current key layout for AltGr + */ + inline void handleKeyboardChange(void); + + /** + * Windows call back routine for our window class. + */ + static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + /** + * Toggles console + * \param action + * - 0 - Hides + * - 1 - Shows + * - 2 - Toggles + * - 3 - Hides if it runs not from command line + * - * - Does nothing + * \return current status (1 -visible, 0 - hidden) + */ + int toggleConsole(int action); + + /** 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; + /** AltGr on current keyboard layout. */ + bool m_hasAltGr; + /** language identifier. */ + WORD m_langId; + /** stores keyboard layout. */ + HKL m_keylayout; + + /** Console status */ + int m_consoleStatus; + + /** Wheel delta accumulator */ + int m_wheelDeltaAccum; }; -inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const +inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys &keys) const { - keys = m_modifierKeys; + keys = m_modifierKeys; } -inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys) +inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys &keys) { - m_modifierKeys = keys; + m_modifierKeys = keys; } inline void GHOST_SystemWin32::handleKeyboardChange(void) { - m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread - int i; - SHORT s; - - // save the language identifier. - m_langId = LOWORD(m_keylayout); - - for (m_hasAltGr = false, i = 32; i < 256; ++i) { - s = VkKeyScanEx((char)i, m_keylayout); - // s == -1 means no key that translates passed char code - // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed - // if both are pressed, we have AltGr keycombo on keylayout - if (s != -1 && (s & 0x600) == 0x600) { - m_hasAltGr = true; - break; - } - } + m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread + int i; + SHORT s; + + // save the language identifier. + m_langId = LOWORD(m_keylayout); + + for (m_hasAltGr = false, i = 32; i < 256; ++i) { + s = VkKeyScanEx((char)i, m_keylayout); + // s == -1 means no key that translates passed char code + // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed + // if both are pressed, we have AltGr keycombo on keylayout + if (s != -1 && (s & 0x600) == 0x600) { + m_hasAltGr = true; + break; + } + } } -#endif // __GHOST_SYSTEMWIN32_H__ +#endif // __GHOST_SYSTEMWIN32_H__ diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index ef08a6d7bb7..4d467f3b913 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -55,13 +55,13 @@ #endif #ifdef WITH_XF86KEYSYM -#include <X11/XF86keysym.h> +# include <X11/XF86keysym.h> #endif #ifdef WITH_X11_XFIXES # include <X11/extensions/Xfixes.h> /* Workaround for XWayland grab glitch: T53004. */ -#define WITH_XWAYLAND_HACK +# define WITH_XWAYLAND_HACK #endif /* for XIWarpPointer */ @@ -92,12 +92,11 @@ * See T47228 and D1746 */ #define USE_NON_LATIN_KB_WORKAROUND -static GHOST_TKey ghost_key_from_keysym( - const KeySym key); -static GHOST_TKey ghost_key_from_keycode( - const XkbDescPtr xkb_descr, const KeyCode keycode); -static GHOST_TKey ghost_key_from_keysym_or_keycode( - const KeySym key, const XkbDescPtr xkb_descr, const KeyCode keycode); +static GHOST_TKey ghost_key_from_keysym(const KeySym key); +static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode); +static GHOST_TKey ghost_key_from_keysym_or_keycode(const KeySym key, + const XkbDescPtr xkb_descr, + const KeyCode keycode); /* these are for copy and select copy */ static char *txt_cut_buffer = NULL; @@ -109,285 +108,277 @@ static bool use_xwayland_hack = false; using namespace std; -GHOST_SystemX11:: -GHOST_SystemX11( - ) - : GHOST_System(), - m_xkb_descr(NULL), - m_start_time(0) +GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(NULL), m_start_time(0) { - XInitThreads(); - m_display = XOpenDisplay(NULL); + XInitThreads(); + m_display = XOpenDisplay(NULL); - if (!m_display) { - std::cerr << "Unable to open a display" << std::endl; - abort(); /* was return before, but this would just mean it will crash later */ - } + if (!m_display) { + std::cerr << "Unable to open a display" << std::endl; + abort(); /* was return before, but this would just mean it will crash later */ + } #ifdef USE_X11_ERROR_HANDLERS - (void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler); - (void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); + (void)XSetErrorHandler(GHOST_X11_ApplicationErrorHandler); + (void)XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - /* note -- don't open connection to XIM server here, because the locale - * has to be set before opening the connection but setlocale() has not - * been called yet. the connection will be opened after entering - * the event loop. */ - m_xim = NULL; + /* note -- don't open connection to XIM server here, because the locale + * has to be set before opening the connection but setlocale() has not + * been called yet. the connection will be opened after entering + * the event loop. */ + m_xim = NULL; #endif -#define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True); } (void)0 -#define GHOST_INTERN_ATOM(atom) { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0 - - GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW); - GHOST_INTERN_ATOM(WM_PROTOCOLS); - GHOST_INTERN_ATOM(WM_TAKE_FOCUS); - GHOST_INTERN_ATOM(WM_STATE); - GHOST_INTERN_ATOM(WM_CHANGE_STATE); - GHOST_INTERN_ATOM(_NET_WM_STATE); - GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); - GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); - - GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN); - GHOST_INTERN_ATOM(_MOTIF_WM_HINTS); - GHOST_INTERN_ATOM(TARGETS); - GHOST_INTERN_ATOM(STRING); - GHOST_INTERN_ATOM(COMPOUND_TEXT); - GHOST_INTERN_ATOM(TEXT); - GHOST_INTERN_ATOM(CLIPBOARD); - GHOST_INTERN_ATOM(PRIMARY); - GHOST_INTERN_ATOM(XCLIP_OUT); - GHOST_INTERN_ATOM(INCR); - GHOST_INTERN_ATOM(UTF8_STRING); +#define GHOST_INTERN_ATOM_IF_EXISTS(atom) \ + { \ + m_atom.atom = XInternAtom(m_display, #atom, True); \ + } \ + (void)0 +#define GHOST_INTERN_ATOM(atom) \ + { \ + m_atom.atom = XInternAtom(m_display, #atom, False); \ + } \ + (void)0 + + GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW); + GHOST_INTERN_ATOM(WM_PROTOCOLS); + GHOST_INTERN_ATOM(WM_TAKE_FOCUS); + GHOST_INTERN_ATOM(WM_STATE); + GHOST_INTERN_ATOM(WM_CHANGE_STATE); + GHOST_INTERN_ATOM(_NET_WM_STATE); + GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); + GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); + + GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN); + GHOST_INTERN_ATOM(_MOTIF_WM_HINTS); + GHOST_INTERN_ATOM(TARGETS); + GHOST_INTERN_ATOM(STRING); + GHOST_INTERN_ATOM(COMPOUND_TEXT); + GHOST_INTERN_ATOM(TEXT); + GHOST_INTERN_ATOM(CLIPBOARD); + GHOST_INTERN_ATOM(PRIMARY); + GHOST_INTERN_ATOM(XCLIP_OUT); + GHOST_INTERN_ATOM(INCR); + GHOST_INTERN_ATOM(UTF8_STRING); #ifdef WITH_X11_XINPUT - m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False); + m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False); #endif #undef GHOST_INTERN_ATOM_IF_EXISTS #undef GHOST_INTERN_ATOM - m_last_warp = 0; - m_last_release_keycode = 0; - m_last_release_time = 0; + m_last_warp = 0; + m_last_release_keycode = 0; + m_last_release_time = 0; - /* compute the initial time */ - timeval tv; - if (gettimeofday(&tv, NULL) == -1) { - GHOST_ASSERT(false, "Could not instantiate timer!"); - } + /* compute the initial time */ + timeval tv; + if (gettimeofday(&tv, NULL) == -1) { + GHOST_ASSERT(false, "Could not instantiate timer!"); + } - /* Taking care not to overflow the tv.tv_sec * 1000 */ - m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; + /* Taking care not to overflow the tv.tv_sec * 1000 */ + m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; + /* use detectable autorepeate, mac and windows also do this */ + int use_xkb; + int xkb_opcode, xkb_event, xkb_error; + int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion; - /* use detectable autorepeate, mac and windows also do this */ - int use_xkb; - int xkb_opcode, xkb_event, xkb_error; - int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion; + use_xkb = XkbQueryExtension( + m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor); + if (use_xkb) { + XkbSetDetectableAutoRepeat(m_display, true, NULL); - use_xkb = XkbQueryExtension(m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor); - if (use_xkb) { - XkbSetDetectableAutoRepeat(m_display, true, NULL); - - m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd); - if (m_xkb_descr) { - XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr); - } - } + m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd); + if (m_xkb_descr) { + XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr); + } + } #ifdef WITH_XWAYLAND_HACK - use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL; + use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL; #endif #ifdef WITH_X11_XINPUT - /* detect if we have xinput (for reuse) */ - { - memset(&m_xinput_version, 0, sizeof(m_xinput_version)); - XExtensionVersion *version = XGetExtensionVersion(m_display, INAME); - if (version && (version != (XExtensionVersion *)NoSuchExtension)) { - if (version->present) { - m_xinput_version = *version; - } - XFree(version); - } - } - -#ifdef USE_XINPUT_HOTPLUG - if (m_xinput_version.present) { - XEventClass class_presence; - int xi_presence; - DevicePresence(m_display, xi_presence, class_presence); - XSelectExtensionEvent( - m_display, - RootWindow(m_display, DefaultScreen(m_display)), - &class_presence, 1); - (void)xi_presence; - } -#endif /* USE_XINPUT_HOTPLUG */ - - refreshXInputDevices(); -#endif /* WITH_X11_XINPUT */ + /* detect if we have xinput (for reuse) */ + { + memset(&m_xinput_version, 0, sizeof(m_xinput_version)); + XExtensionVersion *version = XGetExtensionVersion(m_display, INAME); + if (version && (version != (XExtensionVersion *)NoSuchExtension)) { + if (version->present) { + m_xinput_version = *version; + } + XFree(version); + } + } + +# ifdef USE_XINPUT_HOTPLUG + if (m_xinput_version.present) { + XEventClass class_presence; + int xi_presence; + DevicePresence(m_display, xi_presence, class_presence); + XSelectExtensionEvent( + m_display, RootWindow(m_display, DefaultScreen(m_display)), &class_presence, 1); + (void)xi_presence; + } +# endif /* USE_XINPUT_HOTPLUG */ + + refreshXInputDevices(); +#endif /* WITH_X11_XINPUT */ } -GHOST_SystemX11:: -~GHOST_SystemX11() +GHOST_SystemX11::~GHOST_SystemX11() { #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - if (m_xim) { - XCloseIM(m_xim); - } + if (m_xim) { + XCloseIM(m_xim); + } #endif #ifdef WITH_X11_XINPUT - /* Close tablet devices. */ - clearXInputDevices(); + /* Close tablet devices. */ + clearXInputDevices(); #endif /* WITH_X11_XINPUT */ - if (m_xkb_descr) { - XkbFreeKeyboard (m_xkb_descr, XkbAllComponentsMask, true); - } + if (m_xkb_descr) { + XkbFreeKeyboard(m_xkb_descr, XkbAllComponentsMask, true); + } - XCloseDisplay(m_display); + XCloseDisplay(m_display); } - -GHOST_TSuccess -GHOST_SystemX11:: -init() +GHOST_TSuccess GHOST_SystemX11::init() { - GHOST_TSuccess success = GHOST_System::init(); + GHOST_TSuccess success = GHOST_System::init(); - if (success) { + if (success) { #ifdef WITH_INPUT_NDOF - m_ndofManager = new GHOST_NDOFManagerUnix(*this); + m_ndofManager = new GHOST_NDOFManagerUnix(*this); #endif - m_displayManager = new GHOST_DisplayManagerX11(this); + m_displayManager = new GHOST_DisplayManagerX11(this); - if (m_displayManager) { - return GHOST_kSuccess; - } - } + if (m_displayManager) { + return GHOST_kSuccess; + } + } - return GHOST_kFailure; + return GHOST_kFailure; } -GHOST_TUns64 -GHOST_SystemX11:: -getMilliSeconds() const +GHOST_TUns64 GHOST_SystemX11::getMilliSeconds() const { - timeval tv; - if (gettimeofday(&tv, NULL) == -1) { - GHOST_ASSERT(false, "Could not compute time!"); - } + timeval tv; + if (gettimeofday(&tv, NULL) == -1) { + GHOST_ASSERT(false, "Could not compute time!"); + } - /* Taking care not to overflow the tv.tv_sec * 1000 */ - return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; + /* Taking care not to overflow the tv.tv_sec * 1000 */ + return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; } -GHOST_TUns8 -GHOST_SystemX11:: -getNumDisplays() const +GHOST_TUns8 GHOST_SystemX11::getNumDisplays() const { - return GHOST_TUns8(1); + 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 +void GHOST_SystemX11::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - if (m_display) { - /* note, for this to work as documented, - * we would need to use Xinerama check r54370 for code that did this, - * we've since removed since its not worth the extra dep - campbell */ - getAllDisplayDimensions(width, height); - } + if (m_display) { + /* note, for this to work as documented, + * we would need to use Xinerama check r54370 for code that did this, + * we've since removed since its not worth the extra dep - campbell */ + getAllDisplayDimensions(width, height); + } } - /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ -void -GHOST_SystemX11:: -getAllDisplayDimensions( - GHOST_TUns32& width, - GHOST_TUns32& height) const +void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const { - if (m_display) { - width = DisplayWidth(m_display, DefaultScreen(m_display)); - height = DisplayHeight(m_display, DefaultScreen(m_display)); - } + 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. + * \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 glSettings: Misc OpenGL settings. * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent (embedder) window - * \return The new window (or 0 if creation failed). + * \param parentWindow Parent (embedder) 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, - GHOST_GLSettings glSettings, - const bool exclusive, - const GHOST_TEmbedderWindowID parentWindow) +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, + GHOST_GLSettings glSettings, + const bool exclusive, + const GHOST_TEmbedderWindowID parentWindow) { - GHOST_WindowX11 *window = NULL; - - if (!m_display) return 0; - - window = new GHOST_WindowX11(this, m_display, title, - left, top, width, height, - state, parentWindow, type, - ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive, - ((glSettings.flags & GHOST_glAlphaBackground) != 0), - glSettings.numOfAASamples, (glSettings.flags & GHOST_glDebugContext) != 0); - - if (window) { - /* Both are now handle in GHOST_WindowX11.cpp - * Focus and Delete atoms. */ - - if (window->getValid()) { - /* Store the pointer to the window */ - m_windowManager->addWindow(window); - m_windowManager->setActiveWindow(window); - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) ); - } - else { - delete window; - window = NULL; - } - } - return window; + GHOST_WindowX11 *window = NULL; + + if (!m_display) + return 0; + + window = new GHOST_WindowX11(this, + m_display, + title, + left, + top, + width, + height, + state, + parentWindow, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0), + exclusive, + ((glSettings.flags & GHOST_glAlphaBackground) != 0), + glSettings.numOfAASamples, + (glSettings.flags & GHOST_glDebugContext) != 0); + + if (window) { + /* Both are now handle in GHOST_WindowX11.cpp + * Focus and Delete atoms. */ + + if (window->getValid()) { + /* Store the pointer to the window */ + m_windowManager->addWindow(window); + m_windowManager->setActiveWindow(window); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + } + else { + delete window; + window = NULL; + } + } + return window; } bool GHOST_SystemX11::supportsNativeDialogs(void) { - return false; + return false; } /** @@ -395,76 +386,76 @@ bool GHOST_SystemX11::supportsNativeDialogs(void) * Never explicitly delete the context, use disposeContext() instead. * \return The new context (or 0 if creation failed). */ -GHOST_IContext * -GHOST_SystemX11:: -createOffscreenContext() +GHOST_IContext *GHOST_SystemX11::createOffscreenContext() { - // During development: - // try 4.x compatibility profile - // try 3.3 compatibility profile - // fall back to 3.0 if needed - // - // Final Blender 2.8: - // try 4.x core profile - // try 3.3 core profile - // no fallbacks + // During development: + // try 4.x compatibility profile + // try 3.3 compatibility profile + // fall back to 3.0 if needed + // + // Final Blender 2.8: + // try 4.x core profile + // try 3.3 core profile + // no fallbacks #if defined(WITH_GL_PROFILE_CORE) - { - const char *version_major = (char*)glewGetString(GLEW_VERSION_MAJOR); - if (version_major != NULL && version_major[0] == '1') { - fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); - abort(); - } - } + { + const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR); + if (version_major != NULL && version_major[0] == '1') { + fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); + abort(); + } + } #endif - const int profile_mask = + const int profile_mask = #if defined(WITH_GL_PROFILE_CORE) - GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + GLX_CONTEXT_CORE_PROFILE_BIT_ARB; #elif defined(WITH_GL_PROFILE_COMPAT) - GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #else -# error // must specify either core or compat at build time +# error // must specify either core or compat at build time #endif - GHOST_Context *context; - - for (int minor = 5; minor >= 0; --minor) { - context = new GHOST_ContextGLX( - false, - 0, - (Window)NULL, - m_display, - (GLXFBConfig)NULL, - profile_mask, - 4, minor, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - } - - context = new GHOST_ContextGLX( - false, - 0, - (Window)NULL, - m_display, - (GLXFBConfig)NULL, - profile_mask, - 3, 3, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - - return NULL; + GHOST_Context *context; + + for (int minor = 5; minor >= 0; --minor) { + context = new GHOST_ContextGLX(false, + 0, + (Window)NULL, + m_display, + (GLXFBConfig)NULL, + profile_mask, + 4, + minor, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + } + + context = new GHOST_ContextGLX(false, + 0, + (Window)NULL, + m_display, + (GLXFBConfig)NULL, + profile_mask, + 3, + 3, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + + return NULL; } /** @@ -472,1743 +463,1695 @@ createOffscreenContext() * \param context Pointer to the context to be disposed. * \return Indication of success. */ -GHOST_TSuccess -GHOST_SystemX11:: -disposeContext(GHOST_IContext *context) +GHOST_TSuccess GHOST_SystemX11::disposeContext(GHOST_IContext *context) { - delete context; + delete context; - return GHOST_kSuccess; + return GHOST_kSuccess; } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/) { - GHOST_PRINT("XIM server died\n"); + GHOST_PRINT("XIM server died\n"); - if (ptr) - *(XIM *)ptr = NULL; + if (ptr) + *(XIM *)ptr = NULL; } bool GHOST_SystemX11::openX11_IM() { - if (!m_display) - return false; + if (!m_display) + return false; - /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */ - XSetLocaleModifiers(""); + /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */ + XSetLocaleModifiers(""); - m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS); - if (!m_xim) - return false; + m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS); + if (!m_xim) + return false; - XIMCallback destroy; - destroy.callback = (XIMProc)destroyIMCallback; - destroy.client_data = (XPointer)&m_xim; - XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL); - return true; + XIMCallback destroy; + destroy.callback = (XIMProc)destroyIMCallback; + destroy.client_data = (XPointer)&m_xim; + XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL); + return true; } #endif -GHOST_WindowX11 * -GHOST_SystemX11:: -findGhostWindow( - Window xwind) const +GHOST_WindowX11 *GHOST_SystemX11::findGhostWindow(Window xwind) const { - if (xwind == 0) return NULL; + 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. */ + /* 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 *> &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; + 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_TInt64 maxSleep) { - int fd = ConnectionNumber(display); - fd_set fds; + int fd = ConnectionNumber(display); + fd_set fds; - FD_ZERO(&fds); - FD_SET(fd, &fds); + FD_ZERO(&fds); + FD_SET(fd, &fds); - if (maxSleep == -1) { - select(fd + 1, &fds, NULL, NULL, NULL); - } - else { - timeval tv; + 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; + tv.tv_sec = maxSleep / 1000; + tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000; - select(fd + 1, &fds, NULL, NULL, &tv); - } + select(fd + 1, &fds, NULL, NULL, &tv); + } } /* This function borrowed from Qt's X11 support * qclipboard_x11.cpp * */ struct init_timestamp_data { - Time timestamp; + Time timestamp; }; static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg) { - init_timestamp_data *data = - reinterpret_cast<init_timestamp_data *>(arg); - switch (event->type) { - case ButtonPress: - case ButtonRelease: - data->timestamp = event->xbutton.time; - break; - case MotionNotify: - data->timestamp = event->xmotion.time; - break; - case KeyPress: - case KeyRelease: - data->timestamp = event->xkey.time; - break; - case PropertyNotify: - data->timestamp = event->xproperty.time; - break; - case EnterNotify: - case LeaveNotify: - data->timestamp = event->xcrossing.time; - break; - case SelectionClear: - data->timestamp = event->xselectionclear.time; - break; - default: - break; - } - - return false; + init_timestamp_data *data = reinterpret_cast<init_timestamp_data *>(arg); + switch (event->type) { + case ButtonPress: + case ButtonRelease: + data->timestamp = event->xbutton.time; + break; + case MotionNotify: + data->timestamp = event->xmotion.time; + break; + case KeyPress: + case KeyRelease: + data->timestamp = event->xkey.time; + break; + case PropertyNotify: + data->timestamp = event->xproperty.time; + break; + case EnterNotify: + case LeaveNotify: + data->timestamp = event->xcrossing.time; + break; + case SelectionClear: + data->timestamp = event->xselectionclear.time; + break; + default: + break; + } + + return false; } -Time -GHOST_SystemX11:: -lastEventTime(Time default_time) { - init_timestamp_data data; - data.timestamp = default_time; - XEvent ev; - XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer) & data); +Time GHOST_SystemX11::lastEventTime(Time default_time) +{ + init_timestamp_data data; + data.timestamp = default_time; + XEvent ev; + XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer)&data); - return data.timestamp; + return data.timestamp; } -bool -GHOST_SystemX11:: -processEvents( - bool waitForEvent) +bool GHOST_SystemX11::processEvents(bool waitForEvent) { - /* Get all the current events -- translate them into - * ghost events and call base class pushEvent() method. */ + /* Get all the current events -- translate them into + * ghost events and call base class pushEvent() method. */ - bool anyProcessed = false; + bool anyProcessed = false; - do { - GHOST_TimerManager *timerMgr = getTimerManager(); + do { + GHOST_TimerManager *timerMgr = getTimerManager(); - if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) { - GHOST_TUns64 next = timerMgr->nextFireTime(); + if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) { + GHOST_TUns64 next = timerMgr->nextFireTime(); - if (next == GHOST_kFireTimeNever) { - SleepTillEvent(m_display, -1); - } - else { - GHOST_TInt64 maxSleep = next - getMilliSeconds(); + if (next == GHOST_kFireTimeNever) { + SleepTillEvent(m_display, -1); + } + else { + GHOST_TInt64 maxSleep = next - getMilliSeconds(); - if (maxSleep >= 0) - SleepTillEvent(m_display, next - getMilliSeconds()); - } - } + if (maxSleep >= 0) + SleepTillEvent(m_display, next - getMilliSeconds()); + } + } - if (timerMgr->fireTimers(getMilliSeconds())) { - anyProcessed = true; - } + if (timerMgr->fireTimers(getMilliSeconds())) { + anyProcessed = true; + } - while (XPending(m_display)) { - XEvent xevent; - XNextEvent(m_display, &xevent); + while (XPending(m_display)) { + XEvent xevent; + XNextEvent(m_display, &xevent); #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - /* open connection to XIM server and create input context (XIC) - * when receiving the first FocusIn or KeyPress event after startup, - * or recover XIM and XIC when the XIM server has been restarted */ - if (xevent.type == FocusIn || xevent.type == KeyPress) { - if (!m_xim && openX11_IM()) { - GHOST_PRINT("Connected to XIM server\n"); - } - - if (m_xim) { - GHOST_WindowX11 * window = findGhostWindow(xevent.xany.window); - if (window && !window->getX11_XIC() && window->createX11_XIC()) { - GHOST_PRINT("XIM input context created\n"); - if (xevent.type == KeyPress) - /* we can assume the window has input focus - * here, because key events are received only - * when the window is focused. */ - XSetICFocus(window->getX11_XIC()); - } - } - } - - /* dispatch event to XIM server */ - if ((XFilterEvent(&xevent, (Window)NULL) == True)) { - /* do nothing now, the event is consumed by XIM. */ - continue; - } + /* open connection to XIM server and create input context (XIC) + * when receiving the first FocusIn or KeyPress event after startup, + * or recover XIM and XIC when the XIM server has been restarted */ + if (xevent.type == FocusIn || xevent.type == KeyPress) { + if (!m_xim && openX11_IM()) { + GHOST_PRINT("Connected to XIM server\n"); + } + + if (m_xim) { + GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); + if (window && !window->getX11_XIC() && window->createX11_XIC()) { + GHOST_PRINT("XIM input context created\n"); + if (xevent.type == KeyPress) + /* we can assume the window has input focus + * here, because key events are received only + * when the window is focused. */ + XSetICFocus(window->getX11_XIC()); + } + } + } + + /* dispatch event to XIM server */ + if ((XFilterEvent(&xevent, (Window)NULL) == True)) { + /* do nothing now, the event is consumed by XIM. */ + continue; + } #endif - /* when using autorepeat, some keypress events can actually come *after* the - * last keyrelease. The next code takes care of that */ - if (xevent.type == KeyRelease) { - m_last_release_keycode = xevent.xkey.keycode; - m_last_release_time = xevent.xkey.time; - } - else if (xevent.type == KeyPress) { - if ((xevent.xkey.keycode == m_last_release_keycode) && ((xevent.xkey.time <= m_last_release_time))) - continue; - } - - processEvent(&xevent); - anyProcessed = true; - + /* when using autorepeat, some keypress events can actually come *after* the + * last keyrelease. The next code takes care of that */ + if (xevent.type == KeyRelease) { + m_last_release_keycode = xevent.xkey.keycode; + m_last_release_time = xevent.xkey.time; + } + else if (xevent.type == KeyPress) { + if ((xevent.xkey.keycode == m_last_release_keycode) && + ((xevent.xkey.time <= m_last_release_time))) + continue; + } + + processEvent(&xevent); + anyProcessed = true; #ifdef USE_UNITY_WORKAROUND - /* note: processEvent() can't include this code because - * KeymapNotify event have no valid window information. */ - - /* the X server generates KeymapNotify event immediately after - * every EnterNotify and FocusIn event. we handle this event - * to correct modifier states. */ - if (xevent.type == FocusIn) { - /* use previous event's window, because KeymapNotify event - * has no window information. */ - GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); - if (window && XPending(m_display) >= 2) { - XNextEvent(m_display, &xevent); - - if (xevent.type == KeymapNotify) { - XEvent xev_next; - - /* check if KeyPress or KeyRelease event was generated - * in order to confirm the window is active. */ - XPeekEvent(m_display, &xev_next); - - if (xev_next.type == KeyPress || xev_next.type == KeyRelease) { - /* XK_Hyper_L/R currently unused */ - const static KeySym modifiers[8] = {XK_Shift_L, XK_Shift_R, - XK_Control_L, XK_Control_R, - XK_Alt_L, XK_Alt_R, - XK_Super_L, XK_Super_R}; - - for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) { - KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]); - if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) { - pushEvent(new GHOST_EventKey( - getMilliSeconds(), - GHOST_kEventKeyDown, - window, - ghost_key_from_keysym(modifiers[i]), - '\0', - NULL)); - } - } - } - } - } - } -#endif /* USE_UNITY_WORKAROUND */ - - } - - if (generateWindowExposeEvents()) { - anyProcessed = true; - } + /* note: processEvent() can't include this code because + * KeymapNotify event have no valid window information. */ + + /* the X server generates KeymapNotify event immediately after + * every EnterNotify and FocusIn event. we handle this event + * to correct modifier states. */ + if (xevent.type == FocusIn) { + /* use previous event's window, because KeymapNotify event + * has no window information. */ + GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); + if (window && XPending(m_display) >= 2) { + XNextEvent(m_display, &xevent); + + if (xevent.type == KeymapNotify) { + XEvent xev_next; + + /* check if KeyPress or KeyRelease event was generated + * in order to confirm the window is active. */ + XPeekEvent(m_display, &xev_next); + + if (xev_next.type == KeyPress || xev_next.type == KeyRelease) { + /* XK_Hyper_L/R currently unused */ + const static KeySym modifiers[8] = {XK_Shift_L, + XK_Shift_R, + XK_Control_L, + XK_Control_R, + XK_Alt_L, + XK_Alt_R, + XK_Super_L, + XK_Super_R}; + + for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) { + KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]); + if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) { + pushEvent(new GHOST_EventKey(getMilliSeconds(), + GHOST_kEventKeyDown, + window, + ghost_key_from_keysym(modifiers[i]), + '\0', + NULL)); + } + } + } + } + } + } +#endif /* USE_UNITY_WORKAROUND */ + } + + if (generateWindowExposeEvents()) { + anyProcessed = true; + } #ifdef WITH_INPUT_NDOF - if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) { - anyProcessed = true; - } + if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) { + anyProcessed = true; + } #endif - } while (waitForEvent && !anyProcessed); + } while (waitForEvent && !anyProcessed); - return anyProcessed; + return anyProcessed; } - #ifdef WITH_X11_XINPUT static bool checkTabletProximity(Display *display, XDevice *device) { - /* we could have true/false/not-found return value, but for now false is OK */ - - /* see: state.c from xinput, to get more data out of the device */ - XDeviceState *state; - - if (device == NULL) { - return false; - } - - /* needed since unplugging will abort() without this */ - GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); - - state = XQueryDeviceState(display, device); - - GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); - - if (state) { - XInputClass *cls = state->data; - // printf("%d class%s :\n", state->num_classes, - // (state->num_classes > 1) ? "es" : ""); - for (int loop = 0; loop < state->num_classes; loop++) { - switch (cls->c_class) { - case ValuatorClass: - XValuatorState *val_state = (XValuatorState *)cls; - // printf("ValuatorClass Mode=%s Proximity=%s\n", - // val_state->mode & 1 ? "Absolute" : "Relative", - // val_state->mode & 2 ? "Out" : "In"); - - if ((val_state->mode & 2) == 0) { - XFreeDeviceState(state); - return true; - } - break; - } - cls = (XInputClass *) ((char *)cls + cls->length); - } - XFreeDeviceState(state); - } - return false; + /* we could have true/false/not-found return value, but for now false is OK */ + + /* see: state.c from xinput, to get more data out of the device */ + XDeviceState *state; + + if (device == NULL) { + return false; + } + + /* needed since unplugging will abort() without this */ + GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); + + state = XQueryDeviceState(display, device); + + GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); + + if (state) { + XInputClass *cls = state->data; + // printf("%d class%s :\n", state->num_classes, + // (state->num_classes > 1) ? "es" : ""); + for (int loop = 0; loop < state->num_classes; loop++) { + switch (cls->c_class) { + case ValuatorClass: + XValuatorState *val_state = (XValuatorState *)cls; + // printf("ValuatorClass Mode=%s Proximity=%s\n", + // val_state->mode & 1 ? "Absolute" : "Relative", + // val_state->mode & 2 ? "Out" : "In"); + + if ((val_state->mode & 2) == 0) { + XFreeDeviceState(state); + return true; + } + break; + } + cls = (XInputClass *)((char *)cls + cls->length); + } + XFreeDeviceState(state); + } + return false; } #endif /* WITH_X11_XINPUT */ -void -GHOST_SystemX11::processEvent(XEvent *xe) +void GHOST_SystemX11::processEvent(XEvent *xe) { - GHOST_WindowX11 *window = findGhostWindow(xe->xany.window); - GHOST_Event *g_event = NULL; + GHOST_WindowX11 *window = findGhostWindow(xe->xany.window); + GHOST_Event *g_event = NULL; #ifdef USE_XINPUT_HOTPLUG - /* Hot-Plug support */ - if (m_xinput_version.present) { - XEventClass class_presence; - int xi_presence; - - DevicePresence(m_display, xi_presence, class_presence); - (void)class_presence; - - if (xe->type == xi_presence) { - XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe; - if ((notify_event->devchange == DeviceEnabled) || - (notify_event->devchange == DeviceDisabled) || - (notify_event->devchange == DeviceAdded) || - (notify_event->devchange == DeviceRemoved)) - { - refreshXInputDevices(); - - /* update all window events */ - { - 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); - window->refreshXInputDevices(); - } - } - } - } - } -#endif /* USE_XINPUT_HOTPLUG */ - - - if (!window) { - return; - } + /* Hot-Plug support */ + if (m_xinput_version.present) { + XEventClass class_presence; + int xi_presence; + + DevicePresence(m_display, xi_presence, class_presence); + (void)class_presence; + + if (xe->type == xi_presence) { + XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe; + if ((notify_event->devchange == DeviceEnabled) || + (notify_event->devchange == DeviceDisabled) || + (notify_event->devchange == DeviceAdded) || (notify_event->devchange == DeviceRemoved)) { + refreshXInputDevices(); + + /* update all window events */ + { + 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); + window->refreshXInputDevices(); + } + } + } + } + } +#endif /* USE_XINPUT_HOTPLUG */ + + if (!window) { + return; + } #ifdef WITH_X11_XINPUT - /* Proximity-Out Events are not reliable, if the tablet is active - check on each event - * this adds a little overhead but only while the tablet is in use. - * in the future we could have a ghost call window->CheckTabletProximity() - * but for now enough parts of the code are checking 'Active' - * - campbell */ - if (window->GetTabletData()->Active != GHOST_kTabletModeNone) { - bool any_proximity = false; - - for (GHOST_TabletX11& xtablet: m_xtablets) { - if (checkTabletProximity(xe->xany.display, xtablet.Device)) { - any_proximity = true; - } - } - - if (!any_proximity) { - // printf("proximity disable\n"); - window->GetTabletData()->Active = GHOST_kTabletModeNone; - } - } + /* Proximity-Out Events are not reliable, if the tablet is active - check on each event + * this adds a little overhead but only while the tablet is in use. + * in the future we could have a ghost call window->CheckTabletProximity() + * but for now enough parts of the code are checking 'Active' + * - campbell */ + if (window->GetTabletData()->Active != GHOST_kTabletModeNone) { + bool any_proximity = false; + + for (GHOST_TabletX11 &xtablet : m_xtablets) { + if (checkTabletProximity(xe->xany.display, xtablet.Device)) { + any_proximity = true; + } + } + + if (!any_proximity) { + // printf("proximity disable\n"); + window->GetTabletData()->Active = GHOST_kTabletModeNone; + } + } #endif /* WITH_X11_XINPUT */ - 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; + 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; #ifdef WITH_X11_XINPUT - bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone; + bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone; #else - bool is_tablet = false; + bool is_tablet = false; #endif - if (is_tablet == false && window->getCursorGrabModeIsWarp()) { - GHOST_TInt32 x_new = xme.x_root; - GHOST_TInt32 y_new = xme.y_root; - GHOST_TInt32 x_accum, y_accum; - GHOST_Rect bounds; - - /* fallback to window bounds */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) - window->getClientBounds(bounds); - - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ - window->getCursorGrabAccum(x_accum, y_accum); - - if (x_new != xme.x_root || y_new != xme.y_root) { - if (xme.time > m_last_warp) { - /* when wrapping we don't need to add an event because the - * setCursorPosition call will cause a new event after */ - setCursorPosition(x_new, y_new); /* wrap */ - window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new)); - m_last_warp = lastEventTime(xme.time); - } - else { - setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ - } - } - else { - g_event = new - GHOST_EventCursor( - getMilliSeconds(), - GHOST_kEventCursorMove, - window, - xme.x_root + x_accum, - xme.y_root + y_accum - ); - } - } - else { - 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; - char ascii; + if (is_tablet == false && window->getCursorGrabModeIsWarp()) { + GHOST_TInt32 x_new = xme.x_root; + GHOST_TInt32 y_new = xme.y_root; + GHOST_TInt32 x_accum, y_accum; + GHOST_Rect bounds; + + /* fallback to window bounds */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) + window->getClientBounds(bounds); + + /* could also clamp to screen bounds + * wrap with a window outside the view will fail atm */ + bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ + window->getCursorGrabAccum(x_accum, y_accum); + + if (x_new != xme.x_root || y_new != xme.y_root) { + if (xme.time > m_last_warp) { + /* when wrapping we don't need to add an event because the + * setCursorPosition call will cause a new event after */ + setCursorPosition(x_new, y_new); /* wrap */ + window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), + y_accum + (xme.y_root - y_new)); + m_last_warp = lastEventTime(xme.time); + } + else { + setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ + } + } + else { + g_event = new GHOST_EventCursor(getMilliSeconds(), + GHOST_kEventCursorMove, + window, + xme.x_root + x_accum, + xme.y_root + y_accum); + } + } + else { + 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; + char ascii; #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - /* utf8_array[] is initial buffer used for Xutf8LookupString(). - * if the length of the utf8 string exceeds this array, allocate - * another memory area and call Xutf8LookupString() again. - * the last 5 bytes are used to avoid segfault that might happen - * at the end of this buffer when the constructor of GHOST_EventKey - * reads 6 bytes regardless of the effective data length. */ - char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */ - char *utf8_buf = utf8_array; - int len = 1; /* at least one null character will be stored */ + /* utf8_array[] is initial buffer used for Xutf8LookupString(). + * if the length of the utf8 string exceeds this array, allocate + * another memory area and call Xutf8LookupString() again. + * the last 5 bytes are used to avoid segfault that might happen + * at the end of this buffer when the constructor of GHOST_EventKey + * reads 6 bytes regardless of the effective data length. */ + char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */ + char *utf8_buf = utf8_array; + int len = 1; /* at least one null character will be stored */ #else - char *utf8_buf = NULL; + char *utf8_buf = NULL; #endif - GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; + GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; - GHOST_TKey gkey; + GHOST_TKey gkey; #ifdef USE_NON_LATIN_KB_WORKAROUND - /* XXX Code below is kinda awfully convoluted... Issues are: - * - * - In keyboards like latin ones, numbers need a 'Shift' to be accessed but key_sym - * is unmodified (or anyone swapping the keys with xmodmap). - * - * - XLookupKeysym seems to always use first defined keymap (see T47228), which generates - * keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps. - * - * To address this, we: - * - * - Try to get a 'number' key_sym using XLookupKeysym (with virtual shift modifier), - * in a very restrictive set of cases. - * - Fallback to XLookupString to get a key_sym from active user-defined keymap. - * - * Note that: - * - This effectively 'lock' main number keys to always output number events (except when using alt-gr). - * - This enforces users to use an ascii-compatible keymap with Blender - but at least it gives - * predictable and consistent results. - * - * Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different - * key_sym results... - * - * [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c - */ - KeySym key_sym_str; - /* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply - * that 'forced number' hack. */ - const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch); - const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask; - if ((xke->keycode >= 10 && xke->keycode < 20) && ((xke->state & number_hack_forbidden_kmods_mask) == 0)) { - key_sym = XLookupKeysym(xke, ShiftMask); - if (!((key_sym >= XK_0) && (key_sym <= XK_9))) { - key_sym = XLookupKeysym(xke, 0); - } - } - else { - key_sym = XLookupKeysym(xke, 0); - } - - if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) { - ascii = '\0'; - } - - /* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString, - * unless it gives unknown key... */ - gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode); - switch (gkey) { - case GHOST_kKeyRightAlt: - case GHOST_kKeyLeftAlt: - case GHOST_kKeyRightShift: - case GHOST_kKeyLeftShift: - case GHOST_kKeyRightControl: - case GHOST_kKeyLeftControl: - case GHOST_kKeyOS: - case GHOST_kKey0: - case GHOST_kKey1: - case GHOST_kKey2: - case GHOST_kKey3: - case GHOST_kKey4: - case GHOST_kKey5: - case GHOST_kKey6: - case GHOST_kKey7: - case GHOST_kKey8: - case GHOST_kKey9: - case GHOST_kKeyNumpad0: - case GHOST_kKeyNumpad1: - case GHOST_kKeyNumpad2: - case GHOST_kKeyNumpad3: - case GHOST_kKeyNumpad4: - case GHOST_kKeyNumpad5: - case GHOST_kKeyNumpad6: - case GHOST_kKeyNumpad7: - case GHOST_kKeyNumpad8: - case GHOST_kKeyNumpad9: - case GHOST_kKeyNumpadPeriod: - case GHOST_kKeyNumpadEnter: - case GHOST_kKeyNumpadPlus: - case GHOST_kKeyNumpadMinus: - case GHOST_kKeyNumpadAsterisk: - case GHOST_kKeyNumpadSlash: - break; - default: - { - GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str); - if (gkey_str != GHOST_kKeyUnknown) { - gkey = gkey_str; - } - } - } + /* XXX Code below is kinda awfully convoluted... Issues are: + * + * - In keyboards like latin ones, numbers need a 'Shift' to be accessed but key_sym + * is unmodified (or anyone swapping the keys with xmodmap). + * + * - XLookupKeysym seems to always use first defined keymap (see T47228), which generates + * keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps. + * + * To address this, we: + * + * - Try to get a 'number' key_sym using XLookupKeysym (with virtual shift modifier), + * in a very restrictive set of cases. + * - Fallback to XLookupString to get a key_sym from active user-defined keymap. + * + * Note that: + * - This effectively 'lock' main number keys to always output number events (except when using alt-gr). + * - This enforces users to use an ascii-compatible keymap with Blender - but at least it gives + * predictable and consistent results. + * + * Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different + * key_sym results... + * + * [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c + */ + KeySym key_sym_str; + /* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply + * that 'forced number' hack. */ + const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch); + const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask; + if ((xke->keycode >= 10 && xke->keycode < 20) && + ((xke->state & number_hack_forbidden_kmods_mask) == 0)) { + key_sym = XLookupKeysym(xke, ShiftMask); + if (!((key_sym >= XK_0) && (key_sym <= XK_9))) { + key_sym = XLookupKeysym(xke, 0); + } + } + else { + key_sym = XLookupKeysym(xke, 0); + } + + if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) { + ascii = '\0'; + } + + /* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString, + * unless it gives unknown key... */ + gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode); + switch (gkey) { + case GHOST_kKeyRightAlt: + case GHOST_kKeyLeftAlt: + case GHOST_kKeyRightShift: + case GHOST_kKeyLeftShift: + case GHOST_kKeyRightControl: + case GHOST_kKeyLeftControl: + case GHOST_kKeyOS: + case GHOST_kKey0: + case GHOST_kKey1: + case GHOST_kKey2: + case GHOST_kKey3: + case GHOST_kKey4: + case GHOST_kKey5: + case GHOST_kKey6: + case GHOST_kKey7: + case GHOST_kKey8: + case GHOST_kKey9: + case GHOST_kKeyNumpad0: + case GHOST_kKeyNumpad1: + case GHOST_kKeyNumpad2: + case GHOST_kKeyNumpad3: + case GHOST_kKeyNumpad4: + case GHOST_kKeyNumpad5: + case GHOST_kKeyNumpad6: + case GHOST_kKeyNumpad7: + case GHOST_kKeyNumpad8: + case GHOST_kKeyNumpad9: + case GHOST_kKeyNumpadPeriod: + case GHOST_kKeyNumpadEnter: + case GHOST_kKeyNumpadPlus: + case GHOST_kKeyNumpadMinus: + case GHOST_kKeyNumpadAsterisk: + case GHOST_kKeyNumpadSlash: + break; + default: { + GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str); + if (gkey_str != GHOST_kKeyUnknown) { + gkey = gkey_str; + } + } + } #else - /* In keyboards like latin ones, - * numbers needs a 'Shift' to be accessed but key_sym - * is unmodified (or anyone swapping the keys with xmodmap). - * - * Here we look at the 'Shifted' version of the key. - * If it is a number, then we take it instead of the normal key. - * - * The modified key is sent in the 'ascii's variable anyway. - */ - if ((xke->keycode >= 10 && xke->keycode < 20) && - ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9)) - { - /* pass (keep shift'ed key_sym) */ - } - else { - /* regular case */ - key_sym = XLookupKeysym(xke, 0); - } - - gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode); - - if (!XLookupString(xke, &ascii, 1, NULL, NULL)) { - ascii = '\0'; - } + /* In keyboards like latin ones, + * numbers needs a 'Shift' to be accessed but key_sym + * is unmodified (or anyone swapping the keys with xmodmap). + * + * Here we look at the 'Shifted' version of the key. + * If it is a number, then we take it instead of the normal key. + * + * The modified key is sent in the 'ascii's variable anyway. + */ + if ((xke->keycode >= 10 && xke->keycode < 20) && + ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9)) { + /* pass (keep shift'ed key_sym) */ + } + else { + /* regular case */ + key_sym = XLookupKeysym(xke, 0); + } + + gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode); + + if (!XLookupString(xke, &ascii, 1, NULL, NULL)) { + ascii = '\0'; + } #endif #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - /* getting unicode on key-up events gives XLookupNone status */ - XIC xic = window->getX11_XIC(); - if (xic && xke->type == KeyPress) { - Status status; - - /* use utf8 because its not locale depentant, from xorg docs */ - if (!(len = Xutf8LookupString(xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) { - utf8_buf[0] = '\0'; - } - - if (status == XBufferOverflow) { - utf8_buf = (char *) malloc(len + 5); - len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status); - } - - if ((status == XLookupChars || status == XLookupBoth)) { - if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */ - /* do nothing for now, this is valid utf8 */ - } - else { - utf8_buf[0] = '\0'; - } - } - else if (status == XLookupKeySym) { - /* this key doesn't have a text representation, it is a command - * key of some sort */ - } - else { - printf("Bad keycode lookup. Keysym 0x%x Status: %s\n", - (unsigned int) key_sym, - (status == XLookupNone ? "XLookupNone" : - status == XLookupKeySym ? "XLookupKeySym" : - "Unknown status")); - - printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim); - } - } - else { - utf8_buf[0] = '\0'; - } + /* getting unicode on key-up events gives XLookupNone status */ + XIC xic = window->getX11_XIC(); + if (xic && xke->type == KeyPress) { + Status status; + + /* use utf8 because its not locale depentant, from xorg docs */ + if (!(len = Xutf8LookupString( + xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) { + utf8_buf[0] = '\0'; + } + + if (status == XBufferOverflow) { + utf8_buf = (char *)malloc(len + 5); + len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status); + } + + if ((status == XLookupChars || status == XLookupBoth)) { + if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */ + /* do nothing for now, this is valid utf8 */ + } + else { + utf8_buf[0] = '\0'; + } + } + else if (status == XLookupKeySym) { + /* this key doesn't have a text representation, it is a command + * key of some sort */ + } + else { + printf("Bad keycode lookup. Keysym 0x%x Status: %s\n", + (unsigned int)key_sym, + (status == XLookupNone ? + "XLookupNone" : + status == XLookupKeySym ? "XLookupKeySym" : "Unknown status")); + + printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim); + } + } + else { + utf8_buf[0] = '\0'; + } #endif - g_event = new - GHOST_EventKey( - getMilliSeconds(), - type, - window, - gkey, - ascii, - utf8_buf - ); + g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, ascii, utf8_buf); #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - /* when using IM for some languages such as Japanese, - * one event inserts multiple utf8 characters */ - if (xic && xke->type == KeyPress) { - unsigned char c; - int i = 0; - while (1) { - /* search character boundary */ - if ((unsigned char)utf8_buf[i++] > 0x7f) { - for (; i < len; ++i) { - c = utf8_buf[i]; - if (c < 0x80 || c > 0xbf) break; - } - } - - if (i >= len) break; - - /* enqueue previous character */ - pushEvent(g_event); - - g_event = new - GHOST_EventKey( - getMilliSeconds(), - type, - window, - gkey, - '\0', - &utf8_buf[i] - ); - } - } - - if (utf8_buf != utf8_array) - free(utf8_buf); + /* when using IM for some languages such as Japanese, + * one event inserts multiple utf8 characters */ + if (xic && xke->type == KeyPress) { + unsigned char c; + int i = 0; + while (1) { + /* search character boundary */ + if ((unsigned char)utf8_buf[i++] > 0x7f) { + for (; i < len; ++i) { + c = utf8_buf[i]; + if (c < 0x80 || c > 0xbf) + break; + } + } + + if (i >= len) + break; + + /* enqueue previous character */ + pushEvent(g_event); + + g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, '\0', &utf8_buf[i]); + } + } + + if (utf8_buf != utf8_array) + free(utf8_buf); #endif - break; - } - - case ButtonPress: - case ButtonRelease: - { - XButtonEvent & xbe = xe->xbutton; - GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft; - GHOST_TEventType type = (xbe.type == ButtonPress) ? - GHOST_kEventButtonDown : GHOST_kEventButtonUp; - - /* process wheel mouse events and break, only pass on press events */ - if (xbe.button == Button4) { - if (xbe.type == ButtonPress) - g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1); - break; - } - else if (xbe.button == Button5) { - if (xbe.type == ButtonPress) - g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1); - break; - } - - /* process rest of normal mouse buttons */ - if (xbe.button == Button1) - gbmask = GHOST_kButtonMaskLeft; - else if (xbe.button == Button2) - gbmask = GHOST_kButtonMaskMiddle; - else if (xbe.button == Button3) - gbmask = GHOST_kButtonMaskRight; - /* It seems events 6 and 7 are for horizontal scrolling. - * you can re-order button mapping like this... (swaps 6,7 with 8,9) - * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" - */ - else if (xbe.button == 6) - gbmask = GHOST_kButtonMaskButton6; - else if (xbe.button == 7) - gbmask = GHOST_kButtonMaskButton7; - else if (xbe.button == 8) - gbmask = GHOST_kButtonMaskButton4; - else if (xbe.button == 9) - gbmask = GHOST_kButtonMaskButton5; - else - break; - - 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; - - /* TODO: make sure this is the correct place for activate/deactivate */ - // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window); - - /* May have to look at the type of event and filter some out. */ - - GHOST_TEventType gtype = (xfe.type == FocusIn) ? - GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate; + break; + } + + case ButtonPress: + case ButtonRelease: { + XButtonEvent &xbe = xe->xbutton; + GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft; + GHOST_TEventType type = (xbe.type == ButtonPress) ? GHOST_kEventButtonDown : + GHOST_kEventButtonUp; + + /* process wheel mouse events and break, only pass on press events */ + if (xbe.button == Button4) { + if (xbe.type == ButtonPress) + g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1); + break; + } + else if (xbe.button == Button5) { + if (xbe.type == ButtonPress) + g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1); + break; + } + + /* process rest of normal mouse buttons */ + if (xbe.button == Button1) + gbmask = GHOST_kButtonMaskLeft; + else if (xbe.button == Button2) + gbmask = GHOST_kButtonMaskMiddle; + else if (xbe.button == Button3) + gbmask = GHOST_kButtonMaskRight; + /* It seems events 6 and 7 are for horizontal scrolling. + * you can re-order button mapping like this... (swaps 6,7 with 8,9) + * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" + */ + else if (xbe.button == 6) + gbmask = GHOST_kButtonMaskButton6; + else if (xbe.button == 7) + gbmask = GHOST_kButtonMaskButton7; + else if (xbe.button == 8) + gbmask = GHOST_kButtonMaskButton4; + else if (xbe.button == 9) + gbmask = GHOST_kButtonMaskButton5; + else + break; + + 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; + + /* TODO: make sure this is the correct place for activate/deactivate */ + // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window); + + /* May have to look at the type of event and filter some out. */ + + GHOST_TEventType gtype = (xfe.type == FocusIn) ? GHOST_kEventWindowActivate : + GHOST_kEventWindowDeactivate; #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - XIC xic = window->getX11_XIC(); - if (xic) { - if (xe->type == FocusIn) - XSetICFocus(xic); - else - XUnsetICFocus(xic); - } + XIC xic = window->getX11_XIC(); + if (xic) { + if (xe->type == FocusIn) + XSetICFocus(xic); + else + XUnsetICFocus(xic); + } #endif - g_event = new - GHOST_Event( - getMilliSeconds(), - gtype, - window - ); - break; - - } - case ClientMessage: - { - XClientMessageEvent & xcme = xe->xclient; - - if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) { - g_event = new - GHOST_Event( - getMilliSeconds(), - GHOST_kEventWindowClose, - window - ); - } - else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) { - XWindowAttributes attr; - Window fwin; - int revert_to; - - /* as ICCCM say, we need reply this event - * with a SetInputFocus, the data[1] have - * the valid timestamp (send by the wm). - * - * Some WM send this event before the - * window is really mapped (for example - * change from virtual desktop), so we need - * to be sure that our windows is mapped - * or this call fail and close blender. - */ - if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) { - if (XGetInputFocus(m_display, &fwin, &revert_to) == True) { - if (attr.map_state == IsViewable) { - if (fwin != xcme.window) - XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]); - } - } - } - } - else { + g_event = new GHOST_Event(getMilliSeconds(), gtype, window); + break; + } + case ClientMessage: { + XClientMessageEvent &xcme = xe->xclient; + + if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) { + g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window); + } + else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) { + XWindowAttributes attr; + Window fwin; + int revert_to; + + /* as ICCCM say, we need reply this event + * with a SetInputFocus, the data[1] have + * the valid timestamp (send by the wm). + * + * Some WM send this event before the + * window is really mapped (for example + * change from virtual desktop), so we need + * to be sure that our windows is mapped + * or this call fail and close blender. + */ + if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) { + if (XGetInputFocus(m_display, &fwin, &revert_to) == True) { + if (attr.map_state == IsViewable) { + if (fwin != xcme.window) + XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]); + } + } + } + } + else { #ifdef WITH_XDND - /* try to handle drag event (if there's no such events, GHOST_HandleClientMessage will return zero) */ - if (window->getDropTarget()->GHOST_HandleClientMessage(xe) == false) { - /* Unknown client message, ignore */ - } + /* try to handle drag event (if there's no such events, GHOST_HandleClientMessage will return zero) */ + if (window->getDropTarget()->GHOST_HandleClientMessage(xe) == false) { + /* Unknown client message, ignore */ + } #else - /* Unknown client message, ignore */ + /* Unknown client message, ignore */ #endif - } - - break; - } - - case DestroyNotify: - ::exit(-1); - /* We're not interested in the following things.(yet...) */ - case NoExpose: - case GraphicsExpose: - break; - - case EnterNotify: - case LeaveNotify: - { - /* XCrossingEvents pointer leave enter window. - * also do cursor move here, MotionNotify only - * happens when motion starts & ends inside window. - * we only do moves when the crossing mode is 'normal' - * (really crossing between windows) since some windowmanagers - * also send grab/ungrab crossings for mousewheel events. - */ - XCrossingEvent &xce = xe->xcrossing; - if (xce.mode == NotifyNormal) { - g_event = new - GHOST_EventCursor( - getMilliSeconds(), - GHOST_kEventCursorMove, - window, - xce.x_root, - xce.y_root - ); - } - - // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window); - - if (xce.type == EnterNotify) - m_windowManager->setActiveWindow(window); - else - m_windowManager->setWindowInactive(window); - - break; - } - case MapNotify: - /* - * From ICCCM: - * [ Clients can select for StructureNotify on their - * top-level windows to track transition between - * Normal and Iconic states. Receipt of a MapNotify - * event will indicate a transition to the Normal - * state, and receipt of an UnmapNotify event will - * indicate a transition to the Iconic state. ] - */ - if (window->m_post_init == True) { - /* - * Now we are sure that the window is - * mapped, so only need change the state. - */ - window->setState(window->m_post_state); - window->m_post_init = False; - } - break; - case UnmapNotify: - break; - case MappingNotify: - case ReparentNotify: - break; - case SelectionRequest: - { - XEvent nxe; - Atom target, utf8_string, string, compound_text, c_string; - XSelectionRequestEvent *xse = &xe->xselectionrequest; - - target = XInternAtom(m_display, "TARGETS", False); - utf8_string = XInternAtom(m_display, "UTF8_STRING", False); - string = XInternAtom(m_display, "STRING", False); - compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False); - c_string = XInternAtom(m_display, "C_STRING", False); - - /* support obsolete clients */ - if (xse->property == None) { - xse->property = xse->target; - } - - nxe.xselection.type = SelectionNotify; - nxe.xselection.requestor = xse->requestor; - nxe.xselection.property = xse->property; - nxe.xselection.display = xse->display; - nxe.xselection.selection = xse->selection; - nxe.xselection.target = xse->target; - nxe.xselection.time = xse->time; - - /* Check to see if the requestor is asking for String */ - if (xse->target == utf8_string || - xse->target == string || - xse->target == compound_text || - xse->target == c_string) - { - if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) { - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, - (unsigned char *)txt_select_buffer, strlen(txt_select_buffer)); - } - else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) { - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, - (unsigned char *)txt_cut_buffer, strlen(txt_cut_buffer)); - } - } - else if (xse->target == target) { - Atom alist[5]; - alist[0] = target; - alist[1] = utf8_string; - alist[2] = string; - alist[3] = compound_text; - alist[4] = c_string; - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace, - (unsigned char *)alist, 5); - XFlush(m_display); - } - else { - /* Change property to None because we do not support anything but STRING */ - nxe.xselection.property = None; - } - - /* Send the event to the client 0 0 == False, SelectionNotify */ - XSendEvent(m_display, xse->requestor, 0, 0, &nxe); - XFlush(m_display); - break; - } - - default: - { + } + + break; + } + + case DestroyNotify: + ::exit(-1); + /* We're not interested in the following things.(yet...) */ + case NoExpose: + case GraphicsExpose: + break; + + case EnterNotify: + case LeaveNotify: { + /* XCrossingEvents pointer leave enter window. + * also do cursor move here, MotionNotify only + * happens when motion starts & ends inside window. + * we only do moves when the crossing mode is 'normal' + * (really crossing between windows) since some windowmanagers + * also send grab/ungrab crossings for mousewheel events. + */ + XCrossingEvent &xce = xe->xcrossing; + if (xce.mode == NotifyNormal) { + g_event = new GHOST_EventCursor( + getMilliSeconds(), GHOST_kEventCursorMove, window, xce.x_root, xce.y_root); + } + + // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window); + + if (xce.type == EnterNotify) + m_windowManager->setActiveWindow(window); + else + m_windowManager->setWindowInactive(window); + + break; + } + case MapNotify: + /* + * From ICCCM: + * [ Clients can select for StructureNotify on their + * top-level windows to track transition between + * Normal and Iconic states. Receipt of a MapNotify + * event will indicate a transition to the Normal + * state, and receipt of an UnmapNotify event will + * indicate a transition to the Iconic state. ] + */ + if (window->m_post_init == True) { + /* + * Now we are sure that the window is + * mapped, so only need change the state. + */ + window->setState(window->m_post_state); + window->m_post_init = False; + } + break; + case UnmapNotify: + break; + case MappingNotify: + case ReparentNotify: + break; + case SelectionRequest: { + XEvent nxe; + Atom target, utf8_string, string, compound_text, c_string; + XSelectionRequestEvent *xse = &xe->xselectionrequest; + + target = XInternAtom(m_display, "TARGETS", False); + utf8_string = XInternAtom(m_display, "UTF8_STRING", False); + string = XInternAtom(m_display, "STRING", False); + compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False); + c_string = XInternAtom(m_display, "C_STRING", False); + + /* support obsolete clients */ + if (xse->property == None) { + xse->property = xse->target; + } + + nxe.xselection.type = SelectionNotify; + nxe.xselection.requestor = xse->requestor; + nxe.xselection.property = xse->property; + nxe.xselection.display = xse->display; + nxe.xselection.selection = xse->selection; + nxe.xselection.target = xse->target; + nxe.xselection.time = xse->time; + + /* Check to see if the requestor is asking for String */ + if (xse->target == utf8_string || xse->target == string || xse->target == compound_text || + xse->target == c_string) { + if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) { + XChangeProperty(m_display, + xse->requestor, + xse->property, + xse->target, + 8, + PropModeReplace, + (unsigned char *)txt_select_buffer, + strlen(txt_select_buffer)); + } + else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) { + XChangeProperty(m_display, + xse->requestor, + xse->property, + xse->target, + 8, + PropModeReplace, + (unsigned char *)txt_cut_buffer, + strlen(txt_cut_buffer)); + } + } + else if (xse->target == target) { + Atom alist[5]; + alist[0] = target; + alist[1] = utf8_string; + alist[2] = string; + alist[3] = compound_text; + alist[4] = c_string; + XChangeProperty(m_display, + xse->requestor, + xse->property, + xse->target, + 32, + PropModeReplace, + (unsigned char *)alist, + 5); + XFlush(m_display); + } + else { + /* Change property to None because we do not support anything but STRING */ + nxe.xselection.property = None; + } + + /* Send the event to the client 0 0 == False, SelectionNotify */ + XSendEvent(m_display, xse->requestor, 0, 0, &nxe); + XFlush(m_display); + break; + } + + default: { #ifdef WITH_X11_XINPUT - for (GHOST_TabletX11& xtablet: m_xtablets) { - if (xe->type == xtablet.MotionEvent || xe->type == xtablet.PressEvent) { - XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe; - if (data->deviceid != xtablet.ID) { - continue; - } - - const unsigned char axis_first = data->first_axis; - const unsigned char axes_end = axis_first + data->axes_count; /* after the last */ - int axis_value; - - /* stroke might begin without leading ProxyIn event, - * this happens when window is opened when stylus is already hovering - * around tablet surface */ - window->GetTabletData()->Active = xtablet.mode; - - /* Note: This event might be generated with incomplete dataset (don't exactly know why, looks like in - * some cases, if the value does not change, it is not included in subsequent XDeviceMotionEvent - * events). So we have to check which values this event actually contains! - */ - -#define AXIS_VALUE_GET(axis, val) \ - ((axis_first <= axis && axes_end > axis) && ((void)(val = data->axis_data[axis - axis_first]), true)) - - if (AXIS_VALUE_GET(2, axis_value)) { - window->GetTabletData()->Pressure = axis_value / ((float)xtablet.PressureLevels); - } - - /* the (short) cast and the & 0xffff is bizarre and unexplained anywhere, - * but I got garbage data without it. Found it in the xidump.c source --matt - * - * The '& 0xffff' just truncates the value to its two lowest bytes, this probably means - * some drivers do not properly set the whole int value? Since we convert to float afterward, - * I don't think we need to cast to short here, but do not have a device to check this. --mont29 - */ - if (AXIS_VALUE_GET(3, axis_value)) { - window->GetTabletData()->Xtilt = (short)(axis_value & 0xffff) / - ((float)xtablet.XtiltLevels); - } - if (AXIS_VALUE_GET(4, axis_value)) { - window->GetTabletData()->Ytilt = (short)(axis_value & 0xffff) / - ((float)xtablet.YtiltLevels); - } - -#undef AXIS_VALUE_GET - - } - else if (xe->type == xtablet.ProxInEvent) { - XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe; - if (data->deviceid != xtablet.ID) { - continue; - } - - window->GetTabletData()->Active = xtablet.mode; - } - else if (xe->type == xtablet.ProxOutEvent) { - window->GetTabletData()->Active = GHOST_kTabletModeNone; - } - } -#endif // WITH_X11_XINPUT - break; - } - } - - if (g_event) { - pushEvent(g_event); - } + for (GHOST_TabletX11 &xtablet : m_xtablets) { + if (xe->type == xtablet.MotionEvent || xe->type == xtablet.PressEvent) { + XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe; + if (data->deviceid != xtablet.ID) { + continue; + } + + const unsigned char axis_first = data->first_axis; + const unsigned char axes_end = axis_first + data->axes_count; /* after the last */ + int axis_value; + + /* stroke might begin without leading ProxyIn event, + * this happens when window is opened when stylus is already hovering + * around tablet surface */ + window->GetTabletData()->Active = xtablet.mode; + + /* Note: This event might be generated with incomplete dataset (don't exactly know why, looks like in + * some cases, if the value does not change, it is not included in subsequent XDeviceMotionEvent + * events). So we have to check which values this event actually contains! + */ + +# define AXIS_VALUE_GET(axis, val) \ + ((axis_first <= axis && axes_end > axis) && \ + ((void)(val = data->axis_data[axis - axis_first]), true)) + + if (AXIS_VALUE_GET(2, axis_value)) { + window->GetTabletData()->Pressure = axis_value / ((float)xtablet.PressureLevels); + } + + /* the (short) cast and the & 0xffff is bizarre and unexplained anywhere, + * but I got garbage data without it. Found it in the xidump.c source --matt + * + * The '& 0xffff' just truncates the value to its two lowest bytes, this probably means + * some drivers do not properly set the whole int value? Since we convert to float afterward, + * I don't think we need to cast to short here, but do not have a device to check this. --mont29 + */ + if (AXIS_VALUE_GET(3, axis_value)) { + window->GetTabletData()->Xtilt = (short)(axis_value & 0xffff) / + ((float)xtablet.XtiltLevels); + } + if (AXIS_VALUE_GET(4, axis_value)) { + window->GetTabletData()->Ytilt = (short)(axis_value & 0xffff) / + ((float)xtablet.YtiltLevels); + } + +# undef AXIS_VALUE_GET + } + else if (xe->type == xtablet.ProxInEvent) { + XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe; + if (data->deviceid != xtablet.ID) { + continue; + } + + window->GetTabletData()->Active = xtablet.mode; + } + else if (xe->type == xtablet.ProxOutEvent) { + window->GetTabletData()->Active = GHOST_kTabletModeNone; + } + } +#endif // WITH_X11_XINPUT + break; + } + } + + if (g_event) { + pushEvent(g_event); + } } -GHOST_TSuccess -GHOST_SystemX11:: -getModifierKeys( - GHOST_ModifierKeys& keys) const +GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const { - /* analyse the masks retuned from XQueryPointer. */ - - memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector)); - - XQueryKeymap(m_display, (char *)m_keyboard_vector); - - /* now translate key symbols into keycodes and - * test with vector. */ - - const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L); - const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R); - const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L); - const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R); - const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L); - const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R); - const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L); - const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R); - - /* shift */ - keys.set(GHOST_kModifierKeyLeftShift, ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0); - keys.set(GHOST_kModifierKeyRightShift, ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0); - /* control */ - keys.set(GHOST_kModifierKeyLeftControl, ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0); - keys.set(GHOST_kModifierKeyRightControl, ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0); - /* alt */ - keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0); - keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0); - /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */ - keys.set(GHOST_kModifierKeyOS, ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) || - ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) != 0); - - return GHOST_kSuccess; + /* analyse the masks retuned from XQueryPointer. */ + + memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector)); + + XQueryKeymap(m_display, (char *)m_keyboard_vector); + + /* now translate key symbols into keycodes and + * test with vector. */ + + const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L); + const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R); + const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L); + const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R); + const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L); + const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R); + const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L); + const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R); + + /* shift */ + keys.set(GHOST_kModifierKeyLeftShift, + ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0); + keys.set(GHOST_kModifierKeyRightShift, + ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0); + /* control */ + keys.set(GHOST_kModifierKeyLeftControl, + ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0); + keys.set(GHOST_kModifierKeyRightControl, + ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0); + /* alt */ + keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0); + keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0); + /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */ + keys.set(GHOST_kModifierKeyOS, + (((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) || + ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0); + + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_SystemX11:: -getButtons( - GHOST_Buttons& buttons) const +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) == True) - { - buttons.set(GHOST_kButtonMaskLeft, (mask_return & Button1Mask) != 0); - buttons.set(GHOST_kButtonMaskMiddle, (mask_return & Button2Mask) != 0); - buttons.set(GHOST_kButtonMaskRight, (mask_return & Button3Mask) != 0); - } - else { - return GHOST_kFailure; - } - - return GHOST_kSuccess; + 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) == True) { + buttons.set(GHOST_kButtonMaskLeft, (mask_return & Button1Mask) != 0); + buttons.set(GHOST_kButtonMaskMiddle, (mask_return & Button2Mask) != 0); + buttons.set(GHOST_kButtonMaskRight, (mask_return & Button3Mask) != 0); + } + else { + return GHOST_kFailure; + } + + return GHOST_kSuccess; } -static GHOST_TSuccess getCursorPosition_impl( - Display *display, - GHOST_TInt32& x, - GHOST_TInt32& y, - Window *child_return) +static GHOST_TSuccess getCursorPosition_impl(Display *display, + GHOST_TInt32 &x, + GHOST_TInt32 &y, + Window *child_return) { - int rx, ry, wx, wy; - unsigned int mask_return; - Window root_return; - - if (XQueryPointer( - display, - RootWindow(display, DefaultScreen(display)), - &root_return, - child_return, - &rx, &ry, - &wx, &wy, - &mask_return - ) == False) { - return GHOST_kFailure; - } - else { - x = rx; - y = ry; - } - return GHOST_kSuccess; + int rx, ry, wx, wy; + unsigned int mask_return; + Window root_return; + + if (XQueryPointer(display, + RootWindow(display, DefaultScreen(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:: -getCursorPosition( - GHOST_TInt32& x, - GHOST_TInt32& y) const +GHOST_TSuccess GHOST_SystemX11::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - Window child_return; - return getCursorPosition_impl(m_display, x, y, &child_return); + Window child_return; + return getCursorPosition_impl(m_display, x, y, &child_return); } - -GHOST_TSuccess -GHOST_SystemX11:: -setCursorPosition( - GHOST_TInt32 x, - GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemX11::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { - /* This is a brute force move in screen coordinates - * XWarpPointer does relative moves so first determine the - * current pointer position. */ + /* This is a brute force move in screen coordinates + * XWarpPointer does relative moves so first determine the + * current pointer position. */ - int cx, cy; + int cx, cy; #ifdef WITH_XWAYLAND_HACK - Window child_return = None; - if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) { - return GHOST_kFailure; - } + Window child_return = None; + if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) { + return GHOST_kFailure; + } #else - if (getCursorPosition(cx, cy) == GHOST_kFailure) { - return GHOST_kFailure; - } + if (getCursorPosition(cx, cy) == GHOST_kFailure) { + return GHOST_kFailure; + } #endif - int relx = x - cx; - int rely = y - cy; + int relx = x - cx; + int rely = y - cy; #ifdef WITH_XWAYLAND_HACK - if (use_xwayland_hack) { - if (child_return != None) { - XFixesHideCursor(m_display, child_return); - } - } + if (use_xwayland_hack) { + if (child_return != None) { + XFixesHideCursor(m_display, child_return); + } + } #endif #if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP) - if ((m_xinput_version.present) && - (m_xinput_version.major_version >= 2)) - { - /* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */ - int device_id; - if (XIGetClientPointer(m_display, None, &device_id) != False) { - XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely); - } - } - else + if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) { + /* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */ + int device_id; + if (XIGetClientPointer(m_display, None, &device_id) != False) { + XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely); + } + } + else #endif - { - XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely); - } + { + XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely); + } #ifdef WITH_XWAYLAND_HACK - if (use_xwayland_hack) { - if (child_return != None) { - XFixesShowCursor(m_display, child_return); - } - } + if (use_xwayland_hack) { + if (child_return != None) { + XFixesShowCursor(m_display, child_return); + } + } #endif - XSync(m_display, 0); /* Sync to process all requests */ + XSync(m_display, 0); /* Sync to process all requests */ - return GHOST_kSuccess; + return GHOST_kSuccess; } - -void -GHOST_SystemX11:: -addDirtyWindow( - GHOST_WindowX11 *bad_wind) +void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind) { - GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)"); + GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)"); - m_dirty_windows.push_back(bad_wind); + m_dirty_windows.push_back(bad_wind); } - -bool -GHOST_SystemX11:: -generateWindowExposeEvents() +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; + 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; } -static GHOST_TKey -ghost_key_from_keysym_or_keycode(const KeySym keysym, XkbDescPtr xkb_descr, const KeyCode keycode) +static GHOST_TKey ghost_key_from_keysym_or_keycode(const KeySym keysym, + XkbDescPtr xkb_descr, + const KeyCode keycode) { - GHOST_TKey type = ghost_key_from_keysym(keysym); - if (type == GHOST_kKeyUnknown) { - if (xkb_descr) { - type = ghost_key_from_keycode(xkb_descr, keycode); - } - } - return type; + GHOST_TKey type = ghost_key_from_keysym(keysym); + if (type == GHOST_kKeyUnknown) { + if (xkb_descr) { + type = ghost_key_from_keycode(xkb_descr, keycode); + } + } + return type; } -#define GXMAP(k, x, y) case x: k = y; break +#define GXMAP(k, x, y) \ + case x: \ + k = y; \ + break -static GHOST_TKey -ghost_key_from_keysym(const KeySym key) +static GHOST_TKey ghost_key_from_keysym(const KeySym 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_ISO_Left_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_plus, GHOST_kKeyPlus); - 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_Super_L, GHOST_kKeyOS); - GXMAP(type, XK_Super_R, GHOST_kKeyOS); - - 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); - - /* Media keys in some keyboards and laptops with XFree86/Xorg */ + 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_ISO_Left_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_plus, GHOST_kKeyPlus); + 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_Super_L, GHOST_kKeyOS); + GXMAP(type, XK_Super_R, GHOST_kKeyOS); + + 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); + + /* Media keys in some keyboards and laptops with XFree86/Xorg */ #ifdef WITH_XF86KEYSYM - GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay); - GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop); - GXMAP(type, XF86XK_AudioPrev, GHOST_kKeyMediaFirst); - GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst); - GXMAP(type, XF86XK_AudioNext, GHOST_kKeyMediaLast); -#ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */ - GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast); + GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay); + GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop); + GXMAP(type, XF86XK_AudioPrev, GHOST_kKeyMediaFirst); + GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst); + GXMAP(type, XF86XK_AudioNext, GHOST_kKeyMediaLast); +# ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */ + GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast); +# endif #endif -#endif - default: + default: #ifdef GHOST_DEBUG - printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key); + printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key); #endif - type = GHOST_kKeyUnknown; - break; - } - } + type = GHOST_kKeyUnknown; + break; + } + } - return type; + return type; } #undef GXMAP #define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) -static GHOST_TKey -ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode) +static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode) { - GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!"); - if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) { - const char *id_str = xkb_descr->names->keys[keycode].name; - const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]); - switch (id) { - case MAKE_ID('T', 'L', 'D', 'E'): - return GHOST_kKeyAccentGrave; + GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!"); + if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) { + const char *id_str = xkb_descr->names->keys[keycode].name; + const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]); + switch (id) { + case MAKE_ID('T', 'L', 'D', 'E'): + return GHOST_kKeyAccentGrave; #ifdef GHOST_DEBUG - default: - printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str); - break; + default: + printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str); + break; #endif - } - } - else if (keycode != 0) { - GHOST_ASSERT(false, "KeyCode out of range!"); - } - return GHOST_kKeyUnknown; + } + } + else if (keycode != 0) { + GHOST_ASSERT(false, "KeyCode out of range!"); + } + return GHOST_kKeyUnknown; } #undef MAKE_ID /* from xclip.c xcout() v0.11 */ -#define XCLIB_XCOUT_NONE 0 /* no context */ -#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */ -#define XCLIB_XCOUT_INCR 2 /* in an incr loop */ -#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */ -#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */ -#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */ -#define XCLIB_XCOUT_FALLBACK_TEXT 6 +#define XCLIB_XCOUT_NONE 0 /* no context */ +#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */ +#define XCLIB_XCOUT_INCR 2 /* in an incr loop */ +#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */ +#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */ +#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */ +#define XCLIB_XCOUT_FALLBACK_TEXT 6 /* Retrieves the contents of a selections. */ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt, - Atom sel, Atom target, unsigned char **txt, - unsigned long *len, unsigned int *context) const + Atom sel, + Atom target, + unsigned char **txt, + unsigned long *len, + unsigned int *context) const { - Atom pty_type; - int pty_format; - unsigned char *buffer; - unsigned long pty_size, pty_items; - unsigned char *ltxt = *txt; - - vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); - vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); - GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); - Window win = window->getXWindow(); - - switch (*context) { - /* There is no context, do an XConvertSelection() */ - case XCLIB_XCOUT_NONE: - /* Initialise return length to 0 */ - if (*len > 0) { - free(*txt); - *len = 0; - } - - /* Send a selection request */ - XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime); - *context = XCLIB_XCOUT_SENTCONVSEL; - return; - - case XCLIB_XCOUT_SENTCONVSEL: - if (evt->type != SelectionNotify) - return; - - if (target == m_atom.UTF8_STRING && evt->xselection.property == None) { - *context = XCLIB_XCOUT_FALLBACK_UTF8; - return; - } - else if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) { - *context = XCLIB_XCOUT_FALLBACK_COMP; - return; - } - else if (target == m_atom.TEXT && evt->xselection.property == None) { - *context = XCLIB_XCOUT_FALLBACK_TEXT; - return; - } - - /* find the size and format of the data in property */ - XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False, - AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, &buffer); - XFree(buffer); - - if (pty_type == m_atom.INCR) { - /* start INCR mechanism by deleting property */ - XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); - XFlush(m_display); - *context = XCLIB_XCOUT_INCR; - return; - } - - /* if it's not incr, and not format == 8, then there's - * nothing in the selection (that xclip understands, anyway) */ - - if (pty_format != 8) { - *context = XCLIB_XCOUT_NONE; - return; - } - - // not using INCR mechanism, just read the property - XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size, - False, AnyPropertyType, &pty_type, - &pty_format, &pty_items, &pty_size, &buffer); - - /* finished with property, delete it */ - XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); - - /* copy the buffer to the pointer for returned data */ - ltxt = (unsigned char *) malloc(pty_items); - memcpy(ltxt, buffer, pty_items); - - /* set the length of the returned data */ - *len = pty_items; - *txt = ltxt; - - /* free the buffer */ - XFree(buffer); - - *context = XCLIB_XCOUT_NONE; - - /* complete contents of selection fetched, return 1 */ - return; - - case XCLIB_XCOUT_INCR: - /* To use the INCR method, we basically delete the - * property with the selection in it, wait for an - * event indicating that the property has been created, - * then read it, delete it, etc. */ - - /* make sure that the event is relevant */ - if (evt->type != PropertyNotify) - return; - - /* skip unless the property has a new value */ - if (evt->xproperty.state != PropertyNewValue) - return; - - /* check size and format of the property */ - XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False, - AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, &buffer); - - if (pty_format != 8) { - /* property does not contain text, delete it - * to tell the other X client that we have read - * it and to send the next property */ - XFree(buffer); - XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); - return; - } - - if (pty_size == 0) { - /* no more data, exit from loop */ - XFree(buffer); - XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); - *context = XCLIB_XCOUT_NONE; - - /* this means that an INCR transfer is now - * complete, return 1 */ - return; - } - - XFree(buffer); - - /* if we have come this far, the property contains - * text, we know the size. */ - XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size, - False, AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, &buffer); - - /* allocate memory to accommodate data in *txt */ - if (*len == 0) { - *len = pty_items; - ltxt = (unsigned char *) malloc(*len); - } - else { - *len += pty_items; - ltxt = (unsigned char *) realloc(ltxt, *len); - } - - /* add data to ltxt */ - memcpy(<xt[*len - pty_items], buffer, pty_items); - - *txt = ltxt; - XFree(buffer); - - /* delete property to get the next item */ - XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); - XFlush(m_display); - return; - } - return; + Atom pty_type; + int pty_format; + unsigned char *buffer; + unsigned long pty_size, pty_items; + unsigned char *ltxt = *txt; + + vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows(); + vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); + GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); + Window win = window->getXWindow(); + + switch (*context) { + /* There is no context, do an XConvertSelection() */ + case XCLIB_XCOUT_NONE: + /* Initialise return length to 0 */ + if (*len > 0) { + free(*txt); + *len = 0; + } + + /* Send a selection request */ + XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime); + *context = XCLIB_XCOUT_SENTCONVSEL; + return; + + case XCLIB_XCOUT_SENTCONVSEL: + if (evt->type != SelectionNotify) + return; + + if (target == m_atom.UTF8_STRING && evt->xselection.property == None) { + *context = XCLIB_XCOUT_FALLBACK_UTF8; + return; + } + else if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) { + *context = XCLIB_XCOUT_FALLBACK_COMP; + return; + } + else if (target == m_atom.TEXT && evt->xselection.property == None) { + *context = XCLIB_XCOUT_FALLBACK_TEXT; + return; + } + + /* find the size and format of the data in property */ + XGetWindowProperty(m_display, + win, + m_atom.XCLIP_OUT, + 0, + 0, + False, + AnyPropertyType, + &pty_type, + &pty_format, + &pty_items, + &pty_size, + &buffer); + XFree(buffer); + + if (pty_type == m_atom.INCR) { + /* start INCR mechanism by deleting property */ + XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); + XFlush(m_display); + *context = XCLIB_XCOUT_INCR; + return; + } + + /* if it's not incr, and not format == 8, then there's + * nothing in the selection (that xclip understands, anyway) */ + + if (pty_format != 8) { + *context = XCLIB_XCOUT_NONE; + return; + } + + // not using INCR mechanism, just read the property + XGetWindowProperty(m_display, + win, + m_atom.XCLIP_OUT, + 0, + (long)pty_size, + False, + AnyPropertyType, + &pty_type, + &pty_format, + &pty_items, + &pty_size, + &buffer); + + /* finished with property, delete it */ + XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); + + /* copy the buffer to the pointer for returned data */ + ltxt = (unsigned char *)malloc(pty_items); + memcpy(ltxt, buffer, pty_items); + + /* set the length of the returned data */ + *len = pty_items; + *txt = ltxt; + + /* free the buffer */ + XFree(buffer); + + *context = XCLIB_XCOUT_NONE; + + /* complete contents of selection fetched, return 1 */ + return; + + case XCLIB_XCOUT_INCR: + /* To use the INCR method, we basically delete the + * property with the selection in it, wait for an + * event indicating that the property has been created, + * then read it, delete it, etc. */ + + /* make sure that the event is relevant */ + if (evt->type != PropertyNotify) + return; + + /* skip unless the property has a new value */ + if (evt->xproperty.state != PropertyNewValue) + return; + + /* check size and format of the property */ + XGetWindowProperty(m_display, + win, + m_atom.XCLIP_OUT, + 0, + 0, + False, + AnyPropertyType, + &pty_type, + &pty_format, + &pty_items, + &pty_size, + &buffer); + + if (pty_format != 8) { + /* property does not contain text, delete it + * to tell the other X client that we have read + * it and to send the next property */ + XFree(buffer); + XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); + return; + } + + if (pty_size == 0) { + /* no more data, exit from loop */ + XFree(buffer); + XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); + *context = XCLIB_XCOUT_NONE; + + /* this means that an INCR transfer is now + * complete, return 1 */ + return; + } + + XFree(buffer); + + /* if we have come this far, the property contains + * text, we know the size. */ + XGetWindowProperty(m_display, + win, + m_atom.XCLIP_OUT, + 0, + (long)pty_size, + False, + AnyPropertyType, + &pty_type, + &pty_format, + &pty_items, + &pty_size, + &buffer); + + /* allocate memory to accommodate data in *txt */ + if (*len == 0) { + *len = pty_items; + ltxt = (unsigned char *)malloc(*len); + } + else { + *len += pty_items; + ltxt = (unsigned char *)realloc(ltxt, *len); + } + + /* add data to ltxt */ + memcpy(<xt[*len - pty_items], buffer, pty_items); + + *txt = ltxt; + XFree(buffer); + + /* delete property to get the next item */ + XDeleteProperty(m_display, win, m_atom.XCLIP_OUT); + XFlush(m_display); + return; + } + return; } GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const { - Atom sseln; - Atom target = m_atom.UTF8_STRING; - Window owner; - - /* from xclip.c doOut() v0.11 */ - unsigned char *sel_buf; - unsigned long sel_len = 0; - XEvent evt; - unsigned int context = XCLIB_XCOUT_NONE; - - if (selection == True) - sseln = m_atom.PRIMARY; - else - sseln = m_atom.CLIPBOARD; - - vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); - vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); - GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); - Window win = window->getXWindow(); - - /* check if we are the owner. */ - owner = XGetSelectionOwner(m_display, sseln); - if (owner == win) { - if (sseln == m_atom.CLIPBOARD) { - sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); - strcpy((char *)sel_buf, txt_cut_buffer); - return sel_buf; - } - else { - sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1); - strcpy((char *)sel_buf, txt_select_buffer); - return sel_buf; - } - } - else if (owner == None) - return(NULL); - - while (1) { - /* only get an event if xcout() is doing something */ - if (context != XCLIB_XCOUT_NONE) - XNextEvent(m_display, &evt); - - /* fetch the selection, or part of it */ - getClipboard_xcout(&evt, sseln, target, &sel_buf, &sel_len, &context); - - /* fallback is needed. set XA_STRING to target and restart the loop. */ - if (context == XCLIB_XCOUT_FALLBACK) { - context = XCLIB_XCOUT_NONE; - target = m_atom.STRING; - continue; - } - else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { - /* utf8 fail, move to compouned text. */ - context = XCLIB_XCOUT_NONE; - target = m_atom.COMPOUND_TEXT; - continue; - } - else if (context == XCLIB_XCOUT_FALLBACK_COMP) { - /* compouned text fail, move to text. */ - context = XCLIB_XCOUT_NONE; - target = m_atom.TEXT; - continue; - } - else if (context == XCLIB_XCOUT_FALLBACK_TEXT) { - /* text fail, nothing else to try, break. */ - context = XCLIB_XCOUT_NONE; - } - - /* only continue if xcout() is doing something */ - if (context == XCLIB_XCOUT_NONE) - break; - } - - if (sel_len) { - /* only print the buffer out, and free it, if it's not - * empty - */ - unsigned char *tmp_data = (unsigned char *) malloc(sel_len + 1); - memcpy((char *)tmp_data, (char *)sel_buf, sel_len); - tmp_data[sel_len] = '\0'; - - if (sseln == m_atom.STRING) - XFree(sel_buf); - else - free(sel_buf); - - return tmp_data; - } - return(NULL); + Atom sseln; + Atom target = m_atom.UTF8_STRING; + Window owner; + + /* from xclip.c doOut() v0.11 */ + unsigned char *sel_buf; + unsigned long sel_len = 0; + XEvent evt; + unsigned int context = XCLIB_XCOUT_NONE; + + if (selection == True) + sseln = m_atom.PRIMARY; + else + sseln = m_atom.CLIPBOARD; + + vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows(); + vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); + GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); + Window win = window->getXWindow(); + + /* check if we are the owner. */ + owner = XGetSelectionOwner(m_display, sseln); + if (owner == win) { + if (sseln == m_atom.CLIPBOARD) { + sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); + strcpy((char *)sel_buf, txt_cut_buffer); + return sel_buf; + } + else { + sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1); + strcpy((char *)sel_buf, txt_select_buffer); + return sel_buf; + } + } + else if (owner == None) + return (NULL); + + while (1) { + /* only get an event if xcout() is doing something */ + if (context != XCLIB_XCOUT_NONE) + XNextEvent(m_display, &evt); + + /* fetch the selection, or part of it */ + getClipboard_xcout(&evt, sseln, target, &sel_buf, &sel_len, &context); + + /* fallback is needed. set XA_STRING to target and restart the loop. */ + if (context == XCLIB_XCOUT_FALLBACK) { + context = XCLIB_XCOUT_NONE; + target = m_atom.STRING; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { + /* utf8 fail, move to compouned text. */ + context = XCLIB_XCOUT_NONE; + target = m_atom.COMPOUND_TEXT; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_COMP) { + /* compouned text fail, move to text. */ + context = XCLIB_XCOUT_NONE; + target = m_atom.TEXT; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_TEXT) { + /* text fail, nothing else to try, break. */ + context = XCLIB_XCOUT_NONE; + } + + /* only continue if xcout() is doing something */ + if (context == XCLIB_XCOUT_NONE) + break; + } + + if (sel_len) { + /* only print the buffer out, and free it, if it's not + * empty + */ + unsigned char *tmp_data = (unsigned char *)malloc(sel_len + 1); + memcpy((char *)tmp_data, (char *)sel_buf, sel_len); + tmp_data[sel_len] = '\0'; + + if (sseln == m_atom.STRING) + XFree(sel_buf); + else + free(sel_buf); + + return tmp_data; + } + return (NULL); } void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const { - Window m_window, owner; - - vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); - vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); - GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); - m_window = window->getXWindow(); - - if (buffer) { - if (selection == False) { - XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime); - owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD); - if (txt_cut_buffer) - free((void *)txt_cut_buffer); - - txt_cut_buffer = (char *) malloc(strlen(buffer) + 1); - strcpy(txt_cut_buffer, buffer); - } - else { - XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime); - owner = XGetSelectionOwner(m_display, m_atom.PRIMARY); - if (txt_select_buffer) - free((void *)txt_select_buffer); - - txt_select_buffer = (char *) malloc(strlen(buffer) + 1); - strcpy(txt_select_buffer, buffer); - } - - if (owner != m_window) - fprintf(stderr, "failed to own primary\n"); - } + Window m_window, owner; + + vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows(); + vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); + GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it); + m_window = window->getXWindow(); + + if (buffer) { + if (selection == False) { + XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime); + owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD); + if (txt_cut_buffer) + free((void *)txt_cut_buffer); + + txt_cut_buffer = (char *)malloc(strlen(buffer) + 1); + strcpy(txt_cut_buffer, buffer); + } + else { + XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime); + owner = XGetSelectionOwner(m_display, m_atom.PRIMARY); + if (txt_select_buffer) + free((void *)txt_select_buffer); + + txt_select_buffer = (char *)malloc(strlen(buffer) + 1); + strcpy(txt_select_buffer, buffer); + } + + if (owner != m_window) + fprintf(stderr, "failed to own primary\n"); + } } #ifdef WITH_XDND GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, - GHOST_TDragnDropTypes draggedObjectType, - GHOST_IWindow *window, - int mouseX, int mouseY, - void *data) + GHOST_TDragnDropTypes draggedObjectType, + GHOST_IWindow *window, + int mouseX, + int mouseY, + void *data) { - GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem()); - return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(), - eventType, - draggedObjectType, - window, mouseX, mouseY, data) - ); + GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem()); + return system->pushEvent(new GHOST_EventDragnDrop( + system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data)); } #endif /** @@ -2220,28 +2163,31 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, */ int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *event) { - char error_code_str[512]; - - XGetErrorText(display, event->error_code, error_code_str, sizeof(error_code_str)); - - fprintf(stderr, - "Received X11 Error:\n" - "\terror code: %d\n" - "\trequest code: %d\n" - "\tminor code: %d\n" - "\terror text: %s\n", - event->error_code, event->request_code, event->minor_code, error_code_str); - - /* No exit! - but keep lint happy */ - return 0; + char error_code_str[512]; + + XGetErrorText(display, event->error_code, error_code_str, sizeof(error_code_str)); + + fprintf(stderr, + "Received X11 Error:\n" + "\terror code: %d\n" + "\trequest code: %d\n" + "\tminor code: %d\n" + "\terror text: %s\n", + event->error_code, + event->request_code, + event->minor_code, + error_code_str); + + /* No exit! - but keep lint happy */ + return 0; } int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/) { - fprintf(stderr, "Ignoring Xlib error: error IO\n"); + fprintf(stderr, "Ignoring Xlib error: error IO\n"); - /* No exit! - but keep lint happy */ - return 0; + /* No exit! - but keep lint happy */ + return 0; } #ifdef WITH_X11_XINPUT @@ -2249,22 +2195,22 @@ int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/) /* These C functions are copied from Wine 3.12's wintab.c */ static bool match_token(const char *haystack, const char *needle) { - const char *p, *q; - for (p = haystack; *p; ) { - while (*p && isspace(*p)) - p++; - if (!*p) - break; - - for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++) - p++; - if (!*q && (isspace(*p) || !*p)) - return true; - - while (*p && !isspace(*p)) - p++; - } - return false; + const char *p, *q; + for (p = haystack; *p;) { + while (*p && isspace(*p)) + p++; + if (!*p) + break; + + for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++) + p++; + if (!*q && (isspace(*p) || !*p)) + return true; + + while (*p && !isspace(*p)) + p++; + } + return false; } /* Determining if an X device is a Tablet style device is an imperfect science. @@ -2279,130 +2225,118 @@ static bool match_token(const char *haystack, const char *needle) */ static GHOST_TTabletMode tablet_mode_from_name(const char *name, const char *type) { - int i; - static const char* tablet_stylus_whitelist[] = { - "stylus", - "wizardpen", - "acecad", - "pen", - NULL - }; - - static const char* type_blacklist[] = { - "pad", - "cursor", - "touch", - NULL - }; - - /* Skip some known unsupported types. */ - for (i=0; type_blacklist[i] != NULL; i++) { - if (type && (strcasecmp(type, type_blacklist[i]) == 0)) { - return GHOST_kTabletModeNone; - } - } - - /* First check device type to avoid cases where name is "Pen and Eraser" and type is "ERASER" */ - for (i=0; tablet_stylus_whitelist[i] != NULL; i++) { - if (type && match_token(type, tablet_stylus_whitelist[i])) { - return GHOST_kTabletModeStylus; - } - } - if (type && match_token(type, "eraser")) { - return GHOST_kTabletModeEraser; - } - for (i=0; tablet_stylus_whitelist[i] != NULL; i++) { - if (name && match_token(name, tablet_stylus_whitelist[i])) { - return GHOST_kTabletModeStylus; - } - } - if (name && match_token(name, "eraser")) { - return GHOST_kTabletModeEraser; - } - - return GHOST_kTabletModeNone; + int i; + static const char *tablet_stylus_whitelist[] = {"stylus", "wizardpen", "acecad", "pen", NULL}; + + static const char *type_blacklist[] = {"pad", "cursor", "touch", NULL}; + + /* Skip some known unsupported types. */ + for (i = 0; type_blacklist[i] != NULL; i++) { + if (type && (strcasecmp(type, type_blacklist[i]) == 0)) { + return GHOST_kTabletModeNone; + } + } + + /* First check device type to avoid cases where name is "Pen and Eraser" and type is "ERASER" */ + for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) { + if (type && match_token(type, tablet_stylus_whitelist[i])) { + return GHOST_kTabletModeStylus; + } + } + if (type && match_token(type, "eraser")) { + return GHOST_kTabletModeEraser; + } + for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) { + if (name && match_token(name, tablet_stylus_whitelist[i])) { + return GHOST_kTabletModeStylus; + } + } + if (name && match_token(name, "eraser")) { + return GHOST_kTabletModeEraser; + } + + return GHOST_kTabletModeNone; } /* End code copied from Wine. */ void GHOST_SystemX11::refreshXInputDevices() { - if (m_xinput_version.present) { - /* Close tablet devices. */ - clearXInputDevices(); - - /* Install our error handler to override Xlib's termination behavior */ - GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); - - { - int device_count; - XDeviceInfo *device_info = XListInputDevices(m_display, &device_count); - - - for (int i = 0; i < device_count; ++i) { - char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL; - GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type); - -// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i); - - if (device_type) { - XFree((void *)device_type); - } - - if (!(tablet_mode == GHOST_kTabletModeStylus || tablet_mode == GHOST_kTabletModeEraser)) { - continue; - } - - GHOST_TabletX11 xtablet = {tablet_mode}; - xtablet.ID = device_info[i].id; - xtablet.Device = XOpenDevice(m_display, xtablet.ID); - - if (xtablet.Device != NULL) { - /* Find how many pressure levels tablet has */ - XAnyClassPtr ici = device_info[i].inputclassinfo; - - for (int j = 0; j < xtablet.Device->num_classes; ++j) { - if (ici->c_class == ValuatorClass) { - XValuatorInfo *xvi = (XValuatorInfo *)ici; - xtablet.PressureLevels = xvi->axes[2].max_value; - - if (xvi->num_axes > 3) { - /* this is assuming that the tablet has the same tilt resolution in both - * positive and negative directions. It would be rather weird if it didn't.. */ - xtablet.XtiltLevels = xvi->axes[3].max_value; - xtablet.YtiltLevels = xvi->axes[4].max_value; - } - else { - xtablet.XtiltLevels = 0; - xtablet.YtiltLevels = 0; - } - - break; - } - - ici = (XAnyClassPtr)(((char *)ici) + ici->length); - } - - m_xtablets.push_back(xtablet); - } - - } - - XFreeDeviceList(device_info); - } - - GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); - } + if (m_xinput_version.present) { + /* Close tablet devices. */ + clearXInputDevices(); + + /* Install our error handler to override Xlib's termination behavior */ + GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); + + { + int device_count; + XDeviceInfo *device_info = XListInputDevices(m_display, &device_count); + + for (int i = 0; i < device_count; ++i) { + char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : + NULL; + GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type); + + // printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i); + + if (device_type) { + XFree((void *)device_type); + } + + if (!(tablet_mode == GHOST_kTabletModeStylus || tablet_mode == GHOST_kTabletModeEraser)) { + continue; + } + + GHOST_TabletX11 xtablet = {tablet_mode}; + xtablet.ID = device_info[i].id; + xtablet.Device = XOpenDevice(m_display, xtablet.ID); + + if (xtablet.Device != NULL) { + /* Find how many pressure levels tablet has */ + XAnyClassPtr ici = device_info[i].inputclassinfo; + + for (int j = 0; j < xtablet.Device->num_classes; ++j) { + if (ici->c_class == ValuatorClass) { + XValuatorInfo *xvi = (XValuatorInfo *)ici; + xtablet.PressureLevels = xvi->axes[2].max_value; + + if (xvi->num_axes > 3) { + /* this is assuming that the tablet has the same tilt resolution in both + * positive and negative directions. It would be rather weird if it didn't.. */ + xtablet.XtiltLevels = xvi->axes[3].max_value; + xtablet.YtiltLevels = xvi->axes[4].max_value; + } + else { + xtablet.XtiltLevels = 0; + xtablet.YtiltLevels = 0; + } + + break; + } + + ici = (XAnyClassPtr)(((char *)ici) + ici->length); + } + + m_xtablets.push_back(xtablet); + } + } + + XFreeDeviceList(device_info); + } + + GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store); + } } void GHOST_SystemX11::clearXInputDevices() { - for (GHOST_TabletX11& xtablet: m_xtablets) { - if (xtablet.Device) - XCloseDevice(m_display, xtablet.Device); - } + for (GHOST_TabletX11 &xtablet : m_xtablets) { + if (xtablet.Device) + XCloseDevice(m_display, xtablet.Device); + } - m_xtablets.clear(); + m_xtablets.clear(); } #endif /* WITH_X11_XINPUT */ diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index e415757d925..d73582b52fa 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -43,7 +43,7 @@ #endif #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) -# define GHOST_X11_RES_NAME "Blender" /* res_name */ +# define GHOST_X11_RES_NAME "Blender" /* res_name */ # define GHOST_X11_RES_CLASS "Blender" /* res_class */ #endif @@ -52,19 +52,20 @@ int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent); int GHOST_X11_ApplicationIOErrorHandler(Display *display); #define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var) \ - struct { \ - XErrorHandler handler; \ - XIOErrorHandler handler_io; \ - } var = { \ - XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \ - XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \ - } + struct { \ + XErrorHandler handler; \ + XIOErrorHandler handler_io; \ + } var = { \ + XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \ + XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \ + } #define GHOST_X11_ERROR_HANDLERS_RESTORE(var) \ - { \ - (void)XSetErrorHandler(var.handler); \ - (void)XSetIOErrorHandler(var.handler_io); \ - } ((void)0) + { \ + (void)XSetErrorHandler(var.handler); \ + (void)XSetIOErrorHandler(var.handler_io); \ + } \ + ((void)0) class GHOST_WindowX11; @@ -74,358 +75,305 @@ class GHOST_WindowX11; */ class GHOST_SystemX11 : public GHOST_System { -public: - - /** - * Constructor - * this class should only be instanciated by GHOST_ISystem. - */ - - GHOST_SystemX11( - ); - - /** - * Destructor. - */ - ~GHOST_SystemX11(); - - - GHOST_TSuccess - init( - ); - - /** - * Informs if the system provides native dialogs (eg. confirm quit) - */ - virtual bool supportsNativeDialogs(void); - - /** - * \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; - - /** - * Returns the dimensions of all displays on this system. - * \return The dimension of the main display. - */ - void - getAllDisplayDimensions( - 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. - * \param exclusive Use to show the window ontop and ignore others - * (used fullscreen). - * \param parentWindow Parent (embedder) window - * \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, - GHOST_GLSettings glSettings, - const bool exclusive = false, - const GHOST_TEmbedderWindowID parentWindow = 0 - ); - - - /** - * Create a new offscreen context. - * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). - */ - GHOST_IContext * - createOffscreenContext( - ); - - /** - * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. - */ - GHOST_TSuccess - disposeContext( - GHOST_IContext *context - ); - - /** - * 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 - ); - - GHOST_TSuccess - getCursorPosition( - GHOST_TInt32& x, - GHOST_TInt32& y - ) const; - - GHOST_TSuccess - setCursorPosition( - GHOST_TInt32 x, - GHOST_TInt32 y - ); - - /** - * 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; - - /** - * 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; - } + public: + /** + * Constructor + * this class should only be instanciated by GHOST_ISystem. + */ + + GHOST_SystemX11(); + + /** + * Destructor. + */ + ~GHOST_SystemX11(); + + GHOST_TSuccess init(); + + /** + * Informs if the system provides native dialogs (eg. confirm quit) + */ + virtual bool supportsNativeDialogs(void); + + /** + * \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; + + /** + * Returns the dimensions of all displays on this system. + * \return The dimension of the main display. + */ + void getAllDisplayDimensions(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. + * \param exclusive Use to show the window ontop and ignore others + * (used fullscreen). + * \param parentWindow Parent (embedder) window + * \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, + GHOST_GLSettings glSettings, + const bool exclusive = false, + const GHOST_TEmbedderWindowID parentWindow = 0); + + /** + * Create a new offscreen context. + * Never explicitly delete the context, use disposeContext() instead. + * \return The new context (or 0 if creation failed). + */ + GHOST_IContext *createOffscreenContext(); + + /** + * Dispose of a context. + * \param context Pointer to the context to be disposed. + * \return Indication of success. + */ + GHOST_TSuccess disposeContext(GHOST_IContext *context); + + /** + * 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); + + GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + + GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + + /** + * 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; + + /** + * 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; + } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - XIM - getX11_XIM() - { - return m_xim; - } + XIM getX11_XIM() + { + return m_xim; + } #endif - /* Helped function for get data from the clipboard. */ - void getClipboard_xcout(const XEvent *evt, Atom sel, Atom target, - unsigned char **txt, unsigned long *len, - unsigned int *context) const; - - /** - * Returns unsigned char from CUT_BUFFER0 - * \param selection Get selection, X11 only feature - * \return Returns the Clipboard indicated by Flag - */ - GHOST_TUns8 *getClipboard(bool selection) const; - - /** - * Puts buffer to system clipboard - * \param buffer The buffer to copy to the clipboard - * \param selection Set the selection into the clipboard, X11 only feature - */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + /* Helped function for get data from the clipboard. */ + void getClipboard_xcout(const XEvent *evt, + Atom sel, + Atom target, + unsigned char **txt, + unsigned long *len, + unsigned int *context) const; + + /** + * Returns unsigned char from CUT_BUFFER0 + * \param selection Get selection, X11 only feature + * \return Returns the Clipboard indicated by Flag + */ + GHOST_TUns8 *getClipboard(bool selection) const; + + /** + * Puts buffer to system clipboard + * \param buffer The buffer to copy to the clipboard + * \param selection Set the selection into the clipboard, X11 only feature + */ + void putClipboard(GHOST_TInt8 *buffer, bool selection) const; #ifdef WITH_XDND - /** - * Creates a drag'n'drop event and pushes it immediately onto the event queue. - * Called by GHOST_DropTargetX11 class. - * \param eventType The type of drag'n'drop event - * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap) - * \param mouseX x mouse coordinate (in window coordinates) - * \param mouseY y mouse coordinate - * \param window The window on which the event occurred - * \return Indication whether the event was handled. - */ - static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_IWindow *window, int mouseX, int mouseY, void *data); + /** + * Creates a drag'n'drop event and pushes it immediately onto the event queue. + * Called by GHOST_DropTargetX11 class. + * \param eventType The type of drag'n'drop event + * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap) + * \param mouseX x mouse coordinate (in window coordinates) + * \param mouseY y mouse coordinate + * \param window The window on which the event occurred + * \return Indication whether the event was handled. + */ + static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, + GHOST_TDragnDropTypes draggedObjectType, + GHOST_IWindow *window, + int mouseX, + int mouseY, + void *data); #endif - /** - * \see GHOST_ISystem - */ - int toggleConsole(int /*action*/) { - return 0; - } + /** + * \see GHOST_ISystem + */ + int toggleConsole(int /*action*/) + { + return 0; + } #ifdef WITH_X11_XINPUT - typedef struct GHOST_TabletX11 { - GHOST_TTabletMode mode; - XDevice *Device; - XID ID; - - int MotionEvent; - int ProxInEvent; - int ProxOutEvent; - int PressEvent; - - int PressureLevels; - int XtiltLevels, YtiltLevels; - } GHOST_TabletX11; - - std::vector<GHOST_TabletX11> &GetXTablets() - { - return m_xtablets; - } -#endif // WITH_X11_XINPUT - - struct { - /** - * Atom used for ICCCM, WM-spec and Motif. - * We only need get this atom at the start, it's relative - * to the display not the window and are public for every - * window that need it. - */ - Atom WM_STATE; - Atom WM_CHANGE_STATE; - Atom _NET_WM_STATE; - Atom _NET_WM_STATE_MAXIMIZED_HORZ; - Atom _NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_FULLSCREEN; - Atom _MOTIF_WM_HINTS; - Atom WM_TAKE_FOCUS; - Atom WM_PROTOCOLS; - Atom WM_DELETE_WINDOW; - - /* Atoms for Selection, copy & paste. */ - Atom TARGETS; - Atom STRING; - Atom COMPOUND_TEXT; - Atom TEXT; - Atom CLIPBOARD; - Atom PRIMARY; - Atom XCLIP_OUT; - Atom INCR; - Atom UTF8_STRING; + typedef struct GHOST_TabletX11 { + GHOST_TTabletMode mode; + XDevice *Device; + XID ID; + + int MotionEvent; + int ProxInEvent; + int ProxOutEvent; + int PressEvent; + + int PressureLevels; + int XtiltLevels, YtiltLevels; + } GHOST_TabletX11; + + std::vector<GHOST_TabletX11> &GetXTablets() + { + return m_xtablets; + } +#endif // WITH_X11_XINPUT + + struct { + /** + * Atom used for ICCCM, WM-spec and Motif. + * We only need get this atom at the start, it's relative + * to the display not the window and are public for every + * window that need it. + */ + Atom WM_STATE; + Atom WM_CHANGE_STATE; + Atom _NET_WM_STATE; + Atom _NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_FULLSCREEN; + Atom _MOTIF_WM_HINTS; + Atom WM_TAKE_FOCUS; + Atom WM_PROTOCOLS; + Atom WM_DELETE_WINDOW; + + /* Atoms for Selection, copy & paste. */ + Atom TARGETS; + Atom STRING; + Atom COMPOUND_TEXT; + Atom TEXT; + Atom CLIPBOARD; + Atom PRIMARY; + Atom XCLIP_OUT; + Atom INCR; + Atom UTF8_STRING; #ifdef WITH_X11_XINPUT - Atom TABLET; + Atom TABLET; #endif - } m_atom; + } m_atom; #ifdef WITH_X11_XINPUT - XExtensionVersion m_xinput_version; + XExtensionVersion m_xinput_version; #endif -private: + private: + Display *m_display; - Display *m_display; - - /* Use for scancode lookups. */ - XkbDescRec *m_xkb_descr; + /* Use for scancode lookups. */ + XkbDescRec *m_xkb_descr; #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - XIM m_xim; + XIM m_xim; #endif #ifdef WITH_X11_XINPUT - /* Tablet devices */ - std::vector<GHOST_TabletX11> m_xtablets; + /* Tablet devices */ + std::vector<GHOST_TabletX11> m_xtablets; #endif - /// The vector of windows that need to be updated. - std::vector<GHOST_WindowX11 *> m_dirty_windows; + /// 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; + /// Start time at initialization. + GHOST_TUns64 m_start_time; - /// A vector of keyboard key masks - char m_keyboard_vector[32]; + /// A vector of keyboard key masks + char m_keyboard_vector[32]; - /* to prevent multiple warp, we store the time of the last warp event - * and stop accumulating all events generated before that */ - Time m_last_warp; + /* to prevent multiple warp, we store the time of the last warp event + * and stop accumulating all events generated before that */ + Time m_last_warp; - /* detect autorepeat glitch */ - unsigned int m_last_release_keycode; - Time m_last_release_time; + /* detect autorepeat glitch */ + unsigned int m_last_release_keycode; + Time m_last_release_time; - /** - * Return the ghost window associated with the - * X11 window xwind - */ + /** + * Return the ghost window associated with the + * X11 window xwind + */ #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - bool openX11_IM(); + bool openX11_IM(); #endif #ifdef WITH_X11_XINPUT - void clearXInputDevices(); - void refreshXInputDevices(); + void clearXInputDevices(); + void refreshXInputDevices(); #endif - GHOST_WindowX11 * - findGhostWindow( - Window xwind - ) const; + GHOST_WindowX11 *findGhostWindow(Window xwind) const; - void - processEvent( - XEvent *xe - ); + void processEvent(XEvent *xe); - Time - lastEventTime( - Time default_time - ); + Time lastEventTime(Time default_time); - bool - generateWindowExposeEvents( - ); + bool generateWindowExposeEvents(); }; #endif diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h index 670272b30cd..b1b81337494 100644 --- a/intern/ghost/intern/GHOST_TaskbarWin32.h +++ b/intern/ghost/intern/GHOST_TaskbarWin32.h @@ -21,8 +21,8 @@ #define __GHOST_TASKBARWIN32_H__ #ifndef WIN32 -#error WIN32 only! -#endif // WIN32 +# error WIN32 only! +#endif // WIN32 /* require Windows XP or newer */ #undef _WIN32_WINNT @@ -32,99 +32,105 @@ #include <windows.h> #include <shlobj.h> - // ITaskbarList, ITaskbarList2 and ITaskbarList3 might be missing, present here in that case. // Note, ITaskbarList3 is supported only since Windows 7, though. Check for that is done in // GHOST_WindowWin32 #ifndef __ITaskbarList_INTERFACE_DEFINED__ -#define __ITaskbarList_INTERFACE_DEFINED__ +# define __ITaskbarList_INTERFACE_DEFINED__ extern "C" { - const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; - const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; +const GUID CLSID_TaskbarList = { + 0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; +const GUID IID_ITaskbarList = { + 0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; } -class ITaskbarList : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0; - virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0; - virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0; - virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0; - virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0; +class ITaskbarList : public IUnknown { + public: + virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0; + virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0; }; -#endif /* ITaskbarList */ +#endif /* ITaskbarList */ #ifndef __ITaskbarList2_INTERFACE_DEFINED__ -#define __ITaskbarList2_INTERFACE_DEFINED__ +# define __ITaskbarList2_INTERFACE_DEFINED__ extern "C" { - const GUID IID_ITaskbarList2 = {0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}}; +const GUID IID_ITaskbarList2 = { + 0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}}; } -class ITaskbarList2 : public ITaskbarList -{ -public: - virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0; +class ITaskbarList2 : public ITaskbarList { + public: + virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0; }; -#endif /* ITaskbarList2 */ +#endif /* ITaskbarList2 */ #ifndef __ITaskbarList3_INTERFACE_DEFINED__ -#define __ITaskbarList3_INTERFACE_DEFINED__ +# define __ITaskbarList3_INTERFACE_DEFINED__ typedef enum THUMBBUTTONFLAGS { - THBF_ENABLED = 0, - THBF_DISABLED = 0x1, - THBF_DISMISSONCLICK = 0x2, - THBF_NOBACKGROUND = 0x4, - THBF_HIDDEN = 0x8, - THBF_NONINTERACTIVE = 0x10, -} -THUMBBUTTONFLAGS; + THBF_ENABLED = 0, + THBF_DISABLED = 0x1, + THBF_DISMISSONCLICK = 0x2, + THBF_NOBACKGROUND = 0x4, + THBF_HIDDEN = 0x8, + THBF_NONINTERACTIVE = 0x10, +} THUMBBUTTONFLAGS; typedef enum THUMBBUTTONMASK { - THB_BITMAP = 0x1, - THB_ICON = 0x2, - THB_TOOLTIP = 0x4, - THB_FLAGS = 0x8, -} -THUMBBUTTONMASK; + THB_BITMAP = 0x1, + THB_ICON = 0x2, + THB_TOOLTIP = 0x4, + THB_FLAGS = 0x8, +} THUMBBUTTONMASK; typedef struct THUMBBUTTON { - THUMBBUTTONMASK dwMask; - UINT iId; - UINT iBitmap; - HICON hIcon; - WCHAR szTip[260]; - THUMBBUTTONFLAGS dwFlags; + THUMBBUTTONMASK dwMask; + UINT iId; + UINT iBitmap; + HICON hIcon; + WCHAR szTip[260]; + THUMBBUTTONFLAGS dwFlags; } THUMBBUTTON; typedef enum TBPFLAG { - TBPF_NOPROGRESS = 0, - TBPF_INDETERMINATE = 0x1, - TBPF_NORMAL = 0x2, - TBPF_ERROR = 0x4, - TBPF_PAUSED = 0x8, + TBPF_NOPROGRESS = 0, + TBPF_INDETERMINATE = 0x1, + TBPF_NORMAL = 0x2, + TBPF_ERROR = 0x4, + TBPF_PAUSED = 0x8, } TBPFLAG; -#define THBN_CLICKED 0x1800 +# define THBN_CLICKED 0x1800 extern "C" { - const GUID IID_ITaskList3 = {0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}}; +const GUID IID_ITaskList3 = { + 0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}}; } -class ITaskbarList3 : public ITaskbarList2 -{ -public: - virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0; - virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0; - virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0; - virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0; - virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0; - virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; - virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, UINT cButtons, THUMBBUTTON *pButton) = 0; - virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, UINT cButtons, THUMBBUTTON *pButton) = 0; - virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0; - virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0; - virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0; - virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0; +class ITaskbarList3 : public ITaskbarList2 { + public: + virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, + ULONGLONG ullCompleted, + ULONGLONG ullTotal) = 0; + virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0; + virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0; + virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0; + virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0; + virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, + UINT cButtons, + THUMBBUTTON *pButton) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, + UINT cButtons, + THUMBBUTTON *pButton) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0; + virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, + HICON hIcon, + LPCWSTR pszDescription) = 0; + virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0; + virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0; }; -#endif /* ITaskbarList3 */ +#endif /* ITaskbarList3 */ #endif /*__GHOST_TASKBARWIN32_H__*/ diff --git a/intern/ghost/intern/GHOST_TaskbarX11.cpp b/intern/ghost/intern/GHOST_TaskbarX11.cpp index fbf51605bf0..e33c84fe4d8 100644 --- a/intern/ghost/intern/GHOST_TaskbarX11.cpp +++ b/intern/ghost/intern/GHOST_TaskbarX11.cpp @@ -25,10 +25,10 @@ #include <cassert> #include <cstdlib> -typedef void*(*unity_get_entry_t)(const char*); -typedef void(*unity_set_progress_t)(void*, double); -typedef void(*unity_set_progress_visible_t)(void*, int); -typedef int(*unity_event_loop_t)(void*, int); +typedef void *(*unity_get_entry_t)(const char *); +typedef void (*unity_set_progress_t)(void *, double); +typedef void (*unity_set_progress_visible_t)(void *, int); +typedef int (*unity_event_loop_t)(void *, int); static unity_get_entry_t unity_get_entry; static unity_set_progress_t unity_set_progress; @@ -41,83 +41,87 @@ static void *libunity_handle = NULL; void GHOST_TaskBarX11::free() { - if(libunity_handle) { - dlclose(libunity_handle); - libunity_handle = NULL; - } + if (libunity_handle) { + dlclose(libunity_handle); + libunity_handle = NULL; + } } bool GHOST_TaskBarX11::init() { - if(libunity_initialized) { - return libunity_available; - } - - libunity_initialized = true; - - const char *libunity_names[] = {"libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", NULL}; - for(int i = 0; libunity_names[i]; i++) { - libunity_handle = dlopen(libunity_names[i], RTLD_LAZY); - if(libunity_handle) { - break; - } - } - - if(!libunity_handle) { - return false; - } - - unity_get_entry = (unity_get_entry_t) dlsym(libunity_handle, "unity_launcher_entry_get_for_desktop_id"); - if(!unity_get_entry) { - fprintf(stderr, "failed to load libunity: %s\n", dlerror()); - return false; - } - unity_set_progress = (unity_set_progress_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress"); - if(!unity_set_progress) { - fprintf(stderr, "failed to load libunity: %s\n", dlerror()); - return false; - } - unity_set_progress_visible = (unity_set_progress_visible_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress_visible"); - if(!unity_set_progress_visible) { - fprintf(stderr, "failed to load libunity: %s\n", dlerror()); - return false; - } - unity_event_loop = (unity_event_loop_t) dlsym(libunity_handle, "g_main_context_iteration"); - if(!unity_event_loop) { - fprintf(stderr, "failed to load libunity: %s\n", dlerror()); - return false; - } - - atexit(GHOST_TaskBarX11::free); - - libunity_available = true; - return true; + if (libunity_initialized) { + return libunity_available; + } + + libunity_initialized = true; + + const char *libunity_names[] = { + "libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", NULL}; + for (int i = 0; libunity_names[i]; i++) { + libunity_handle = dlopen(libunity_names[i], RTLD_LAZY); + if (libunity_handle) { + break; + } + } + + if (!libunity_handle) { + return false; + } + + unity_get_entry = (unity_get_entry_t)dlsym(libunity_handle, + "unity_launcher_entry_get_for_desktop_id"); + if (!unity_get_entry) { + fprintf(stderr, "failed to load libunity: %s\n", dlerror()); + return false; + } + unity_set_progress = (unity_set_progress_t)dlsym(libunity_handle, + "unity_launcher_entry_set_progress"); + if (!unity_set_progress) { + fprintf(stderr, "failed to load libunity: %s\n", dlerror()); + return false; + } + unity_set_progress_visible = (unity_set_progress_visible_t)dlsym( + libunity_handle, "unity_launcher_entry_set_progress_visible"); + if (!unity_set_progress_visible) { + fprintf(stderr, "failed to load libunity: %s\n", dlerror()); + return false; + } + unity_event_loop = (unity_event_loop_t)dlsym(libunity_handle, "g_main_context_iteration"); + if (!unity_event_loop) { + fprintf(stderr, "failed to load libunity: %s\n", dlerror()); + return false; + } + + atexit(GHOST_TaskBarX11::free); + + libunity_available = true; + return true; } GHOST_TaskBarX11::GHOST_TaskBarX11(const char *name) { - if(GHOST_TaskBarX11::init()) { - handle = unity_get_entry(name); - } - else { - handle = NULL; - } + if (GHOST_TaskBarX11::init()) { + handle = unity_get_entry(name); + } + else { + handle = NULL; + } } bool GHOST_TaskBarX11::is_valid() { - return (handle != NULL); + return (handle != NULL); } void GHOST_TaskBarX11::set_progress(double progress) { - assert(is_valid()); - unity_set_progress(handle, progress); + assert(is_valid()); + unity_set_progress(handle, progress); } void GHOST_TaskBarX11::set_progress_enabled(bool enabled) { - assert(is_valid()); - unity_set_progress_visible(handle, enabled ? 1 : 0); - unity_event_loop(NULL, 0); + assert(is_valid()); + unity_set_progress_visible(handle, enabled ? 1 : 0); + unity_event_loop(NULL, 0); } diff --git a/intern/ghost/intern/GHOST_TaskbarX11.h b/intern/ghost/intern/GHOST_TaskbarX11.h index 65043635762..cd00e25106c 100644 --- a/intern/ghost/intern/GHOST_TaskbarX11.h +++ b/intern/ghost/intern/GHOST_TaskbarX11.h @@ -20,19 +20,19 @@ #ifndef __GHOST_TASKBARX11_H__ #define __GHOST_TASKBARX11_H__ -class GHOST_TaskBarX11 -{ -public: - static bool init(); - static void free(); +class GHOST_TaskBarX11 { + public: + static bool init(); + static void free(); - GHOST_TaskBarX11(const char *name); + GHOST_TaskBarX11(const char *name); - bool is_valid(); - void set_progress(double progress); - void set_progress_enabled(bool enabled); -private: - void *handle; + bool is_valid(); + void set_progress(double progress); + void set_progress_enabled(bool enabled); + + private: + void *handle; }; #endif /*__GHOST_TASKBARX11_H__*/ diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp index f1d0d13e5ba..22f646320ce 100644 --- a/intern/ghost/intern/GHOST_TimerManager.cpp +++ b/intern/ghost/intern/GHOST_TimerManager.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -32,121 +31,113 @@ #include "GHOST_TimerTask.h" - GHOST_TimerManager::GHOST_TimerManager() { } - GHOST_TimerManager::~GHOST_TimerManager() { - disposeTimers(); + disposeTimers(); } - GHOST_TUns32 GHOST_TimerManager::getNumTimers() { - return (GHOST_TUns32)m_timers.size(); + 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(); + 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 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; - success = GHOST_kSuccess; - } - else { - success = GHOST_kFailure; - } - return success; + 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; + success = GHOST_kSuccess; + } + else { + success = GHOST_kFailure; + } + return success; } GHOST_TUns64 GHOST_TimerManager::nextFireTime() { - GHOST_TUns64 smallest = GHOST_kFireTimeNever; - TTimerVector::iterator iter; + GHOST_TUns64 smallest = GHOST_kFireTimeNever; + TTimerVector::iterator iter; - for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { - GHOST_TUns64 next = (*iter)->getNext(); + for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { + GHOST_TUns64 next = (*iter)->getNext(); - if (next < smallest) - smallest = next; - } + if (next < smallest) + smallest = next; + } - return smallest; + return smallest; } bool GHOST_TimerManager::fireTimers(GHOST_TUns64 time) { - TTimerVector::iterator iter; - bool anyProcessed = false; + TTimerVector::iterator iter; + bool anyProcessed = false; - for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { - if (fireTimer(time, *iter)) - anyProcessed = true; - } + for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { + if (fireTimer(time, *iter)) + anyProcessed = true; + } - return anyProcessed; + 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; - } + 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.empty() == false) { - delete m_timers[0]; - m_timers.erase(m_timers.begin()); - } + while (m_timers.empty() == false) { + delete m_timers[0]; + m_timers.erase(m_timers.begin()); + } } diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h index 538198e208d..039663a7a0e 100644 --- a/intern/ghost/intern/GHOST_TimerManager.h +++ b/intern/ghost/intern/GHOST_TimerManager.h @@ -31,89 +31,86 @@ 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. - */ - ~GHOST_TimerManager(); - - /** - * Returns the number of timer tasks. - * \return The number of events on the stack. - */ - GHOST_TUns32 getNumTimers(); - - /** - * Returns whether this timer task ins in our list. - * \return Indication of presence. - */ - 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. - */ - 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. - */ - 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. - */ - 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. - */ - 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. - */ - 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; - +class GHOST_TimerManager { + public: + /** + * Constructor. + */ + GHOST_TimerManager(); + + /** + * Destructor. + */ + ~GHOST_TimerManager(); + + /** + * Returns the number of timer tasks. + * \return The number of events on the stack. + */ + GHOST_TUns32 getNumTimers(); + + /** + * Returns whether this timer task ins in our list. + * \return Indication of presence. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_TimerManager") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_TimerManager") #endif }; -#endif // __GHOST_TIMERMANAGER_H__ +#endif // __GHOST_TIMERMANAGER_H__ diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h index 375de377a25..561d9b3e705 100644 --- a/intern/ghost/intern/GHOST_TimerTask.h +++ b/intern/ghost/intern/GHOST_TimerTask.h @@ -27,159 +27,157 @@ #include "GHOST_ITimerTask.h" - /** * Implementation of a timer task. */ -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 callback invoked when the interval expires. - * \param userData: The timer user data. - */ - GHOST_TimerTask(GHOST_TUns64 start, - GHOST_TUns64 interval, - GHOST_TimerProcPtr timerProc, - GHOST_TUserDataPtr userData = NULL) - : 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 GHOST_TUns64 getStart() const - { - return m_start; - } - - /** - * Changes the timer start time. - * \param start The timer start time. - */ - void setStart(GHOST_TUns64 start) - { - m_start = start; - } - - /** - * Returns the timer interval. - * \return The timer interval. - */ - inline GHOST_TUns64 getInterval() const - { - return m_interval; - } - - /** - * Changes the timer interval. - * \param interval The timer interval. - */ - 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 GHOST_TUns64 getNext() const - { - return m_next; - } - - /** - * Changes the time the timerProc will be called. - * \param next The time the timerProc will be called. - */ - void setNext(GHOST_TUns64 next) - { - m_next = next; - } - - /** - * Returns the timer callback. - * \return the timer callback. - */ - inline GHOST_TimerProcPtr getTimerProc() const - { - return m_timerProc; - } - - /** - * Changes the timer callback. - * \param timerProc: The timer callback. - */ - inline void setTimerProc(const GHOST_TimerProcPtr timerProc) - { - m_timerProc = timerProc; - } - - /** - * Returns the timer user data. - * \return The timer user data. - */ - inline GHOST_TUserDataPtr getUserData() const - { - return m_userData; - } - - /** - * Changes the time user data. - * \param userData: The timer user data. - */ - void setUserData(const GHOST_TUserDataPtr userData) - { - m_userData = userData; - } - - /** - * Returns the auxiliary storage room. - * \return The auxiliary storage room. - */ - inline GHOST_TUns32 getAuxData() const - { - return m_auxData; - } - - /** - * Changes the auxiliary storage room. - * \param auxData The auxiliary storage room. - */ - 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; +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 callback invoked when the interval expires. + * \param userData: The timer user data. + */ + GHOST_TimerTask(GHOST_TUns64 start, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData = NULL) + : 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 GHOST_TUns64 getStart() const + { + return m_start; + } + + /** + * Changes the timer start time. + * \param start The timer start time. + */ + void setStart(GHOST_TUns64 start) + { + m_start = start; + } + + /** + * Returns the timer interval. + * \return The timer interval. + */ + inline GHOST_TUns64 getInterval() const + { + return m_interval; + } + + /** + * Changes the timer interval. + * \param interval The timer interval. + */ + 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 GHOST_TUns64 getNext() const + { + return m_next; + } + + /** + * Changes the time the timerProc will be called. + * \param next The time the timerProc will be called. + */ + void setNext(GHOST_TUns64 next) + { + m_next = next; + } + + /** + * Returns the timer callback. + * \return the timer callback. + */ + inline GHOST_TimerProcPtr getTimerProc() const + { + return m_timerProc; + } + + /** + * Changes the timer callback. + * \param timerProc: The timer callback. + */ + inline void setTimerProc(const GHOST_TimerProcPtr timerProc) + { + m_timerProc = timerProc; + } + + /** + * Returns the timer user data. + * \return The timer user data. + */ + inline GHOST_TUserDataPtr getUserData() const + { + return m_userData; + } + + /** + * Changes the time user data. + * \param userData: The timer user data. + */ + void setUserData(const GHOST_TUserDataPtr userData) + { + m_userData = userData; + } + + /** + * Returns the auxiliary storage room. + * \return The auxiliary storage room. + */ + inline GHOST_TUns32 getAuxData() const + { + return m_auxData; + } + + /** + * Changes the auxiliary storage room. + * \param auxData The auxiliary storage room. + */ + 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_TIMERTASK_H__ +#endif // __GHOST_TIMERTASK_H__ diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 0334cdf5f20..06b76aee23d 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -32,12 +31,12 @@ #include <assert.h> -GHOST_Window::GHOST_Window( - GHOST_TUns32 width, GHOST_TUns32 height, - GHOST_TWindowState state, - const bool wantStereoVisual, - const bool /*exclusive*/, - const GHOST_TUns16 wantNumOfAASamples) +GHOST_Window::GHOST_Window(GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const bool wantStereoVisual, + const bool /*exclusive*/, + const GHOST_TUns16 wantNumOfAASamples) : m_drawingContextType(GHOST_kDrawingContextTypeNone), m_cursorVisible(true), m_cursorGrab(GHOST_kGrabDisable), @@ -46,189 +45,197 @@ GHOST_Window::GHOST_Window( m_wantNumOfAASamples(wantNumOfAASamples), m_context(new GHOST_ContextNone(false, 0)) { - m_isUnsavedChanges = false; - m_canAcceptDragOperation = false; + m_isUnsavedChanges = false; + m_canAcceptDragOperation = false; - m_progressBarVisible = false; + m_progressBarVisible = false; - m_cursorGrabAccumPos[0] = 0; - m_cursorGrabAccumPos[1] = 0; + m_cursorGrabAccumPos[0] = 0; + m_cursorGrabAccumPos[1] = 0; - m_nativePixelSize = 1.0f; + m_nativePixelSize = 1.0f; - m_fullScreen = state == GHOST_kWindowStateFullScreen; - if (m_fullScreen) { - m_fullScreenWidth = width; - m_fullScreenHeight = height; - } + m_fullScreen = state == GHOST_kWindowStateFullScreen; + if (m_fullScreen) { + m_fullScreenWidth = width; + m_fullScreenHeight = height; + } } - GHOST_Window::~GHOST_Window() { - delete m_context; + delete m_context; } void *GHOST_Window::getOSWindow() const { - return NULL; + return NULL; } GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type) { - if (type != m_drawingContextType) { - delete m_context; - m_context = NULL; + if (type != m_drawingContextType) { + delete m_context; + m_context = NULL; - if (type != GHOST_kDrawingContextTypeNone) - m_context = newDrawingContext(type); + if (type != GHOST_kDrawingContextTypeNone) + m_context = newDrawingContext(type); - if (m_context != NULL) { - m_drawingContextType = type; - } - else { - m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples); - m_drawingContextType = GHOST_kDrawingContextTypeNone; - } + if (m_context != NULL) { + m_drawingContextType = type; + } + else { + m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples); + m_drawingContextType = GHOST_kDrawingContextTypeNone; + } - return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure; - } - else { - return GHOST_kSuccess; - } + return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure; + } + else { + return GHOST_kSuccess; + } } GHOST_TSuccess GHOST_Window::swapBuffers() { - return m_context->swapBuffers(); + return m_context->swapBuffers(); } GHOST_TSuccess GHOST_Window::setSwapInterval(int interval) { - return m_context->setSwapInterval(interval); + return m_context->setSwapInterval(interval); } -GHOST_TSuccess GHOST_Window::getSwapInterval(int& intervalOut) +GHOST_TSuccess GHOST_Window::getSwapInterval(int &intervalOut) { - return m_context->getSwapInterval(intervalOut); + return m_context->getSwapInterval(intervalOut); } GHOST_TUns16 GHOST_Window::getNumOfAASamples() { - return m_context->getNumOfAASamples(); + return m_context->getNumOfAASamples(); } GHOST_TSuccess GHOST_Window::activateDrawingContext() { - return m_context->activateDrawingContext(); + return m_context->activateDrawingContext(); } GHOST_TSuccess GHOST_Window::updateDrawingContext() { - return m_context->updateDrawingContext(); + return m_context->updateDrawingContext(); } GHOST_TSuccess GHOST_Window::releaseNativeHandles() { - return m_context->releaseNativeHandles(); + return m_context->releaseNativeHandles(); } GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) { - if (setWindowCursorVisibility(visible)) { - m_cursorVisible = visible; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (setWindowCursorVisibility(visible)) { + m_cursorVisible = visible; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } -GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) +GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, + GHOST_Rect *bounds, + GHOST_TInt32 mouse_ungrab_xy[2]) { - if (m_cursorGrab == mode) - return GHOST_kSuccess; + if (m_cursorGrab == mode) + return GHOST_kSuccess; - /* override with new location */ - if (mouse_ungrab_xy) { - assert(mode == GHOST_kGrabDisable); - m_cursorGrabInitPos[0] = mouse_ungrab_xy[0]; - m_cursorGrabInitPos[1] = mouse_ungrab_xy[1]; - } + /* override with new location */ + if (mouse_ungrab_xy) { + assert(mode == GHOST_kGrabDisable); + m_cursorGrabInitPos[0] = mouse_ungrab_xy[0]; + m_cursorGrabInitPos[1] = mouse_ungrab_xy[1]; + } - if (setWindowCursorGrab(mode)) { + if (setWindowCursorGrab(mode)) { - if (mode == GHOST_kGrabDisable) - m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; - else if (bounds) { - m_cursorGrabBounds = *bounds; - } - else { /* if bounds not defined, use window */ - getClientBounds(m_cursorGrabBounds); - } - m_cursorGrab = mode; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (mode == GHOST_kGrabDisable) + m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; + else if (bounds) { + m_cursorGrabBounds = *bounds; + } + else { /* if bounds not defined, use window */ + getClientBounds(m_cursorGrabBounds); + } + m_cursorGrab = mode; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } -GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds) +GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) { - bounds = m_cursorGrabBounds; - return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess; + bounds = m_cursorGrabBounds; + return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess; } GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape) { - if (setWindowCursorShape(cursorShape)) { - m_cursorShape = cursorShape; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + 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) +GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) { - return setCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, - 16, 16, hotX, hotY, 0, 1); + return setCustomCursorShape( + (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1); } -GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, - int sizex, int sizey, int hotX, int hotY, - int fg_color, int bg_color) +GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color) { - if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color)) { - m_cursorShape = GHOST_kStandardCursorCustom; - return GHOST_kSuccess; - } - else { - return GHOST_kFailure; - } + if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color)) { + m_cursorShape = GHOST_kStandardCursorCustom; + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } } void GHOST_Window::setAcceptDragOperation(bool canAccept) { - m_canAcceptDragOperation = canAccept; + m_canAcceptDragOperation = canAccept; } bool GHOST_Window::canAcceptDragOperation() const { - return m_canAcceptDragOperation; + return m_canAcceptDragOperation; } GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges) { - m_isUnsavedChanges = isUnsavedChanges; + m_isUnsavedChanges = isUnsavedChanges; - return GHOST_kSuccess; + return GHOST_kSuccess; } bool GHOST_Window::getModifiedState() { - return m_isUnsavedChanges; + return m_isUnsavedChanges; } diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index c84fced2f2d..8c01d66bbfd 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -37,417 +37,425 @@ class GHOST_Context; * Implements part of the GHOST_IWindow interface and adds some methods to * be implemented by childs of this class. */ -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 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. - * \param exclusive Use to show the window ontop and ignore others - * (used fullscreen). - * \param numOfAASamples Number of samples used for AA (zero if no AA) - */ - GHOST_Window( - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - const bool wantStereoVisual = false, - const bool exclusive = false, - const GHOST_TUns16 wantNumOfAASamples = 0); - - /** - * \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 setSwapInterval() = 0; - * virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0; - * virtual GHOST_TSuccess activateDrawingContext() = 0; - * virtual GHOST_TSuccess invalidate() = 0; - */ - - /** - * Destructor. - * Closes the window and disposes resources allocated. - */ - virtual ~GHOST_Window(); - - /** - * Returns indication as to whether the window is valid. - * \return The validity of the window. - */ - virtual bool getValid() const { - return m_context != NULL; - } - - /** - * Returns the associated OS object/handle - * \return The associated OS object/handle - */ - virtual void *getOSWindow() const; - - /** - * Returns the current cursor shape. - * \return The current cursor shape. - */ - inline GHOST_TStandardCursor getCursorShape() const; - - /** - * Set the shape of the cursor. - * \param cursorShape: The new cursor shape type id. - * \return Indication of success. - */ - 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. - */ - GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], - int hotX, - int hotY); - - GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, int sizey, - int hotX, int hotY, - int fg_color, int bg_color); - - /** - * Returns the visibility state of the cursor. - * \return The visibility state of the cursor. - */ - inline bool getCursorVisibility() const; - inline GHOST_TGrabCursorMode getCursorGrabMode() const; - inline bool getCursorGrabModeIsWarp() const; - inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); - - /** - * Shows or hides the cursor. - * \param visible The new visibility state of the cursor. - * \return Indication of success. - */ - GHOST_TSuccess setCursorVisibility(bool visible); - - /** - * Sets the cursor grab. - * \param mode The new grab state of the cursor. - * \return Indication of success. - */ - GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]); - - /** - * Gets the cursor grab region, if unset the window is used. - * reset when grab is disabled. - */ - GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds); - - /** - * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % (0.0 to 1.0) - */ - virtual GHOST_TSuccess setProgressBar(float /*progress*/) { - return GHOST_kFailure; - } - - /** - * Hides the progress bar in the icon - */ - virtual GHOST_TSuccess endProgressBar() { - return GHOST_kFailure; - } - - /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. - * \return A boolean success indicator. - */ - GHOST_TSuccess setSwapInterval(int interval); - - /** - * Gets the current swap interval for swapBuffers. - * \return An integer. - */ - GHOST_TSuccess getSwapInterval(int& intervalOut); - - /** - * Gets the current swap interval for swapBuffers. - * \return Number of AA Samples (0 if there is no multisample buffer) - */ - GHOST_TUns16 getNumOfAASamples(); - - /** - * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop - */ - void setAcceptDragOperation(bool canAccept); - - /** - * Returns acceptance of the dropped object - * Usually called by the "object dropped" event handling function - */ - bool canAcceptDragOperation() const; - - /** - * Sets the window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not - * \return Indication of success. - */ - virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges); - - /** - * Gets the window "modified" status, indicating unsaved changes - * \return True if there are unsaved changes - */ - virtual bool getModifiedState(); - - /** - * Returns the type of drawing context used in this window. - * \return The current type of drawing context. - */ - inline GHOST_TDrawingContextType getDrawingContextType(); - - /** - * Tries to install a rendering context in this window. - * Child classes do not need to overload this method, - * They should overload newDrawingContext instead. - * \param type The type of rendering context installed. - * \return Indication as to whether installation has succeeded. - */ - GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type); - - /** - * Swaps front and back buffers of a window. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess swapBuffers(); - - /** - * Activates the drawing context of this window. - * \return A boolean success indicator. - */ - virtual GHOST_TSuccess activateDrawingContext(); - - /** - * Updates the drawing context of this window. Needed - * whenever the window is changed. - * \return Indication of success. - */ - GHOST_TSuccess updateDrawingContext(); - - /** - * Returns the window user data. - * \return The window user data. - */ - inline GHOST_TUserDataPtr getUserData() const - { - return m_userData; - } - - /** - * Changes the window user data. - * \param userData: The window user data. - */ - void setUserData(const GHOST_TUserDataPtr userData) - { - m_userData = userData; - } - - float getNativePixelSize(void) - { - if (m_nativePixelSize > 0.0f) - return m_nativePixelSize; - return 1.0f; - } - - /** - * Returns the recommended DPI for this window. - * \return The recommended DPI for this window. - */ - virtual inline GHOST_TUns16 getDPIHint() - { - return 96; - } +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 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. + * \param exclusive Use to show the window ontop and ignore others + * (used fullscreen). + * \param numOfAASamples Number of samples used for AA (zero if no AA) + */ + GHOST_Window(GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const bool wantStereoVisual = false, + const bool exclusive = false, + const GHOST_TUns16 wantNumOfAASamples = 0); + + /** + * \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 setSwapInterval() = 0; + * virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0; + * virtual GHOST_TSuccess activateDrawingContext() = 0; + * virtual GHOST_TSuccess invalidate() = 0; + */ + + /** + * Destructor. + * Closes the window and disposes resources allocated. + */ + virtual ~GHOST_Window(); + + /** + * Returns indication as to whether the window is valid. + * \return The validity of the window. + */ + virtual bool getValid() const + { + return m_context != NULL; + } + + /** + * Returns the associated OS object/handle + * \return The associated OS object/handle + */ + virtual void *getOSWindow() const; + + /** + * Returns the current cursor shape. + * \return The current cursor shape. + */ + inline GHOST_TStandardCursor getCursorShape() const; + + /** + * Set the shape of the cursor. + * \param cursorShape: The new cursor shape type id. + * \return Indication of success. + */ + 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. + */ + GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY); + + GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); + + /** + * Returns the visibility state of the cursor. + * \return The visibility state of the cursor. + */ + inline bool getCursorVisibility() const; + inline GHOST_TGrabCursorMode getCursorGrabMode() const; + inline bool getCursorGrabModeIsWarp() const; + inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); + + /** + * Shows or hides the cursor. + * \param visible The new visibility state of the cursor. + * \return Indication of success. + */ + GHOST_TSuccess setCursorVisibility(bool visible); + + /** + * Sets the cursor grab. + * \param mode The new grab state of the cursor. + * \return Indication of success. + */ + GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, + GHOST_Rect *bounds, + GHOST_TInt32 mouse_ungrab_xy[2]); + + /** + * Gets the cursor grab region, if unset the window is used. + * reset when grab is disabled. + */ + GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds); + + /** + * Sets the progress bar value displayed in the window/application icon + * \param progress The progress % (0.0 to 1.0) + */ + virtual GHOST_TSuccess setProgressBar(float /*progress*/) + { + return GHOST_kFailure; + } + + /** + * Hides the progress bar in the icon + */ + virtual GHOST_TSuccess endProgressBar() + { + return GHOST_kFailure; + } + + /** + * Sets the swap interval for swapBuffers. + * \param interval The swap interval to use. + * \return A boolean success indicator. + */ + GHOST_TSuccess setSwapInterval(int interval); + + /** + * Gets the current swap interval for swapBuffers. + * \return An integer. + */ + GHOST_TSuccess getSwapInterval(int &intervalOut); + + /** + * Gets the current swap interval for swapBuffers. + * \return Number of AA Samples (0 if there is no multisample buffer) + */ + GHOST_TUns16 getNumOfAASamples(); + + /** + * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop + */ + void setAcceptDragOperation(bool canAccept); + + /** + * Returns acceptance of the dropped object + * Usually called by the "object dropped" event handling function + */ + bool canAcceptDragOperation() const; + + /** + * Sets the window "modified" status, indicating unsaved changes + * \param isUnsavedChanges Unsaved changes or not + * \return Indication of success. + */ + virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges); + + /** + * Gets the window "modified" status, indicating unsaved changes + * \return True if there are unsaved changes + */ + virtual bool getModifiedState(); + + /** + * Returns the type of drawing context used in this window. + * \return The current type of drawing context. + */ + inline GHOST_TDrawingContextType getDrawingContextType(); + + /** + * Tries to install a rendering context in this window. + * Child classes do not need to overload this method, + * They should overload newDrawingContext instead. + * \param type The type of rendering context installed. + * \return Indication as to whether installation has succeeded. + */ + GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type); + + /** + * Swaps front and back buffers of a window. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess swapBuffers(); + + /** + * Activates the drawing context of this window. + * \return A boolean success indicator. + */ + virtual GHOST_TSuccess activateDrawingContext(); + + /** + * Updates the drawing context of this window. Needed + * whenever the window is changed. + * \return Indication of success. + */ + GHOST_TSuccess updateDrawingContext(); + + /** + * Returns the window user data. + * \return The window user data. + */ + inline GHOST_TUserDataPtr getUserData() const + { + return m_userData; + } + + /** + * Changes the window user data. + * \param userData: The window user data. + */ + void setUserData(const GHOST_TUserDataPtr userData) + { + m_userData = userData; + } + + float getNativePixelSize(void) + { + if (m_nativePixelSize > 0.0f) + return m_nativePixelSize; + return 1.0f; + } + + /** + * Returns the recommended DPI for this window. + * \return The recommended DPI for this window. + */ + virtual inline GHOST_TUns16 getDPIHint() + { + return 96; + } #ifdef WITH_INPUT_IME - virtual void beginIME(GHOST_TInt32 x, - GHOST_TInt32 y, - GHOST_TInt32 w, - GHOST_TInt32 h, - int completed) - { - /* do nothing temporarily if not in windows */ - } - - virtual void endIME() - { - /* do nothing temporarily if not in windows */ - } + virtual void beginIME( + GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) + { + /* do nothing temporarily if not in windows */ + } + + virtual void endIME() + { + /* do nothing temporarily if not in windows */ + } #endif /* WITH_INPUT_IME */ -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_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0; - - /** - * Sets the cursor visibility on the window using - * native window system calls. - */ - virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0; - - /** - * Sets the cursor grab on the window using - * native window system calls. - */ - virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) { - return GHOST_kSuccess; - } - - /** - * 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; - - virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, - int szx, int szy, int hotX, int hotY, int fg, int bg) = 0; - - GHOST_TSuccess releaseNativeHandles(); - - /** The 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 grabbed state of the cursor */ - GHOST_TGrabCursorMode m_cursorGrab; - - /** Initial grab location. */ - GHOST_TInt32 m_cursorGrabInitPos[2]; - - /** Accumulated offset from m_cursorGrabInitPos. */ - GHOST_TInt32 m_cursorGrabAccumPos[2]; - - /** Wrap the cursor within this region. */ - GHOST_Rect m_cursorGrabBounds; - - /** The current shape of the cursor */ - GHOST_TStandardCursor m_cursorShape; - - /** The presence of progress indicator with the application icon */ - bool m_progressBarVisible; - - /** The acceptance of the "drop candidate" of the current drag'n'drop operation */ - bool m_canAcceptDragOperation; - - /** Modified state : are there unsaved changes */ - bool m_isUnsavedChanges; - - /** Stores whether this is a full screen window. */ - bool m_fullScreen; - - /** Whether to attempt to initialize a context with a stereo framebuffer. */ - bool m_wantStereoVisual; - - /** Attempt to initialize a context with this many samples. */ - GHOST_TUns16 m_wantNumOfAASamples; - - /** Full-screen width */ - GHOST_TUns32 m_fullScreenWidth; - /** Full-screen height */ - GHOST_TUns32 m_fullScreenHeight; - - /* OSX only, retina screens */ - float m_nativePixelSize; - -private: - GHOST_Context *m_context; + 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_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0; + + /** + * Sets the cursor visibility on the window using + * native window system calls. + */ + virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0; + + /** + * Sets the cursor grab on the window using + * native window system calls. + */ + virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) + { + return GHOST_kSuccess; + } + + /** + * 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; + + virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int szx, + int szy, + int hotX, + int hotY, + int fg, + int bg) = 0; + + GHOST_TSuccess releaseNativeHandles(); + + /** The 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 grabbed state of the cursor */ + GHOST_TGrabCursorMode m_cursorGrab; + + /** Initial grab location. */ + GHOST_TInt32 m_cursorGrabInitPos[2]; + + /** Accumulated offset from m_cursorGrabInitPos. */ + GHOST_TInt32 m_cursorGrabAccumPos[2]; + + /** Wrap the cursor within this region. */ + GHOST_Rect m_cursorGrabBounds; + + /** The current shape of the cursor */ + GHOST_TStandardCursor m_cursorShape; + + /** The presence of progress indicator with the application icon */ + bool m_progressBarVisible; + + /** The acceptance of the "drop candidate" of the current drag'n'drop operation */ + bool m_canAcceptDragOperation; + + /** Modified state : are there unsaved changes */ + bool m_isUnsavedChanges; + + /** Stores whether this is a full screen window. */ + bool m_fullScreen; + + /** Whether to attempt to initialize a context with a stereo framebuffer. */ + bool m_wantStereoVisual; + + /** Attempt to initialize a context with this many samples. */ + GHOST_TUns16 m_wantNumOfAASamples; + + /** Full-screen width */ + GHOST_TUns32 m_fullScreenWidth; + /** Full-screen height */ + GHOST_TUns32 m_fullScreenHeight; + + /* OSX only, retina screens */ + float m_nativePixelSize; + + private: + GHOST_Context *m_context; }; - inline GHOST_TDrawingContextType GHOST_Window::getDrawingContextType() { - return m_drawingContextType; + return m_drawingContextType; } inline bool GHOST_Window::getCursorVisibility() const { - return m_cursorVisible; + return m_cursorVisible; } inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const { - return m_cursorGrab; + return m_cursorGrab; } inline bool GHOST_Window::getCursorGrabModeIsWarp() const { - return (m_cursorGrab == GHOST_kGrabWrap) || - (m_cursorGrab == GHOST_kGrabHide); + return (m_cursorGrab == GHOST_kGrabWrap) || (m_cursorGrab == GHOST_kGrabHide); } inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - x = m_cursorGrabInitPos[0]; - y = m_cursorGrabInitPos[1]; + x = m_cursorGrabInitPos[0]; + y = m_cursorGrabInitPos[1]; } inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - x = m_cursorGrabAccumPos[0]; - y = m_cursorGrabAccumPos[1]; + x = m_cursorGrabAccumPos[0]; + y = m_cursorGrabAccumPos[1]; } inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y) { - m_cursorGrabAccumPos[0] = x; - m_cursorGrabAccumPos[1] = y; + m_cursorGrabAccumPos[0] = x; + m_cursorGrabAccumPos[1] = y; } inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const { - return m_cursorShape; + return m_cursorShape; } -#endif // _GHOST_WINDOW_H +#endif // _GHOST_WINDOW_H diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 0b3aa6be732..acda109eb7f 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -26,8 +26,8 @@ #define __GHOST_WINDOWCOCOA_H__ #ifndef __APPLE__ -#error Apple OSX only! -#endif // __APPLE__ +# error Apple OSX only! +#endif // __APPLE__ #include "GHOST_Window.h" #include "STR_String.h" @@ -40,263 +40,295 @@ class GHOST_SystemCocoa; class GHOST_WindowCocoa : 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 systemCocoa The associated system class to forward events to - * \param title The text shown in the title bar of the window. - * \param left The coordinate of the left edge of the window. - * \param bottom The coordinate of the bottom 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. - * \param numOfAASamples Number of samples used for AA (zero if no AA) - */ - GHOST_WindowCocoa( - GHOST_SystemCocoa *systemCocoa, - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 bottom, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, - const bool stereoVisual = false, - const GHOST_TUns16 numOfAASamples = 0, - bool is_debug = false - ); - - /** - * Destructor. - * Closes the window and disposes resources allocated. - */ - ~GHOST_WindowCocoa(); - - /** - * Returns indication as to whether the window is valid. - * \return The validity of the window. - */ - bool getValid() const; - - /** - * Returns the associated NSWindow object - * \return The associated NSWindow object - */ - void *getOSWindow() const; - - /** - * Sets the title displayed in the title bar. - * \param title The title to display in the title bar. - */ - void setTitle(const STR_String& title); - - /** - * Returns the title displayed in the title bar. - * \param title The title displayed in the title bar. - */ - 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. - */ - 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 client area of the window. - */ - void getClientBounds(GHOST_Rect& bounds) const; - - /** - * Resizes client rectangle width. - * \param width The new width of the client area of the window. - */ - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); - - /** - * Resizes client rectangle height. - * \param height The new height of the client area of the window. - */ - 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. - */ - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); - - /** - * Returns the state of the window (normal, minimized, maximized). - * \return The state of the window. - */ - GHOST_TWindowState getState() const; - - /** - * Sets the window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not - * \return Indication of success. - */ - GHOST_TSuccess setModifiedState(bool isUnsavedChanges); - - /** - * 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. - */ - 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. - */ - void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const; - - /** - * Converts a point in screen coordinates to client rectangle coordinates - * but without the y coordinate conversion needed for ghost compatibility. - * \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. - */ - void clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const; - - /** - * Converts a point in screen coordinates to client rectangle coordinates, - * but without the y coordinate conversion needed for ghost compatibility. - * \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. - */ - void screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const; - - /** - * Gets the screen the window is displayed in - * \return The NSScreen object - */ - NSScreen *getScreen(); - - /** - * Sets the state of the window (normal, minimized, maximized). - * \param state The state of the window. - * \return Indication of success. - */ - 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. - */ - GHOST_TSuccess setOrder(GHOST_TWindowOrder order); - - void loadCursor(bool visible, GHOST_TStandardCursor cursor) const; - - const GHOST_TabletData *GetTabletData() - { - return &m_tablet; - } - - GHOST_TabletData& GetCocoaTabletData() - { - return m_tablet; - } - - /** - * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % (0.0 to 1.0) - */ - GHOST_TSuccess setProgressBar(float progress); - - /** - * Hides the progress bar icon - */ - GHOST_TSuccess endProgressBar(); - - - void setNativePixelSize(void); - - GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;} - - GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;} - - /** public function to get the window containing the OpenGL view */ - CocoaWindow *getCocoaWindow() const {return m_window;}; - - /* Internal value to ensure proper redraws during animations */ - void setImmediateDraw(bool value) { m_immediateDraw = value; } - bool getImmediateDraw(void) const { return m_immediateDraw; } - -protected: - - /** - * \param type The type of rendering context create. - * \return Indication of success. - */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); - - /** - * Invalidates the contents of this window. - * \return Indication of success. - */ - GHOST_TSuccess invalidate(); - - /** - * Sets the cursor visibility on the window using - * native window system calls. - */ - GHOST_TSuccess setWindowCursorVisibility(bool visible); - - /** - * Sets the cursor grab on the window using - * native window system calls. - */ - GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); - - /** - * 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, GHOST_TUns8 *mask, - int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color); - - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY); - - /** The window containing the OpenGL view */ - CocoaWindow *m_window; - - /** The openGL view */ - CocoaOpenGLView *m_openGLView; - - /** The mother SystemCocoa class to send events */ - GHOST_SystemCocoa *m_systemCocoa; - - NSCursor *m_customCursor; - - GHOST_TabletData m_tablet; - - bool m_immediateDraw; - bool m_debug_context; // for debug messages during context setup + public: + /** + * Constructor. + * Creates a new window and opens it. + * To check if the window was created properly, use the getValid() method. + * \param systemCocoa The associated system class to forward events to + * \param title The text shown in the title bar of the window. + * \param left The coordinate of the left edge of the window. + * \param bottom The coordinate of the bottom 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. + * \param numOfAASamples Number of samples used for AA (zero if no AA) + */ + GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 bottom, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, + const bool stereoVisual = false, + const GHOST_TUns16 numOfAASamples = 0, + bool is_debug = false); + + /** + * Destructor. + * Closes the window and disposes resources allocated. + */ + ~GHOST_WindowCocoa(); + + /** + * Returns indication as to whether the window is valid. + * \return The validity of the window. + */ + bool getValid() const; + + /** + * Returns the associated NSWindow object + * \return The associated NSWindow object + */ + void *getOSWindow() const; + + /** + * Sets the title displayed in the title bar. + * \param title The title to display in the title bar. + */ + void setTitle(const STR_String &title); + + /** + * Returns the title displayed in the title bar. + * \param title The title displayed in the title bar. + */ + 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. + */ + 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 client area of the window. + */ + void getClientBounds(GHOST_Rect &bounds) const; + + /** + * Resizes client rectangle width. + * \param width The new width of the client area of the window. + */ + GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + + /** + * Resizes client rectangle height. + * \param height The new height of the client area of the window. + */ + 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. + */ + GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + + /** + * Returns the state of the window (normal, minimized, maximized). + * \return The state of the window. + */ + GHOST_TWindowState getState() const; + + /** + * Sets the window "modified" status, indicating unsaved changes + * \param isUnsavedChanges Unsaved changes or not + * \return Indication of success. + */ + GHOST_TSuccess setModifiedState(bool isUnsavedChanges); + + /** + * 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. + */ + 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. + */ + void clientToScreen(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const; + + /** + * Converts a point in screen coordinates to client rectangle coordinates + * but without the y coordinate conversion needed for ghost compatibility. + * \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. + */ + void clientToScreenIntern(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const; + + /** + * Converts a point in screen coordinates to client rectangle coordinates, + * but without the y coordinate conversion needed for ghost compatibility. + * \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. + */ + void screenToClientIntern(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const; + + /** + * Gets the screen the window is displayed in + * \return The NSScreen object + */ + NSScreen *getScreen(); + + /** + * Sets the state of the window (normal, minimized, maximized). + * \param state The state of the window. + * \return Indication of success. + */ + 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. + */ + GHOST_TSuccess setOrder(GHOST_TWindowOrder order); + + void loadCursor(bool visible, GHOST_TStandardCursor cursor) const; + + const GHOST_TabletData *GetTabletData() + { + return &m_tablet; + } + + GHOST_TabletData &GetCocoaTabletData() + { + return m_tablet; + } + + /** + * Sets the progress bar value displayed in the window/application icon + * \param progress The progress % (0.0 to 1.0) + */ + GHOST_TSuccess setProgressBar(float progress); + + /** + * Hides the progress bar icon + */ + GHOST_TSuccess endProgressBar(); + + void setNativePixelSize(void); + + GHOST_TSuccess beginFullScreen() const + { + return GHOST_kFailure; + } + + GHOST_TSuccess endFullScreen() const + { + return GHOST_kFailure; + } + + /** public function to get the window containing the OpenGL view */ + CocoaWindow *getCocoaWindow() const + { + return m_window; + }; + + /* Internal value to ensure proper redraws during animations */ + void setImmediateDraw(bool value) + { + m_immediateDraw = value; + } + bool getImmediateDraw(void) const + { + return m_immediateDraw; + } + + protected: + /** + * \param type The type of rendering context create. + * \return Indication of success. + */ + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); + + /** + * Invalidates the contents of this window. + * \return Indication of success. + */ + GHOST_TSuccess invalidate(); + + /** + * Sets the cursor visibility on the window using + * native window system calls. + */ + GHOST_TSuccess setWindowCursorVisibility(bool visible); + + /** + * Sets the cursor grab on the window using + * native window system calls. + */ + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); + + /** + * 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, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); + + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY); + + /** The window containing the OpenGL view */ + CocoaWindow *m_window; + + /** The openGL view */ + CocoaOpenGLView *m_openGLView; + + /** The mother SystemCocoa class to send events */ + GHOST_SystemCocoa *m_systemCocoa; + + NSCursor *m_customCursor; + + GHOST_TabletData m_tablet; + + bool m_immediateDraw; + bool m_debug_context; // for debug messages during context setup }; -#endif // __GHOST_WINDOWCOCOA_H__ +#endif // __GHOST_WINDOWCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 1af39f11f08..46343e17e46 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -34,14 +34,14 @@ #pragma mark Cocoa window delegate object -@interface CocoaWindowDelegate : NSObject -<NSWindowDelegate> +@interface CocoaWindowDelegate : NSObject <NSWindowDelegate> { - GHOST_SystemCocoa *systemCocoa; - GHOST_WindowCocoa *associatedWindow; + GHOST_SystemCocoa *systemCocoa; + GHOST_WindowCocoa *associatedWindow; } -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa; - (void)windowDidBecomeKey:(NSNotification *)notification; - (void)windowDidResignKey:(NSNotification *)notification; - (void)windowDidExpose:(NSNotification *)notification; @@ -53,183 +53,207 @@ @end @implementation CocoaWindowDelegate : NSObject -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa { - systemCocoa = sysCocoa; - associatedWindow = winCocoa; + systemCocoa = sysCocoa; + associatedWindow = winCocoa; } - (void)windowDidBecomeKey:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow); - // work around for broken appswitching when combining cmd-tab and missioncontrol - [(NSWindow*)associatedWindow->getOSWindow() orderFrontRegardless]; + systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow); + // work around for broken appswitching when combining cmd-tab and missioncontrol + [(NSWindow *)associatedWindow->getOSWindow() orderFrontRegardless]; } - (void)windowDidResignKey:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); + systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); } - (void)windowDidExpose:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow); + systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow); } - (void)windowDidMove:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow); + systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow); } - (void)windowWillMove:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow); + systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow); } - (void)windowWillEnterFullScreen:(NSNotification *)notification { - associatedWindow->setImmediateDraw(true); + associatedWindow->setImmediateDraw(true); } - (void)windowDidEnterFullScreen:(NSNotification *)notification { - associatedWindow->setImmediateDraw(false); + associatedWindow->setImmediateDraw(false); } - (void)windowWillExitFullScreen:(NSNotification *)notification { - associatedWindow->setImmediateDraw(true); + associatedWindow->setImmediateDraw(true); } - (void)windowDidExitFullScreen:(NSNotification *)notification { - associatedWindow->setImmediateDraw(false); + associatedWindow->setImmediateDraw(false); } - (void)windowDidResize:(NSNotification *)notification { - //if (![[notification object] inLiveResize]) { - //Send event only once, at end of resize operation (when user has released mouse button) - systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow); - //} - /* Live resize, send event, gets handled in wm_window.c. Needed because live resize runs in a modal loop, not letting main loop run */ - if ([[notification object] inLiveResize]) { - systemCocoa->dispatchEvents(); - } + //if (![[notification object] inLiveResize]) { + //Send event only once, at end of resize operation (when user has released mouse button) + systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow); + //} + /* Live resize, send event, gets handled in wm_window.c. Needed because live resize runs in a modal loop, not letting main loop run */ + if ([[notification object] inLiveResize]) { + systemCocoa->dispatchEvents(); + } } - (void)windowDidChangeBackingProperties:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventNativeResolutionChange, associatedWindow); + systemCocoa->handleWindowEvent(GHOST_kEventNativeResolutionChange, associatedWindow); } - (BOOL)windowShouldClose:(id)sender; { - //Let Blender close the window rather than closing immediately - systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow); - return false; + //Let Blender close the window rather than closing immediately + systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow); + return false; } @end #pragma mark NSWindow subclass //We need to subclass it to tell that even borderless (fullscreen), it can become key (receive user events) -@interface CocoaWindow: NSWindow +@interface CocoaWindow : NSWindow { - GHOST_SystemCocoa *systemCocoa; - GHOST_WindowCocoa *associatedWindow; - GHOST_TDragnDropTypes m_draggedObjectType; + GHOST_SystemCocoa *systemCocoa; + GHOST_WindowCocoa *associatedWindow; + GHOST_TDragnDropTypes m_draggedObjectType; } -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; -- (GHOST_SystemCocoa*)systemCocoa; +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa; +- (GHOST_SystemCocoa *)systemCocoa; @end @implementation CocoaWindow -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa { - systemCocoa = sysCocoa; - associatedWindow = winCocoa; + systemCocoa = sysCocoa; + associatedWindow = winCocoa; } -- (GHOST_SystemCocoa*)systemCocoa +- (GHOST_SystemCocoa *)systemCocoa { - return systemCocoa; + return systemCocoa; } --(BOOL)canBecomeKeyWindow +- (BOOL)canBecomeKeyWindow { - return YES; + return YES; } //The drag'n'drop dragging destination methods -- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender -{ - NSPoint mouseLocation = [sender draggingLocation]; - NSPasteboard *draggingPBoard = [sender draggingPasteboard]; - - if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap; - else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames; - else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString; - else return NSDragOperationNone; - - associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default - systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); - return NSDragOperationCopy; +- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender +{ + NSPoint mouseLocation = [sender draggingLocation]; + NSPasteboard *draggingPBoard = [sender draggingPasteboard]; + + if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) + m_draggedObjectType = GHOST_kDragnDropTypeBitmap; + else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) + m_draggedObjectType = GHOST_kDragnDropTypeFilenames; + else if ([[draggingPBoard types] containsObject:NSStringPboardType]) + m_draggedObjectType = GHOST_kDragnDropTypeString; + else + return NSDragOperationNone; + + associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default + systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, + m_draggedObjectType, + associatedWindow, + mouseLocation.x, + mouseLocation.y, + nil); + return NSDragOperationCopy; } - (BOOL)wantsPeriodicDraggingUpdates { - return NO; //No need to overflow blender event queue. Events shall be sent only on changes + return NO; //No need to overflow blender event queue. Events shall be sent only on changes } -- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender +- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender { - NSPoint mouseLocation = [sender draggingLocation]; + NSPoint mouseLocation = [sender draggingLocation]; - systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); - return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone; + systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, + m_draggedObjectType, + associatedWindow, + mouseLocation.x, + mouseLocation.y, + nil); + return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone; } -- (void)draggingExited:(id < NSDraggingInfo >)sender +- (void)draggingExited:(id<NSDraggingInfo>)sender { - systemCocoa->handleDraggingEvent(GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil); - m_draggedObjectType = GHOST_kDragnDropTypeUnknown; + systemCocoa->handleDraggingEvent( + GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil); + m_draggedObjectType = GHOST_kDragnDropTypeUnknown; } -- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender +- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender { - if (associatedWindow->canAcceptDragOperation()) - return YES; - else - return NO; + if (associatedWindow->canAcceptDragOperation()) + return YES; + else + return NO; } -- (BOOL)performDragOperation:(id < NSDraggingInfo >)sender +- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { - NSPoint mouseLocation = [sender draggingLocation]; - NSPasteboard *draggingPBoard = [sender draggingPasteboard]; - NSImage *droppedImg; - id data; + NSPoint mouseLocation = [sender draggingLocation]; + NSPasteboard *draggingPBoard = [sender draggingPasteboard]; + NSImage *droppedImg; + id data; - switch (m_draggedObjectType) { - case GHOST_kDragnDropTypeBitmap: - if ([NSImage canInitWithPasteboard:draggingPBoard]) { - droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard]; - data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; - } - else return NO; - break; - case GHOST_kDragnDropTypeFilenames: - data = [draggingPBoard propertyListForType:NSFilenamesPboardType]; - break; - case GHOST_kDragnDropTypeString: - data = [draggingPBoard stringForType:NSStringPboardType]; - break; - default: - return NO; - break; - } - systemCocoa->handleDraggingEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, (void*)data); - return YES; + switch (m_draggedObjectType) { + case GHOST_kDragnDropTypeBitmap: + if ([NSImage canInitWithPasteboard:draggingPBoard]) { + droppedImg = [[NSImage alloc] initWithPasteboard:draggingPBoard]; + data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; + } + else + return NO; + break; + case GHOST_kDragnDropTypeFilenames: + data = [draggingPBoard propertyListForType:NSFilenamesPboardType]; + break; + case GHOST_kDragnDropTypeString: + data = [draggingPBoard stringForType:NSStringPboardType]; + break; + default: + return NO; + break; + } + systemCocoa->handleDraggingEvent(GHOST_kEventDraggingDropDone, + m_draggedObjectType, + associatedWindow, + mouseLocation.x, + mouseLocation.y, + (void *)data); + return YES; } @end @@ -238,204 +262,204 @@ //We need to subclass it in order to give Cocoa the feeling key events are trapped @interface CocoaOpenGLView : NSOpenGLView <NSTextInput> { - GHOST_SystemCocoa *systemCocoa; - GHOST_WindowCocoa *associatedWindow; + GHOST_SystemCocoa *systemCocoa; + GHOST_WindowCocoa *associatedWindow; - bool composing; - NSString *composing_text; + bool composing; + NSString *composing_text; - bool immediate_draw; + bool immediate_draw; } -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa; @end @implementation CocoaOpenGLView -- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa + windowCocoa:(GHOST_WindowCocoa *)winCocoa { - systemCocoa = sysCocoa; - associatedWindow = winCocoa; + systemCocoa = sysCocoa; + associatedWindow = winCocoa; - composing = false; - composing_text = nil; + composing = false; + composing_text = nil; - immediate_draw = false; + immediate_draw = false; } - (BOOL)acceptsFirstResponder { - return YES; + return YES; } // The trick to prevent Cocoa from complaining (beeping) - (void)keyDown:(NSEvent *)event { - systemCocoa->handleKeyEvent(event); + systemCocoa->handleKeyEvent(event); - /* Start or continue composing? */ - if ([[event characters] length] == 0 || - [[event charactersIgnoringModifiers] length] == 0 || - composing) - { - composing = YES; + /* Start or continue composing? */ + if ([[event characters] length] == 0 || [[event charactersIgnoringModifiers] length] == 0 || + composing) { + composing = YES; - // interpret event to call insertText - NSMutableArray *events; - events = [[NSMutableArray alloc] initWithCapacity:1]; - [events addObject:event]; - [self interpretKeyEvents:events]; // calls insertText - [events removeObject:event]; - [events release]; - return; - } + // interpret event to call insertText + NSMutableArray *events; + events = [[NSMutableArray alloc] initWithCapacity:1]; + [events addObject:event]; + [self interpretKeyEvents:events]; // calls insertText + [events removeObject:event]; + [events release]; + return; + } } - (void)keyUp:(NSEvent *)event { - systemCocoa->handleKeyEvent(event); + systemCocoa->handleKeyEvent(event); } - (void)flagsChanged:(NSEvent *)event { - systemCocoa->handleKeyEvent(event); + systemCocoa->handleKeyEvent(event); } - (void)mouseDown:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)mouseUp:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)rightMouseDown:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)rightMouseUp:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)mouseMoved:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)mouseDragged:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)rightMouseDragged:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)scrollWheel:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)otherMouseDown:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)otherMouseUp:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)otherMouseDragged:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)magnifyWithEvent:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)rotateWithEvent:(NSEvent *)event { - systemCocoa->handleMouseEvent(event); + systemCocoa->handleMouseEvent(event); } - (void)tabletPoint:(NSEvent *)event { - systemCocoa->handleTabletEvent(event,[event type]); + systemCocoa->handleTabletEvent(event, [event type]); } - (void)tabletProximity:(NSEvent *)event { - systemCocoa->handleTabletEvent(event,[event type]); + systemCocoa->handleTabletEvent(event, [event type]); } - (BOOL)isOpaque { - return YES; + return YES; } -- (void) drawRect:(NSRect)rect +- (void)drawRect:(NSRect)rect { - if ([self inLiveResize]) { - /* Don't redraw while in live resize */ - } - else { - [super drawRect:rect]; - systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow); + if ([self inLiveResize]) { + /* Don't redraw while in live resize */ + } + else { + [super drawRect:rect]; + systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow); - /* For some cases like entering fullscreen we need to redraw immediately - * so our window does not show blank during the animation */ - if (associatedWindow->getImmediateDraw()) - systemCocoa->dispatchEvents(); - } + /* For some cases like entering fullscreen we need to redraw immediately + * so our window does not show blank during the animation */ + if (associatedWindow->getImmediateDraw()) + systemCocoa->dispatchEvents(); + } } // Text input - (void)composing_free { - composing = NO; + composing = NO; - if (composing_text) { - [composing_text release]; - composing_text = nil; - } + if (composing_text) { + [composing_text release]; + composing_text = nil; + } } - (void)insertText:(id)chars { - [self composing_free]; + [self composing_free]; } - (void)setMarkedText:(id)chars selectedRange:(NSRange)range { - [self composing_free]; - if ([chars length] == 0) - return; + [self composing_free]; + if ([chars length] == 0) + return; - // start composing - composing = YES; - composing_text = [chars copy]; + // start composing + composing = YES; + composing_text = [chars copy]; - // if empty, cancel - if ([composing_text length] == 0) - [self composing_free]; + // if empty, cancel + if ([composing_text length] == 0) + [self composing_free]; } - (void)unmarkText { - [self composing_free]; + [self composing_free]; } - (BOOL)hasMarkedText { - return (composing) ? YES : NO; + return (composing) ? YES : NO; } - (void)doCommandBySelector:(SEL)selector @@ -444,457 +468,463 @@ - (BOOL)isComposing { - return composing; + return composing; } - (NSInteger)conversationIdentifier { - return (NSInteger)self; + return (NSInteger)self; } - (NSAttributedString *)attributedSubstringFromRange:(NSRange)range { - return [NSAttributedString new]; // XXX does this leak? + return [NSAttributedString new]; // XXX does this leak? } - (NSRange)markedRange { - unsigned int length = (composing_text) ? [composing_text length] : 0; + unsigned int length = (composing_text) ? [composing_text length] : 0; - if (composing) - return NSMakeRange(0, length); + if (composing) + return NSMakeRange(0, length); - return NSMakeRange(NSNotFound, 0); + return NSMakeRange(NSNotFound, 0); } - (NSRange)selectedRange { - unsigned int length = (composing_text) ? [composing_text length] : 0; - return NSMakeRange(0, length); + unsigned int length = (composing_text) ? [composing_text length] : 0; + return NSMakeRange(0, length); } - (NSRect)firstRectForCharacterRange:(NSRange)range { - return NSZeroRect; + return NSZeroRect; } - (NSUInteger)characterIndexForPoint:(NSPoint)point { - return NSNotFound; + return NSNotFound; } -- (NSArray*)validAttributesForMarkedText +- (NSArray *)validAttributesForMarkedText { - return [NSArray array]; // XXX does this leak? + return [NSArray array]; // XXX does this leak? } @end #pragma mark initialization / finalization -GHOST_WindowCocoa::GHOST_WindowCocoa( - GHOST_SystemCocoa *systemCocoa, - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 bottom, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples, bool is_debug -) : - GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), - m_customCursor(0), - m_debug_context(is_debug) +GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 bottom, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + const bool stereoVisual, + const GHOST_TUns16 numOfAASamples, + bool is_debug) + : GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), + m_customCursor(0), + m_debug_context(is_debug) { - m_systemCocoa = systemCocoa; - m_fullScreen = false; - m_immediateDraw = false; + m_systemCocoa = systemCocoa; + m_fullScreen = false; + m_immediateDraw = false; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //Creates the window - NSRect rect; - NSSize minSize; + //Creates the window + NSRect rect; + NSSize minSize; - rect.origin.x = left; - rect.origin.y = bottom; - rect.size.width = width; - rect.size.height = height; + rect.origin.x = left; + rect.origin.y = bottom; + rect.size.width = width; + rect.size.height = height; - m_window = [[CocoaWindow alloc] initWithContentRect:rect - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask - backing:NSBackingStoreBuffered defer:NO]; + m_window = [[CocoaWindow alloc] + initWithContentRect:rect + styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | + NSMiniaturizableWindowMask + backing:NSBackingStoreBuffered + defer:NO]; - if (m_window == nil) { - [pool drain]; - return; - } + if (m_window == nil) { + [pool drain]; + return; + } - [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; + [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; - //Forbid to resize the window below the blender defined minimum one - minSize.width = 320; - minSize.height = 240; - [m_window setContentMinSize:minSize]; + //Forbid to resize the window below the blender defined minimum one + minSize.width = 320; + minSize.height = 240; + [m_window setContentMinSize:minSize]; - //Creates the OpenGL View inside the window - m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect]; + //Creates the OpenGL View inside the window + m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect]; - if (m_systemCocoa->m_nativePixel) { - // Needs to happen early when building with the 10.14 SDK, otherwise - // has no effect until resizeing the window. - if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { - [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; - } - } + if (m_systemCocoa->m_nativePixel) { + // Needs to happen early when building with the 10.14 SDK, otherwise + // has no effect until resizeing the window. + if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { + [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; + } + } - [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; + [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; - [m_window setContentView:m_openGLView]; - [m_window setInitialFirstResponder:m_openGLView]; + [m_window setContentView:m_openGLView]; + [m_window setInitialFirstResponder:m_openGLView]; - [m_window makeKeyAndOrderFront:nil]; + [m_window makeKeyAndOrderFront:nil]; - setDrawingContextType(type); - updateDrawingContext(); - activateDrawingContext(); + setDrawingContextType(type); + updateDrawingContext(); + activateDrawingContext(); - setTitle(title); + setTitle(title); - m_tablet.Active = GHOST_kTabletModeNone; + m_tablet.Active = GHOST_kTabletModeNone; - CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; - [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; - [m_window setDelegate:windowDelegate]; + CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; + [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; + [m_window setDelegate:windowDelegate]; - [m_window setAcceptsMouseMovedEvents:YES]; + [m_window setAcceptsMouseMovedEvents:YES]; - NSView *view = [m_window contentView]; - [view setAcceptsTouchEvents:YES]; + NSView *view = [m_window contentView]; + [view setAcceptsTouchEvents:YES]; - [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, - NSStringPboardType, NSTIFFPboardType, nil]]; + [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, + NSStringPboardType, + NSTIFFPboardType, + nil]]; - if (state != GHOST_kWindowStateFullScreen) { - [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - } + if (state != GHOST_kWindowStateFullScreen) { + [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } - if (state == GHOST_kWindowStateFullScreen) - setState(GHOST_kWindowStateFullScreen); + if (state == GHOST_kWindowStateFullScreen) + setState(GHOST_kWindowStateFullScreen); - setNativePixelSize(); + setNativePixelSize(); - [pool drain]; + [pool drain]; } - GHOST_WindowCocoa::~GHOST_WindowCocoa() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (m_customCursor) { - [m_customCursor release]; - m_customCursor = nil; - } + if (m_customCursor) { + [m_customCursor release]; + m_customCursor = nil; + } - releaseNativeHandles(); + releaseNativeHandles(); - [m_openGLView release]; + [m_openGLView release]; - if (m_window) { - [m_window close]; - } + if (m_window) { + [m_window close]; + } - // Check for other blender opened windows and make the frontmost key - // Note: for some reason the closed window is still in the list - NSArray *windowsList = [NSApp orderedWindows]; - for (int a = 0; a < [windowsList count]; a++) { - if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { - [[windowsList objectAtIndex:a] makeKeyWindow]; - break; - } - } - m_window = nil; + // Check for other blender opened windows and make the frontmost key + // Note: for some reason the closed window is still in the list + NSArray *windowsList = [NSApp orderedWindows]; + for (int a = 0; a < [windowsList count]; a++) { + if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { + [[windowsList objectAtIndex:a] makeKeyWindow]; + break; + } + } + m_window = nil; - [pool drain]; + [pool drain]; } #pragma mark accessors bool GHOST_WindowCocoa::getValid() const { - return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL; + return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL; } -void* GHOST_WindowCocoa::getOSWindow() const +void *GHOST_WindowCocoa::getOSWindow() const { - return (void*)m_window; + return (void *)m_window; } -void GHOST_WindowCocoa::setTitle(const STR_String& title) +void GHOST_WindowCocoa::setTitle(const STR_String &title) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //Set associated file if applicable - if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { - NSRange fileStrRange; - NSString *associatedFileName; - int len; + NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; - fileStrRange.location = [windowTitle rangeOfString:@"["].location+1; - len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; + //Set associated file if applicable + if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { + NSRange fileStrRange; + NSString *associatedFileName; + int len; - if (len > 0) { - fileStrRange.length = len; - associatedFileName = [windowTitle substringWithRange:fileStrRange]; - [m_window setTitle:[associatedFileName lastPathComponent]]; + fileStrRange.location = [windowTitle rangeOfString:@"["].location + 1; + len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; - //Blender used file open/save functions converte file names into legal URL ones - associatedFileName = [associatedFileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - @try { - [m_window setRepresentedFilename:associatedFileName]; - } - @catch (NSException * e) { - printf("\nInvalid file path given in window title"); - } - } - else { - [m_window setTitle:windowTitle]; - [m_window setRepresentedFilename:@""]; - } + if (len > 0) { + fileStrRange.length = len; + associatedFileName = [windowTitle substringWithRange:fileStrRange]; + [m_window setTitle:[associatedFileName lastPathComponent]]; - } - else { - [m_window setTitle:windowTitle]; - [m_window setRepresentedFilename:@""]; - } + //Blender used file open/save functions converte file names into legal URL ones + associatedFileName = [associatedFileName + stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + @try { + [m_window setRepresentedFilename:associatedFileName]; + } + @catch (NSException *e) { + printf("\nInvalid file path given in window title"); + } + } + else { + [m_window setTitle:windowTitle]; + [m_window setRepresentedFilename:@""]; + } + } + else { + [m_window setTitle:windowTitle]; + [m_window setRepresentedFilename:@""]; + } - - [windowTitle release]; - [pool drain]; + [windowTitle release]; + [pool drain]; } - -void GHOST_WindowCocoa::getTitle(STR_String& title) const +void GHOST_WindowCocoa::getTitle(STR_String &title) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *windowTitle = [m_window title]; + NSString *windowTitle = [m_window title]; - if (windowTitle != nil) { - title = [windowTitle UTF8String]; - } + if (windowTitle != nil) { + title = [windowTitle UTF8String]; + } - [pool drain]; + [pool drain]; } - -void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const +void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect &bounds) const { - NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); + NSRect rect; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSRect screenSize = [[m_window screen] visibleFrame]; + NSRect screenSize = [[m_window screen] visibleFrame]; - rect = [m_window frame]; + rect = [m_window frame]; - bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y); - bounds.m_l = rect.origin.x -screenSize.origin.x; - bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width; - bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y); + bounds.m_b = screenSize.size.height - (rect.origin.y - screenSize.origin.y); + bounds.m_l = rect.origin.x - screenSize.origin.x; + bounds.m_r = rect.origin.x - screenSize.origin.x + rect.size.width; + bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height - screenSize.origin.y); - [pool drain]; + [pool drain]; } - -void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const +void GHOST_WindowCocoa::getClientBounds(GHOST_Rect &bounds) const { - NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); + NSRect rect; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSRect screenSize = [[m_window screen] visibleFrame]; + NSRect screenSize = [[m_window screen] visibleFrame]; - //Max window contents as screen size (excluding title bar...) - NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; + //Max window contents as screen size (excluding title bar...) + NSRect contentRect = [CocoaWindow + contentRectForFrameRect:screenSize + styleMask:(NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask)]; - rect = [m_window contentRectForFrameRect:[m_window frame]]; + rect = [m_window contentRectForFrameRect:[m_window frame]]; - bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); - bounds.m_l = rect.origin.x -contentRect.origin.x; - bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; - bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); - [pool drain]; + bounds.m_b = contentRect.size.height - (rect.origin.y - contentRect.origin.y); + bounds.m_l = rect.origin.x - contentRect.origin.x; + bounds.m_r = rect.origin.x - contentRect.origin.x + rect.size.width; + bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height - contentRect.origin.y); + [pool drain]; } - GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_Rect cBnds, wBnds; - getClientBounds(cBnds); - if (((GHOST_TUns32)cBnds.getWidth()) != width) { - NSSize size; - size.width=width; - size.height=cBnds.getHeight(); - [m_window setContentSize:size]; - } - [pool drain]; - return GHOST_kSuccess; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if (((GHOST_TUns32)cBnds.getWidth()) != width) { + NSSize size; + size.width = width; + size.height = cBnds.getHeight(); + [m_window setContentSize:size]; + } + [pool drain]; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_Rect cBnds, wBnds; - getClientBounds(cBnds); - if (((GHOST_TUns32)cBnds.getHeight()) != height) { - NSSize size; - size.width=cBnds.getWidth(); - size.height=height; - [m_window setContentSize:size]; - } - [pool drain]; - return GHOST_kSuccess; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if (((GHOST_TUns32)cBnds.getHeight()) != height) { + NSSize size; + size.width = cBnds.getWidth(); + size.height = height; + [m_window setContentSize:size]; + } + [pool drain]; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_Rect cBnds, wBnds; - getClientBounds(cBnds); - if ((((GHOST_TUns32)cBnds.getWidth()) != width) || - (((GHOST_TUns32)cBnds.getHeight()) != height)) - { - NSSize size; - size.width=width; - size.height=height; - [m_window setContentSize:size]; - } - [pool drain]; - return GHOST_kSuccess; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if ((((GHOST_TUns32)cBnds.getWidth()) != width) || + (((GHOST_TUns32)cBnds.getHeight()) != height)) { + NSSize size; + size.width = width; + size.height = height; + [m_window setContentSize:size]; + } + [pool drain]; + return GHOST_kSuccess; } - GHOST_TWindowState GHOST_WindowCocoa::getState() const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_TWindowState state; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_TWindowState state; - NSUInteger masks = [m_window styleMask]; + NSUInteger masks = [m_window styleMask]; - if (masks & NSFullScreenWindowMask) { - // Lion style fullscreen - if (!m_immediateDraw) { - state = GHOST_kWindowStateFullScreen; - } - else { - state = GHOST_kWindowStateNormal; - } - } - else if ([m_window isMiniaturized]) { - state = GHOST_kWindowStateMinimized; - } - else if ([m_window isZoomed]) { - state = GHOST_kWindowStateMaximized; - } - else { - if (m_immediateDraw) { - state = GHOST_kWindowStateFullScreen; - } - else { - state = GHOST_kWindowStateNormal; - } - } - [pool drain]; - return state; + if (masks & NSFullScreenWindowMask) { + // Lion style fullscreen + if (!m_immediateDraw) { + state = GHOST_kWindowStateFullScreen; + } + else { + state = GHOST_kWindowStateNormal; + } + } + else if ([m_window isMiniaturized]) { + state = GHOST_kWindowStateMinimized; + } + else if ([m_window isZoomed]) { + state = GHOST_kWindowStateMaximized; + } + else { + if (m_immediateDraw) { + state = GHOST_kWindowStateFullScreen; + } + else { + state = GHOST_kWindowStateNormal; + } + } + [pool drain]; + return state; } - -void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid"); + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid"); - screenToClientIntern(inX, inY, outX, outY); + screenToClientIntern(inX, inY, outX, outY); - /* switch y to match ghost convention */ - GHOST_Rect cBnds; - getClientBounds(cBnds); - outY = (cBnds.getHeight() - 1) - outY; + /* switch y to match ghost convention */ + GHOST_Rect cBnds; + getClientBounds(cBnds); + outY = (cBnds.getHeight() - 1) - outY; } - -void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid"); + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid"); - /* switch y to match ghost convention */ - GHOST_Rect cBnds; - getClientBounds(cBnds); - inY = (cBnds.getHeight() - 1) - inY; + /* switch y to match ghost convention */ + GHOST_Rect cBnds; + getClientBounds(cBnds); + inY = (cBnds.getHeight() - 1) - inY; - clientToScreenIntern(inX, inY, outX, outY); + clientToScreenIntern(inX, inY, outX, outY); } -void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - NSRect screenCoord; - NSRect baseCoord; + NSRect screenCoord; + NSRect baseCoord; - screenCoord.origin.x = inX; - screenCoord.origin.y = inY; + screenCoord.origin.x = inX; + screenCoord.origin.y = inY; - baseCoord = [m_window convertRectFromScreen:screenCoord]; + baseCoord = [m_window convertRectFromScreen:screenCoord]; - outX = baseCoord.origin.x; - outY = baseCoord.origin.y; + outX = baseCoord.origin.x; + outY = baseCoord.origin.y; } -void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - NSRect screenCoord; - NSRect baseCoord; + NSRect screenCoord; + NSRect baseCoord; - baseCoord.origin.x = inX; - baseCoord.origin.y = inY; + baseCoord.origin.x = inX; + baseCoord.origin.y = inY; - screenCoord = [m_window convertRectToScreen:baseCoord]; + screenCoord = [m_window convertRectToScreen:baseCoord]; - outX = screenCoord.origin.x; - outY = screenCoord.origin.y; + outX = screenCoord.origin.x; + outY = screenCoord.origin.y; } - -NSScreen* GHOST_WindowCocoa::getScreen() +NSScreen *GHOST_WindowCocoa::getScreen() { - return [m_window screen]; + return [m_window screen]; } /* called for event, when window leaves monitor to another */ void GHOST_WindowCocoa::setNativePixelSize(void) { - NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; + NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; - GHOST_Rect rect; - getClientBounds(rect); + GHOST_Rect rect; + getClientBounds(rect); - m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth(); + m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth(); } /** @@ -906,430 +936,436 @@ void GHOST_WindowCocoa::setNativePixelSize(void) */ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); - switch (state) { - case GHOST_kWindowStateMinimized: - [m_window miniaturize:nil]; - break; - case GHOST_kWindowStateMaximized: - [m_window zoom:nil]; - break; - - case GHOST_kWindowStateFullScreen: - { - NSUInteger masks = [m_window styleMask]; - - if (!(masks & NSFullScreenWindowMask)) { - [m_window toggleFullScreen:nil]; - } - break; - } - case GHOST_kWindowStateNormal: - default: - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSUInteger masks = [m_window styleMask]; - - if (masks & NSFullScreenWindowMask) { - // Lion style fullscreen - [m_window toggleFullScreen:nil]; - } - else if ([m_window isMiniaturized]) - [m_window deminiaturize:nil]; - else if ([m_window isZoomed]) - [m_window zoom:nil]; - [pool drain]; - break; - } - - return GHOST_kSuccess; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); + switch (state) { + case GHOST_kWindowStateMinimized: + [m_window miniaturize:nil]; + break; + case GHOST_kWindowStateMaximized: + [m_window zoom:nil]; + break; + + case GHOST_kWindowStateFullScreen: { + NSUInteger masks = [m_window styleMask]; + + if (!(masks & NSFullScreenWindowMask)) { + [m_window toggleFullScreen:nil]; + } + break; + } + case GHOST_kWindowStateNormal: + default: + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSUInteger masks = [m_window styleMask]; + + if (masks & NSFullScreenWindowMask) { + // Lion style fullscreen + [m_window toggleFullScreen:nil]; + } + else if ([m_window isMiniaturized]) + [m_window deminiaturize:nil]; + else if ([m_window isZoomed]) + [m_window zoom:nil]; + [pool drain]; + break; + } + + return GHOST_kSuccess; } GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_window setDocumentEdited:isUnsavedChanges]; + [m_window setDocumentEdited:isUnsavedChanges]; - [pool drain]; - return GHOST_Window::setModifiedState(isUnsavedChanges); + [pool drain]; + return GHOST_Window::setModifiedState(isUnsavedChanges); } - - GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); - if (order == GHOST_kWindowOrderTop) { - [m_window makeKeyAndOrderFront:nil]; - } - else { - NSArray *windowsList; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); + if (order == GHOST_kWindowOrderTop) { + [m_window makeKeyAndOrderFront:nil]; + } + else { + NSArray *windowsList; - [m_window orderBack:nil]; + [m_window orderBack:nil]; - //Check for other blender opened windows and make the frontmost key - windowsList = [NSApp orderedWindows]; - if ([windowsList count]) { - [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; - } - } + //Check for other blender opened windows and make the frontmost key + windowsList = [NSApp orderedWindows]; + if ([windowsList count]) { + [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + } + } - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } #pragma mark Drawing context GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type) { - if (type == GHOST_kDrawingContextTypeOpenGL) { + if (type == GHOST_kDrawingContextTypeOpenGL) { - GHOST_Context *context = new GHOST_ContextCGL( - m_wantStereoVisual, - m_wantNumOfAASamples, - m_window, - m_openGLView, + GHOST_Context *context = new GHOST_ContextCGL(m_wantStereoVisual, + m_wantNumOfAASamples, + m_window, + m_openGLView, #if defined(WITH_GL_PROFILE_CORE) - GL_CONTEXT_CORE_PROFILE_BIT, - 3, 3, + GL_CONTEXT_CORE_PROFILE_BIT, + 3, + 3, #else - 0, // no profile bit - 2, 1, + 0, // no profile bit + 2, + 1, #endif - GHOST_OPENGL_CGL_CONTEXT_FLAGS, - GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); + GHOST_OPENGL_CGL_CONTEXT_FLAGS, + GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); - if (context->initializeDrawingContext()) - return context; - else - delete context; - } + if (context->initializeDrawingContext()) + return context; + else + delete context; + } - return NULL; + return NULL; } #pragma mark invalidate GHOST_TSuccess GHOST_WindowCocoa::invalidate() { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid"); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLView setNeedsDisplay:YES]; - [pool drain]; - return GHOST_kSuccess; + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid"); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLView setNeedsDisplay:YES]; + [pool drain]; + return GHOST_kSuccess; } #pragma mark Progress bar GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if ((progress >=0.0) && (progress <=1.0)) { - NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; + if ((progress >= 0.0) && (progress <= 1.0)) { + NSImage *dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)]; - [dockIcon lockFocus]; - NSRect progressBox = {{4, 4}, {120, 16}}; + [dockIcon lockFocus]; + NSRect progressBox = {{4, 4}, {120, 16}}; - [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; + [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:1.0]; - // Track & Outline - [[NSColor blackColor] setFill]; - NSRectFill(progressBox); + // Track & Outline + [[NSColor blackColor] setFill]; + NSRectFill(progressBox); - [[NSColor whiteColor] set]; - NSFrameRect(progressBox); + [[NSColor whiteColor] set]; + NSFrameRect(progressBox); - // Progress fill - progressBox = NSInsetRect(progressBox, 1, 1); + // Progress fill + progressBox = NSInsetRect(progressBox, 1, 1); - progressBox.size.width = progressBox.size.width * progress; - NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[NSColor lightGrayColor]]; - [gradient drawInRect:progressBox angle:90]; - [gradient release]; + progressBox.size.width = progressBox.size.width * progress; + NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] + endingColor:[NSColor lightGrayColor]]; + [gradient drawInRect:progressBox angle:90]; + [gradient release]; - [dockIcon unlockFocus]; + [dockIcon unlockFocus]; - [NSApp setApplicationIconImage:dockIcon]; - [dockIcon release]; + [NSApp setApplicationIconImage:dockIcon]; + [dockIcon release]; - m_progressBarVisible = true; - } + m_progressBarVisible = true; + } - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } static void postNotification() { - NSUserNotification *notification = [[NSUserNotification alloc] init]; - notification.title = @"Blender progress notification"; - notification.informativeText = @"Calculation is finished"; - notification.soundName = NSUserNotificationDefaultSoundName; - [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; - [notification release]; + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = @"Blender progress notification"; + notification.informativeText = @"Calculation is finished"; + notification.soundName = NSUserNotificationDefaultSoundName; + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + [notification release]; } GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() { - if (!m_progressBarVisible) return GHOST_kFailure; - m_progressBarVisible = false; + if (!m_progressBarVisible) + return GHOST_kFailure; + m_progressBarVisible = false; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; - [dockIcon lockFocus]; - [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; - [dockIcon unlockFocus]; - [NSApp setApplicationIconImage:dockIcon]; + NSImage *dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)]; + [dockIcon lockFocus]; + [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:1.0]; + [dockIcon unlockFocus]; + [NSApp setApplicationIconImage:dockIcon]; - // We use notifications to inform the user when the progress reached 100% - // Atm. just fire this when the progressbar ends, the behavior is controlled - // in the NotificationCenter If Blender is not frontmost window, a message - // pops up with sound, in any case an entry in notifications - if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { - postNotification(); - } + // We use notifications to inform the user when the progress reached 100% + // Atm. just fire this when the progressbar ends, the behavior is controlled + // in the NotificationCenter If Blender is not frontmost window, a message + // pops up with sound, in any case an entry in notifications + if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { + postNotification(); + } - [dockIcon release]; + [dockIcon release]; - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } #pragma mark Cursor handling void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const { - static bool systemCursorVisible = true; - - NSCursor *tmpCursor =nil; - - if (visible != systemCursorVisible) { - if (visible) { - [NSCursor unhide]; - systemCursorVisible = true; - } - else { - [NSCursor hide]; - systemCursorVisible = false; - } - } - - if (cursor == GHOST_kStandardCursorCustom && m_customCursor) { - tmpCursor = m_customCursor; - } - else { - switch (cursor) { - case GHOST_kStandardCursorDestroy: - tmpCursor = [NSCursor disappearingItemCursor]; - break; - case GHOST_kStandardCursorText: - tmpCursor = [NSCursor IBeamCursor]; - break; - case GHOST_kStandardCursorCrosshair: - tmpCursor = [NSCursor crosshairCursor]; - break; - case GHOST_kStandardCursorUpDown: - tmpCursor = [NSCursor resizeUpDownCursor]; - break; - case GHOST_kStandardCursorLeftRight: - tmpCursor = [NSCursor resizeLeftRightCursor]; - break; - case GHOST_kStandardCursorTopSide: - tmpCursor = [NSCursor resizeUpCursor]; - break; - case GHOST_kStandardCursorBottomSide: - tmpCursor = [NSCursor resizeDownCursor]; - break; - case GHOST_kStandardCursorLeftSide: - tmpCursor = [NSCursor resizeLeftCursor]; - break; - case GHOST_kStandardCursorRightSide: - tmpCursor = [NSCursor resizeRightCursor]; - break; - case GHOST_kStandardCursorRightArrow: - case GHOST_kStandardCursorInfo: - case GHOST_kStandardCursorLeftArrow: - case GHOST_kStandardCursorHelp: - case GHOST_kStandardCursorCycle: - case GHOST_kStandardCursorSpray: - case GHOST_kStandardCursorWait: - case GHOST_kStandardCursorTopLeftCorner: - case GHOST_kStandardCursorTopRightCorner: - case GHOST_kStandardCursorBottomRightCorner: - case GHOST_kStandardCursorBottomLeftCorner: - case GHOST_kStandardCursorCopy: - case GHOST_kStandardCursorDefault: - default: - tmpCursor = [NSCursor arrowCursor]; - break; - }; - } - [tmpCursor set]; + static bool systemCursorVisible = true; + + NSCursor *tmpCursor = nil; + + if (visible != systemCursorVisible) { + if (visible) { + [NSCursor unhide]; + systemCursorVisible = true; + } + else { + [NSCursor hide]; + systemCursorVisible = false; + } + } + + if (cursor == GHOST_kStandardCursorCustom && m_customCursor) { + tmpCursor = m_customCursor; + } + else { + switch (cursor) { + case GHOST_kStandardCursorDestroy: + tmpCursor = [NSCursor disappearingItemCursor]; + break; + case GHOST_kStandardCursorText: + tmpCursor = [NSCursor IBeamCursor]; + break; + case GHOST_kStandardCursorCrosshair: + tmpCursor = [NSCursor crosshairCursor]; + break; + case GHOST_kStandardCursorUpDown: + tmpCursor = [NSCursor resizeUpDownCursor]; + break; + case GHOST_kStandardCursorLeftRight: + tmpCursor = [NSCursor resizeLeftRightCursor]; + break; + case GHOST_kStandardCursorTopSide: + tmpCursor = [NSCursor resizeUpCursor]; + break; + case GHOST_kStandardCursorBottomSide: + tmpCursor = [NSCursor resizeDownCursor]; + break; + case GHOST_kStandardCursorLeftSide: + tmpCursor = [NSCursor resizeLeftCursor]; + break; + case GHOST_kStandardCursorRightSide: + tmpCursor = [NSCursor resizeRightCursor]; + break; + case GHOST_kStandardCursorRightArrow: + case GHOST_kStandardCursorInfo: + case GHOST_kStandardCursorLeftArrow: + case GHOST_kStandardCursorHelp: + case GHOST_kStandardCursorCycle: + case GHOST_kStandardCursorSpray: + case GHOST_kStandardCursorWait: + case GHOST_kStandardCursorTopLeftCorner: + case GHOST_kStandardCursorTopRightCorner: + case GHOST_kStandardCursorBottomRightCorner: + case GHOST_kStandardCursorBottomLeftCorner: + case GHOST_kStandardCursorCopy: + case GHOST_kStandardCursorDefault: + default: + tmpCursor = [NSCursor arrowCursor]; + break; + }; + } + [tmpCursor set]; } - - GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if ([m_window isVisible]) { - loadCursor(visible, getCursorShape()); - } + if ([m_window isVisible]) { + loadCursor(visible, getCursorShape()); + } - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } - GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode) { - GHOST_TSuccess err = GHOST_kSuccess; + GHOST_TSuccess err = GHOST_kSuccess; - if (mode != GHOST_kGrabDisable) { - //No need to perform grab without warp as it is always on in OS X - if (mode != GHOST_kGrabNormal) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + if (mode != GHOST_kGrabDisable) { + //No need to perform grab without warp as it is always on in OS X + if (mode != GHOST_kGrabNormal) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setCursorGrabAccum(0, 0); + m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setCursorGrabAccum(0, 0); - if (mode == GHOST_kGrabHide) { - setWindowCursorVisibility(false); - } + if (mode == GHOST_kGrabHide) { + setWindowCursorVisibility(false); + } - //Make window key if it wasn't to get the mouse move events - [m_window makeKeyWindow]; + //Make window key if it wasn't to get the mouse move events + [m_window makeKeyWindow]; - [pool drain]; - } - } - else { - if (m_cursorGrab==GHOST_kGrabHide) { - m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setWindowCursorVisibility(true); - } + [pool drain]; + } + } + else { + if (m_cursorGrab == GHOST_kGrabHide) { + m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setWindowCursorVisibility(true); + } - /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - setCursorGrabAccum(0, 0); - m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */ - } - return err; + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); + m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ + } + return err; } GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (m_customCursor) { - [m_customCursor release]; - m_customCursor = nil; - } + if (m_customCursor) { + [m_customCursor release]; + m_customCursor = nil; + } - if ([m_window isVisible]) { - loadCursor(getCursorVisibility(), shape); - } + if ([m_window isVisible]) { + loadCursor(getCursorVisibility(), shape); + } - [pool drain]; - return GHOST_kSuccess; + [pool drain]; + return GHOST_kSuccess; } /** Reverse the bits in a GHOST_TUns8 static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) { - ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); - ch= ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); - ch= ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0); - return ch; + ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); + ch= ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); + ch= ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0); + return ch; } */ - /** 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_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, - int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color) -{ - int y,nbUns16; - NSPoint hotSpotPoint; - NSBitmapImageRep *cursorImageRep; - NSImage *cursorImage; - NSSize imSize; - GHOST_TUns16 *cursorBitmap; - - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - if (m_customCursor) { - [m_customCursor release]; - m_customCursor = nil; - } - - - cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil - pixelsWide:sizex - pixelsHigh:sizey - bitsPerSample:1 - samplesPerPixel:2 - hasAlpha:YES - isPlanar:YES - colorSpaceName:NSDeviceWhiteColorSpace - bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0)) - bitsPerPixel:1]; - - - cursorBitmap = (GHOST_TUns16*)[cursorImageRep bitmapData]; - nbUns16 = [cursorImageRep bytesPerPlane]/2; - - for (y=0; y<nbUns16; y++) { + 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_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color) +{ + int y, nbUns16; + NSPoint hotSpotPoint; + NSBitmapImageRep *cursorImageRep; + NSImage *cursorImage; + NSSize imSize; + GHOST_TUns16 *cursorBitmap; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (m_customCursor) { + [m_customCursor release]; + m_customCursor = nil; + } + + cursorImageRep = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:nil + pixelsWide:sizex + pixelsHigh:sizey + bitsPerSample:1 + samplesPerPixel:2 + hasAlpha:YES + isPlanar:YES + colorSpaceName:NSDeviceWhiteColorSpace + bytesPerRow:(sizex / 8 + (sizex % 8 > 0 ? 1 : 0)) + bitsPerPixel:1]; + + cursorBitmap = (GHOST_TUns16 *)[cursorImageRep bitmapData]; + nbUns16 = [cursorImageRep bytesPerPlane] / 2; + + for (y = 0; y < nbUns16; y++) { #if !defined(__LITTLE_ENDIAN__) - cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); - cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8)); + cursorBitmap[y] = ~uns16ReverseBits((bitmap[2 * y] << 0) | (bitmap[2 * y + 1] << 8)); + cursorBitmap[nbUns16 + y] = uns16ReverseBits((mask[2 * y] << 0) | (mask[2 * y + 1] << 8)); #else - cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); - cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8)); + cursorBitmap[y] = ~uns16ReverseBits((bitmap[2 * y + 1] << 0) | (bitmap[2 * y] << 8)); + cursorBitmap[nbUns16 + y] = uns16ReverseBits((mask[2 * y + 1] << 0) | (mask[2 * y] << 8)); #endif + } - } - - - imSize.width = sizex; - imSize.height= sizey; - cursorImage = [[NSImage alloc] initWithSize:imSize]; - [cursorImage addRepresentation:cursorImageRep]; + imSize.width = sizex; + imSize.height = sizey; + cursorImage = [[NSImage alloc] initWithSize:imSize]; + [cursorImage addRepresentation:cursorImageRep]; - hotSpotPoint.x = hotX; - hotSpotPoint.y = hotY; + hotSpotPoint.x = hotX; + hotSpotPoint.y = hotY; - //foreground and background color parameter is not handled for now (10.6) - m_customCursor = [[NSCursor alloc] initWithImage:cursorImage - hotSpot:hotSpotPoint]; + //foreground and background color parameter is not handled for now (10.6) + m_customCursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpotPoint]; - [cursorImageRep release]; - [cursorImage release]; + [cursorImageRep release]; + [cursorImage release]; - if ([m_window isVisible]) { - loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); - } - [pool drain]; - return GHOST_kSuccess; + if ([m_window isVisible]) { + loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); + } + [pool drain]; + return GHOST_kSuccess; } GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], int hotX, int hotY) + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) { - return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1); + return setWindowCustomCursorShape( + (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1); } diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index d05f701be32..ca557e472f7 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -21,7 +21,6 @@ * \ingroup GHOST */ - /** * Copyright (C) 2001 NaN Technologies B.V. */ @@ -31,178 +30,164 @@ #include "GHOST_Debug.h" #include "GHOST_Window.h" - -GHOST_WindowManager::GHOST_WindowManager() : - m_fullScreenWindow(0), - m_activeWindow(0), - m_activeWindowBeforeFullScreen(0) +GHOST_WindowManager::GHOST_WindowManager() + : m_fullScreenWindow(0), m_activeWindow(0), m_activeWindowBeforeFullScreen(0) { } - GHOST_WindowManager::~GHOST_WindowManager() { - /* m_windows is freed by GHOST_System::disposeWindow */ + /* m_windows is freed by GHOST_System::disposeWindow */ } - 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 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 { - std::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; + GHOST_TSuccess success = GHOST_kFailure; + if (window) { + if (window == m_fullScreenWindow) { + endFullScreen(); + } + else { + std::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 { - std::vector<GHOST_IWindow *>::const_iterator result = find(m_windows.begin(), m_windows.end(), window); - if (result != m_windows.end()) { - found = true; - } - } - } - return found; + bool found = false; + if (window) { + if (getFullScreen() && (window == m_fullScreenWindow)) { + found = true; + } + else { + std::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 != NULL; + return m_fullScreenWindow != NULL; } - GHOST_IWindow *GHOST_WindowManager::getFullScreenWindow(void) const { - return m_fullScreenWindow; + return m_fullScreenWindow; } - -GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow *window, - bool /*stereoVisual*/) +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; - m_activeWindowBeforeFullScreen = getActiveWindow(); - setActiveWindow(m_fullScreenWindow); - m_fullScreenWindow->beginFullScreen(); - success = GHOST_kSuccess; - } - return success; + 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; + m_activeWindowBeforeFullScreen = getActiveWindow(); + setActiveWindow(m_fullScreenWindow); + m_fullScreenWindow->beginFullScreen(); + success = GHOST_kSuccess; + } + return success; } GHOST_TSuccess GHOST_WindowManager::endFullScreen(void) { - GHOST_TSuccess success = GHOST_kFailure; - if (getFullScreen()) { - if (m_fullScreenWindow != NULL) { - //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n"); - setWindowInactive(m_fullScreenWindow); - m_fullScreenWindow->endFullScreen(); - delete m_fullScreenWindow; - //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n"); - m_fullScreenWindow = NULL; - if (m_activeWindowBeforeFullScreen) { - setActiveWindow(m_activeWindowBeforeFullScreen); - } - } - success = GHOST_kSuccess; - } - return success; + GHOST_TSuccess success = GHOST_kFailure; + if (getFullScreen()) { + if (m_fullScreenWindow != NULL) { + //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n"); + setWindowInactive(m_fullScreenWindow); + m_fullScreenWindow->endFullScreen(); + delete m_fullScreenWindow; + //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n"); + m_fullScreenWindow = NULL; + if (m_activeWindowBeforeFullScreen) { + setActiveWindow(m_activeWindowBeforeFullScreen); + } + } + 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_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; + return m_activeWindow; } - void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow *window) { - if (window == m_activeWindow) { - m_activeWindow = NULL; - } + if (window == m_activeWindow) { + m_activeWindow = NULL; + } } - std::vector<GHOST_IWindow *> &GHOST_WindowManager::getWindows() { - return m_windows; + return m_windows; } - GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(void *osWindow) { - std::vector<GHOST_IWindow *>::iterator iter; + std::vector<GHOST_IWindow *>::iterator iter; - for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) { - if ((*iter)->getOSWindow() == osWindow) - return *iter; - } + for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) { + if ((*iter)->getOSWindow() == osWindow) + return *iter; + } - return NULL; + return NULL; } bool GHOST_WindowManager::getAnyModifiedState() { - bool isAnyModified = false; - std::vector<GHOST_IWindow *>::iterator iter; + bool isAnyModified = false; + std::vector<GHOST_IWindow *>::iterator iter; - for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) { - if ((*iter)->getModifiedState()) - isAnyModified = true; - } + for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) { + if ((*iter)->getModifiedState()) + isAnyModified = true; + } - return isAnyModified; + return isAnyModified; } diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h index fe1db0fed52..025d84f1f3d 100644 --- a/intern/ghost/intern/GHOST_WindowManager.h +++ b/intern/ghost/intern/GHOST_WindowManager.h @@ -30,131 +30,126 @@ #include "GHOST_Rect.h" #include "GHOST_IWindow.h" - /** * Manages system windows (platform independent implementation). */ -class GHOST_WindowManager -{ -public: - /** - * Constructor. - */ - GHOST_WindowManager(); - - /** - * Destructor. - */ - ~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. - */ - 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. - */ - 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. - */ - bool getWindowFound(const GHOST_IWindow *window) const; - - /** - * Returns whether one of the windows is fullscreen. - * \return A boolean indicator. - */ - bool getFullScreen(void) const; - - /** - * Returns pointer to the full-screen window. - * \return The full-screen window (NULL if not in full-screen). - */ - GHOST_IWindow *getFullScreenWindow(void) const; - - /** - * Activates fullscreen mode for a window. - * \param window The window displayed fullscreen. - * \return Indication of success. - */ - GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual); - - /** - * Closes fullscreen mode down. - * \return Indication of success. - */ - 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. - */ - 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). - */ - GHOST_IWindow *getActiveWindow(void) const; - - - /** - * Set this window to be inactive (not receiving events). - * \param window The window to deactivate. - */ - 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(); - - /** - * Finds the window associated with an OS window object/handle - * \param osWindow The OS window object/handle - * \return The associated window, null if none corresponds - */ - GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow); - - /** - * Return true if any windows has a modified status - * \return True if any window has unsaved changes - */ - bool getAnyModifiedState(); - -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; - - /** Window that was active before entering fullscreen state. */ - GHOST_IWindow *m_activeWindowBeforeFullScreen; +class GHOST_WindowManager { + public: + /** + * Constructor. + */ + GHOST_WindowManager(); + + /** + * Destructor. + */ + ~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. + */ + 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. + */ + 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. + */ + bool getWindowFound(const GHOST_IWindow *window) const; + + /** + * Returns whether one of the windows is fullscreen. + * \return A boolean indicator. + */ + bool getFullScreen(void) const; + + /** + * Returns pointer to the full-screen window. + * \return The full-screen window (NULL if not in full-screen). + */ + GHOST_IWindow *getFullScreenWindow(void) const; + + /** + * Activates fullscreen mode for a window. + * \param window The window displayed fullscreen. + * \return Indication of success. + */ + GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual); + + /** + * Closes fullscreen mode down. + * \return Indication of success. + */ + 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. + */ + 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). + */ + GHOST_IWindow *getActiveWindow(void) const; + + /** + * Set this window to be inactive (not receiving events). + * \param window The window to deactivate. + */ + 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(); + + /** + * Finds the window associated with an OS window object/handle + * \param osWindow The OS window object/handle + * \return The associated window, null if none corresponds + */ + GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow); + + /** + * Return true if any windows has a modified status + * \return True if any window has unsaved changes + */ + bool getAnyModifiedState(); + + 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; + + /** Window that was active before entering fullscreen state. */ + GHOST_IWindow *m_activeWindowBeforeFullScreen; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager") + MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager") #endif - }; -#endif // __GHOST_WINDOWMANAGER_H__ +#endif // __GHOST_WINDOWMANAGER_H__ diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index c7d9efcdc51..3ac3389291d 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -29,69 +29,163 @@ class STR_String; class GHOST_SystemNULL; -class GHOST_WindowNULL : public GHOST_Window -{ -public: - const GHOST_TabletData* GetTabletData() { return NULL; } +class GHOST_WindowNULL : public GHOST_Window { + public: + const GHOST_TabletData *GetTabletData() + { + return NULL; + } - GHOST_WindowNULL( - GHOST_SystemNULL *system, - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - const GHOST_TEmbedderWindowID parentWindow, - GHOST_TDrawingContextType type, - const bool stereoVisual, - const GHOST_TUns16 numOfAASamples - ) : - GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), - m_system(system) - { - setTitle(title); - } + GHOST_WindowNULL(GHOST_SystemNULL *system, + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type, + const bool stereoVisual, + const GHOST_TUns16 numOfAASamples) + : GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), m_system(system) + { + setTitle(title); + } -protected: - GHOST_TSuccess installDrawingContext( GHOST_TDrawingContextType type ) { return GHOST_kSuccess; } - GHOST_TSuccess removeDrawingContext( ) { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorGrab( GHOST_TGrabCursorMode mode ) { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorShape( GHOST_TStandardCursor shape ) { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY ) { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color ) { return GHOST_kSuccess; } + protected: + GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type) + { + return GHOST_kSuccess; + } + GHOST_TSuccess removeDrawingContext() + { + return GHOST_kSuccess; + } + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) + { + return GHOST_kSuccess; + } + GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) + { + return GHOST_kSuccess; + } + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) + { + return GHOST_kSuccess; + } + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color) + { + return GHOST_kSuccess; + } - bool getValid( ) const { return true; } - void setTitle( const STR_String& title ) { /* nothing */ } - void getTitle( STR_String& title ) const { title= "untitled"; } - void getWindowBounds( GHOST_Rect& bounds ) const { getClientBounds(bounds); } - void getClientBounds( GHOST_Rect& bounds ) const { /* nothing */ } - GHOST_TSuccess setClientWidth( GHOST_TUns32 width ) { return GHOST_kFailure; } - GHOST_TSuccess setClientHeight( GHOST_TUns32 height ) { return GHOST_kFailure; } - GHOST_TSuccess setClientSize( GHOST_TUns32 width, GHOST_TUns32 height ) { return GHOST_kFailure; } - void screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } - void clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } - GHOST_TSuccess swapBuffers( ) { return GHOST_kFailure; } - GHOST_TSuccess activateDrawingContext( ) { return GHOST_kFailure; } - ~GHOST_WindowNULL( ) { /* nothing */ } - GHOST_TSuccess setWindowCursorVisibility( bool visible ) { return GHOST_kSuccess; } - GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; } - GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; } - GHOST_TSuccess invalidate() { return GHOST_kSuccess; } - GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; } + bool getValid() const + { + return true; + } + void setTitle(const STR_String &title) + { /* nothing */ + } + void getTitle(STR_String &title) const + { + title = "untitled"; + } + void getWindowBounds(GHOST_Rect &bounds) const + { + getClientBounds(bounds); + } + void getClientBounds(GHOST_Rect &bounds) const + { /* nothing */ + } + GHOST_TSuccess setClientWidth(GHOST_TUns32 width) + { + return GHOST_kFailure; + } + GHOST_TSuccess setClientHeight(GHOST_TUns32 height) + { + return GHOST_kFailure; + } + GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) + { + return GHOST_kFailure; + } + void screenToClient(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const + { + outX = inX; + outY = inY; + } + void clientToScreen(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const + { + outX = inX; + outY = inY; + } + GHOST_TSuccess swapBuffers() + { + return GHOST_kFailure; + } + GHOST_TSuccess activateDrawingContext() + { + return GHOST_kFailure; + } + ~GHOST_WindowNULL() + { /* nothing */ + } + GHOST_TSuccess setWindowCursorVisibility(bool visible) + { + return GHOST_kSuccess; + } + GHOST_TSuccess setState(GHOST_TWindowState state) + { + return GHOST_kSuccess; + } + GHOST_TWindowState getState() const + { + return GHOST_kWindowStateNormal; + } + GHOST_TSuccess invalidate() + { + return GHOST_kSuccess; + } + GHOST_TSuccess setOrder(GHOST_TWindowOrder order) + { + return GHOST_kSuccess; + } - GHOST_TSuccess beginFullScreen() const { return GHOST_kSuccess; } - GHOST_TSuccess endFullScreen() const { return GHOST_kSuccess; } + GHOST_TSuccess beginFullScreen() const + { + return GHOST_kSuccess; + } + GHOST_TSuccess endFullScreen() const + { + return GHOST_kSuccess; + } -private: - GHOST_SystemNULL *m_system; + private: + GHOST_SystemNULL *m_system; - /** - * \param type The type of rendering context create. - * \return Indication of success. - */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) { return NULL; } + /** + * \param type The type of rendering context create. + * \return Indication of success. + */ + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) + { + return NULL; + } }; - -#endif // __GHOST_WINDOWNULL_H__ +#endif // __GHOST_WINDOWNULL_H__ diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp index f9d1b7c3677..d40377acc3a 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.cpp +++ b/intern/ghost/intern/GHOST_WindowSDL.cpp @@ -27,7 +27,7 @@ #include <assert.h> GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, - const STR_String& title, + const STR_String &title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, @@ -37,8 +37,7 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, GHOST_TDrawingContextType type, const bool stereoVisual, const bool exclusive, - const GHOST_TUns16 numOfAASamples - ) + const GHOST_TUns16 numOfAASamples) : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples), m_system(system), m_valid_setup(false), @@ -46,407 +45,541 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, m_sdl_custom_cursor(NULL) { - /* creating the window _must_ come after setting attributes */ - m_sdl_win = SDL_CreateWindow( - title, - left, top, - width, height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); - - /* now set up the rendering context. */ - if (setDrawingContextType(type) == GHOST_kSuccess) { - m_valid_setup = true; - GHOST_PRINT("Created window\n"); - } - - if (exclusive) { - SDL_RaiseWindow(m_sdl_win); - } - - setTitle(title); + /* creating the window _must_ come after setting attributes */ + m_sdl_win = SDL_CreateWindow(title, + left, + top, + width, + height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); + + /* now set up the rendering context. */ + if (setDrawingContextType(type) == GHOST_kSuccess) { + m_valid_setup = true; + GHOST_PRINT("Created window\n"); + } + + if (exclusive) { + SDL_RaiseWindow(m_sdl_win); + } + + setTitle(title); } GHOST_WindowSDL::~GHOST_WindowSDL() { - if (m_sdl_custom_cursor) { - SDL_FreeCursor(m_sdl_custom_cursor); - } + if (m_sdl_custom_cursor) { + SDL_FreeCursor(m_sdl_custom_cursor); + } - releaseNativeHandles(); + releaseNativeHandles(); - SDL_DestroyWindow(m_sdl_win); + SDL_DestroyWindow(m_sdl_win); } - -GHOST_Context * -GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type) +GHOST_Context *GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type) { - if (type == GHOST_kDrawingContextTypeOpenGL) { - GHOST_Context *context = new GHOST_ContextSDL( - m_wantStereoVisual, - m_wantNumOfAASamples, - m_sdl_win, - 0, // profile bit - 3, 3, - GHOST_OPENGL_SDL_CONTEXT_FLAGS, - GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - } - - return NULL; + if (type == GHOST_kDrawingContextTypeOpenGL) { + GHOST_Context *context = new GHOST_ContextSDL(m_wantStereoVisual, + m_wantNumOfAASamples, + m_sdl_win, + 0, // profile bit + 3, + 3, + GHOST_OPENGL_SDL_CONTEXT_FLAGS, + GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + } + + return NULL; } - -GHOST_TSuccess -GHOST_WindowSDL::invalidate(void) +GHOST_TSuccess GHOST_WindowSDL::invalidate(void) { - if (m_invalid_window == false) { - m_system->addDirtyWindow(this); - m_invalid_window = true; - } + if (m_invalid_window == false) { + m_system->addDirtyWindow(this); + m_invalid_window = true; + } - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowSDL::setState(GHOST_TWindowState state) +GHOST_TSuccess GHOST_WindowSDL::setState(GHOST_TWindowState state) { - switch (state) { - case GHOST_kWindowStateNormal: - SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); - SDL_RestoreWindow(m_sdl_win); - break; - case GHOST_kWindowStateMaximized: - SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); - SDL_MaximizeWindow(m_sdl_win); - break; - case GHOST_kWindowStateMinimized: - SDL_MinimizeWindow(m_sdl_win); - break; - case GHOST_kWindowStateFullScreen: - SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE); - break; - default: - break; - } - - return GHOST_kSuccess; + switch (state) { + case GHOST_kWindowStateNormal: + SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); + SDL_RestoreWindow(m_sdl_win); + break; + case GHOST_kWindowStateMaximized: + SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); + SDL_MaximizeWindow(m_sdl_win); + break; + case GHOST_kWindowStateMinimized: + SDL_MinimizeWindow(m_sdl_win); + break; + case GHOST_kWindowStateFullScreen: + SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE); + break; + default: + break; + } + + return GHOST_kSuccess; } - -GHOST_TWindowState -GHOST_WindowSDL::getState() const +GHOST_TWindowState GHOST_WindowSDL::getState() const { - Uint32 flags = SDL_GetWindowFlags(m_sdl_win); - - if (flags & SDL_WINDOW_FULLSCREEN) return GHOST_kWindowStateFullScreen; - else if (flags & SDL_WINDOW_MAXIMIZED) return GHOST_kWindowStateMaximized; - else if (flags & SDL_WINDOW_MINIMIZED) return GHOST_kWindowStateMinimized; - return GHOST_kWindowStateNormal; + Uint32 flags = SDL_GetWindowFlags(m_sdl_win); + + if (flags & SDL_WINDOW_FULLSCREEN) + return GHOST_kWindowStateFullScreen; + else if (flags & SDL_WINDOW_MAXIMIZED) + return GHOST_kWindowStateMaximized; + else if (flags & SDL_WINDOW_MINIMIZED) + return GHOST_kWindowStateMinimized; + return GHOST_kWindowStateNormal; } -bool -GHOST_WindowSDL:: -getValid() const +bool GHOST_WindowSDL::getValid() const { - return GHOST_Window::getValid() && m_valid_setup; + return GHOST_Window::getValid() && m_valid_setup; } -void -GHOST_WindowSDL::setTitle(const STR_String& title) +void GHOST_WindowSDL::setTitle(const STR_String &title) { - SDL_SetWindowTitle(m_sdl_win, title.ReadPtr()); + SDL_SetWindowTitle(m_sdl_win, title.ReadPtr()); } - -void -GHOST_WindowSDL::getTitle(STR_String& title) const +void GHOST_WindowSDL::getTitle(STR_String &title) const { - title = SDL_GetWindowTitle(m_sdl_win); + title = SDL_GetWindowTitle(m_sdl_win); } - -void -GHOST_WindowSDL::getWindowBounds(GHOST_Rect& bounds) const +void GHOST_WindowSDL::getWindowBounds(GHOST_Rect &bounds) const { - getClientBounds(bounds); + getClientBounds(bounds); } - -void -GHOST_WindowSDL::getClientBounds(GHOST_Rect& bounds) const +void GHOST_WindowSDL::getClientBounds(GHOST_Rect &bounds) const { - int x, y, w, h; - SDL_GetWindowSize(m_sdl_win, &w, &h); - SDL_GetWindowPosition(m_sdl_win, &x, &y); - - bounds.m_l = x; - bounds.m_r = x + w; - bounds.m_t = y; - bounds.m_b = y + h; + int x, y, w, h; + SDL_GetWindowSize(m_sdl_win, &w, &h); + SDL_GetWindowPosition(m_sdl_win, &x, &y); + + bounds.m_l = x; + bounds.m_r = x + w; + bounds.m_t = y; + bounds.m_b = y + h; } -GHOST_TSuccess -GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) { - int height; - SDL_GetWindowSize(m_sdl_win, NULL, &height); - SDL_SetWindowSize(m_sdl_win, width, height); - return GHOST_kSuccess; + int height; + SDL_GetWindowSize(m_sdl_win, NULL, &height); + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) { - int width; - SDL_GetWindowSize(m_sdl_win, &width, NULL); - SDL_SetWindowSize(m_sdl_win, width, height); - return GHOST_kSuccess; + int width; + SDL_GetWindowSize(m_sdl_win, &width, NULL); + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, - GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) { - SDL_SetWindowSize(m_sdl_win, width, height); - return GHOST_kSuccess; + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; } -void -GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - /* XXXSDL_WEAK_ABS_COORDS */ - int x_win, y_win; - SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); + /* XXXSDL_WEAK_ABS_COORDS */ + int x_win, y_win; + SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); - outX = inX - x_win; - outY = inY - y_win; + outX = inX - x_win; + outY = inY - y_win; } -void -GHOST_WindowSDL::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const +void GHOST_WindowSDL::clientToScreen(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - /* XXXSDL_WEAK_ABS_COORDS */ - int x_win, y_win; - SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); + /* XXXSDL_WEAK_ABS_COORDS */ + int x_win, y_win; + SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); - outX = inX + x_win; - outY = inY + y_win; + outX = inX + x_win; + outY = inY + y_win; } /* mouse cursor */ -static unsigned char sdl_std_cursor_mask_xterm[] = {0xef, 0x01, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xef, 0x01, }; -static unsigned char sdl_std_cursor_xterm[] = {0x00, 0x77, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_xterm 9 +static unsigned char sdl_std_cursor_mask_xterm[] = { + 0xef, 0x01, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, + 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xef, 0x01, +}; +static unsigned char sdl_std_cursor_xterm[] = { + 0x00, 0x77, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_xterm 9 #define sdl_std_cursor_HEIGHT_xterm 16 -#define sdl_std_cursor_HOT_X_xterm -3 -#define sdl_std_cursor_HOT_Y_xterm -7 - -static unsigned char sdl_std_cursor_mask_watch[] = {0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, }; -static unsigned char sdl_std_cursor_watch[] = {0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0xfc, 0x0f, 0x86, 0x18, 0x83, 0x30, 0x81, 0xe0, 0xc1, 0xe1, 0xc1, 0xe1, 0x21, 0xe0, 0x13, 0x30, 0x06, 0x18, 0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, }; -#define sdl_std_cursor_WIDTH_watch 16 +#define sdl_std_cursor_HOT_X_xterm -3 +#define sdl_std_cursor_HOT_Y_xterm -7 + +static unsigned char sdl_std_cursor_mask_watch[] = { + 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, +}; +static unsigned char sdl_std_cursor_watch[] = { + 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0xfc, 0x0f, 0x86, 0x18, 0x83, 0x30, 0x81, 0xe0, 0xc1, 0xe1, + 0xc1, 0xe1, 0x21, 0xe0, 0x13, 0x30, 0x06, 0x18, 0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, +}; +#define sdl_std_cursor_WIDTH_watch 16 #define sdl_std_cursor_HEIGHT_watch 16 -#define sdl_std_cursor_HOT_X_watch -15 -#define sdl_std_cursor_HOT_Y_watch -7 - -static unsigned char sdl_std_cursor_mask_umbrella[] = {0xe8, 0x76, 0xfb, 0xdf, 0xfd, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0x79, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0x80, 0x03, }; -static unsigned char sdl_std_cursor_umbrella[] = {0x88, 0x04, 0x20, 0x0a, 0xc9, 0x32, 0xf2, 0x09, 0x4c, 0x06, 0x43, 0x18, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_umbrella 16 +#define sdl_std_cursor_HOT_X_watch -15 +#define sdl_std_cursor_HOT_Y_watch -7 + +static unsigned char sdl_std_cursor_mask_umbrella[] = { + 0xe8, 0x76, 0xfb, 0xdf, 0xfd, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0x79, 0xc0, 0x01, + 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0x80, 0x03, +}; +static unsigned char sdl_std_cursor_umbrella[] = { + 0x88, 0x04, 0x20, 0x0a, 0xc9, 0x32, 0xf2, 0x09, 0x4c, 0x06, 0x43, 0x18, 0x40, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_umbrella 16 #define sdl_std_cursor_HEIGHT_umbrella 16 -#define sdl_std_cursor_HOT_X_umbrella -7 -#define sdl_std_cursor_HOT_Y_umbrella -12 - -static unsigned char sdl_std_cursor_mask_top_side[] = {0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xdc, 0x1d, 0xcc, 0x19, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, }; -static unsigned char sdl_std_cursor_top_side[] = {0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x50, 0x01, 0x48, 0x02, 0x44, 0x04, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_top_side 15 +#define sdl_std_cursor_HOT_X_umbrella -7 +#define sdl_std_cursor_HOT_Y_umbrella -12 + +static unsigned char sdl_std_cursor_mask_top_side[] = { + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, + 0xdc, 0x1d, 0xcc, 0x19, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, +}; +static unsigned char sdl_std_cursor_top_side[] = { + 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x50, 0x01, 0x48, 0x02, 0x44, 0x04, + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_top_side 15 #define sdl_std_cursor_HEIGHT_top_side 16 -#define sdl_std_cursor_HOT_X_top_side -6 -#define sdl_std_cursor_HOT_Y_top_side -14 - -static unsigned char sdl_std_cursor_mask_top_right_corner[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xc0, 0xf7, 0xe0, 0xf7, 0x70, 0xf7, 0x38, 0xf7, 0x1c, 0xf7, 0x0c, 0xf7, 0x00, 0xf0, 0x00, 0xf0, }; -static unsigned char sdl_std_cursor_top_right_corner[] = {0xff, 0x3f, 0xff, 0x3f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xfc, 0x31, 0x80, 0x31, 0x40, 0x31, 0x20, 0x31, 0x10, 0x31, 0x08, 0x31, 0x04, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_top_right_corner 16 +#define sdl_std_cursor_HOT_X_top_side -6 +#define sdl_std_cursor_HOT_Y_top_side -14 + +static unsigned char sdl_std_cursor_mask_top_right_corner[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, + 0xc0, 0xf7, 0xe0, 0xf7, 0x70, 0xf7, 0x38, 0xf7, 0x1c, 0xf7, 0x0c, 0xf7, 0x00, 0xf0, 0x00, 0xf0, +}; +static unsigned char sdl_std_cursor_top_right_corner[] = { + 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xfc, 0x31, 0x80, 0x31, 0x40, 0x31, + 0x20, 0x31, 0x10, 0x31, 0x08, 0x31, 0x04, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_top_right_corner 16 #define sdl_std_cursor_HEIGHT_top_right_corner 16 -#define sdl_std_cursor_HOT_X_top_right_corner -13 -#define sdl_std_cursor_HOT_Y_top_right_corner -14 - -static unsigned char sdl_std_cursor_mask_top_left_corner[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x03, 0xef, 0x07, 0xef, 0x0e, 0xef, 0x1c, 0xef, 0x38, 0xef, 0x30, 0x0f, 0x00, 0x0f, 0x00, }; -static unsigned char sdl_std_cursor_top_left_corner[] = {0xff, 0x3f, 0xff, 0x3f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x0f, 0x63, 0x00, 0xa3, 0x00, 0x23, 0x01, 0x23, 0x02, 0x23, 0x04, 0x23, 0x08, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_top_left_corner 16 +#define sdl_std_cursor_HOT_X_top_right_corner -13 +#define sdl_std_cursor_HOT_Y_top_right_corner -14 + +static unsigned char sdl_std_cursor_mask_top_left_corner[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, + 0xef, 0x03, 0xef, 0x07, 0xef, 0x0e, 0xef, 0x1c, 0xef, 0x38, 0xef, 0x30, 0x0f, 0x00, 0x0f, 0x00, +}; +static unsigned char sdl_std_cursor_top_left_corner[] = { + 0xff, 0x3f, 0xff, 0x3f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x0f, 0x63, 0x00, 0xa3, 0x00, + 0x23, 0x01, 0x23, 0x02, 0x23, 0x04, 0x23, 0x08, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_top_left_corner 16 #define sdl_std_cursor_HEIGHT_top_left_corner 16 -#define sdl_std_cursor_HOT_X_top_left_corner 0 -#define sdl_std_cursor_HOT_Y_top_left_corner -14 - -static unsigned char sdl_std_cursor_mask_spraycan[] = {0x00, 0x0c, 0x18, 0x0d, 0x7c, 0x0d, 0x7c, 0x0d, 0x7e, 0x0d, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, }; -static unsigned char sdl_std_cursor_spraycan[] = {0x00, 0x06, 0x80, 0x00, 0x2c, 0x06, 0x9e, 0x00, 0x16, 0x06, 0x3f, 0x00, 0x21, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x27, 0x00, 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, }; -#define sdl_std_cursor_WIDTH_spraycan 12 +#define sdl_std_cursor_HOT_X_top_left_corner 0 +#define sdl_std_cursor_HOT_Y_top_left_corner -14 + +static unsigned char sdl_std_cursor_mask_spraycan[] = { + 0x00, 0x0c, 0x18, 0x0d, 0x7c, 0x0d, 0x7c, 0x0d, 0x7e, 0x0d, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, +}; +static unsigned char sdl_std_cursor_spraycan[] = { + 0x00, 0x06, 0x80, 0x00, 0x2c, 0x06, 0x9e, 0x00, 0x16, 0x06, 0x3f, 0x00, 0x21, 0x00, 0x27, 0x00, + 0x25, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x27, 0x00, 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, +}; +#define sdl_std_cursor_WIDTH_spraycan 12 #define sdl_std_cursor_HEIGHT_spraycan 16 -#define sdl_std_cursor_HOT_X_spraycan -9 -#define sdl_std_cursor_HOT_Y_spraycan -14 - -static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[] = {0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, }; -static unsigned char sdl_std_cursor_sb_v_double_arrow[] = {0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00, }; -#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9 +#define sdl_std_cursor_HOT_X_spraycan -9 +#define sdl_std_cursor_HOT_Y_spraycan -14 + +static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[] = { + 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x7c, 0x00, 0x7c, + 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, +}; +static unsigned char sdl_std_cursor_sb_v_double_arrow[] = { + 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, + 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00, +}; +#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9 #define sdl_std_cursor_HEIGHT_sb_v_double_arrow 15 -#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3 -#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8 - -static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = {0x18, 0x0c, 0x1c, 0x1c, 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xfe, 0x3f, 0x1c, 0x1c, 0x18, 0x0c, }; -static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {0x00, 0x00, 0x08, 0x08, 0x0c, 0x18, 0xfe, 0x3f, 0x0f, 0x78, 0xfe, 0x3f, 0x0c, 0x18, 0x08, 0x08, 0x00, 0x00}; -#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15 +#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3 +#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8 + +static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = { + 0x18, + 0x0c, + 0x1c, + 0x1c, + 0xfe, + 0x3f, + 0xff, + 0x7f, + 0xff, + 0x7f, + 0xff, + 0x7f, + 0xfe, + 0x3f, + 0x1c, + 0x1c, + 0x18, + 0x0c, +}; +static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {0x00, + 0x00, + 0x08, + 0x08, + 0x0c, + 0x18, + 0xfe, + 0x3f, + 0x0f, + 0x78, + 0xfe, + 0x3f, + 0x0c, + 0x18, + 0x08, + 0x08, + 0x00, + 0x00}; +#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15 #define sdl_std_cursor_HEIGHT_sb_h_double_arrow 9 -#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7 -#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4 - -static unsigned char sdl_std_cursor_mask_right_side[] = {0x00, 0xf0, 0x00, 0xf0, 0xc0, 0xf0, 0xc0, 0xf1, 0x80, 0xf3, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf7, 0x80, 0xf3, 0xc0, 0xf1, 0xc0, 0xf0, 0x00, 0xf0, 0x00, 0xf0, }; -static unsigned char sdl_std_cursor_right_side[] = {0x00, 0x30, 0x00, 0x30, 0x40, 0x30, 0x80, 0x30, 0x00, 0x31, 0x00, 0x32, 0xff, 0x37, 0x00, 0x32, 0x00, 0x31, 0x80, 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_right_side 16 +#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7 +#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4 + +static unsigned char sdl_std_cursor_mask_right_side[] = { + 0x00, 0xf0, 0x00, 0xf0, 0xc0, 0xf0, 0xc0, 0xf1, 0x80, 0xf3, 0x00, 0xf7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xf7, 0x80, 0xf3, 0xc0, 0xf1, 0xc0, 0xf0, 0x00, 0xf0, 0x00, 0xf0, +}; +static unsigned char sdl_std_cursor_right_side[] = { + 0x00, 0x30, 0x00, 0x30, 0x40, 0x30, 0x80, 0x30, 0x00, 0x31, 0x00, 0x32, 0xff, 0x37, 0x00, + 0x32, 0x00, 0x31, 0x80, 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_right_side 16 #define sdl_std_cursor_HEIGHT_right_side 15 -#define sdl_std_cursor_HOT_X_right_side -13 -#define sdl_std_cursor_HOT_Y_right_side -7 - -static unsigned char sdl_std_cursor_mask_right_ptr[] = {0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xfe, 0x03, 0xff, 0x03, 0xff, 0x03, 0xf8, 0x03, 0xbc, 0x03, 0x3c, 0x03, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00, }; -static unsigned char sdl_std_cursor_right_ptr[] = {0x00, 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xff, 0x00, 0xf8, 0x00, 0xd8, 0x00, 0x8c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_right_ptr 10 +#define sdl_std_cursor_HOT_X_right_side -13 +#define sdl_std_cursor_HOT_Y_right_side -7 + +static unsigned char sdl_std_cursor_mask_right_ptr[] = { + 0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xfe, 0x03, + 0xff, 0x03, 0xff, 0x03, 0xf8, 0x03, 0xbc, 0x03, 0x3c, 0x03, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00, +}; +static unsigned char sdl_std_cursor_right_ptr[] = { + 0x00, 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xff, + 0x00, 0xf8, 0x00, 0xd8, 0x00, 0x8c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_right_ptr 10 #define sdl_std_cursor_HEIGHT_right_ptr 16 -#define sdl_std_cursor_HOT_X_right_ptr -7 -#define sdl_std_cursor_HOT_Y_right_ptr -14 - -static unsigned char sdl_std_cursor_mask_question_arrow[] = {0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07, 0x8f, 0x07, 0x9f, 0x07, 0xde, 0x07, 0xfc, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, }; -static unsigned char sdl_std_cursor_question_arrow[] = {0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x87, 0x01, 0xc6, 0x01, 0xe0, 0x00, 0x78, 0x00, 0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0xee, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_question_arrow 11 +#define sdl_std_cursor_HOT_X_right_ptr -7 +#define sdl_std_cursor_HOT_Y_right_ptr -14 + +static unsigned char sdl_std_cursor_mask_question_arrow[] = { + 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07, 0x8f, 0x07, 0x9f, 0x07, 0xde, 0x07, 0xfc, 0x03, + 0xf8, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, +}; +static unsigned char sdl_std_cursor_question_arrow[] = { + 0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x87, 0x01, 0xc6, 0x01, 0xe0, 0x00, 0x78, 0x00, + 0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0xee, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_question_arrow 11 #define sdl_std_cursor_HEIGHT_question_arrow 16 -#define sdl_std_cursor_HOT_X_question_arrow -4 -#define sdl_std_cursor_HOT_Y_question_arrow -8 - -static unsigned char sdl_std_cursor_mask_pirate[] = {0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07, 0xf1, 0x83, 0xf1, 0xe3, 0xf3, 0xf3, 0xef, 0x39, 0x1e, 0x1e, 0xe0, 0x01, 0xfe, 0xc7, 0xff, 0xff, 0x0f, 0x7c, }; -static unsigned char sdl_std_cursor_pirate[] = {0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x07, 0xcc, 0x0c, 0xcc, 0x0c, 0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01, 0xe1, 0x21, 0xe1, 0x61, 0xc2, 0x10, 0x1c, 0x0e, 0xe0, 0x01, 0xf8, 0x47, 0x0f, 0x7c, 0x01, 0x20, }; -#define sdl_std_cursor_WIDTH_pirate 16 +#define sdl_std_cursor_HOT_X_question_arrow -4 +#define sdl_std_cursor_HOT_Y_question_arrow -8 + +static unsigned char sdl_std_cursor_mask_pirate[] = { + 0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07, 0xf1, 0x83, + 0xf1, 0xe3, 0xf3, 0xf3, 0xef, 0x39, 0x1e, 0x1e, 0xe0, 0x01, 0xfe, 0xc7, 0xff, 0xff, 0x0f, 0x7c, +}; +static unsigned char sdl_std_cursor_pirate[] = { + 0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x07, 0xcc, 0x0c, 0xcc, 0x0c, 0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01, + 0xe1, 0x21, 0xe1, 0x61, 0xc2, 0x10, 0x1c, 0x0e, 0xe0, 0x01, 0xf8, 0x47, 0x0f, 0x7c, 0x01, 0x20, +}; +#define sdl_std_cursor_WIDTH_pirate 16 #define sdl_std_cursor_HEIGHT_pirate 16 -#define sdl_std_cursor_HOT_X_pirate -7 -#define sdl_std_cursor_HOT_Y_pirate -4 - -static unsigned char sdl_std_cursor_mask_left_side[] = {0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x03, 0x8f, 0x03, 0xcf, 0x01, 0xef, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0xcf, 0x01, 0x8f, 0x03, 0x0f, 0x03, 0x0f, 0x00, 0x0f, 0x00, }; -static unsigned char sdl_std_cursor_left_side[] = {0x03, 0x00, 0x03, 0x00, 0x83, 0x00, 0x43, 0x00, 0x23, 0x00, 0x13, 0x00, 0xfb, 0x3f, 0x13, 0x00, 0x23, 0x00, 0x43, 0x00, 0x83, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_left_side 16 +#define sdl_std_cursor_HOT_X_pirate -7 +#define sdl_std_cursor_HOT_Y_pirate -4 + +static unsigned char sdl_std_cursor_mask_left_side[] = { + 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x03, 0x8f, 0x03, 0xcf, 0x01, 0xef, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xef, 0x00, 0xcf, 0x01, 0x8f, 0x03, 0x0f, 0x03, 0x0f, 0x00, 0x0f, 0x00, +}; +static unsigned char sdl_std_cursor_left_side[] = { + 0x03, 0x00, 0x03, 0x00, 0x83, 0x00, 0x43, 0x00, 0x23, 0x00, 0x13, 0x00, 0xfb, 0x3f, 0x13, + 0x00, 0x23, 0x00, 0x43, 0x00, 0x83, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_left_side 16 #define sdl_std_cursor_HEIGHT_left_side 15 -#define sdl_std_cursor_HOT_X_left_side 0 -#define sdl_std_cursor_HOT_Y_left_side -7 - -static unsigned char sdl_std_cursor_mask_left_ptr[] = {0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x03, 0x7f, 0x00, 0xf7, 0x00, 0xf3, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00, }; -static unsigned char sdl_std_cursor_left_ptr[] = {0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_left_ptr 10 +#define sdl_std_cursor_HOT_X_left_side 0 +#define sdl_std_cursor_HOT_Y_left_side -7 + +static unsigned char sdl_std_cursor_mask_left_ptr[] = { + 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, + 0xff, 0x03, 0xff, 0x03, 0x7f, 0x00, 0xf7, 0x00, 0xf3, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00, +}; +static unsigned char sdl_std_cursor_left_ptr[] = { + 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00, + 0xfe, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_left_ptr 10 #define sdl_std_cursor_HEIGHT_left_ptr 16 -#define sdl_std_cursor_HOT_X_left_ptr -8 -#define sdl_std_cursor_HOT_Y_left_ptr -14 - -static unsigned char sdl_std_cursor_mask_exchange[] = {0xe3, 0x07, 0xf7, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0x3f, 0x38, 0xff, 0x30, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x0c, 0xfe, 0x1c, 0xfc, 0xfc, 0xff, 0xf8, 0xff, 0xf0, 0xef, 0xe0, 0xc7, }; -static unsigned char sdl_std_cursor_exchange[] = {0xf1, 0x03, 0xfb, 0x07, 0x1f, 0x0c, 0x09, 0x08, 0x19, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x26, 0x04, 0x24, 0x0c, 0x3e, 0xf8, 0x37, 0xf0, 0x23, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_exchange 16 +#define sdl_std_cursor_HOT_X_left_ptr -8 +#define sdl_std_cursor_HOT_Y_left_ptr -14 + +static unsigned char sdl_std_cursor_mask_exchange[] = { + 0xe3, 0x07, 0xf7, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0x3f, 0x38, 0xff, 0x30, 0xff, 0x00, 0xff, 0x00, + 0x00, 0xff, 0x00, 0xff, 0x0c, 0xfe, 0x1c, 0xfc, 0xfc, 0xff, 0xf8, 0xff, 0xf0, 0xef, 0xe0, 0xc7, +}; +static unsigned char sdl_std_cursor_exchange[] = { + 0xf1, 0x03, 0xfb, 0x07, 0x1f, 0x0c, 0x09, 0x08, 0x19, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0x00, 0x26, 0x04, 0x24, 0x0c, 0x3e, 0xf8, 0x37, 0xf0, 0x23, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_exchange 16 #define sdl_std_cursor_HEIGHT_exchange 16 -#define sdl_std_cursor_HOT_X_exchange -6 -#define sdl_std_cursor_HOT_Y_exchange -8 - -static unsigned char sdl_std_cursor_mask_crosshair[] = {0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, }; -static unsigned char sdl_std_cursor_crosshair[] = {0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_crosshair 16 +#define sdl_std_cursor_HOT_X_exchange -6 +#define sdl_std_cursor_HOT_Y_exchange -8 + +static unsigned char sdl_std_cursor_mask_crosshair[] = { + 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, +}; +static unsigned char sdl_std_cursor_crosshair[] = { + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_crosshair 16 #define sdl_std_cursor_HEIGHT_crosshair 16 -#define sdl_std_cursor_HOT_X_crosshair -7 -#define sdl_std_cursor_HOT_Y_crosshair -8 - -static unsigned char sdl_std_cursor_mask_bottom_side[] = {0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xcc, 0x19, 0xdc, 0x1d, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, }; -static unsigned char sdl_std_cursor_bottom_side[] = {0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x44, 0x04, 0x48, 0x02, 0x50, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_bottom_side 15 +#define sdl_std_cursor_HOT_X_crosshair -7 +#define sdl_std_cursor_HOT_Y_crosshair -8 + +static unsigned char sdl_std_cursor_mask_bottom_side[] = { + 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xcc, 0x19, 0xdc, 0x1d, + 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, +}; +static unsigned char sdl_std_cursor_bottom_side[] = { + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x44, 0x04, 0x48, 0x02, + 0x50, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_bottom_side 15 #define sdl_std_cursor_HEIGHT_bottom_side 16 -#define sdl_std_cursor_HOT_X_bottom_side -6 -#define sdl_std_cursor_HOT_Y_bottom_side -1 - -static unsigned char sdl_std_cursor_mask_bottom_right_corner[] = {0x00, 0xf0, 0x00, 0xf0, 0x0c, 0xf7, 0x1c, 0xf7, 0x38, 0xf7, 0x70, 0xf7, 0xe0, 0xf7, 0xc0, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; -static unsigned char sdl_std_cursor_bottom_right_corner[] = {0x00, 0x30, 0x00, 0x30, 0x04, 0x31, 0x08, 0x31, 0x10, 0x31, 0x20, 0x31, 0x40, 0x31, 0x80, 0x31, 0xfc, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_bottom_right_corner 16 +#define sdl_std_cursor_HOT_X_bottom_side -6 +#define sdl_std_cursor_HOT_Y_bottom_side -1 + +static unsigned char sdl_std_cursor_mask_bottom_right_corner[] = { + 0x00, 0xf0, 0x00, 0xf0, 0x0c, 0xf7, 0x1c, 0xf7, 0x38, 0xf7, 0x70, 0xf7, 0xe0, 0xf7, 0xc0, 0xf7, + 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +static unsigned char sdl_std_cursor_bottom_right_corner[] = { + 0x00, 0x30, 0x00, 0x30, 0x04, 0x31, 0x08, 0x31, 0x10, 0x31, 0x20, 0x31, 0x40, 0x31, 0x80, 0x31, + 0xfc, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_bottom_right_corner 16 #define sdl_std_cursor_HEIGHT_bottom_right_corner 16 -#define sdl_std_cursor_HOT_X_bottom_right_corner -13 -#define sdl_std_cursor_HOT_Y_bottom_right_corner -1 - -static unsigned char sdl_std_cursor_mask_bottom_left_corner[] = {0x0f, 0x00, 0x0f, 0x00, 0xef, 0x30, 0xef, 0x38, 0xef, 0x1c, 0xef, 0x0e, 0xef, 0x07, 0xef, 0x03, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; -static unsigned char sdl_std_cursor_bottom_left_corner[] = {0x03, 0x00, 0x03, 0x00, 0x23, 0x08, 0x23, 0x04, 0x23, 0x02, 0x23, 0x01, 0xa3, 0x00, 0x63, 0x00, 0xe3, 0x0f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_bottom_left_corner 16 +#define sdl_std_cursor_HOT_X_bottom_right_corner -13 +#define sdl_std_cursor_HOT_Y_bottom_right_corner -1 + +static unsigned char sdl_std_cursor_mask_bottom_left_corner[] = { + 0x0f, 0x00, 0x0f, 0x00, 0xef, 0x30, 0xef, 0x38, 0xef, 0x1c, 0xef, 0x0e, 0xef, 0x07, 0xef, 0x03, + 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +static unsigned char sdl_std_cursor_bottom_left_corner[] = { + 0x03, 0x00, 0x03, 0x00, 0x23, 0x08, 0x23, 0x04, 0x23, 0x02, 0x23, 0x01, 0xa3, 0x00, 0x63, 0x00, + 0xe3, 0x0f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_bottom_left_corner 16 #define sdl_std_cursor_HEIGHT_bottom_left_corner 16 -#define sdl_std_cursor_HOT_X_bottom_left_corner 0 -#define sdl_std_cursor_HOT_Y_bottom_left_corner -1 - -static unsigned char sdl_std_cursor_mask_arrow[] = {0x00, 0xe0, 0x00, 0xf8, 0x00, 0xfe, 0x80, 0x7f, 0xe0, 0x7f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f, 0xe0, 0x1f, 0xf0, 0x0f, 0xf8, 0x0f, 0x7c, 0x07, 0x3e, 0x07, 0x1f, 0x02, 0x0e, 0x00, 0x04, 0x00, }; -static unsigned char sdl_std_cursor_arrow[] = {0x00, 0x30, 0x00, 0x3c, 0x00, 0x1f, 0xc0, 0x1f, 0xf0, 0x0f, 0xfc, 0x0f, 0xc0, 0x07, 0xe0, 0x07, 0x70, 0x03, 0x38, 0x03, 0x1c, 0x01, 0x0e, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define sdl_std_cursor_WIDTH_arrow 16 +#define sdl_std_cursor_HOT_X_bottom_left_corner 0 +#define sdl_std_cursor_HOT_Y_bottom_left_corner -1 + +static unsigned char sdl_std_cursor_mask_arrow[] = { + 0x00, 0xe0, 0x00, 0xf8, 0x00, 0xfe, 0x80, 0x7f, 0xe0, 0x7f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f, + 0xe0, 0x1f, 0xf0, 0x0f, 0xf8, 0x0f, 0x7c, 0x07, 0x3e, 0x07, 0x1f, 0x02, 0x0e, 0x00, 0x04, 0x00, +}; +static unsigned char sdl_std_cursor_arrow[] = { + 0x00, 0x30, 0x00, 0x3c, 0x00, 0x1f, 0xc0, 0x1f, 0xf0, 0x0f, 0xfc, 0x0f, 0xc0, 0x07, 0xe0, 0x07, + 0x70, 0x03, 0x38, 0x03, 0x1c, 0x01, 0x0e, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#define sdl_std_cursor_WIDTH_arrow 16 #define sdl_std_cursor_HEIGHT_arrow 16 -#define sdl_std_cursor_HOT_X_arrow -13 -#define sdl_std_cursor_HOT_Y_arrow -14 +#define sdl_std_cursor_HOT_X_arrow -13 +#define sdl_std_cursor_HOT_Y_arrow -14 /* end cursor data */ - static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors] = {0}; /* utility function mostly a copy of SDL_CreateCursor but allows us to change * color and supports blenders flipped bits */ -static SDL_Cursor * -sdl_ghost_CreateCursor(const Uint8 *data, - const Uint8 *mask, - int w, - int h, - int hot_x, - int hot_y) +static SDL_Cursor *sdl_ghost_CreateCursor( + const Uint8 *data, const Uint8 *mask, int w, int h, int hot_x, int hot_y) { - SDL_Surface *surface; - SDL_Cursor *cursor; - int x, y; - Uint32 *pixel; - Uint8 datab = 0, maskb = 0; - const Uint32 black = 0xFF000000; - const Uint32 white = 0xFFFFFFFF; - const Uint32 transparent = 0x00000000; - - /* Make sure the width is a multiple of 8 */ - w = ((w + 7) & ~7); - - /* Create the surface from a bitmap */ - surface = SDL_CreateRGBSurface(0, w, h, 32, - 0x00FF0000, - 0x0000FF00, - 0x000000FF, - 0xFF000000); - if (!surface) { - return NULL; - } - for (y = 0; y < h; ++y) { - pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch); - for (x = 0; x < w; ++x) { - if ((x % 8) == 0) { - datab = *data++; - maskb = *mask++; - - /* reverse bit order */ - datab = (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023; - maskb = (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023; - } - if (maskb & 0x80) { - *pixel++ = (datab & 0x80) ? white : black; - } - else { - *pixel++ = (datab & 0x80) ? white : transparent; - } - datab <<= 1; - maskb <<= 1; - } - } - - cursor = SDL_CreateColorCursor(surface, hot_x, hot_y); - - SDL_FreeSurface(surface); - - return cursor; + SDL_Surface *surface; + SDL_Cursor *cursor; + int x, y; + Uint32 *pixel; + Uint8 datab = 0, maskb = 0; + const Uint32 black = 0xFF000000; + const Uint32 white = 0xFFFFFFFF; + const Uint32 transparent = 0x00000000; + + /* Make sure the width is a multiple of 8 */ + w = ((w + 7) & ~7); + + /* Create the surface from a bitmap */ + surface = SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + if (!surface) { + return NULL; + } + for (y = 0; y < h; ++y) { + pixel = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); + for (x = 0; x < w; ++x) { + if ((x % 8) == 0) { + datab = *data++; + maskb = *mask++; + + /* reverse bit order */ + datab = (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023; + maskb = (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023; + } + if (maskb & 0x80) { + *pixel++ = (datab & 0x80) ? white : black; + } + else { + *pixel++ = (datab & 0x80) ? white : transparent; + } + datab <<= 1; + maskb <<= 1; + } + } + + cursor = SDL_CreateColorCursor(surface, hot_x, hot_y); + + SDL_FreeSurface(surface); + + return cursor; } /* TODO, this is currently never freed but it wont leak either. */ @@ -454,122 +587,107 @@ static void sdl_cursor_init(void) { #define DEF_CURSOR(name, ind) \ - { \ - sdl_std_cursor_array[(int)ind] = \ - sdl_ghost_CreateCursor(sdl_std_cursor_##name, \ - sdl_std_cursor_mask_##name, \ - sdl_std_cursor_WIDTH_##name, \ - sdl_std_cursor_HEIGHT_##name, \ - (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \ - (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1); \ - assert(sdl_std_cursor_array[(int)ind] != NULL); \ - } (void)0 - - - DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault); - DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow); - DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow); - DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one. - DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy); - DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp); - DEF_CURSOR(exchange, GHOST_kStandardCursorCycle); - DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray); - DEF_CURSOR(watch, GHOST_kStandardCursorWait); - DEF_CURSOR(xterm, GHOST_kStandardCursorText); - DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair); - DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown); - DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight); - DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide); - DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide); - DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide); - DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide); - DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner); - DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner); - DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner); - DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner); - DEF_CURSOR(arrow, GHOST_kStandardCursorCopy); - //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom); - DEF_CURSOR(arrow, GHOST_kStandardCursorPencil); + { \ + sdl_std_cursor_array[(int)ind] = sdl_ghost_CreateCursor( \ + sdl_std_cursor_##name, \ + sdl_std_cursor_mask_##name, \ + sdl_std_cursor_WIDTH_##name, \ + sdl_std_cursor_HEIGHT_##name, \ + (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \ + (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1); \ + assert(sdl_std_cursor_array[(int)ind] != NULL); \ + } \ + (void)0 + + DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault); + DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow); + DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow); + DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one. + DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy); + DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp); + DEF_CURSOR(exchange, GHOST_kStandardCursorCycle); + DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray); + DEF_CURSOR(watch, GHOST_kStandardCursorWait); + DEF_CURSOR(xterm, GHOST_kStandardCursorText); + DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair); + DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown); + DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight); + DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide); + DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide); + DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide); + DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide); + DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner); + DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner); + DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner); + DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner); + DEF_CURSOR(arrow, GHOST_kStandardCursorCopy); + //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom); + DEF_CURSOR(arrow, GHOST_kStandardCursorPencil); #undef DEF_CURSOR - } - - -GHOST_TSuccess -GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode) +GHOST_TSuccess GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode) { - return GHOST_kSuccess; + return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape) +GHOST_TSuccess GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape) { - if (sdl_std_cursor_array[0] == NULL) { - sdl_cursor_init(); - } + if (sdl_std_cursor_array[0] == NULL) { + sdl_cursor_init(); + } - SDL_SetCursor(sdl_std_cursor_array[(int)shape]); - return GHOST_kSuccess; + SDL_SetCursor(sdl_std_cursor_array[(int)shape]); + return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], - int hotX, - int hotY) +GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) { - return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, - (GHOST_TUns8 *)mask, - 16, 16, - hotX, hotY, - 0, 1); + return setWindowCustomCursorShape( + (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1); } - -GHOST_TSuccess -GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, int sizey, - int hotX, int hotY, - int fg_color, int bg_color) +GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color) { - if (m_sdl_custom_cursor) { - SDL_FreeCursor(m_sdl_custom_cursor); - } + if (m_sdl_custom_cursor) { + SDL_FreeCursor(m_sdl_custom_cursor); + } - m_sdl_custom_cursor = sdl_ghost_CreateCursor((const Uint8 *)bitmap, - (const Uint8 *)mask, - sizex, sizex, - hotX, hotY); + m_sdl_custom_cursor = sdl_ghost_CreateCursor( + (const Uint8 *)bitmap, (const Uint8 *)mask, sizex, sizex, hotX, hotY); - SDL_SetCursor(m_sdl_custom_cursor); - return GHOST_kSuccess; + SDL_SetCursor(m_sdl_custom_cursor); + return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_WindowSDL::setWindowCursorVisibility(bool visible) +GHOST_TSuccess GHOST_WindowSDL::setWindowCursorVisibility(bool visible) { - SDL_ShowCursor(visible); - return GHOST_kSuccess; + SDL_ShowCursor(visible); + return GHOST_kSuccess; } -GHOST_TUns16 -GHOST_WindowSDL::getDPIHint() +GHOST_TUns16 GHOST_WindowSDL::getDPIHint() { - int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win); - if (displayIndex < 0) { - return 96; - } + int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win); + if (displayIndex < 0) { + return 96; + } - float ddpi; - if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) { - return 96; - } + float ddpi; + if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) { + return 96; + } - return (int)ddpi; + return (int)ddpi; } diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h index c7325240862..3a9a1ad7df2 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.h +++ b/intern/ghost/intern/GHOST_WindowSDL.h @@ -28,7 +28,7 @@ #include <map> extern "C" { - #include "SDL.h" +#include "SDL.h" } #if !SDL_VERSION_ATLEAST(2, 0, 0) @@ -38,133 +38,128 @@ extern "C" { class STR_String; class GHOST_SystemSDL; -class GHOST_WindowSDL : public GHOST_Window -{ -private: - GHOST_SystemSDL *m_system; - bool m_valid_setup; - bool m_invalid_window; +class GHOST_WindowSDL : public GHOST_Window { + private: + GHOST_SystemSDL *m_system; + bool m_valid_setup; + bool m_invalid_window; - SDL_Window *m_sdl_win; - SDL_Cursor *m_sdl_custom_cursor; + SDL_Window *m_sdl_win; + SDL_Cursor *m_sdl_custom_cursor; -public: + public: + const GHOST_TabletData *GetTabletData() + { + return NULL; + } + + GHOST_WindowSDL(GHOST_SystemSDL *system, + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, + const bool stereoVisual = false, + const bool exclusive = false, + const GHOST_TUns16 numOfAASamples = 0); - const GHOST_TabletData *GetTabletData() { - return NULL; - } + ~GHOST_WindowSDL(); - GHOST_WindowSDL(GHOST_SystemSDL *system, - const STR_String& title, - GHOST_TInt32 left, GHOST_TInt32 top, - GHOST_TUns32 width, GHOST_TUns32 height, - GHOST_TWindowState state, - const GHOST_TEmbedderWindowID parentWindow, - GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, - const bool stereoVisual = false, - const bool exclusive = false, - const GHOST_TUns16 numOfAASamples = 0 - ); + /* SDL specific */ + SDL_Window *getSDLWindow() + { + return m_sdl_win; + } - ~GHOST_WindowSDL(); + GHOST_TSuccess invalidate(void); - /* SDL specific */ - SDL_Window * - getSDLWindow() - { - return m_sdl_win; - } + /** + * called by the X11 system implementation when expose events + * for the window have been pushed onto the GHOST queue + */ + void validate() + { + m_invalid_window = false; + } - GHOST_TSuccess invalidate(void); + bool getValid() const; - /** - * called by the X11 system implementation when expose events - * for the window have been pushed onto the GHOST queue - */ + void getWindowBounds(GHOST_Rect &bounds) const; + void getClientBounds(GHOST_Rect &bounds) const; - void validate() - { - m_invalid_window = false; - } + protected: + /** + * \param type The type of rendering context create. + * \return Indication of success. + */ + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); - bool getValid() const; + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); - void getWindowBounds(GHOST_Rect& bounds) const; - void getClientBounds(GHOST_Rect& bounds) const; + GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape); -protected: + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY); - /** - * \param type The type of rendering context create. - * \return Indication of success. - */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); - GHOST_TSuccess - setWindowCursorGrab(GHOST_TGrabCursorMode mode); + GHOST_TSuccess setWindowCursorVisibility(bool visible); - GHOST_TSuccess - setWindowCursorShape(GHOST_TStandardCursor shape); + void setTitle(const STR_String &title); - GHOST_TSuccess - setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], - int hotX, int hotY); + void getTitle(STR_String &title) const; - GHOST_TSuccess - setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, int sizey, - int hotX, int hotY, - int fg_color, int bg_color); + GHOST_TSuccess setClientWidth(GHOST_TUns32 width); - GHOST_TSuccess - setWindowCursorVisibility(bool visible); + GHOST_TSuccess setClientHeight(GHOST_TUns32 height); - void - setTitle(const STR_String& title); + GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); - void - getTitle(STR_String& title) const; + void screenToClient(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const; - GHOST_TSuccess - setClientWidth(GHOST_TUns32 width); + void clientToScreen(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const; - GHOST_TSuccess - setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setState(GHOST_TWindowState state); + + GHOST_TWindowState getState() const; - GHOST_TSuccess - setClientSize(GHOST_TUns32 width, - GHOST_TUns32 height); + GHOST_TSuccess setOrder(GHOST_TWindowOrder order) + { + // TODO + return GHOST_kSuccess; + } + + // TODO + GHOST_TSuccess beginFullScreen() const + { + return GHOST_kFailure; + } - void - screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, - GHOST_TInt32& outX, GHOST_TInt32& outY) const; + GHOST_TSuccess endFullScreen() const + { + return GHOST_kFailure; + } - void - clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, - GHOST_TInt32& outX, GHOST_TInt32& outY) const; - - GHOST_TSuccess - setState(GHOST_TWindowState state); - - GHOST_TWindowState - getState() const; - - GHOST_TSuccess setOrder(GHOST_TWindowOrder order) - { - // TODO - return GHOST_kSuccess; - } - - // TODO - GHOST_TSuccess beginFullScreen() const { return GHOST_kFailure; } - - GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; } - - GHOST_TUns16 getDPIHint(); + GHOST_TUns16 getDPIHint(); }; - -#endif // __GHOST_WINDOWSDL_H__ +#endif // __GHOST_WINDOWSDL_H__ diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 21d1ec0c5b1..2feda927998 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -36,7 +36,7 @@ # include "GHOST_ContextWGL.h" #endif #ifdef WIN32_COMPOSITING -#include <Dwmapi.h> +# include <Dwmapi.h> #endif #include <windowsx.h> @@ -45,35 +45,31 @@ #include <assert.h> #ifndef GET_POINTERID_WPARAM -#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) -#endif // GET_POINTERID_WPARAM +# define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) +#endif // GET_POINTERID_WPARAM const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass"; const int GHOST_WindowWin32::s_maxTitleLength = 128; - - - /* force NVidia Optimus to used dedicated graphics */ extern "C" { - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; } GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, - const STR_String &title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - bool wantStereoVisual, - bool alphaBackground, - GHOST_TUns16 wantNumOfAASamples, - GHOST_TEmbedderWindowID parentwindowhwnd, - bool is_debug) - : GHOST_Window(width, height, state, - wantStereoVisual, false, wantNumOfAASamples), + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + bool wantStereoVisual, + bool alphaBackground, + GHOST_TUns16 wantNumOfAASamples, + GHOST_TEmbedderWindowID parentwindowhwnd, + bool is_debug) + : GHOST_Window(width, height, state, wantStereoVisual, false, wantNumOfAASamples), m_inLiveResize(false), m_system(system), m_hDC(0), @@ -90,1144 +86,1196 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_parentWindowHwnd(parentwindowhwnd), m_debug_context(is_debug) { - // Initialize tablet variables - memset(&m_wintab, 0, sizeof(m_wintab)); - memset(&m_tabletData, 0, sizeof(m_tabletData)); - m_tabletData.Active = GHOST_kTabletModeNone; + // Initialize tablet variables + memset(&m_wintab, 0, sizeof(m_wintab)); + memset(&m_tabletData, 0, sizeof(m_tabletData)); + m_tabletData.Active = GHOST_kTabletModeNone; - // Create window - if (state != GHOST_kWindowStateFullScreen) { - RECT rect; - MONITORINFO monitor; - GHOST_TUns32 tw, th; + // Create window + if (state != GHOST_kWindowStateFullScreen) { + RECT rect; + MONITORINFO monitor; + GHOST_TUns32 tw, th; #ifndef _MSC_VER - int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME); - int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME); + int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME); + int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME); #else - // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows - // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values - RECT cxrect = {0, 0, 0, 0}; - AdjustWindowRectEx(&cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0); - - int cxsizeframe = abs(cxrect.bottom); - int cysizeframe = abs(cxrect.left); + // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows + // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values + RECT cxrect = {0, 0, 0, 0}; + AdjustWindowRectEx( + &cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0); + + int cxsizeframe = abs(cxrect.bottom); + int cysizeframe = abs(cxrect.left); #endif - width += cxsizeframe * 2; - height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION); - - rect.left = left; - rect.right = left + width; - rect.top = top; - rect.bottom = top + height; - - monitor.cbSize = sizeof(monitor); - monitor.dwFlags = 0; - - // take taskbar into account - GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor); - - th = monitor.rcWork.bottom - monitor.rcWork.top; - tw = monitor.rcWork.right - monitor.rcWork.left; - - if (tw < width) { - width = tw; - left = monitor.rcWork.left; - } - else if (monitor.rcWork.right < left + (int)width) - left = monitor.rcWork.right - width; - else if (left < monitor.rcWork.left) - left = monitor.rcWork.left; - - if (th < height) { - height = th; - top = monitor.rcWork.top; - } - else if (monitor.rcWork.bottom < top + (int)height) - top = monitor.rcWork.bottom - height; - else if (top < monitor.rcWork.top) - top = monitor.rcWork.top; - - int wintype = WS_OVERLAPPEDWINDOW; - if (m_parentWindowHwnd != 0) { - wintype = WS_CHILD; - GetWindowRect((HWND)m_parentWindowHwnd, &rect); - left = 0; - top = 0; - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - - wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); - m_hWnd = ::CreateWindowW( - s_windowClassName, // pointer to registered class name - title_16, // pointer to window name - wintype, // window style - left, // horizontal position of window - top, // vertical position of window - width, // window width - height, // window height - (HWND)m_parentWindowHwnd, // 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 - free(title_16); - } - else { - wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); - m_hWnd = ::CreateWindowW( - s_windowClassName, // pointer to registered class name - title_16, // pointer to window name - WS_MAXIMIZE, // window style - left, // horizontal position of window - top, // vertical position of window - width, // window width - height, // window height - HWND_DESKTOP, // 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 - free(title_16); - } - - m_user32 = ::LoadLibrary("user32.dll"); - - if (m_hWnd) { - if (m_user32) { - // Touch enabled screens with pen support by default have gestures - // enabled, which results in a delay between the pointer down event - // and the first move when using the stylus. RegisterTouchWindow - // disables the new gesture architecture enabling the events to be - // sent immediately to the application rather than being absorbed by - // the gesture API. - GHOST_WIN32_RegisterTouchWindow pRegisterTouchWindow = - (GHOST_WIN32_RegisterTouchWindow)GetProcAddress(m_user32, "RegisterTouchWindow"); - if (pRegisterTouchWindow) { - pRegisterTouchWindow(m_hWnd, 0); - } - } - - // Register this window as a droptarget. Requires m_hWnd to be valid. - // Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32. - m_dropTarget = new GHOST_DropTargetWin32(this, m_system); - if (m_dropTarget) { - ::RegisterDragDrop(m_hWnd, m_dropTarget); - } - - // Store a pointer to this class in the window structure - ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR) this); - - if (!m_system->m_windowFocus) { - // Lower to bottom and don't activate if we don't want focus - ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - - // Store the device context - m_hDC = ::GetDC(m_hWnd); - - GHOST_TSuccess success = setDrawingContextType(type); - - if (success) { - // Show the window - int nCmdShow; - switch (state) { - case GHOST_kWindowStateMaximized: - nCmdShow = SW_SHOWMAXIMIZED; - break; - case GHOST_kWindowStateMinimized: - nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE; - break; - case GHOST_kWindowStateNormal: - default: - nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE; - break; - } - - ::ShowWindow(m_hWnd, nCmdShow); + width += cxsizeframe * 2; + height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION); + + rect.left = left; + rect.right = left + width; + rect.top = top; + rect.bottom = top + height; + + monitor.cbSize = sizeof(monitor); + monitor.dwFlags = 0; + + // take taskbar into account + GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor); + + th = monitor.rcWork.bottom - monitor.rcWork.top; + tw = monitor.rcWork.right - monitor.rcWork.left; + + if (tw < width) { + width = tw; + left = monitor.rcWork.left; + } + else if (monitor.rcWork.right < left + (int)width) + left = monitor.rcWork.right - width; + else if (left < monitor.rcWork.left) + left = monitor.rcWork.left; + + if (th < height) { + height = th; + top = monitor.rcWork.top; + } + else if (monitor.rcWork.bottom < top + (int)height) + top = monitor.rcWork.bottom - height; + else if (top < monitor.rcWork.top) + top = monitor.rcWork.top; + + int wintype = WS_OVERLAPPEDWINDOW; + if (m_parentWindowHwnd != 0) { + wintype = WS_CHILD; + GetWindowRect((HWND)m_parentWindowHwnd, &rect); + left = 0; + top = 0; + width = rect.right - rect.left; + height = rect.bottom - rect.top; + } + + wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); + m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name + title_16, // pointer to window name + wintype, // window style + left, // horizontal position of window + top, // vertical position of window + width, // window width + height, // window height + (HWND)m_parentWindowHwnd, // 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 + free(title_16); + } + else { + wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); + m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name + title_16, // pointer to window name + WS_MAXIMIZE, // window style + left, // horizontal position of window + top, // vertical position of window + width, // window width + height, // window height + HWND_DESKTOP, // 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 + free(title_16); + } + + m_user32 = ::LoadLibrary("user32.dll"); + + if (m_hWnd) { + if (m_user32) { + // Touch enabled screens with pen support by default have gestures + // enabled, which results in a delay between the pointer down event + // and the first move when using the stylus. RegisterTouchWindow + // disables the new gesture architecture enabling the events to be + // sent immediately to the application rather than being absorbed by + // the gesture API. + GHOST_WIN32_RegisterTouchWindow pRegisterTouchWindow = (GHOST_WIN32_RegisterTouchWindow) + GetProcAddress(m_user32, "RegisterTouchWindow"); + if (pRegisterTouchWindow) { + pRegisterTouchWindow(m_hWnd, 0); + } + } + + // Register this window as a droptarget. Requires m_hWnd to be valid. + // Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32. + m_dropTarget = new GHOST_DropTargetWin32(this, m_system); + if (m_dropTarget) { + ::RegisterDragDrop(m_hWnd, m_dropTarget); + } + + // Store a pointer to this class in the window structure + ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this); + + if (!m_system->m_windowFocus) { + // Lower to bottom and don't activate if we don't want focus + ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + + // Store the device context + m_hDC = ::GetDC(m_hWnd); + + GHOST_TSuccess success = setDrawingContextType(type); + + if (success) { + // Show the window + int nCmdShow; + switch (state) { + case GHOST_kWindowStateMaximized: + nCmdShow = SW_SHOWMAXIMIZED; + break; + case GHOST_kWindowStateMinimized: + nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE; + break; + case GHOST_kWindowStateNormal: + default: + nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE; + break; + } + + ::ShowWindow(m_hWnd, nCmdShow); #ifdef WIN32_COMPOSITING - if (alphaBackground && parentwindowhwnd == 0) { + if (alphaBackground && parentwindowhwnd == 0) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; - // Create and populate the Blur Behind structure - DWM_BLURBEHIND bb = { 0 }; + // Create and populate the Blur Behind structure + DWM_BLURBEHIND bb = {0}; - // Enable Blur Behind and apply to the entire client area - bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; - bb.fEnable = true; - bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); + // Enable Blur Behind and apply to the entire client area + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.fEnable = true; + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); - // Apply Blur Behind - hr = DwmEnableBlurBehindWindow(m_hWnd, &bb); - DeleteObject(bb.hRgnBlur); - } + // Apply Blur Behind + hr = DwmEnableBlurBehindWindow(m_hWnd, &bb); + DeleteObject(bb.hRgnBlur); + } #endif - // Force an initial paint of the window - ::UpdateWindow(m_hWnd); - } - else { - //invalidate the window - ::DestroyWindow(m_hWnd); - m_hWnd = NULL; - } - } - - if (parentwindowhwnd != 0) { - RAWINPUTDEVICE device = {0}; - device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/ - device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ - device.dwFlags |= RIDEV_INPUTSINK; // makes WM_INPUT is visible for ghost when has parent window - device.hwndTarget = m_hWnd; - RegisterRawInputDevices(&device, 1, sizeof(device)); - } - - // Initialize Windows Ink - if (m_user32) { - m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo"); - m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo"); - m_fpGetPointerTouchInfo = (GHOST_WIN32_GetPointerTouchInfo) ::GetProcAddress(m_user32, "GetPointerTouchInfo"); - } - - // Initialize Wintab - m_wintab.handle = ::LoadLibrary("Wintab32.dll"); - if (m_wintab.handle) { - // Get API functions - m_wintab.info = (GHOST_WIN32_WTInfo) ::GetProcAddress(m_wintab.handle, "WTInfoA"); - m_wintab.open = (GHOST_WIN32_WTOpen) ::GetProcAddress(m_wintab.handle, "WTOpenA"); - m_wintab.close = (GHOST_WIN32_WTClose) ::GetProcAddress(m_wintab.handle, "WTClose"); - m_wintab.packet = (GHOST_WIN32_WTPacket) ::GetProcAddress(m_wintab.handle, "WTPacket"); - m_wintab.enable = (GHOST_WIN32_WTEnable) ::GetProcAddress(m_wintab.handle, "WTEnable"); - m_wintab.overlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab.handle, "WTOverlap"); - - // Let's see if we can initialize tablet here. - // Check if WinTab available by getting system context info. - LOGCONTEXT lc = { 0 }; - lc.lcOptions |= CXO_SYSTEM; - if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) { - // Now init the tablet - /* The maximum tablet size, pressure and orientation (tilt) */ - AXIS TabletX, TabletY, Pressure, Orientation[3]; - - // Open a Wintab context - - // Open the context - lc.lcPktData = PACKETDATA; - lc.lcPktMode = PACKETMODE; - lc.lcOptions |= CXO_MESSAGES; - lc.lcMoveMask = PACKETDATA; - - /* Set the entire tablet as active */ - m_wintab.info(WTI_DEVICES, DVC_X, &TabletX); - m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY); - - /* get the max pressure, to divide into a float */ - BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); - if (pressureSupport) - m_wintab.maxPressure = Pressure.axMax; - else - m_wintab.maxPressure = 0; - - /* get the max tilt axes, to divide into floats */ - BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); - if (tiltSupport) { - /* does the tablet support azimuth ([0]) and altitude ([1]) */ - if (Orientation[0].axResolution && Orientation[1].axResolution) { - /* all this assumes the minimum is 0 */ - m_wintab.maxAzimuth = Orientation[0].axMax; - m_wintab.maxAltitude = Orientation[1].axMax; - } - else { /* no so dont do tilt stuff */ - m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; - } - } - - // The Wintab spec says we must open the context disabled if we are using cursor masks. - m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE); - if (m_wintab.enable && m_wintab.tablet) { - m_wintab.enable(m_wintab.tablet, TRUE); - } - } - } - CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar); + // Force an initial paint of the window + ::UpdateWindow(m_hWnd); + } + else { + //invalidate the window + ::DestroyWindow(m_hWnd); + m_hWnd = NULL; + } + } + + if (parentwindowhwnd != 0) { + RAWINPUTDEVICE device = {0}; + device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/ + device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ + device.dwFlags |= + RIDEV_INPUTSINK; // makes WM_INPUT is visible for ghost when has parent window + device.hwndTarget = m_hWnd; + RegisterRawInputDevices(&device, 1, sizeof(device)); + } + + // Initialize Windows Ink + if (m_user32) { + m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo)::GetProcAddress(m_user32, "GetPointerInfo"); + m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo)::GetProcAddress(m_user32, + "GetPointerPenInfo"); + m_fpGetPointerTouchInfo = (GHOST_WIN32_GetPointerTouchInfo)::GetProcAddress( + m_user32, "GetPointerTouchInfo"); + } + + // Initialize Wintab + m_wintab.handle = ::LoadLibrary("Wintab32.dll"); + if (m_wintab.handle) { + // Get API functions + m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA"); + m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA"); + m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose"); + m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket"); + m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable"); + m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"); + + // Let's see if we can initialize tablet here. + // Check if WinTab available by getting system context info. + LOGCONTEXT lc = {0}; + lc.lcOptions |= CXO_SYSTEM; + if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) { + // Now init the tablet + /* The maximum tablet size, pressure and orientation (tilt) */ + AXIS TabletX, TabletY, Pressure, Orientation[3]; + + // Open a Wintab context + + // Open the context + lc.lcPktData = PACKETDATA; + lc.lcPktMode = PACKETMODE; + lc.lcOptions |= CXO_MESSAGES; + lc.lcMoveMask = PACKETDATA; + + /* Set the entire tablet as active */ + m_wintab.info(WTI_DEVICES, DVC_X, &TabletX); + m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY); + + /* get the max pressure, to divide into a float */ + BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); + if (pressureSupport) + m_wintab.maxPressure = Pressure.axMax; + else + m_wintab.maxPressure = 0; + + /* get the max tilt axes, to divide into floats */ + BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); + if (tiltSupport) { + /* does the tablet support azimuth ([0]) and altitude ([1]) */ + if (Orientation[0].axResolution && Orientation[1].axResolution) { + /* all this assumes the minimum is 0 */ + m_wintab.maxAzimuth = Orientation[0].axMax; + m_wintab.maxAltitude = Orientation[1].axMax; + } + else { /* no so dont do tilt stuff */ + m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; + } + } + + // The Wintab spec says we must open the context disabled if we are using cursor masks. + m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE); + if (m_wintab.enable && m_wintab.tablet) { + m_wintab.enable(m_wintab.tablet, TRUE); + } + } + } + CoCreateInstance( + CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar); } - GHOST_WindowWin32::~GHOST_WindowWin32() { - if (m_Bar) { - m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS); - m_Bar->Release(); - m_Bar = NULL; - } - - if (m_wintab.handle) { - if (m_wintab.close && m_wintab.tablet) { - m_wintab.close(m_wintab.tablet); - } - - FreeLibrary(m_wintab.handle); - memset(&m_wintab, 0, sizeof(m_wintab)); - } - - if (m_user32) { - FreeLibrary(m_user32); - m_user32 = NULL; - m_fpGetPointerInfo = NULL; - m_fpGetPointerPenInfo = NULL; - m_fpGetPointerTouchInfo = NULL; - } - - if (m_customCursor) { - DestroyCursor(m_customCursor); - m_customCursor = NULL; - } - - if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) { - ::ReleaseDC(m_hWnd, m_hDC); - m_hDC = NULL; - } - - if (m_hWnd) { - if (m_dropTarget) { - // Disable DragDrop - RevokeDragDrop(m_hWnd); - // Release our reference of the DropTarget and it will delete itself eventually. - m_dropTarget->Release(); - m_dropTarget = NULL; - } - ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL); - ::DestroyWindow(m_hWnd); - m_hWnd = 0; - } + if (m_Bar) { + m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS); + m_Bar->Release(); + m_Bar = NULL; + } + + if (m_wintab.handle) { + if (m_wintab.close && m_wintab.tablet) { + m_wintab.close(m_wintab.tablet); + } + + FreeLibrary(m_wintab.handle); + memset(&m_wintab, 0, sizeof(m_wintab)); + } + + if (m_user32) { + FreeLibrary(m_user32); + m_user32 = NULL; + m_fpGetPointerInfo = NULL; + m_fpGetPointerPenInfo = NULL; + m_fpGetPointerTouchInfo = NULL; + } + + if (m_customCursor) { + DestroyCursor(m_customCursor); + m_customCursor = NULL; + } + + if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) { + ::ReleaseDC(m_hWnd, m_hDC); + m_hDC = NULL; + } + + if (m_hWnd) { + if (m_dropTarget) { + // Disable DragDrop + RevokeDragDrop(m_hWnd); + // Release our reference of the DropTarget and it will delete itself eventually. + m_dropTarget->Release(); + m_dropTarget = NULL; + } + ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL); + ::DestroyWindow(m_hWnd); + m_hWnd = 0; + } } bool GHOST_WindowWin32::getValid() const { - return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0; + return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0; } HWND GHOST_WindowWin32::getHWND() const { - return m_hWnd; + return m_hWnd; } void GHOST_WindowWin32::setTitle(const STR_String &title) { - wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); - ::SetWindowTextW(m_hWnd, (wchar_t *)title_16); - free(title_16); + wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); + ::SetWindowTextW(m_hWnd, (wchar_t *)title_16); + free(title_16); } - void GHOST_WindowWin32::getTitle(STR_String &title) const { - char buf[s_maxTitleLength]; /*CHANGE + never used yet*/ - ::GetWindowText(m_hWnd, buf, s_maxTitleLength); - STR_String temp(buf); - title = buf; + char buf[s_maxTitleLength]; /*CHANGE + never used yet*/ + ::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; + 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; - POINT coord; - if (!IsIconic(m_hWnd)) { - ::GetClientRect(m_hWnd, &rect); - - coord.x = rect.left; - coord.y = rect.top; - ::ClientToScreen(m_hWnd, &coord); - - bounds.m_l = coord.x; - bounds.m_t = coord.y; - - coord.x = rect.right; - coord.y = rect.bottom; - ::ClientToScreen(m_hWnd, &coord); - - bounds.m_r = coord.x; - bounds.m_b = coord.y; - } - else { - bounds.m_b = 0; - bounds.m_l = 0; - bounds.m_r = 0; - bounds.m_t = 0; - } + RECT rect; + POINT coord; + if (!IsIconic(m_hWnd)) { + ::GetClientRect(m_hWnd, &rect); + + coord.x = rect.left; + coord.y = rect.top; + ::ClientToScreen(m_hWnd, &coord); + + bounds.m_l = coord.x; + bounds.m_t = coord.y; + + coord.x = rect.right; + coord.y = rect.bottom; + ::ClientToScreen(m_hWnd, &coord); + + bounds.m_r = coord.x; + bounds.m_b = coord.y; + } + else { + bounds.m_b = 0; + bounds.m_l = 0; + bounds.m_r = 0; + bounds.m_t = 0; + } } - GHOST_TSuccess GHOST_WindowWin32::setClientWidth(GHOST_TUns32 width) { - GHOST_TSuccess success; - GHOST_Rect cBnds, wBnds; - getClientBounds(cBnds); - if (cBnds.getWidth() != (GHOST_TInt32)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 success; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if (cBnds.getWidth() != (GHOST_TInt32)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() != (GHOST_TInt32)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 success; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if (cBnds.getHeight() != (GHOST_TInt32)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() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)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_TSuccess success; + GHOST_Rect cBnds, wBnds; + getClientBounds(cBnds); + if ((cBnds.getWidth() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)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; - - // XXX 27.04.2011 - // we need to find a way to combine parented windows + resizing if we simply set the - // state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else. - // It's also strange that in Windows is the only platform we need to make this separation. - if (m_parentWindowHwnd != 0) { - state = GHOST_kWindowStateEmbedded; - return state; - } - - if (::IsIconic(m_hWnd)) { - state = GHOST_kWindowStateMinimized; - } - else if (::IsZoomed(m_hWnd)) { - LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); - if ((result & (WS_DLGFRAME | WS_MAXIMIZE)) == (WS_DLGFRAME | WS_MAXIMIZE)) - state = GHOST_kWindowStateMaximized; - else - state = GHOST_kWindowStateFullScreen; - } - else { - state = GHOST_kWindowStateNormal; - } - return state; + GHOST_TWindowState state; + + // XXX 27.04.2011 + // we need to find a way to combine parented windows + resizing if we simply set the + // state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else. + // It's also strange that in Windows is the only platform we need to make this separation. + if (m_parentWindowHwnd != 0) { + state = GHOST_kWindowStateEmbedded; + return state; + } + + if (::IsIconic(m_hWnd)) { + state = GHOST_kWindowStateMinimized; + } + else if (::IsZoomed(m_hWnd)) { + LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); + if ((result & (WS_DLGFRAME | WS_MAXIMIZE)) == (WS_DLGFRAME | WS_MAXIMIZE)) + state = GHOST_kWindowStateMaximized; + else + state = GHOST_kWindowStateFullScreen; + } + else { + state = GHOST_kWindowStateNormal; + } + return state; } - -void GHOST_WindowWin32::screenToClient( - GHOST_TInt32 inX, GHOST_TInt32 inY, - GHOST_TInt32 &outX, GHOST_TInt32 &outY) const +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; + 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 +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; + POINT point = {inX, inY}; + ::ClientToScreen(m_hWnd, &point); + outX = point.x; + outY = point.y; } - GHOST_TSuccess GHOST_WindowWin32::setState(GHOST_TWindowState state) { - GHOST_TWindowState curstate = getState(); - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - ::GetWindowPlacement(m_hWnd, &wp); - - if (state == GHOST_kWindowStateNormal) - state = m_normal_state; - - switch (state) { - case GHOST_kWindowStateMinimized: - wp.showCmd = SW_SHOWMINIMIZED; - break; - case GHOST_kWindowStateMaximized: - wp.showCmd = SW_SHOWMAXIMIZED; - ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); - break; - case GHOST_kWindowStateFullScreen: - if (curstate != state && curstate != GHOST_kWindowStateMinimized) - m_normal_state = curstate; - wp.showCmd = SW_SHOWMAXIMIZED; - wp.ptMaxPosition.x = 0; - wp.ptMaxPosition.y = 0; - ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_MAXIMIZE); - break; - case GHOST_kWindowStateEmbedded: - ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD); - break; - case GHOST_kWindowStateNormal: - default: - wp.showCmd = SW_SHOWNORMAL; - ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); - break; - } - /* Clears window cache for SetWindowLongPtr */ - ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure; + GHOST_TWindowState curstate = getState(); + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + ::GetWindowPlacement(m_hWnd, &wp); + + if (state == GHOST_kWindowStateNormal) + state = m_normal_state; + + switch (state) { + case GHOST_kWindowStateMinimized: + wp.showCmd = SW_SHOWMINIMIZED; + break; + case GHOST_kWindowStateMaximized: + wp.showCmd = SW_SHOWMAXIMIZED; + ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); + break; + case GHOST_kWindowStateFullScreen: + if (curstate != state && curstate != GHOST_kWindowStateMinimized) + m_normal_state = curstate; + wp.showCmd = SW_SHOWMAXIMIZED; + wp.ptMaxPosition.x = 0; + wp.ptMaxPosition.y = 0; + ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_MAXIMIZE); + break; + case GHOST_kWindowStateEmbedded: + ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD); + break; + case GHOST_kWindowStateNormal: + default: + wp.showCmd = SW_SHOWNORMAL; + ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); + break; + } + /* Clears window cache for SetWindowLongPtr */ + ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + + return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure; } - GHOST_TSuccess GHOST_WindowWin32::setOrder(GHOST_TWindowOrder order) { - HWND hWndInsertAfter, hWndToRaise; - - if (order == GHOST_kWindowOrderBottom) { - hWndInsertAfter = HWND_BOTTOM; - hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */ - } - else { - hWndInsertAfter = HWND_TOP; - hWndToRaise = NULL; - } - - if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) { - return GHOST_kFailure; - } - - if (hWndToRaise && ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) { - return GHOST_kFailure; - } - return GHOST_kSuccess; + HWND hWndInsertAfter, hWndToRaise; + + if (order == GHOST_kWindowOrderBottom) { + hWndInsertAfter = HWND_BOTTOM; + hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */ + } + else { + hWndInsertAfter = HWND_TOP; + hWndToRaise = NULL; + } + + if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) { + return GHOST_kFailure; + } + + if (hWndToRaise && + ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) { + return GHOST_kFailure; + } + return GHOST_kSuccess; } - 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 success; + if (m_hWnd) { + success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure; + } + else { + success = GHOST_kFailure; + } + return success; } - GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type) { - if (type == GHOST_kDrawingContextTypeOpenGL) { - GHOST_Context *context; + if (type == GHOST_kDrawingContextTypeOpenGL) { + GHOST_Context *context; #if defined(WITH_GL_PROFILE_CORE) - /* - AMD and Intel give us exactly this version - * - NVIDIA gives at least this version <-- desired behavior - * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system. */ - for (int minor = 5; minor >= 0; --minor) { - context = new GHOST_ContextWGL( - m_wantStereoVisual, - m_wantAlphaBackground, - m_wantNumOfAASamples, - m_hWnd, - m_hDC, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 4, minor, - (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } - } - context = new GHOST_ContextWGL( - m_wantStereoVisual, - m_wantAlphaBackground, - m_wantNumOfAASamples, - m_hWnd, - m_hDC, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 3, 3, - (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - MessageBox( - m_hWnd, - "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n" - "Installing the latest driver for your graphics card may resolve the issue.\n\n" - "The program will now close.", - "Blender - Unsupported Graphics Card or Driver", - MB_OK | MB_ICONERROR); - delete context; - exit(0); - } + /* - AMD and Intel give us exactly this version + * - NVIDIA gives at least this version <-- desired behavior + * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system. */ + for (int minor = 5; minor >= 0; --minor) { + context = new GHOST_ContextWGL(m_wantStereoVisual, + m_wantAlphaBackground, + m_wantNumOfAASamples, + m_hWnd, + m_hDC, + WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 4, + minor, + (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + else { + delete context; + } + } + context = new GHOST_ContextWGL(m_wantStereoVisual, + m_wantAlphaBackground, + m_wantNumOfAASamples, + m_hWnd, + m_hDC, + WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 3, + 3, + (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + else { + MessageBox(m_hWnd, + "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n" + "Installing the latest driver for your graphics card may resolve the issue.\n\n" + "The program will now close.", + "Blender - Unsupported Graphics Card or Driver", + MB_OK | MB_ICONERROR); + delete context; + exit(0); + } #elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL( - m_wantStereoVisual, - m_wantAlphaBackground, - m_wantNumOfAASamples, - m_hWnd, - m_hDC, - 0, // no profile bit - 2, 1, - (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } + // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile) + // 2.1 ignores the profile bit & is incompatible with core profile + context = new GHOST_ContextWGL(m_wantStereoVisual, + m_wantAlphaBackground, + m_wantNumOfAASamples, + m_hWnd, + m_hDC, + 0, // no profile bit + 2, + 1, + (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + else { + delete context; + } #else -# error // must specify either core or compat at build time +# error // must specify either core or compat at build time #endif - } + } - return NULL; + return NULL; } void GHOST_WindowWin32::lostMouseCapture() { - if (m_hasMouseCaptured) { - m_hasGrabMouse = false; - m_nPressedButtons = 0; - m_hasMouseCaptured = false; - } + if (m_hasMouseCaptured) { + m_hasGrabMouse = false; + m_nPressedButtons = 0; + m_hasMouseCaptured = false; + } } void GHOST_WindowWin32::registerMouseClickEvent(int press) { - switch (press) { - case 0: m_nPressedButtons++; break; - case 1: if (m_nPressedButtons) m_nPressedButtons--; break; - case 2: m_hasGrabMouse = true; break; - case 3: m_hasGrabMouse = false; break; - } - - if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) { - ::ReleaseCapture(); - m_hasMouseCaptured = false; - } - else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) { - ::SetCapture(m_hWnd); - m_hasMouseCaptured = true; - - } + switch (press) { + case 0: + m_nPressedButtons++; + break; + case 1: + if (m_nPressedButtons) + m_nPressedButtons--; + break; + case 2: + m_hasGrabMouse = true; + break; + case 3: + m_hasGrabMouse = false; + break; + } + + if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) { + ::ReleaseCapture(); + m_hasMouseCaptured = false; + } + else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) { + ::SetCapture(m_hWnd); + m_hasMouseCaptured = true; + } } - 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; break; - 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; - case GHOST_kStandardCursorPencil: id = IDC_ARROW; break; - case GHOST_kStandardCursorCopy: id = IDC_ARROW; break; - default: - success = false; - } - - if (success) { - ::SetCursor(::LoadCursor(0, id)); - } - } + 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; + break; + 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; + case GHOST_kStandardCursorPencil: + id = IDC_ARROW; + break; + case GHOST_kStandardCursorCopy: + id = IDC_ARROW; + break; + default: + success = false; + } + + if (success) { + ::SetCursor(::LoadCursor(0, id)); + } + } } GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible) { - if (::GetForegroundWindow() == m_hWnd) { - loadCursor(visible, getCursorShape()); - } + if (::GetForegroundWindow() == m_hWnd) { + loadCursor(visible, getCursorShape()); + } - return GHOST_kSuccess; + return GHOST_kSuccess; } GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode) { - if (mode != GHOST_kGrabDisable) { - if (mode != GHOST_kGrabNormal) { - m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setCursorGrabAccum(0, 0); - - if (mode == GHOST_kGrabHide) - setWindowCursorVisibility(false); - } - registerMouseClickEvent(2); - } - else { - if (m_cursorGrab == GHOST_kGrabHide) { - m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setWindowCursorVisibility(true); - } - if (m_cursorGrab != GHOST_kGrabNormal) { - /* use to generate a mouse move event, otherwise the last event - * blender gets can be outside the screen causing menus not to show - * properly unless the user moves the mouse */ - GHOST_TInt32 pos[2]; - m_system->getCursorPosition(pos[0], pos[1]); - m_system->setCursorPosition(pos[0], pos[1]); - } - - /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - setCursorGrabAccum(0, 0); - m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ - registerMouseClickEvent(3); - } - - return GHOST_kSuccess; + if (mode != GHOST_kGrabDisable) { + if (mode != GHOST_kGrabNormal) { + m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setCursorGrabAccum(0, 0); + + if (mode == GHOST_kGrabHide) + setWindowCursorVisibility(false); + } + registerMouseClickEvent(2); + } + else { + if (m_cursorGrab == GHOST_kGrabHide) { + m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setWindowCursorVisibility(true); + } + if (m_cursorGrab != GHOST_kGrabNormal) { + /* use to generate a mouse move event, otherwise the last event + * blender gets can be outside the screen causing menus not to show + * properly unless the user moves the mouse */ + GHOST_TInt32 pos[2]; + m_system->getCursorPosition(pos[0], pos[1]); + m_system->setCursorPosition(pos[0], pos[1]); + } + + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); + m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ + registerMouseClickEvent(3); + } + + return GHOST_kSuccess; } GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape) { - if (m_customCursor) { - DestroyCursor(m_customCursor); - m_customCursor = NULL; - } + if (m_customCursor) { + DestroyCursor(m_customCursor); + m_customCursor = NULL; + } - if (::GetForegroundWindow() == m_hWnd) { - loadCursor(getCursorVisibility(), cursorShape); - } + if (::GetForegroundWindow() == m_hWnd) { + loadCursor(getCursorVisibility(), cursorShape); + } - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam) +GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, + WPARAM wParam, + LPARAM lParam) { - ZeroMemory(pointerInfo, sizeof(GHOST_PointerInfoWin32)); - - // Obtain the basic information from the event - pointerInfo->pointerId = GET_POINTERID_WPARAM(wParam); - pointerInfo->isInContact = IS_POINTER_INCONTACT_WPARAM(wParam); - pointerInfo->isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam); - - // Obtain more accurate and predicted information from the Pointer API - POINTER_INFO pointerApiInfo; - if (!(m_fpGetPointerInfo && m_fpGetPointerInfo(pointerInfo->pointerId, &pointerApiInfo))) { - return GHOST_kFailure; - } - - pointerInfo->hasButtonMask = GHOST_kSuccess; - switch (pointerApiInfo.ButtonChangeType) { - case POINTER_CHANGE_FIRSTBUTTON_DOWN: - case POINTER_CHANGE_FIRSTBUTTON_UP: - pointerInfo->buttonMask = GHOST_kButtonMaskLeft; - break; - case POINTER_CHANGE_SECONDBUTTON_DOWN: - case POINTER_CHANGE_SECONDBUTTON_UP: - pointerInfo->buttonMask = GHOST_kButtonMaskRight; - break; - case POINTER_CHANGE_THIRDBUTTON_DOWN: - case POINTER_CHANGE_THIRDBUTTON_UP: - pointerInfo->buttonMask = GHOST_kButtonMaskMiddle; - break; - case POINTER_CHANGE_FOURTHBUTTON_DOWN: - case POINTER_CHANGE_FOURTHBUTTON_UP: - pointerInfo->buttonMask = GHOST_kButtonMaskButton4; - break; - case POINTER_CHANGE_FIFTHBUTTON_DOWN: - case POINTER_CHANGE_FIFTHBUTTON_UP: - pointerInfo->buttonMask = GHOST_kButtonMaskButton5; - break; - default: - pointerInfo->hasButtonMask = GHOST_kFailure; - break; - } - - pointerInfo->pixelLocation = pointerApiInfo.ptPixelLocation; - pointerInfo->tabletData.Active = GHOST_kTabletModeNone; - pointerInfo->tabletData.Pressure = 1.0f; - pointerInfo->tabletData.Xtilt = 0.0f; - pointerInfo->tabletData.Ytilt = 0.0f; - - if (pointerApiInfo.pointerType != PT_PEN) { - return GHOST_kFailure; - } - - POINTER_PEN_INFO pointerPenInfo; - if (m_fpGetPointerPenInfo && m_fpGetPointerPenInfo(pointerInfo->pointerId, &pointerPenInfo)) { - pointerInfo->tabletData.Active = GHOST_kTabletModeStylus; - - if (pointerPenInfo.penMask & PEN_MASK_PRESSURE) { - pointerInfo->tabletData.Pressure = pointerPenInfo.pressure / 1024.0f; - } - - if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) { - pointerInfo->tabletData.Active = GHOST_kTabletModeEraser; - } - - if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) { - pointerInfo->tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f); - } - - if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) { - pointerInfo->tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f); - } - } - - return GHOST_kSuccess; + ZeroMemory(pointerInfo, sizeof(GHOST_PointerInfoWin32)); + + // Obtain the basic information from the event + pointerInfo->pointerId = GET_POINTERID_WPARAM(wParam); + pointerInfo->isInContact = IS_POINTER_INCONTACT_WPARAM(wParam); + pointerInfo->isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam); + + // Obtain more accurate and predicted information from the Pointer API + POINTER_INFO pointerApiInfo; + if (!(m_fpGetPointerInfo && m_fpGetPointerInfo(pointerInfo->pointerId, &pointerApiInfo))) { + return GHOST_kFailure; + } + + pointerInfo->hasButtonMask = GHOST_kSuccess; + switch (pointerApiInfo.ButtonChangeType) { + case POINTER_CHANGE_FIRSTBUTTON_DOWN: + case POINTER_CHANGE_FIRSTBUTTON_UP: + pointerInfo->buttonMask = GHOST_kButtonMaskLeft; + break; + case POINTER_CHANGE_SECONDBUTTON_DOWN: + case POINTER_CHANGE_SECONDBUTTON_UP: + pointerInfo->buttonMask = GHOST_kButtonMaskRight; + break; + case POINTER_CHANGE_THIRDBUTTON_DOWN: + case POINTER_CHANGE_THIRDBUTTON_UP: + pointerInfo->buttonMask = GHOST_kButtonMaskMiddle; + break; + case POINTER_CHANGE_FOURTHBUTTON_DOWN: + case POINTER_CHANGE_FOURTHBUTTON_UP: + pointerInfo->buttonMask = GHOST_kButtonMaskButton4; + break; + case POINTER_CHANGE_FIFTHBUTTON_DOWN: + case POINTER_CHANGE_FIFTHBUTTON_UP: + pointerInfo->buttonMask = GHOST_kButtonMaskButton5; + break; + default: + pointerInfo->hasButtonMask = GHOST_kFailure; + break; + } + + pointerInfo->pixelLocation = pointerApiInfo.ptPixelLocation; + pointerInfo->tabletData.Active = GHOST_kTabletModeNone; + pointerInfo->tabletData.Pressure = 1.0f; + pointerInfo->tabletData.Xtilt = 0.0f; + pointerInfo->tabletData.Ytilt = 0.0f; + + if (pointerApiInfo.pointerType != PT_PEN) { + return GHOST_kFailure; + } + + POINTER_PEN_INFO pointerPenInfo; + if (m_fpGetPointerPenInfo && m_fpGetPointerPenInfo(pointerInfo->pointerId, &pointerPenInfo)) { + pointerInfo->tabletData.Active = GHOST_kTabletModeStylus; + + if (pointerPenInfo.penMask & PEN_MASK_PRESSURE) { + pointerInfo->tabletData.Pressure = pointerPenInfo.pressure / 1024.0f; + } + + if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) { + pointerInfo->tabletData.Active = GHOST_kTabletModeEraser; + } + + if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) { + pointerInfo->tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f); + } + + if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) { + pointerInfo->tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f); + } + } + + return GHOST_kSuccess; } -void GHOST_WindowWin32::setTabletData(GHOST_TabletData * pTabletData) +void GHOST_WindowWin32::setTabletData(GHOST_TabletData *pTabletData) { - if (pTabletData) { - m_tabletData = *pTabletData; - } - else { - m_tabletData.Active = GHOST_kTabletModeNone; - m_tabletData.Pressure = 1.0f; - m_tabletData.Xtilt = 0.0f; - m_tabletData.Ytilt = 0.0f; - } + if (pTabletData) { + m_tabletData = *pTabletData; + } + else { + m_tabletData.Active = GHOST_kTabletModeNone; + m_tabletData.Pressure = 1.0f; + m_tabletData.Xtilt = 0.0f; + m_tabletData.Ytilt = 0.0f; + } } void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state) { - if (!useTabletAPI(GHOST_kTabletWintab)) { - return; - } + if (!useTabletAPI(GHOST_kTabletWintab)) { + return; + } - if (m_wintab.enable && m_wintab.tablet) { - m_wintab.enable(m_wintab.tablet, state); + if (m_wintab.enable && m_wintab.tablet) { + m_wintab.enable(m_wintab.tablet, state); - if (m_wintab.overlap && state) { - m_wintab.overlap(m_wintab.tablet, TRUE); - } - } + if (m_wintab.overlap && state) { + m_wintab.overlap(m_wintab.tablet, TRUE); + } + } } bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const { - if (m_system->getTabletAPI() == api) { - return true; - } - else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) { - if (m_wintab.tablet) - return api == GHOST_kTabletWintab; - else - return api == GHOST_kTabletNative; - } - else { - return false; - } + if (m_system->getTabletAPI() == api) { + return true; + } + else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) { + if (m_wintab.tablet) + return api == GHOST_kTabletWintab; + else + return api == GHOST_kTabletNative; + } + else { + return false; + } } void GHOST_WindowWin32::processWin32TabletInitEvent() { - if (!useTabletAPI(GHOST_kTabletWintab)) { - return; - } - - // Let's see if we can initialize tablet here - if (m_wintab.info && m_wintab.tablet) { - AXIS Pressure, Orientation[3]; /* The maximum tablet size */ - - BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); - if (pressureSupport) - m_wintab.maxPressure = Pressure.axMax; - else - m_wintab.maxPressure = 0; - - BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); - if (tiltSupport) { - /* does the tablet support azimuth ([0]) and altitude ([1]) */ - if (Orientation[0].axResolution && Orientation[1].axResolution) { - m_wintab.maxAzimuth = Orientation[0].axMax; - m_wintab.maxAltitude = Orientation[1].axMax; - } - else { /* no so dont do tilt stuff */ - m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; - } - } - - m_tabletData.Active = GHOST_kTabletModeNone; - } - - m_tabletData.Active = GHOST_kTabletModeNone; + if (!useTabletAPI(GHOST_kTabletWintab)) { + return; + } + + // Let's see if we can initialize tablet here + if (m_wintab.info && m_wintab.tablet) { + AXIS Pressure, Orientation[3]; /* The maximum tablet size */ + + BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); + if (pressureSupport) + m_wintab.maxPressure = Pressure.axMax; + else + m_wintab.maxPressure = 0; + + BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); + if (tiltSupport) { + /* does the tablet support azimuth ([0]) and altitude ([1]) */ + if (Orientation[0].axResolution && Orientation[1].axResolution) { + m_wintab.maxAzimuth = Orientation[0].axMax; + m_wintab.maxAltitude = Orientation[1].axMax; + } + else { /* no so dont do tilt stuff */ + m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; + } + } + + m_tabletData.Active = GHOST_kTabletModeNone; + } + + m_tabletData.Active = GHOST_kTabletModeNone; } void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) { - if (!useTabletAPI(GHOST_kTabletWintab)) { - return; - } - - if (m_wintab.packet && m_wintab.tablet) { - PACKET pkt; - if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) { - switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */ - case 0: - m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */ - break; - case 1: - m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */ - break; - case 2: - m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */ - break; - } - - if (m_wintab.maxPressure > 0) { - m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure; - } - else { - m_tabletData.Pressure = 1.0f; - } - - if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) { - ORIENTATION ort = pkt.pkOrientation; - float vecLen; - float altRad, azmRad; /* in radians */ - - /* - * from the wintab spec: - * orAzimuth Specifies the clockwise rotation of the - * cursor about the z axis through a full circular range. - * - * orAltitude Specifies the angle with the x-y plane - * through a signed, semicircular range. Positive values - * specify an angle upward toward the positive z axis; - * negative values specify an angle downward toward the negative z axis. - * - * wintab.h defines .orAltitude as a UINT but documents .orAltitude - * as positive for upward angles and negative for downward angles. - * WACOM uses negative altitude values to show that the pen is inverted; - * therefore we cast .orAltitude as an (int) and then use the absolute value. - */ - - /* convert raw fixed point data to radians */ - altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0); - azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0); - - /* find length of the stylus' projected vector on the XY plane */ - vecLen = cos(altRad); - - /* from there calculate X and Y components based on azimuth */ - m_tabletData.Xtilt = sin(azmRad) * vecLen; - m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen); - - } - else { - m_tabletData.Xtilt = 0.0f; - m_tabletData.Ytilt = 0.0f; - } - } - } + if (!useTabletAPI(GHOST_kTabletWintab)) { + return; + } + + if (m_wintab.packet && m_wintab.tablet) { + PACKET pkt; + if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) { + switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */ + case 0: + m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */ + break; + case 1: + m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */ + break; + case 2: + m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */ + break; + } + + if (m_wintab.maxPressure > 0) { + m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure; + } + else { + m_tabletData.Pressure = 1.0f; + } + + if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) { + ORIENTATION ort = pkt.pkOrientation; + float vecLen; + float altRad, azmRad; /* in radians */ + + /* + * from the wintab spec: + * orAzimuth Specifies the clockwise rotation of the + * cursor about the z axis through a full circular range. + * + * orAltitude Specifies the angle with the x-y plane + * through a signed, semicircular range. Positive values + * specify an angle upward toward the positive z axis; + * negative values specify an angle downward toward the negative z axis. + * + * wintab.h defines .orAltitude as a UINT but documents .orAltitude + * as positive for upward angles and negative for downward angles. + * WACOM uses negative altitude values to show that the pen is inverted; + * therefore we cast .orAltitude as an (int) and then use the absolute value. + */ + + /* convert raw fixed point data to radians */ + altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0); + azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0); + + /* find length of the stylus' projected vector on the XY plane */ + vecLen = cos(altRad); + + /* from there calculate X and Y components based on azimuth */ + m_tabletData.Xtilt = sin(azmRad) * vecLen; + m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen); + } + else { + m_tabletData.Xtilt = 0.0f; + m_tabletData.Ytilt = 0.0f; + } + } + } } void GHOST_WindowWin32::bringTabletContextToFront() { - if (!useTabletAPI(GHOST_kTabletWintab)) { - return; - } + if (!useTabletAPI(GHOST_kTabletWintab)) { + return; + } - if (m_wintab.overlap && m_wintab.tablet) { - m_wintab.overlap(m_wintab.tablet, TRUE); - } + if (m_wintab.overlap && m_wintab.tablet) { + m_wintab.overlap(m_wintab.tablet, TRUE); + } } GHOST_TUns16 GHOST_WindowWin32::getDPIHint() { - if (m_user32) { - GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow"); + if (m_user32) { + GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow)::GetProcAddress( + m_user32, "GetDpiForWindow"); - if (fpGetDpiForWindow) { - return fpGetDpiForWindow(this->m_hWnd); - } - } + if (fpGetDpiForWindow) { + return fpGetDpiForWindow(this->m_hWnd); + } + } - return USER_DEFAULT_SCREEN_DPI; + return USER_DEFAULT_SCREEN_DPI; } /** Reverse the bits in a GHOST_TUns8 */ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) { - ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); - ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); - ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0); - return ch; + ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); + ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); + ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0); + return ch; } -#if 0 /* UNUSED */ +#if 0 /* UNUSED */ /** 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; + 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; } #endif -GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape( - GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], - int hotX, int hotY) +GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) { - return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, - 16, 16, hotX, hotY, 0, 1); + return setWindowCustomCursorShape( + (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1); } -GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape( - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, int sizeX, int sizeY, int hotX, int hotY, - int fg_color, int bg_color) +GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizeX, + int sizeY, + int hotX, + int hotY, + int fg_color, + int bg_color) { - GHOST_TUns32 andData[32]; - GHOST_TUns32 xorData[32]; - GHOST_TUns32 fullBitRow, fullMaskRow; - int x, y, cols; - - cols = sizeX / 8; /* Num of whole bytes per row (width of bm/mask) */ - if (sizeX % 8) cols++; - - if (m_customCursor) { - DestroyCursor(m_customCursor); - m_customCursor = NULL; - } - - memset(&andData, 0xFF, sizeof(andData)); - memset(&xorData, 0, sizeof(xorData)); - - for (y = 0; y < sizeY; y++) { - fullBitRow = 0; - fullMaskRow = 0; - for (x = cols - 1; x >= 0; x--) { - fullBitRow <<= 8; - fullMaskRow <<= 8; - fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]); - fullMaskRow |= uns8ReverseBits(mask[cols * y + x]); - } - 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; + GHOST_TUns32 andData[32]; + GHOST_TUns32 xorData[32]; + GHOST_TUns32 fullBitRow, fullMaskRow; + int x, y, cols; + + cols = sizeX / 8; /* Num of whole bytes per row (width of bm/mask) */ + if (sizeX % 8) + cols++; + + if (m_customCursor) { + DestroyCursor(m_customCursor); + m_customCursor = NULL; + } + + memset(&andData, 0xFF, sizeof(andData)); + memset(&xorData, 0, sizeof(xorData)); + + for (y = 0; y < sizeY; y++) { + fullBitRow = 0; + fullMaskRow = 0; + for (x = cols - 1; x >= 0; x--) { + fullBitRow <<= 8; + fullMaskRow <<= 8; + fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]); + fullMaskRow |= uns8ReverseBits(mask[cols * y + x]); + } + 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; } - GHOST_TSuccess GHOST_WindowWin32::setProgressBar(float progress) { - /*SetProgressValue sets state to TBPF_NORMAL automaticly*/ - if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000)) - return GHOST_kSuccess; + /*SetProgressValue sets state to TBPF_NORMAL automaticly*/ + if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000)) + return GHOST_kSuccess; - return GHOST_kFailure; + return GHOST_kFailure; } GHOST_TSuccess GHOST_WindowWin32::endProgressBar() { - if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS)) - return GHOST_kSuccess; + if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS)) + return GHOST_kSuccess; - return GHOST_kFailure; + return GHOST_kFailure; } - #ifdef WITH_INPUT_IME -void GHOST_WindowWin32::beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) +void GHOST_WindowWin32::beginIME( + GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) { - m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed); + m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed); } - void GHOST_WindowWin32::endIME() { - m_imeInput.EndIME(m_hWnd); + m_imeInput.EndIME(m_hWnd); } #endif /* WITH_INPUT_IME */ diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 5de6a62380a..73791d3fbbf 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -26,8 +26,8 @@ #define __GHOST_WINDOWWIN32_H__ #ifndef WIN32 -#error WIN32 only! -#endif // WIN32 +# error WIN32 only! +#endif // WIN32 #include "GHOST_Window.h" #include "GHOST_TaskbarWin32.h" @@ -36,491 +36,511 @@ #endif #include <wintab.h> -#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR) -#define PACKETMODE PK_BUTTONS +#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR) +#define PACKETMODE PK_BUTTONS #include <pktdef.h> class GHOST_SystemWin32; class GHOST_DropTargetWin32; // typedefs for WinTab functions to allow dynamic loading -typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); -typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL); -typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX); -typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID); -typedef BOOL (API * GHOST_WIN32_WTEnable)(HCTX, BOOL); -typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL); +typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); +typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL); +typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX); +typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID); +typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL); +typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL); // typedef to user32 functions to disable gestures on windows -typedef BOOL(API * GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags); +typedef BOOL(API *GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags); // typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions -typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND); +typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND); #ifndef USER_DEFAULT_SCREEN_DPI -#define USER_DEFAULT_SCREEN_DPI 96 -#endif // USER_DEFAULT_SCREEN_DPI +# define USER_DEFAULT_SCREEN_DPI 96 +#endif // USER_DEFAULT_SCREEN_DPI // typedefs for user32 functions to allow pointer functions enum tagPOINTER_INPUT_TYPE { - PT_POINTER = 1, // Generic pointer - PT_TOUCH = 2, // Touch - PT_PEN = 3, // Pen - PT_MOUSE = 4, // Mouse -#if(WINVER >= 0x0603) - PT_TOUCHPAD = 5, // Touchpad -#endif /* WINVER >= 0x0603 */ + PT_POINTER = 1, // Generic pointer + PT_TOUCH = 2, // Touch + PT_PEN = 3, // Pen + PT_MOUSE = 4, // Mouse +#if (WINVER >= 0x0603) + PT_TOUCHPAD = 5, // Touchpad +#endif /* WINVER >= 0x0603 */ }; typedef enum tagPOINTER_BUTTON_CHANGE_TYPE { - POINTER_CHANGE_NONE, - POINTER_CHANGE_FIRSTBUTTON_DOWN, - POINTER_CHANGE_FIRSTBUTTON_UP, - POINTER_CHANGE_SECONDBUTTON_DOWN, - POINTER_CHANGE_SECONDBUTTON_UP, - POINTER_CHANGE_THIRDBUTTON_DOWN, - POINTER_CHANGE_THIRDBUTTON_UP, - POINTER_CHANGE_FOURTHBUTTON_DOWN, - POINTER_CHANGE_FOURTHBUTTON_UP, - POINTER_CHANGE_FIFTHBUTTON_DOWN, - POINTER_CHANGE_FIFTHBUTTON_UP, + POINTER_CHANGE_NONE, + POINTER_CHANGE_FIRSTBUTTON_DOWN, + POINTER_CHANGE_FIRSTBUTTON_UP, + POINTER_CHANGE_SECONDBUTTON_DOWN, + POINTER_CHANGE_SECONDBUTTON_UP, + POINTER_CHANGE_THIRDBUTTON_DOWN, + POINTER_CHANGE_THIRDBUTTON_UP, + POINTER_CHANGE_FOURTHBUTTON_DOWN, + POINTER_CHANGE_FOURTHBUTTON_UP, + POINTER_CHANGE_FIFTHBUTTON_DOWN, + POINTER_CHANGE_FIFTHBUTTON_UP, } POINTER_BUTTON_CHANGE_TYPE; typedef DWORD POINTER_INPUT_TYPE; typedef UINT32 POINTER_FLAGS; typedef struct tagPOINTER_INFO { - POINTER_INPUT_TYPE pointerType; - UINT32 pointerId; - UINT32 frameId; - POINTER_FLAGS pointerFlags; - HANDLE sourceDevice; - HWND hwndTarget; - POINT ptPixelLocation; - POINT ptHimetricLocation; - POINT ptPixelLocationRaw; - POINT ptHimetricLocationRaw; - DWORD dwTime; - UINT32 historyCount; - INT32 InputData; - DWORD dwKeyStates; - UINT64 PerformanceCount; - POINTER_BUTTON_CHANGE_TYPE ButtonChangeType; + POINTER_INPUT_TYPE pointerType; + UINT32 pointerId; + UINT32 frameId; + POINTER_FLAGS pointerFlags; + HANDLE sourceDevice; + HWND hwndTarget; + POINT ptPixelLocation; + POINT ptHimetricLocation; + POINT ptPixelLocationRaw; + POINT ptHimetricLocationRaw; + DWORD dwTime; + UINT32 historyCount; + INT32 InputData; + DWORD dwKeyStates; + UINT64 PerformanceCount; + POINTER_BUTTON_CHANGE_TYPE ButtonChangeType; } POINTER_INFO; typedef UINT32 PEN_FLAGS; -#define PEN_FLAG_NONE 0x00000000 // Default -#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed -#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted -#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed +#define PEN_FLAG_NONE 0x00000000 // Default +#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed +#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted +#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed typedef UINT32 PEN_MASK; -#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid -#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid -#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid -#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid -#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid +#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid +#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid +#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid +#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid +#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid typedef struct tagPOINTER_PEN_INFO { - POINTER_INFO pointerInfo; - PEN_FLAGS penFlags; - PEN_MASK penMask; - UINT32 pressure; - UINT32 rotation; - INT32 tiltX; - INT32 tiltY; + POINTER_INFO pointerInfo; + PEN_FLAGS penFlags; + PEN_MASK penMask; + UINT32 pressure; + UINT32 rotation; + INT32 tiltX; + INT32 tiltY; } POINTER_PEN_INFO; /* * Flags that appear in pointer input message parameters */ -#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer -#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed -#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact -#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action -#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action -#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button -#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button -#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button -#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary -#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental -#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner +#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer +#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed +#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact +#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action +#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action +#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button +#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button +#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button +#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary +#define POINTER_MESSAGE_FLAG_CONFIDENCE \ + 0x00004000 // Pointer is considered unlikely to be accidental +#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner typedef UINT32 TOUCH_FLAGS; -#define TOUCH_FLAG_NONE 0x00000000 // Default +#define TOUCH_FLAG_NONE 0x00000000 // Default typedef UINT32 TOUCH_MASK; -#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid -#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid -#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid -#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid +#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid +#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid +#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid +#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid typedef struct tagPOINTER_TOUCH_INFO { - POINTER_INFO pointerInfo; - TOUCH_FLAGS touchFlags; - TOUCH_MASK touchMask; - RECT rcContact; - RECT rcContactRaw; - UINT32 orientation; - UINT32 pressure; + POINTER_INFO pointerInfo; + TOUCH_FLAGS touchFlags; + TOUCH_MASK touchMask; + RECT rcContact; + RECT rcContactRaw; + UINT32 orientation; + UINT32 pressure; } POINTER_TOUCH_INFO; - /* +/* * Macros to retrieve information from pointer input message parameters */ -#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) -#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag)) -#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW) -#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE) -#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT) -#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON) -#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON) -#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON) -#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON) -#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON) -#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY) -#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE) -#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED) - -typedef BOOL (API * GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo); -typedef BOOL (API * GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo); -typedef BOOL (API * GHOST_WIN32_GetPointerTouchInfo)(UINT32 pointerId, POINTER_TOUCH_INFO *penInfo); +#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) +#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag)) +#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW) +#define IS_POINTER_INRANGE_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE) +#define IS_POINTER_INCONTACT_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT) +#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON) +#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON) +#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON) +#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON) +#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON) +#define IS_POINTER_PRIMARY_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY) +#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE) +#define IS_POINTER_CANCELED_WPARAM(wParam) \ + IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED) + +typedef BOOL(API *GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo); +typedef BOOL(API *GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo); +typedef BOOL(API *GHOST_WIN32_GetPointerTouchInfo)(UINT32 pointerId, POINTER_TOUCH_INFO *penInfo); struct GHOST_PointerInfoWin32 { - GHOST_TInt32 pointerId; - GHOST_TInt32 isInContact; - GHOST_TInt32 isPrimary; - GHOST_TSuccess hasButtonMask; - GHOST_TButtonMask buttonMask; - POINT pixelLocation; - GHOST_TabletData tabletData; + GHOST_TInt32 pointerId; + GHOST_TInt32 isInContact; + GHOST_TInt32 isPrimary; + GHOST_TSuccess hasButtonMask; + GHOST_TButtonMask buttonMask; + POINT pixelLocation; + GHOST_TabletData tabletData; }; /** * GHOST window on M$ Windows OSs. */ 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 wantStereoVisual Stereo visual for quad buffered stereo. - * \param wantNumOfAASamples Number of samples used for AA (zero if no AA) - * \param parentWindowHwnd - */ - GHOST_WindowWin32(GHOST_SystemWin32 *system, - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, - bool wantStereoVisual = false, - bool alphaBackground = false, - GHOST_TUns16 wantNumOfAASamples = 0, - GHOST_TEmbedderWindowID parentWindowHwnd = 0, - bool is_debug = false); - - /** - * Destructor. - * Closes the window and disposes resources allocated. - */ - ~GHOST_WindowWin32(); - - /** - * Returns indication as to whether the window is valid. - * \return The validity of the window. - */ - bool getValid() const; - - /** - * Access to the handle of the window. - * \return The handle of the window. - */ - HWND getHWND() const; - - /** - * Sets the title displayed in the title bar. - * \param title The title to display in the title bar. - */ - void setTitle(const STR_String& title); - - /** - * Returns the title displayed in the title bar. - * \param title The title displayed in the title bar. - */ - 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. - */ - 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 client area of the window. - */ - void getClientBounds(GHOST_Rect& bounds) const; - - /** - * Resizes client rectangle width. - * \param width The new width of the client area of the window. - */ - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); - - /** - * Resizes client rectangle height. - * \param height The new height of the client area of the window. - */ - 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. - */ - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); - - /** - * Returns the state of the window (normal, minimized, maximized). - * \return The state of the window. - */ - 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. - */ - 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. - */ - 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. - */ - 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. - */ - GHOST_TSuccess setOrder(GHOST_TWindowOrder order); - - /** - * Invalidates the contents of this window. - */ - GHOST_TSuccess invalidate(); - - /** - * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % - */ - GHOST_TSuccess setProgressBar(float progress); - - /** - * Hides the progress bar in the icon - */ - GHOST_TSuccess endProgressBar(); - - - /** - * Register a mouse click event (should be called - * for any real button press, controls mouse - * capturing). - * - * \param press - * 0 - mouse pressed - * 1 - mouse released - * 2 - operator grab - * 3 - operator ungrab - */ - void registerMouseClickEvent(int 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; - - const GHOST_TabletData *GetTabletData() - { - return &m_tabletData; - } - - void setTabletData(GHOST_TabletData * tabletData); - bool useTabletAPI(GHOST_TTabletAPI api) const; - void getPointerInfo(WPARAM wParam); - - void processWin32PointerEvent(WPARAM wParam); - void processWin32TabletActivateEvent(WORD state); - void processWin32TabletInitEvent(); - void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); - void bringTabletContextToFront(); - - GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;} - - GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;} - - GHOST_TUns16 getDPIHint() override; - - GHOST_TSuccess getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam); - - /** if the window currently resizing */ - bool m_inLiveResize; + 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 wantStereoVisual Stereo visual for quad buffered stereo. + * \param wantNumOfAASamples Number of samples used for AA (zero if no AA) + * \param parentWindowHwnd + */ + GHOST_WindowWin32(GHOST_SystemWin32 *system, + const STR_String &title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, + bool wantStereoVisual = false, + bool alphaBackground = false, + GHOST_TUns16 wantNumOfAASamples = 0, + GHOST_TEmbedderWindowID parentWindowHwnd = 0, + bool is_debug = false); + + /** + * Destructor. + * Closes the window and disposes resources allocated. + */ + ~GHOST_WindowWin32(); + + /** + * Returns indication as to whether the window is valid. + * \return The validity of the window. + */ + bool getValid() const; + + /** + * Access to the handle of the window. + * \return The handle of the window. + */ + HWND getHWND() const; + + /** + * Sets the title displayed in the title bar. + * \param title The title to display in the title bar. + */ + void setTitle(const STR_String &title); + + /** + * Returns the title displayed in the title bar. + * \param title The title displayed in the title bar. + */ + 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. + */ + 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 client area of the window. + */ + void getClientBounds(GHOST_Rect &bounds) const; + + /** + * Resizes client rectangle width. + * \param width The new width of the client area of the window. + */ + GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + + /** + * Resizes client rectangle height. + * \param height The new height of the client area of the window. + */ + 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. + */ + GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + + /** + * Returns the state of the window (normal, minimized, maximized). + * \return The state of the window. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + GHOST_TSuccess setOrder(GHOST_TWindowOrder order); + + /** + * Invalidates the contents of this window. + */ + GHOST_TSuccess invalidate(); + + /** + * Sets the progress bar value displayed in the window/application icon + * \param progress The progress % + */ + GHOST_TSuccess setProgressBar(float progress); + + /** + * Hides the progress bar in the icon + */ + GHOST_TSuccess endProgressBar(); + + /** + * Register a mouse click event (should be called + * for any real button press, controls mouse + * capturing). + * + * \param press + * 0 - mouse pressed + * 1 - mouse released + * 2 - operator grab + * 3 - operator ungrab + */ + void registerMouseClickEvent(int 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; + + const GHOST_TabletData *GetTabletData() + { + return &m_tabletData; + } + + void setTabletData(GHOST_TabletData *tabletData); + bool useTabletAPI(GHOST_TTabletAPI api) const; + void getPointerInfo(WPARAM wParam); + + void processWin32PointerEvent(WPARAM wParam); + void processWin32TabletActivateEvent(WORD state); + void processWin32TabletInitEvent(); + void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); + void bringTabletContextToFront(); + + GHOST_TSuccess beginFullScreen() const + { + return GHOST_kFailure; + } + + GHOST_TSuccess endFullScreen() const + { + return GHOST_kFailure; + } + + GHOST_TUns16 getDPIHint() override; + + GHOST_TSuccess getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam); + + /** if the window currently resizing */ + bool m_inLiveResize; #ifdef WITH_INPUT_IME - GHOST_ImeWin32 *getImeInput() {return &m_imeInput;} + GHOST_ImeWin32 *getImeInput() + { + return &m_imeInput; + } - void beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, - GHOST_TInt32 w, GHOST_TInt32 h, - int completed); + void beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed); - void endIME(); + void endIME(); #endif /* WITH_INPUT_IME */ -private: - - /** - * \param type The type of rendering context create. - * \return Indication of success. - */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); - - /** - * Sets the cursor visibility on the window using - * native window system calls. - */ - GHOST_TSuccess setWindowCursorVisibility(bool visible); - - /** - * Sets the cursor grab on the window using native window system calls. - * Using registerMouseClickEvent. - * \param mode GHOST_TGrabCursorMode. - */ - GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); - - /** - * 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); - - GHOST_TSuccess setWindowCustomCursorShape( - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - int fg_color, - int bg_color - ); - - /** Pointer to system */ - GHOST_SystemWin32 *m_system; - /** Pointer to COM IDropTarget implementor */ - GHOST_DropTargetWin32 *m_dropTarget; - /** Window handle. */ - HWND m_hWnd; - /** Device context handle. */ - HDC m_hDC; - - /** Flag for if window has captured the mouse */ - bool m_hasMouseCaptured; - /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab() - * Multiple grabs must be released with a single ungrab */ - bool m_hasGrabMouse; - /** Count of number of pressed buttons */ - int m_nPressedButtons; - /** HCURSOR structure of the custom cursor */ - HCURSOR m_customCursor; - /** request GL context aith alpha channel */ - bool m_wantAlphaBackground; - - /** ITaskbarList3 structure for progress bar*/ - ITaskbarList3 *m_Bar; - - static const wchar_t *s_windowClassName; - static const int s_maxTitleLength; - - /** Tablet data for GHOST */ - GHOST_TabletData m_tabletData; - - /* Wintab API */ - struct { - /** WinTab dll handle */ - HMODULE handle; - - /** API functions */ - GHOST_WIN32_WTInfo info; - GHOST_WIN32_WTOpen open; - GHOST_WIN32_WTClose close; - GHOST_WIN32_WTPacket packet; - GHOST_WIN32_WTEnable enable; - GHOST_WIN32_WTOverlap overlap; - - /** Stores the Tablet context if detected Tablet features using WinTab.dll */ - HCTX tablet; - LONG maxPressure; - LONG maxAzimuth, maxAltitude; - } m_wintab; - - GHOST_TWindowState m_normal_state; - - /** user32 dll handle*/ - HMODULE m_user32; - GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo; - GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo; - GHOST_WIN32_GetPointerTouchInfo m_fpGetPointerTouchInfo; - - /** Hwnd to parent window */ - GHOST_TEmbedderWindowID m_parentWindowHwnd; + private: + /** + * \param type The type of rendering context create. + * \return Indication of success. + */ + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); + + /** + * Sets the cursor visibility on the window using + * native window system calls. + */ + GHOST_TSuccess setWindowCursorVisibility(bool visible); + + /** + * Sets the cursor grab on the window using native window system calls. + * Using registerMouseClickEvent. + * \param mode GHOST_TGrabCursorMode. + */ + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); + + /** + * 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); + + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); + + /** Pointer to system */ + GHOST_SystemWin32 *m_system; + /** Pointer to COM IDropTarget implementor */ + GHOST_DropTargetWin32 *m_dropTarget; + /** Window handle. */ + HWND m_hWnd; + /** Device context handle. */ + HDC m_hDC; + + /** Flag for if window has captured the mouse */ + bool m_hasMouseCaptured; + /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab() + * Multiple grabs must be released with a single ungrab */ + bool m_hasGrabMouse; + /** Count of number of pressed buttons */ + int m_nPressedButtons; + /** HCURSOR structure of the custom cursor */ + HCURSOR m_customCursor; + /** request GL context aith alpha channel */ + bool m_wantAlphaBackground; + + /** ITaskbarList3 structure for progress bar*/ + ITaskbarList3 *m_Bar; + + static const wchar_t *s_windowClassName; + static const int s_maxTitleLength; + + /** Tablet data for GHOST */ + GHOST_TabletData m_tabletData; + + /* Wintab API */ + struct { + /** WinTab dll handle */ + HMODULE handle; + + /** API functions */ + GHOST_WIN32_WTInfo info; + GHOST_WIN32_WTOpen open; + GHOST_WIN32_WTClose close; + GHOST_WIN32_WTPacket packet; + GHOST_WIN32_WTEnable enable; + GHOST_WIN32_WTOverlap overlap; + + /** Stores the Tablet context if detected Tablet features using WinTab.dll */ + HCTX tablet; + LONG maxPressure; + LONG maxAzimuth, maxAltitude; + } m_wintab; + + GHOST_TWindowState m_normal_state; + + /** user32 dll handle*/ + HMODULE m_user32; + GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo; + GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo; + GHOST_WIN32_GetPointerTouchInfo m_fpGetPointerTouchInfo; + + /** Hwnd to parent window */ + GHOST_TEmbedderWindowID m_parentWindowHwnd; #ifdef WITH_INPUT_IME - /** Handle input method editors event */ - GHOST_ImeWin32 m_imeInput; + /** Handle input method editors event */ + GHOST_ImeWin32 m_imeInput; #endif - bool m_debug_context; + bool m_debug_context; }; -#endif // __GHOST_WINDOWWIN32_H__ +#endif // __GHOST_WINDOWWIN32_H__ diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 7a2c9967198..21e42e01aea 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -26,7 +26,7 @@ #include <X11/Xatom.h> #include <X11/Xutil.h> #ifdef WITH_X11_ALPHA -#include <X11/extensions/Xrender.h> +# include <X11/extensions/Xrender.h> #endif #include "GHOST_WindowX11.h" #include "GHOST_SystemX11.h" @@ -66,13 +66,13 @@ * lifted verbatim from blut. */ typedef struct { - long flags; - long functions; - long decorations; - long input_mode; + long flags; + long functions; + long decorations; + long input_mode; } MotifWmHints; -#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_DECORATIONS (1L << 1) #ifndef HOST_NAME_MAX # define HOST_NAME_MAX 64 @@ -90,161 +90,166 @@ typedef struct { #define _NET_WM_STATE_ADD 1 // #define _NET_WM_STATE_TOGGLE 2 // UNUSED -static XVisualInfo *x11_visualinfo_from_glx( - Display *display, - bool stereoVisual, - GHOST_TUns16 *r_numOfAASamples, - bool needAlpha, - GLXFBConfig *fbconfig) +static XVisualInfo *x11_visualinfo_from_glx(Display *display, + bool stereoVisual, + GHOST_TUns16 *r_numOfAASamples, + bool needAlpha, + GLXFBConfig *fbconfig) { - XVisualInfo *visual = NULL; - GHOST_TUns16 numOfAASamples = *r_numOfAASamples; - int glx_major, glx_minor, glx_version; /* GLX version: major.minor */ - GHOST_TUns16 actualSamples; - int glx_attribs[64]; - - *fbconfig = NULL; - - /* Set up the minimum attributes that we require and see if - * X can find us a visual matching those requirements. */ - - if (!glXQueryVersion(display, &glx_major, &glx_minor)) { - fprintf(stderr, - "%s:%d: X11 glXQueryVersion() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); - - return NULL; - } - glx_version = glx_major*100 + glx_minor; - - if (glx_version >= 104) { - actualSamples = numOfAASamples; - } - else { - numOfAASamples = 0; - actualSamples = 0; - } + XVisualInfo *visual = NULL; + GHOST_TUns16 numOfAASamples = *r_numOfAASamples; + int glx_major, glx_minor, glx_version; /* GLX version: major.minor */ + GHOST_TUns16 actualSamples; + int glx_attribs[64]; + + *fbconfig = NULL; + + /* Set up the minimum attributes that we require and see if + * X can find us a visual matching those requirements. */ + + if (!glXQueryVersion(display, &glx_major, &glx_minor)) { + fprintf(stderr, + "%s:%d: X11 glXQueryVersion() failed, " + "verify working openGL system!\n", + __FILE__, + __LINE__); + + return NULL; + } + glx_version = glx_major * 100 + glx_minor; + + if (glx_version >= 104) { + actualSamples = numOfAASamples; + } + else { + numOfAASamples = 0; + actualSamples = 0; + } #ifdef WITH_X11_ALPHA - if ( needAlpha - && glx_version >= 103 - && (glXChooseFBConfig || - (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXChooseFBConfig")) != NULL) - && (glXGetVisualFromFBConfig || - (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVisualFromFBConfig")) != NULL) - ) { - GLXFBConfig *fbconfigs; - int nbfbconfig; - int i; - - for (;;) { - - GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true); - - fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (nbfbconfig > 0) { - /* take a frame buffer config that has alpha cap */ - for (i=0 ;i<nbfbconfig; i++) { - visual = (XVisualInfo*)glXGetVisualFromFBConfig(display, fbconfigs[i]); - if (!visual) - continue; - /* if we don't need a alpha background, the first config will do, otherwise - * test the alphaMask as it won't necessarily be present */ - if (needAlpha) { - XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual); - if (!pict_format) - continue; - if (pict_format->direct.alphaMask <= 0) - continue; - } - *fbconfig = fbconfigs[i]; - break; - } - XFree(fbconfigs); - if (i<nbfbconfig) { - if (actualSamples < numOfAASamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - numOfAASamples, actualSamples); - } - break; - } - visual = NULL; - } - - if (actualSamples == 0) { - /* All options exhausted, cannot continue */ - fprintf(stderr, - "%s:%d: X11 glXChooseVisual() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); - - return NULL; - } - else { - --actualSamples; - } - } - } - else + if (needAlpha && glx_version >= 103 && + (glXChooseFBConfig || (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) != NULL) && + (glXGetVisualFromFBConfig || + (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXGetVisualFromFBConfig")) != NULL)) { + GLXFBConfig *fbconfigs; + int nbfbconfig; + int i; + + for (;;) { + + GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true); + + fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig); + + /* Any sample level or even zero, which means oversampling disabled, is good + * but we need a valid visual to continue */ + if (nbfbconfig > 0) { + /* take a frame buffer config that has alpha cap */ + for (i = 0; i < nbfbconfig; i++) { + visual = (XVisualInfo *)glXGetVisualFromFBConfig(display, fbconfigs[i]); + if (!visual) + continue; + /* if we don't need a alpha background, the first config will do, otherwise + * test the alphaMask as it won't necessarily be present */ + if (needAlpha) { + XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual); + if (!pict_format) + continue; + if (pict_format->direct.alphaMask <= 0) + continue; + } + *fbconfig = fbconfigs[i]; + break; + } + XFree(fbconfigs); + if (i < nbfbconfig) { + if (actualSamples < numOfAASamples) { + fprintf(stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d " + "samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, + actualSamples); + } + break; + } + visual = NULL; + } + + if (actualSamples == 0) { + /* All options exhausted, cannot continue */ + fprintf(stderr, + "%s:%d: X11 glXChooseVisual() failed, " + "verify working openGL system!\n", + __FILE__, + __LINE__); + + return NULL; + } + else { + --actualSamples; + } + } + } + else #endif - { - /* legacy, don't use extension */ - for (;;) { - GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false); - - visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (visual != NULL) { - if (actualSamples < numOfAASamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - numOfAASamples, actualSamples); - } - break; - } - - if (actualSamples == 0) { - /* All options exhausted, cannot continue */ - fprintf(stderr, - "%s:%d: X11 glXChooseVisual() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); - - return NULL; - } - else { - --actualSamples; - } - } - } - *r_numOfAASamples = actualSamples; - return visual; + { + /* legacy, don't use extension */ + for (;;) { + GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false); + + visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs); + + /* Any sample level or even zero, which means oversampling disabled, is good + * but we need a valid visual to continue */ + if (visual != NULL) { + if (actualSamples < numOfAASamples) { + fprintf(stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d " + "samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, + actualSamples); + } + break; + } + + if (actualSamples == 0) { + /* All options exhausted, cannot continue */ + fprintf(stderr, + "%s:%d: X11 glXChooseVisual() failed, " + "verify working openGL system!\n", + __FILE__, + __LINE__); + + return NULL; + } + else { + --actualSamples; + } + } + } + *r_numOfAASamples = actualSamples; + return visual; } -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, - const GHOST_TEmbedderWindowID parentWindow, - GHOST_TDrawingContextType type, - const bool stereoVisual, - const bool exclusive, - const bool alphaBackground, - const GHOST_TUns16 numOfAASamples, const bool is_debug) +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, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type, + const bool stereoVisual, + const bool exclusive, + const bool alphaBackground, + const GHOST_TUns16 numOfAASamples, + const bool is_debug) : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples), m_display(display), m_visualInfo(NULL), @@ -265,893 +270,927 @@ GHOST_WindowX11(GHOST_SystemX11 *system, m_valid_setup(false), m_is_debug_context(is_debug) { - if (type == GHOST_kDrawingContextTypeOpenGL) { - m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples, alphaBackground, (GLXFBConfig*)&m_fbconfig); - } - else { - XVisualInfo tmp = {0}; - int n; - m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n); - } - - /* caller needs to check 'getValid()' */ - if (m_visualInfo == NULL) { - fprintf(stderr, "initial window could not find the GLX extension\n"); - return; - } - - unsigned int xattributes_valuemask = 0; - - XSetWindowAttributes xattributes; - memset(&xattributes, 0, sizeof(xattributes)); - - xattributes_valuemask |= CWBorderPixel; - xattributes.border_pixel = 0; - - /* Specify which events we are interested in hearing. */ - - xattributes_valuemask |= CWEventMask; - xattributes.event_mask = - ExposureMask | StructureNotifyMask | - KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | - ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | FocusChangeMask | - PropertyChangeMask | KeymapStateMask; - - if (exclusive) { - xattributes_valuemask |= CWOverrideRedirect; - xattributes.override_redirect = True; - } - - xattributes_valuemask |= CWColormap; - xattributes.colormap = XCreateColormap( - m_display, - RootWindow(m_display, m_visualInfo->screen), - m_visualInfo->visual, - AllocNone - ); - - /* create the window! */ - if (parentWindow == 0) { - m_window = XCreateWindow( - m_display, - RootWindow(m_display, m_visualInfo->screen), - left, top, width, height, - 0, /* no border. */ - m_visualInfo->depth, - InputOutput, - m_visualInfo->visual, - xattributes_valuemask, - &xattributes); - } - else { - Window root_return; - int x_return, y_return; - unsigned int w_return, h_return, border_w_return, depth_return; - - XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return, - &w_return, &h_return, &border_w_return, &depth_return); - - left = 0; - top = 0; - width = w_return; - height = h_return; - - - m_window = XCreateWindow( - m_display, - parentWindow, /* reparent against embedder */ - left, top, width, height, - 0, /* no border. */ - m_visualInfo->depth, - InputOutput, - m_visualInfo->visual, - xattributes_valuemask, - &xattributes); - - XSelectInput(m_display, parentWindow, SubstructureNotifyMask); - - } + if (type == GHOST_kDrawingContextTypeOpenGL) { + m_visualInfo = x11_visualinfo_from_glx(m_display, + stereoVisual, + &m_wantNumOfAASamples, + alphaBackground, + (GLXFBConfig *)&m_fbconfig); + } + else { + XVisualInfo tmp = {0}; + int n; + m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n); + } + + /* caller needs to check 'getValid()' */ + if (m_visualInfo == NULL) { + fprintf(stderr, "initial window could not find the GLX extension\n"); + return; + } + + unsigned int xattributes_valuemask = 0; + + XSetWindowAttributes xattributes; + memset(&xattributes, 0, sizeof(xattributes)); + + xattributes_valuemask |= CWBorderPixel; + xattributes.border_pixel = 0; + + /* Specify which events we are interested in hearing. */ + + xattributes_valuemask |= CWEventMask; + xattributes.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | + EnterWindowMask | LeaveWindowMask | ButtonPressMask | + ButtonReleaseMask | PointerMotionMask | FocusChangeMask | + PropertyChangeMask | KeymapStateMask; + + if (exclusive) { + xattributes_valuemask |= CWOverrideRedirect; + xattributes.override_redirect = True; + } + + xattributes_valuemask |= CWColormap; + xattributes.colormap = XCreateColormap( + m_display, RootWindow(m_display, m_visualInfo->screen), m_visualInfo->visual, AllocNone); + + /* create the window! */ + if (parentWindow == 0) { + m_window = XCreateWindow(m_display, + RootWindow(m_display, m_visualInfo->screen), + left, + top, + width, + height, + 0, /* no border. */ + m_visualInfo->depth, + InputOutput, + m_visualInfo->visual, + xattributes_valuemask, + &xattributes); + } + else { + Window root_return; + int x_return, y_return; + unsigned int w_return, h_return, border_w_return, depth_return; + + XGetGeometry(m_display, + parentWindow, + &root_return, + &x_return, + &y_return, + &w_return, + &h_return, + &border_w_return, + &depth_return); + + left = 0; + top = 0; + width = w_return; + height = h_return; + + m_window = XCreateWindow(m_display, + parentWindow, /* reparent against embedder */ + left, + top, + width, + height, + 0, /* no border. */ + m_visualInfo->depth, + InputOutput, + m_visualInfo->visual, + xattributes_valuemask, + &xattributes); + + XSelectInput(m_display, parentWindow, SubstructureNotifyMask); + } #ifdef WITH_XDND - /* initialize drop target for newly created window */ - m_dropTarget = new GHOST_DropTargetX11(this, m_system); - GHOST_PRINT("Set drop target\n"); + /* initialize drop target for newly created window */ + m_dropTarget = new GHOST_DropTargetX11(this, m_system); + GHOST_PRINT("Set drop target\n"); #endif - if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) { - Atom atoms[2]; - int count = 0; - if (state == GHOST_kWindowStateMaximized) { - atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT; - atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ; - } - else { - atoms[count++] = m_system->m_atom._NET_WM_STATE_FULLSCREEN; - } - - XChangeProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)atoms, count); - m_post_init = False; - } - /* - * One of the problem with WM-spec is that can't set a property - * to a window that isn't mapped. That is why we can't "just - * call setState" here. - * - * To fix this, we first need know that the window is really - * map waiting for the MapNotify event. - * - * So, m_post_init indicate that we need wait for the MapNotify - * event and then set the Window state to the m_post_state. - */ - else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) { - m_post_init = True; - m_post_state = state; - } - else { - m_post_init = False; - m_post_state = GHOST_kWindowStateNormal; - } - - - /* Create some hints for the window manager on how - * we want this window treated. */ - { - XSizeHints *xsizehints = XAllocSizeHints(); - xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize; - xsizehints->x = left; - xsizehints->y = top; - xsizehints->width = width; - xsizehints->height = height; - xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */ - xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */ - xsizehints->max_width = 65535; - xsizehints->max_height = 65535; - XSetWMNormalHints(m_display, m_window, xsizehints); - XFree(xsizehints); - } - - - /* XClassHint, title */ - { - XClassHint *xclasshint = XAllocClassHint(); - const int len = title.Length() + 1; - char *wmclass = (char *)malloc(sizeof(char) * len); - memcpy(wmclass, title.ReadPtr(), len * sizeof(char)); - xclasshint->res_name = wmclass; - xclasshint->res_class = wmclass; - XSetClassHint(m_display, m_window, xclasshint); - free(wmclass); - XFree(xclasshint); - } - - - /* The basic for a good ICCCM "work" */ - if (m_system->m_atom.WM_PROTOCOLS) { - Atom atoms[2]; - int natom = 0; - - if (m_system->m_atom.WM_DELETE_WINDOW) { - atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW; - natom++; - } - - if (m_system->m_atom.WM_TAKE_FOCUS && m_system->m_windowFocus) { - atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS; - natom++; - } - - if (natom) { - /* printf("Register atoms: %d\n", natom); */ - XSetWMProtocols(m_display, m_window, atoms, natom); - } - } - - /* Set the window hints */ - { - XWMHints *xwmhints = XAllocWMHints(); - xwmhints->initial_state = NormalState; - xwmhints->input = (m_system->m_windowFocus) ? True : False; - xwmhints->flags = InputHint | StateHint; - XSetWMHints(display, m_window, xwmhints); - XFree(xwmhints); - } - - - /* set the icon */ - { - Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False); - XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)BLENDER_ICONS_WM_X11, - sizeof(BLENDER_ICONS_WM_X11) / sizeof(unsigned long)); - } - - /* set the process ID (_NET_WM_PID) */ - { - Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False); - pid_t pid = getpid(); - XChangeProperty(m_display, m_window, _NET_WM_PID, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&pid, 1); - } - - - /* set the hostname (WM_CLIENT_MACHINE) */ - { - char hostname[HOST_NAME_MAX]; - char *text_array[1]; - XTextProperty text_prop; - - gethostname(hostname, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - text_array[0] = hostname; - - XStringListToTextProperty(text_array, 1, &text_prop); - XSetWMClientMachine(m_display, m_window, &text_prop); - XFree(text_prop.value); - } + if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) { + Atom atoms[2]; + int count = 0; + if (state == GHOST_kWindowStateMaximized) { + atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT; + atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ; + } + else { + atoms[count++] = m_system->m_atom._NET_WM_STATE_FULLSCREEN; + } + + XChangeProperty(m_display, + m_window, + m_system->m_atom._NET_WM_STATE, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *)atoms, + count); + m_post_init = False; + } + /* + * One of the problem with WM-spec is that can't set a property + * to a window that isn't mapped. That is why we can't "just + * call setState" here. + * + * To fix this, we first need know that the window is really + * map waiting for the MapNotify event. + * + * So, m_post_init indicate that we need wait for the MapNotify + * event and then set the Window state to the m_post_state. + */ + else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) { + m_post_init = True; + m_post_state = state; + } + else { + m_post_init = False; + m_post_state = GHOST_kWindowStateNormal; + } + + /* Create some hints for the window manager on how + * we want this window treated. */ + { + XSizeHints *xsizehints = XAllocSizeHints(); + xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize; + xsizehints->x = left; + xsizehints->y = top; + xsizehints->width = width; + xsizehints->height = height; + xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */ + xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */ + xsizehints->max_width = 65535; + xsizehints->max_height = 65535; + XSetWMNormalHints(m_display, m_window, xsizehints); + XFree(xsizehints); + } + + /* XClassHint, title */ + { + XClassHint *xclasshint = XAllocClassHint(); + const int len = title.Length() + 1; + char *wmclass = (char *)malloc(sizeof(char) * len); + memcpy(wmclass, title.ReadPtr(), len * sizeof(char)); + xclasshint->res_name = wmclass; + xclasshint->res_class = wmclass; + XSetClassHint(m_display, m_window, xclasshint); + free(wmclass); + XFree(xclasshint); + } + + /* The basic for a good ICCCM "work" */ + if (m_system->m_atom.WM_PROTOCOLS) { + Atom atoms[2]; + int natom = 0; + + if (m_system->m_atom.WM_DELETE_WINDOW) { + atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW; + natom++; + } + + if (m_system->m_atom.WM_TAKE_FOCUS && m_system->m_windowFocus) { + atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS; + natom++; + } + + if (natom) { + /* printf("Register atoms: %d\n", natom); */ + XSetWMProtocols(m_display, m_window, atoms, natom); + } + } + + /* Set the window hints */ + { + XWMHints *xwmhints = XAllocWMHints(); + xwmhints->initial_state = NormalState; + xwmhints->input = (m_system->m_windowFocus) ? True : False; + xwmhints->flags = InputHint | StateHint; + XSetWMHints(display, m_window, xwmhints); + XFree(xwmhints); + } + + /* set the icon */ + { + Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False); + XChangeProperty(m_display, + m_window, + _NET_WM_ICON, + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char *)BLENDER_ICONS_WM_X11, + sizeof(BLENDER_ICONS_WM_X11) / sizeof(unsigned long)); + } + + /* set the process ID (_NET_WM_PID) */ + { + Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False); + pid_t pid = getpid(); + XChangeProperty(m_display, + m_window, + _NET_WM_PID, + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char *)&pid, + 1); + } + + /* set the hostname (WM_CLIENT_MACHINE) */ + { + char hostname[HOST_NAME_MAX]; + char *text_array[1]; + XTextProperty text_prop; + + gethostname(hostname, sizeof(hostname)); + hostname[sizeof(hostname) - 1] = '\0'; + text_array[0] = hostname; + + XStringListToTextProperty(text_array, 1, &text_prop); + XSetWMClientMachine(m_display, m_window, &text_prop); + XFree(text_prop.value); + } #ifdef WITH_X11_XINPUT - refreshXInputDevices(); + refreshXInputDevices(); - m_tabletData.Active = GHOST_kTabletModeNone; + m_tabletData.Active = GHOST_kTabletModeNone; #endif + /* now set up the rendering context. */ + if (setDrawingContextType(type) == GHOST_kSuccess) { + m_valid_setup = true; + GHOST_PRINT("Created window\n"); + } - /* now set up the rendering context. */ - if (setDrawingContextType(type) == GHOST_kSuccess) { - m_valid_setup = true; - GHOST_PRINT("Created window\n"); - } + setTitle(title); - setTitle(title); + if (exclusive && system->m_windowFocus) { + XMapRaised(m_display, m_window); + } + else { + XMapWindow(m_display, m_window); - if (exclusive && system->m_windowFocus) { - XMapRaised(m_display, m_window); - } - else { - XMapWindow(m_display, m_window); + if (!system->m_windowFocus) { + XLowerWindow(m_display, m_window); + } + } + GHOST_PRINT("Mapped window\n"); - if (!system->m_windowFocus) { - XLowerWindow(m_display, m_window); - } - } - GHOST_PRINT("Mapped window\n"); - - XFlush(m_display); + XFlush(m_display); } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) static Bool destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/) { - GHOST_PRINT("XIM input context destroyed\n"); + GHOST_PRINT("XIM input context destroyed\n"); - if (ptr) { - *(XIC *)ptr = NULL; - } - /* Ignored by X11. */ - return True; + if (ptr) { + *(XIC *)ptr = NULL; + } + /* Ignored by X11. */ + return True; } bool GHOST_WindowX11::createX11_XIC() { - XIM xim = m_system->getX11_XIM(); - if (!xim) - return false; - - XICCallback destroy; - destroy.callback = (XICProc)destroyICCallback; - destroy.client_data = (XPointer)&m_xic; - m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNResourceName, GHOST_X11_RES_NAME, - XNResourceClass, GHOST_X11_RES_CLASS, - XNDestroyCallback, &destroy, - NULL); - if (!m_xic) - return false; - - unsigned long fevent; - XGetICValues(m_xic, XNFilterEvents, &fevent, NULL); - XSelectInput(m_display, m_window, - ExposureMask | StructureNotifyMask | - KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | - ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | FocusChangeMask | - PropertyChangeMask | KeymapStateMask | fevent); - return true; + XIM xim = m_system->getX11_XIM(); + if (!xim) + return false; + + XICCallback destroy; + destroy.callback = (XICProc)destroyICCallback; + destroy.client_data = (XPointer)&m_xic; + m_xic = XCreateIC(xim, + XNClientWindow, + m_window, + XNFocusWindow, + m_window, + XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, + XNResourceName, + GHOST_X11_RES_NAME, + XNResourceClass, + GHOST_X11_RES_CLASS, + XNDestroyCallback, + &destroy, + NULL); + if (!m_xic) + return false; + + unsigned long fevent; + XGetICValues(m_xic, XNFilterEvents, &fevent, NULL); + XSelectInput(m_display, + m_window, + ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | + EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | FocusChangeMask | PropertyChangeMask | KeymapStateMask | + fevent); + return true; } #endif #ifdef WITH_X11_XINPUT void GHOST_WindowX11::refreshXInputDevices() { - if (m_system->m_xinput_version.present) { - std::vector<XEventClass> xevents; - - for (GHOST_SystemX11::GHOST_TabletX11& xtablet: m_system->GetXTablets()) { - /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets - * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event, - * otherwise we do not get any tablet motion event once pen is pressed... See T43367. - */ - XEventClass ev; - - DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev); - if (ev) xevents.push_back(ev); - DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev); - if (ev) xevents.push_back(ev); - ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev); - if (ev) xevents.push_back(ev); - ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev); - if (ev) xevents.push_back(ev); - } - - XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size()); - } + if (m_system->m_xinput_version.present) { + std::vector<XEventClass> xevents; + + for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) { + /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets + * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event, + * otherwise we do not get any tablet motion event once pen is pressed... See T43367. + */ + XEventClass ev; + + DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev); + if (ev) + xevents.push_back(ev); + DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev); + if (ev) + xevents.push_back(ev); + ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev); + if (ev) + xevents.push_back(ev); + ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev); + if (ev) + xevents.push_back(ev); + } + + XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size()); + } } #endif /* WITH_X11_XINPUT */ -Window -GHOST_WindowX11:: -getXWindow() +Window GHOST_WindowX11::getXWindow() { - return m_window; + return m_window; } -bool -GHOST_WindowX11:: -getValid() const +bool GHOST_WindowX11::getValid() const { - return GHOST_Window::getValid() && m_valid_setup; + return GHOST_Window::getValid() && m_valid_setup; } -void -GHOST_WindowX11:: -setTitle( - const STR_String& title) +void GHOST_WindowX11::setTitle(const STR_String &title) { - Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0); - Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0); - XChangeProperty(m_display, m_window, - name, utf8str, 8, PropModeReplace, - (const unsigned char *) title.ReadPtr(), - title.Length()); - - /* This should convert to valid x11 string - * and getTitle would need matching change */ - XStoreName(m_display, m_window, title); - - XFlush(m_display); + Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0); + Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0); + XChangeProperty(m_display, + m_window, + name, + utf8str, + 8, + PropModeReplace, + (const unsigned char *)title.ReadPtr(), + title.Length()); + + /* This should convert to valid x11 string + * and getTitle would need matching change */ + XStoreName(m_display, m_window, title); + + XFlush(m_display); } -void -GHOST_WindowX11:: -getTitle( - STR_String& title) const +void GHOST_WindowX11::getTitle(STR_String &title) const { - char *name = NULL; + char *name = NULL; - XFetchName(m_display, m_window, &name); - title = name ? name : "untitled"; - XFree(name); + XFetchName(m_display, m_window, &name); + title = name ? name : "untitled"; + XFree(name); } -void -GHOST_WindowX11:: -getWindowBounds( - GHOST_Rect& bounds) const +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); + /* 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 +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; - + 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) +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); + XWindowChanges values; + unsigned int value_mask = CWWidth; + values.width = width; + XConfigureWindow(m_display, m_window, value_mask, &values); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -setClientHeight( - GHOST_TUns32 height) +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; - + 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) +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; - + 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 +void GHOST_WindowX11::screenToClient(GHOST_TInt32 inX, + GHOST_TInt32 inY, + GHOST_TInt32 &outX, + GHOST_TInt32 &outY) const { - /* This is correct! */ - - int ax, ay; - Window temp; - - XTranslateCoordinates(m_display, - RootWindow(m_display, m_visualInfo->screen), - m_window, - inX, inY, - &ax, &ay, - &temp); - outX = ax; - outY = ay; + /* This is correct! */ + + int ax, ay; + Window temp; + + XTranslateCoordinates( + m_display, RootWindow(m_display, m_visualInfo->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 +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_visualInfo->screen), - inX, inY, - &ax, &ay, - &temp); - outX = ax; - outY = ay; + int ax, ay; + Window temp; + + XTranslateCoordinates( + m_display, m_window, RootWindow(m_display, m_visualInfo->screen), inX, inY, &ax, &ay, &temp); + outX = ax; + outY = ay; } void GHOST_WindowX11::icccmSetState(int state) { - XEvent xev; - - if (state != IconicState) - return; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.display = m_display; - xev.xclient.window = m_window; - xev.xclient.format = 32; - xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE; - xev.xclient.data.l[0] = state; - XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), - False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); + XEvent xev; + + if (state != IconicState) + return; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = m_display; + xev.xclient.window = m_window; + xev.xclient.format = 32; + xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE; + xev.xclient.data.l[0] = state; + XSendEvent(m_display, + RootWindow(m_display, m_visualInfo->screen), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &xev); } int GHOST_WindowX11::icccmGetState(void) const { - struct { - CARD32 state; - XID icon; - } *prop_ret; - unsigned long bytes_after, num_ret; - Atom type_ret; - int ret, format_ret; - CARD32 st; - - prop_ret = NULL; - ret = XGetWindowProperty( - m_display, m_window, m_system->m_atom.WM_STATE, 0, 2, - False, m_system->m_atom.WM_STATE, &type_ret, - &format_ret, &num_ret, &bytes_after, ((unsigned char **)&prop_ret)); - if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) { - st = prop_ret->state; - } - else { - st = NormalState; - } - - if (prop_ret) { - XFree(prop_ret); - } - - return st; + struct { + CARD32 state; + XID icon; + } * prop_ret; + unsigned long bytes_after, num_ret; + Atom type_ret; + int ret, format_ret; + CARD32 st; + + prop_ret = NULL; + ret = XGetWindowProperty(m_display, + m_window, + m_system->m_atom.WM_STATE, + 0, + 2, + False, + m_system->m_atom.WM_STATE, + &type_ret, + &format_ret, + &num_ret, + &bytes_after, + ((unsigned char **)&prop_ret)); + if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) { + st = prop_ret->state; + } + else { + st = NormalState; + } + + if (prop_ret) { + XFree(prop_ret); + } + + return st; } void GHOST_WindowX11::netwmMaximized(bool set) { - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = m_window; - xev.xclient.message_type = m_system->m_atom._NET_WM_STATE; - xev.xclient.format = 32; - - if (set == True) - xev.xclient.data.l[0] = _NET_WM_STATE_ADD; - else - xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; - - xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ; - xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), - False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = m_window; + xev.xclient.message_type = m_system->m_atom._NET_WM_STATE; + xev.xclient.format = 32; + + if (set == True) + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + else + xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + + xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ; + xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + XSendEvent(m_display, + RootWindow(m_display, m_visualInfo->screen), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); } bool GHOST_WindowX11::netwmIsMaximized(void) const { - Atom *prop_ret; - unsigned long bytes_after, num_ret, i; - Atom type_ret; - bool st; - int format_ret, ret, count; - - prop_ret = NULL; - st = False; - ret = XGetWindowProperty( - m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX, - False, XA_ATOM, &type_ret, &format_ret, - &num_ret, &bytes_after, (unsigned char **)&prop_ret); - if ((ret == Success) && (prop_ret) && (format_ret == 32)) { - count = 0; - for (i = 0; i < num_ret; i++) { - if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ) { - count++; - } - if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT) { - count++; - } - if (count == 2) { - st = True; - break; - } - } - } - - if (prop_ret) - XFree(prop_ret); - return (st); + Atom *prop_ret; + unsigned long bytes_after, num_ret, i; + Atom type_ret; + bool st; + int format_ret, ret, count; + + prop_ret = NULL; + st = False; + ret = XGetWindowProperty(m_display, + m_window, + m_system->m_atom._NET_WM_STATE, + 0, + INT_MAX, + False, + XA_ATOM, + &type_ret, + &format_ret, + &num_ret, + &bytes_after, + (unsigned char **)&prop_ret); + if ((ret == Success) && (prop_ret) && (format_ret == 32)) { + count = 0; + for (i = 0; i < num_ret; i++) { + if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ) { + count++; + } + if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT) { + count++; + } + if (count == 2) { + st = True; + break; + } + } + } + + if (prop_ret) + XFree(prop_ret); + return (st); } void GHOST_WindowX11::netwmFullScreen(bool set) { - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = m_window; - xev.xclient.message_type = m_system->m_atom._NET_WM_STATE; - xev.xclient.format = 32; - - if (set == True) - xev.xclient.data.l[0] = _NET_WM_STATE_ADD; - else - xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; - - xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), - False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = m_window; + xev.xclient.message_type = m_system->m_atom._NET_WM_STATE; + xev.xclient.format = 32; + + if (set == True) + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + else + xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + + xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + XSendEvent(m_display, + RootWindow(m_display, m_visualInfo->screen), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); } bool GHOST_WindowX11::netwmIsFullScreen(void) const { - Atom *prop_ret; - unsigned long bytes_after, num_ret, i; - Atom type_ret; - bool st; - int format_ret, ret; - - prop_ret = NULL; - st = False; - ret = XGetWindowProperty( - m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX, - False, XA_ATOM, &type_ret, &format_ret, - &num_ret, &bytes_after, (unsigned char **)&prop_ret); - if ((ret == Success) && (prop_ret) && (format_ret == 32)) { - for (i = 0; i < num_ret; i++) { - if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) { - st = True; - break; - } - } - } - - if (prop_ret) - XFree(prop_ret); - return (st); + Atom *prop_ret; + unsigned long bytes_after, num_ret, i; + Atom type_ret; + bool st; + int format_ret, ret; + + prop_ret = NULL; + st = False; + ret = XGetWindowProperty(m_display, + m_window, + m_system->m_atom._NET_WM_STATE, + 0, + INT_MAX, + False, + XA_ATOM, + &type_ret, + &format_ret, + &num_ret, + &bytes_after, + (unsigned char **)&prop_ret); + if ((ret == Success) && (prop_ret) && (format_ret == 32)) { + for (i = 0; i < num_ret; i++) { + if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) { + st = True; + break; + } + } + } + + if (prop_ret) + XFree(prop_ret); + return (st); } void GHOST_WindowX11::motifFullScreen(bool set) { - MotifWmHints hints; - - hints.flags = MWM_HINTS_DECORATIONS; - if (set == True) - hints.decorations = 0; - else - hints.decorations = 1; - - XChangeProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, - m_system->m_atom._MOTIF_WM_HINTS, 32, PropModeReplace, - (unsigned char *) &hints, 4); + MotifWmHints hints; + + hints.flags = MWM_HINTS_DECORATIONS; + if (set == True) + hints.decorations = 0; + else + hints.decorations = 1; + + XChangeProperty(m_display, + m_window, + m_system->m_atom._MOTIF_WM_HINTS, + m_system->m_atom._MOTIF_WM_HINTS, + 32, + PropModeReplace, + (unsigned char *)&hints, + 4); } bool GHOST_WindowX11::motifIsFullScreen(void) const { - MotifWmHints *prop_ret; - unsigned long bytes_after, num_ret; - Atom type_ret; - bool state; - int format_ret, st; - - prop_ret = NULL; - state = False; - st = XGetWindowProperty( - m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, 0, INT_MAX, - False, m_system->m_atom._MOTIF_WM_HINTS, - &type_ret, &format_ret, &num_ret, - &bytes_after, (unsigned char **)&prop_ret); - if ((st == Success) && prop_ret) { - if (prop_ret->flags & MWM_HINTS_DECORATIONS) { - if (!prop_ret->decorations) - state = True; - } - } - - if (prop_ret) - XFree(prop_ret); - return (state); + MotifWmHints *prop_ret; + unsigned long bytes_after, num_ret; + Atom type_ret; + bool state; + int format_ret, st; + + prop_ret = NULL; + state = False; + st = XGetWindowProperty(m_display, + m_window, + m_system->m_atom._MOTIF_WM_HINTS, + 0, + INT_MAX, + False, + m_system->m_atom._MOTIF_WM_HINTS, + &type_ret, + &format_ret, + &num_ret, + &bytes_after, + (unsigned char **)&prop_ret); + if ((st == Success) && prop_ret) { + if (prop_ret->flags & MWM_HINTS_DECORATIONS) { + if (!prop_ret->decorations) + state = True; + } + } + + if (prop_ret) + XFree(prop_ret); + return (state); } GHOST_TWindowState GHOST_WindowX11::getState() const { - GHOST_TWindowState state_ret; - int state; - - state_ret = GHOST_kWindowStateNormal; - state = icccmGetState(); - /* - * In the Iconic and Withdrawn state, the window - * is unmaped, so only need return a Minimized state. - */ - if ((state == IconicState) || (state == WithdrawnState)) - state_ret = GHOST_kWindowStateMinimized; - else if (netwmIsFullScreen() == True) - state_ret = GHOST_kWindowStateFullScreen; - else if (motifIsFullScreen() == True) - state_ret = GHOST_kWindowStateFullScreen; - else if (netwmIsMaximized() == True) - state_ret = GHOST_kWindowStateMaximized; - return (state_ret); + GHOST_TWindowState state_ret; + int state; + + state_ret = GHOST_kWindowStateNormal; + state = icccmGetState(); + /* + * In the Iconic and Withdrawn state, the window + * is unmaped, so only need return a Minimized state. + */ + if ((state == IconicState) || (state == WithdrawnState)) + state_ret = GHOST_kWindowStateMinimized; + else if (netwmIsFullScreen() == True) + state_ret = GHOST_kWindowStateFullScreen; + else if (motifIsFullScreen() == True) + state_ret = GHOST_kWindowStateFullScreen; + else if (netwmIsMaximized() == True) + state_ret = GHOST_kWindowStateMaximized; + return (state_ret); } GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state) { - GHOST_TWindowState cur_state; - bool is_max, is_full, is_motif_full; - - cur_state = getState(); - if (state == (int)cur_state) - return GHOST_kSuccess; - - if (cur_state != GHOST_kWindowStateMinimized) { - /* - * The window don't have this property's - * if it's not mapped. - */ - is_max = netwmIsMaximized(); - is_full = netwmIsFullScreen(); - } - else { - is_max = False; - is_full = False; - } - - is_motif_full = motifIsFullScreen(); - - if (state == GHOST_kWindowStateNormal) - state = m_normal_state; - - if (state == GHOST_kWindowStateNormal) { - if (is_max == True) - netwmMaximized(False); - if (is_full == True) - netwmFullScreen(False); - if (is_motif_full == True) - motifFullScreen(False); - icccmSetState(NormalState); - return (GHOST_kSuccess); - } - - if (state == GHOST_kWindowStateFullScreen) { - /* - * We can't change to full screen if the window - * isn't mapped. - */ - if (cur_state == GHOST_kWindowStateMinimized) - return (GHOST_kFailure); - - m_normal_state = cur_state; - - if (is_max == True) - netwmMaximized(False); - if (is_full == False) - netwmFullScreen(True); - if (is_motif_full == False) - motifFullScreen(True); - return (GHOST_kSuccess); - } - - if (state == GHOST_kWindowStateMaximized) { - /* - * We can't change to Maximized if the window - * isn't mapped. - */ - if (cur_state == GHOST_kWindowStateMinimized) - return (GHOST_kFailure); - - if (is_full == True) - netwmFullScreen(False); - if (is_motif_full == True) - motifFullScreen(False); - if (is_max == False) - netwmMaximized(True); - return (GHOST_kSuccess); - } - - if (state == GHOST_kWindowStateMinimized) { - /* - * The window manager need save the current state of - * the window (maximized, full screen, etc). - */ - icccmSetState(IconicState); - return (GHOST_kSuccess); - } - - return (GHOST_kFailure); + GHOST_TWindowState cur_state; + bool is_max, is_full, is_motif_full; + + cur_state = getState(); + if (state == (int)cur_state) + return GHOST_kSuccess; + + if (cur_state != GHOST_kWindowStateMinimized) { + /* + * The window don't have this property's + * if it's not mapped. + */ + is_max = netwmIsMaximized(); + is_full = netwmIsFullScreen(); + } + else { + is_max = False; + is_full = False; + } + + is_motif_full = motifIsFullScreen(); + + if (state == GHOST_kWindowStateNormal) + state = m_normal_state; + + if (state == GHOST_kWindowStateNormal) { + if (is_max == True) + netwmMaximized(False); + if (is_full == True) + netwmFullScreen(False); + if (is_motif_full == True) + motifFullScreen(False); + icccmSetState(NormalState); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateFullScreen) { + /* + * We can't change to full screen if the window + * isn't mapped. + */ + if (cur_state == GHOST_kWindowStateMinimized) + return (GHOST_kFailure); + + m_normal_state = cur_state; + + if (is_max == True) + netwmMaximized(False); + if (is_full == False) + netwmFullScreen(True); + if (is_motif_full == False) + motifFullScreen(True); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateMaximized) { + /* + * We can't change to Maximized if the window + * isn't mapped. + */ + if (cur_state == GHOST_kWindowStateMinimized) + return (GHOST_kFailure); + + if (is_full == True) + netwmFullScreen(False); + if (is_motif_full == True) + motifFullScreen(False); + if (is_max == False) + netwmMaximized(True); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateMinimized) { + /* + * The window manager need save the current state of + * the window (maximized, full screen, etc). + */ + icccmSetState(IconicState); + return (GHOST_kSuccess); + } + + return (GHOST_kFailure); } #include <iostream> -GHOST_TSuccess -GHOST_WindowX11:: -setOrder( - GHOST_TWindowOrder order) +GHOST_TSuccess GHOST_WindowX11::setOrder(GHOST_TWindowOrder order) { - if (order == GHOST_kWindowOrderTop) { - XWindowAttributes attr; - Atom atom; - - /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some - * window managers ignore the former (e.g. kwin from kde) and others - * don't implement the latter (e.g. fluxbox pre 0.9.9) */ - - XRaiseWindow(m_display, m_window); - - atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True); - - if (atom != None) { - Window root; - XEvent xev; - long eventmask; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = m_window; - xev.xclient.message_type = atom; - - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = CurrentTime; - xev.xclient.data.l[2] = m_window; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - root = RootWindow(m_display, m_visualInfo->screen); - eventmask = SubstructureRedirectMask | SubstructureNotifyMask; - - XSendEvent(m_display, root, False, eventmask, &xev); - } - - XGetWindowAttributes(m_display, m_window, &attr); - - /* iconized windows give bad match error */ - if (attr.map_state == IsViewable) - XSetInputFocus(m_display, m_window, RevertToPointerRoot, - CurrentTime); - XFlush(m_display); - } - else if (order == GHOST_kWindowOrderBottom) { - XLowerWindow(m_display, m_window); - XFlush(m_display); - } - else { - return GHOST_kFailure; - } - - return GHOST_kSuccess; + if (order == GHOST_kWindowOrderTop) { + XWindowAttributes attr; + Atom atom; + + /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some + * window managers ignore the former (e.g. kwin from kde) and others + * don't implement the latter (e.g. fluxbox pre 0.9.9) */ + + XRaiseWindow(m_display, m_window); + + atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True); + + if (atom != None) { + Window root; + XEvent xev; + long eventmask; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = m_window; + xev.xclient.message_type = atom; + + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = CurrentTime; + xev.xclient.data.l[2] = m_window; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + root = RootWindow(m_display, m_visualInfo->screen); + eventmask = SubstructureRedirectMask | SubstructureNotifyMask; + + XSendEvent(m_display, root, False, eventmask, &xev); + } + + XGetWindowAttributes(m_display, m_window, &attr); + + /* iconized windows give bad match error */ + if (attr.map_state == IsViewable) + XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime); + 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:: -invalidate() +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; + /* 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; } /** @@ -1159,486 +1198,496 @@ invalidate() * for the window have been pushed onto the GHOST queue */ -void -GHOST_WindowX11:: -validate() +void GHOST_WindowX11::validate() { - m_invalid_window = false; + m_invalid_window = false; } - /** * Destructor. * Closes the window and disposes resources allocated. */ -GHOST_WindowX11:: -~GHOST_WindowX11() +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); - } - - if (m_valid_setup) { - static Atom Primary_atom, Clipboard_atom; - Window p_owner, c_owner; - /*Change the owner of the Atoms to None if we are the owner*/ - Primary_atom = XInternAtom(m_display, "PRIMARY", False); - Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False); - - - p_owner = XGetSelectionOwner(m_display, Primary_atom); - c_owner = XGetSelectionOwner(m_display, Clipboard_atom); - - if (p_owner == m_window) { - XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime); - } - if (c_owner == m_window) { - XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime); - } - } - - if (m_visualInfo) { - XFree(m_visualInfo); - } + 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); + } + + if (m_valid_setup) { + static Atom Primary_atom, Clipboard_atom; + Window p_owner, c_owner; + /*Change the owner of the Atoms to None if we are the owner*/ + Primary_atom = XInternAtom(m_display, "PRIMARY", False); + Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False); + + p_owner = XGetSelectionOwner(m_display, Primary_atom); + c_owner = XGetSelectionOwner(m_display, Clipboard_atom); + + if (p_owner == m_window) { + XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime); + } + if (c_owner == m_window) { + XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime); + } + } + + if (m_visualInfo) { + XFree(m_visualInfo); + } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - if (m_xic) { - XDestroyIC(m_xic); - } + if (m_xic) { + XDestroyIC(m_xic); + } #endif #ifdef WITH_XDND - delete m_dropTarget; + delete m_dropTarget; #endif - releaseNativeHandles(); + releaseNativeHandles(); - if (m_valid_setup) { - XDestroyWindow(m_display, m_window); - } + if (m_valid_setup) { + XDestroyWindow(m_display, m_window); + } } - GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type) { - if (type == GHOST_kDrawingContextTypeOpenGL) { - - // During development: - // try 4.x compatibility profile - // try 3.3 compatibility profile - // fall back to 3.0 if needed - // - // Final Blender 2.8: - // try 4.x core profile - // try 3.3 core profile - // no fallbacks + if (type == GHOST_kDrawingContextTypeOpenGL) { + + // During development: + // try 4.x compatibility profile + // try 3.3 compatibility profile + // fall back to 3.0 if needed + // + // Final Blender 2.8: + // try 4.x core profile + // try 3.3 core profile + // no fallbacks #if defined(WITH_GL_PROFILE_CORE) - { - const char *version_major = (char*)glewGetString(GLEW_VERSION_MAJOR); - if (version_major != NULL && version_major[0] == '1') { - fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); - abort(); - } - } + { + const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR); + if (version_major != NULL && version_major[0] == '1') { + fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); + abort(); + } + } #endif - const int profile_mask = + const int profile_mask = #if defined(WITH_GL_PROFILE_CORE) - GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + GLX_CONTEXT_CORE_PROFILE_BIT_ARB; #elif defined(WITH_GL_PROFILE_COMPAT) - GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #else -# error // must specify either core or compat at build time +# error // must specify either core or compat at build time #endif - GHOST_Context *context; - - for (int minor = 5; minor >= 0; --minor) { - context = new GHOST_ContextGLX( - m_wantStereoVisual, - m_wantNumOfAASamples, - m_window, - m_display, - (GLXFBConfig)m_fbconfig, - profile_mask, - 4, minor, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - } - - context = new GHOST_ContextGLX( - m_wantStereoVisual, - m_wantNumOfAASamples, - m_window, - m_display, - (GLXFBConfig)m_fbconfig, - profile_mask, - 3, 3, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) - return context; - else - delete context; - - /* Ugly, but we get crashes unless a whole bunch of systems are patched. */ - fprintf(stderr, "Error! Unsupported graphics card or driver.\n"); - fprintf(stderr, "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"); - fprintf(stderr, "The program will now close.\n"); - fflush(stderr); - exit(1); - } - - return NULL; + GHOST_Context *context; + + for (int minor = 5; minor >= 0; --minor) { + context = new GHOST_ContextGLX(m_wantStereoVisual, + m_wantNumOfAASamples, + m_window, + m_display, + (GLXFBConfig)m_fbconfig, + profile_mask, + 4, + minor, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + } + + context = new GHOST_ContextGLX(m_wantStereoVisual, + m_wantNumOfAASamples, + m_window, + m_display, + (GLXFBConfig)m_fbconfig, + profile_mask, + 3, + 3, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + + /* Ugly, but we get crashes unless a whole bunch of systems are patched. */ + fprintf(stderr, "Error! Unsupported graphics card or driver.\n"); + fprintf(stderr, + "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"); + fprintf(stderr, "The program will now close.\n"); + fflush(stderr); + exit(1); + } + + return NULL; } - -Cursor -GHOST_WindowX11:: -getStandardCursor( - GHOST_TStandardCursor g_cursor) +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; - GtoX(GHOST_kStandardCursorPencil, XC_pencil); break; - GtoX(GHOST_kStandardCursorCopy, XC_arrow); break; - default: - xcursor_id = 0; - } + 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; + GtoX(GHOST_kStandardCursorPencil, XC_pencil); + break; + GtoX(GHOST_kStandardCursorCopy, XC_arrow); + break; + default: + xcursor_id = 0; + } #undef GtoX - if (xcursor_id) { - Cursor xcursor = m_standard_cursors[xcursor_id]; + if (xcursor_id) { + Cursor xcursor = m_standard_cursors[xcursor_id]; - if (!xcursor) { - xcursor = XCreateFontCursor(m_display, xcursor_id); + if (!xcursor) { + xcursor = XCreateFontCursor(m_display, xcursor_id); - m_standard_cursors[xcursor_id] = xcursor; - } + m_standard_cursors[xcursor_id] = xcursor; + } - return xcursor; - } - else { - return None; - } + return xcursor; + } + else { + return None; + } } -Cursor -GHOST_WindowX11:: -getEmptyCursor( - ) { - if (!m_empty_cursor) { - Pixmap blank; - XColor dummy = {0}; - char data[1] = {0}; - - /* make a blank cursor */ - blank = XCreateBitmapFromData( - m_display, - RootWindow(m_display, m_visualInfo->screen), - data, 1, 1 - ); - - m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0); - XFreePixmap(m_display, blank); - } - - return m_empty_cursor; +Cursor GHOST_WindowX11::getEmptyCursor() +{ + if (!m_empty_cursor) { + Pixmap blank; + XColor dummy = {0}; + char data[1] = {0}; + + /* make a blank cursor */ + blank = XCreateBitmapFromData( + m_display, RootWindow(m_display, m_visualInfo->screen), 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) +GHOST_TSuccess GHOST_WindowX11::setWindowCursorVisibility(bool visible) { - Cursor xcursor; - - if (visible) { - if (m_visible_cursor) - xcursor = m_visible_cursor; - else - xcursor = getStandardCursor(getCursorShape() ); - } - else { - xcursor = getEmptyCursor(); - } - - XDefineCursor(m_display, m_window, xcursor); - XFlush(m_display); - - return GHOST_kSuccess; + Cursor xcursor; + + if (visible) { + if (m_visible_cursor) + xcursor = m_visible_cursor; + else + xcursor = getStandardCursor(getCursorShape()); + } + else { + xcursor = getEmptyCursor(); + } + + XDefineCursor(m_display, m_window, xcursor); + XFlush(m_display); + + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -setWindowCursorGrab( - GHOST_TGrabCursorMode mode) +GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode) { - if (mode != GHOST_kGrabDisable) { - if (mode != GHOST_kGrabNormal) { - m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setCursorGrabAccum(0, 0); - - if (mode == GHOST_kGrabHide) - setWindowCursorVisibility(false); - - } + if (mode != GHOST_kGrabDisable) { + if (mode != GHOST_kGrabNormal) { + m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setCursorGrabAccum(0, 0); + + if (mode == GHOST_kGrabHide) + setWindowCursorVisibility(false); + } #ifdef GHOST_X11_GRAB - XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + XGrabPointer(m_display, + m_window, + False, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, + GrabModeAsync, + None, + None, + CurrentTime); #endif - } - else { - if (m_cursorGrab == GHOST_kGrabHide) { - m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - } + } + else { + if (m_cursorGrab == GHOST_kGrabHide) { + m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + } - if (m_cursorGrab != GHOST_kGrabNormal) { - /* use to generate a mouse move event, otherwise the last event - * blender gets can be outside the screen causing menus not to show - * properly unless the user moves the mouse */ + if (m_cursorGrab != GHOST_kGrabNormal) { + /* use to generate a mouse move event, otherwise the last event + * blender gets can be outside the screen causing menus not to show + * properly unless the user moves the mouse */ #if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP) - if ((m_system->m_xinput_version.present) && - (m_system->m_xinput_version.major_version >= 2)) - { - int device_id; - if (XIGetClientPointer(m_display, None, &device_id) != False) { - XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, 0, 0); - } - } - else + if ((m_system->m_xinput_version.present) && + (m_system->m_xinput_version.major_version >= 2)) { + int device_id; + if (XIGetClientPointer(m_display, None, &device_id) != False) { + XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, 0, 0); + } + } + else #endif - { - XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0); - } - } - - /* Perform this last so to workaround XWayland bug, see: T53004. */ - if (m_cursorGrab == GHOST_kGrabHide) { - setWindowCursorVisibility(true); - } - - /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - setCursorGrabAccum(0, 0); - m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ + { + XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0); + } + } + + /* Perform this last so to workaround XWayland bug, see: T53004. */ + if (m_cursorGrab == GHOST_kGrabHide) { + setWindowCursorVisibility(true); + } + + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); + m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ #ifdef GHOST_X11_GRAB - XUngrabPointer(m_display, CurrentTime); + XUngrabPointer(m_display, CurrentTime); #endif - } + } - XFlush(m_display); + XFlush(m_display); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -setWindowCursorShape( - GHOST_TStandardCursor shape) +GHOST_TSuccess GHOST_WindowX11::setWindowCursorShape(GHOST_TStandardCursor shape) { - Cursor xcursor = getStandardCursor(shape); + Cursor xcursor = getStandardCursor(shape); - m_visible_cursor = xcursor; + m_visible_cursor = xcursor; - XDefineCursor(m_display, m_window, xcursor); - XFlush(m_display); + XDefineCursor(m_display, m_window, xcursor); + XFlush(m_display); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -setWindowCustomCursorShape( - GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], - int hotX, - int hotY) +GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) { - setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, - 16, 16, hotX, hotY, 0, 1); - return GHOST_kSuccess; + setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1); + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -setWindowCustomCursorShape( - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - int /*fg_color*/, - int /*bg_color*/) +GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int /*fg_color*/, + int /*bg_color*/) { - Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen); - Pixmap bitmap_pix, mask_pix; - XColor fg, bg; + Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen); + Pixmap bitmap_pix, mask_pix; + XColor fg, bg; - if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure; - if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure; + if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) + return GHOST_kFailure; + if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) + return GHOST_kFailure; - if (m_custom_cursor) { - XFreeCursor(m_display, m_custom_cursor); - } + if (m_custom_cursor) { + XFreeCursor(m_display, m_custom_cursor); + } - bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey); - mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey); + bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *)bitmap, sizex, sizey); + mask_pix = XCreateBitmapFromData(m_display, m_window, (char *)mask, sizex, sizey); - 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); + 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); - m_visible_cursor = m_custom_cursor; + m_visible_cursor = m_custom_cursor; - XFreePixmap(m_display, bitmap_pix); - XFreePixmap(m_display, mask_pix); + XFreePixmap(m_display, bitmap_pix); + XFreePixmap(m_display, mask_pix); - XFreeColors(m_display, colormap, &fg.pixel, 1, 0L); - XFreeColors(m_display, colormap, &bg.pixel, 1, 0L); + XFreeColors(m_display, colormap, &fg.pixel, 1, 0L); + XFreeColors(m_display, colormap, &bg.pixel, 1, 0L); - return GHOST_kSuccess; + return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_WindowX11:: -beginFullScreen() const +GHOST_TSuccess GHOST_WindowX11::beginFullScreen() const { - { - Window root_return; - int x_return, y_return; - unsigned int w_return, h_return, border_w_return, depth_return; - - XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return, - &w_return, &h_return, &border_w_return, &depth_return); - - m_system->setCursorPosition(w_return / 2, h_return / 2); - } - - - /* Grab Keyboard & Mouse */ - int err; - - err = XGrabKeyboard(m_display, m_window, False, - GrabModeAsync, GrabModeAsync, CurrentTime); - if (err != GrabSuccess) printf("XGrabKeyboard failed %d\n", err); - - err = XGrabPointer(m_display, m_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); - if (err != GrabSuccess) printf("XGrabPointer failed %d\n", err); - - return GHOST_kSuccess; + { + Window root_return; + int x_return, y_return; + unsigned int w_return, h_return, border_w_return, depth_return; + + XGetGeometry(m_display, + m_window, + &root_return, + &x_return, + &y_return, + &w_return, + &h_return, + &border_w_return, + &depth_return); + + m_system->setCursorPosition(w_return / 2, h_return / 2); + } + + /* Grab Keyboard & Mouse */ + int err; + + err = XGrabKeyboard(m_display, m_window, False, GrabModeAsync, GrabModeAsync, CurrentTime); + if (err != GrabSuccess) + printf("XGrabKeyboard failed %d\n", err); + + err = XGrabPointer(m_display, + m_window, + False, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, + GrabModeAsync, + m_window, + None, + CurrentTime); + if (err != GrabSuccess) + printf("XGrabPointer failed %d\n", err); + + return GHOST_kSuccess; } -GHOST_TSuccess -GHOST_WindowX11:: -endFullScreen() const +GHOST_TSuccess GHOST_WindowX11::endFullScreen() const { - XUngrabKeyboard(m_display, CurrentTime); - XUngrabPointer(m_display, CurrentTime); + XUngrabKeyboard(m_display, CurrentTime); + XUngrabPointer(m_display, CurrentTime); - return GHOST_kSuccess; + return GHOST_kSuccess; } -GHOST_TUns16 -GHOST_WindowX11:: -getDPIHint() +GHOST_TUns16 GHOST_WindowX11::getDPIHint() { - /* Try to read DPI setting set using xrdb */ - char* resMan = XResourceManagerString(m_display); - if (resMan) { - XrmDatabase xrdb = XrmGetStringDatabase(resMan); - if (xrdb) { - char* type = NULL; - XrmValue val; - - int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val); - if (success && type) { - if (strcmp(type, "String") == 0) { - return atoi((char*)val.addr); - } - } - } - XrmDestroyDatabase(xrdb); - } - - /* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */ - XWindowAttributes attr; - if (!XGetWindowAttributes(m_display, m_window, &attr)) { - /* Failed to get window attributes, return X11 default DPI */ - return 96; - } - - Screen* screen = attr.screen; - int pixelWidth = WidthOfScreen(screen); - int pixelHeight = HeightOfScreen(screen); - int mmWidth = WidthMMOfScreen(screen); - int mmHeight = HeightMMOfScreen(screen); - - double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight)); - double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight)); - float inchDiagonal = mmDiagonal * 0.039f; - int dpi = pixelDiagonal / inchDiagonal; - return dpi; + /* Try to read DPI setting set using xrdb */ + char *resMan = XResourceManagerString(m_display); + if (resMan) { + XrmDatabase xrdb = XrmGetStringDatabase(resMan); + if (xrdb) { + char *type = NULL; + XrmValue val; + + int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val); + if (success && type) { + if (strcmp(type, "String") == 0) { + return atoi((char *)val.addr); + } + } + } + XrmDestroyDatabase(xrdb); + } + + /* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */ + XWindowAttributes attr; + if (!XGetWindowAttributes(m_display, m_window, &attr)) { + /* Failed to get window attributes, return X11 default DPI */ + return 96; + } + + Screen *screen = attr.screen; + int pixelWidth = WidthOfScreen(screen); + int pixelHeight = HeightOfScreen(screen); + int mmWidth = WidthMMOfScreen(screen); + int mmHeight = HeightMMOfScreen(screen); + + double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight)); + double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight)); + float inchDiagonal = mmDiagonal * 0.039f; + int dpi = pixelDiagonal / inchDiagonal; + return dpi; } GHOST_TSuccess GHOST_WindowX11::setProgressBar(float progress) { - if (m_taskbar.is_valid()) { - m_taskbar.set_progress(progress); - m_taskbar.set_progress_enabled(true); - return GHOST_kSuccess; - } + if (m_taskbar.is_valid()) { + m_taskbar.set_progress(progress); + m_taskbar.set_progress_enabled(true); + return GHOST_kSuccess; + } - return GHOST_kFailure; + return GHOST_kFailure; } GHOST_TSuccess GHOST_WindowX11::endProgressBar() { - if (m_taskbar.is_valid()) { - m_taskbar.set_progress_enabled(false); - return GHOST_kSuccess; - } + if (m_taskbar.is_valid()) { + m_taskbar.set_progress_enabled(false); + return GHOST_kSuccess; + } - return GHOST_kFailure; + return GHOST_kFailure; } diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 29f4f212e1e..8378a8b5ef8 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -49,327 +49,258 @@ class GHOST_DropTargetX11; * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. */ -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 parentWindow Parent (embedder) window - * \param type The type of drawing context installed in this window. - * \param stereoVisual Stereo visual for quad buffered stereo. - * \param alphaBackground Enable alpha blending of window with display background - * \param numOfAASamples Number of samples used for AA (zero if no AA) - */ - 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, - const GHOST_TEmbedderWindowID parentWindow, - GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, - const bool stereoVisual = false, - const bool exclusive = false, - const bool alphaBackground = false, - const GHOST_TUns16 numOfAASamples = 0, - const bool is_debug = 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 - invalidate( - ); - - GHOST_TSuccess setProgressBar(float progress); - GHOST_TSuccess endProgressBar(); - - /** - * Destructor. - * Closes the window and disposes resources allocated. - */ - ~GHOST_WindowX11(); - - /** - * \section x11specific 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( - ); +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 parentWindow Parent (embedder) window + * \param type The type of drawing context installed in this window. + * \param stereoVisual Stereo visual for quad buffered stereo. + * \param alphaBackground Enable alpha blending of window with display background + * \param numOfAASamples Number of samples used for AA (zero if no AA) + */ + 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, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, + const bool stereoVisual = false, + const bool exclusive = false, + const bool alphaBackground = false, + const GHOST_TUns16 numOfAASamples = 0, + const bool is_debug = 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 invalidate(); + + GHOST_TSuccess setProgressBar(float progress); + GHOST_TSuccess endProgressBar(); + + /** + * Destructor. + * Closes the window and disposes resources allocated. + */ + ~GHOST_WindowX11(); + + /** + * \section x11specific 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(); #ifdef WITH_X11_XINPUT - GHOST_TabletData *GetTabletData() - { - return &m_tabletData; - } -#else // WITH_X11_XINPUT - const GHOST_TabletData *GetTabletData() - { - return NULL; - } -#endif // WITH_X11_XINPUT + GHOST_TabletData *GetTabletData() + { + return &m_tabletData; + } +#else // WITH_X11_XINPUT + const GHOST_TabletData *GetTabletData() + { + return NULL; + } +#endif // WITH_X11_XINPUT #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - XIC getX11_XIC() { - return m_xic; - } + XIC getX11_XIC() + { + return m_xic; + } - bool createX11_XIC(); + bool createX11_XIC(); #endif #ifdef WITH_X11_XINPUT - void refreshXInputDevices(); + void refreshXInputDevices(); #endif #ifdef WITH_XDND - GHOST_DropTargetX11 *getDropTarget() - { - return m_dropTarget; - } + GHOST_DropTargetX11 *getDropTarget() + { + return m_dropTarget; + } #endif - /* - * Need this in case that we want start the window - * in FullScree or Maximized state. - * Check GHOST_WindowX11.cpp - */ - bool m_post_init; - GHOST_TWindowState m_post_state; - - GHOST_TSuccess beginFullScreen() const; - - GHOST_TSuccess endFullScreen() const; - - GHOST_TUns16 getDPIHint(); - -protected: - /** - * \param type The type of rendering context create. - * \return Indication of success. - */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); - - /** - * Sets the cursor visibility on the window using - * native window system calls. - */ - GHOST_TSuccess - setWindowCursorVisibility( - bool visible - ); - - /** - * Sets the cursor grab on the window using - * native window system calls. - */ - GHOST_TSuccess - setWindowCursorGrab( - GHOST_TGrabCursorMode mode - ); - - GHOST_TGrabCursorMode - getWindowCursorGrab() const; - - /** - * 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 - ); - - /** - * Sets the cursor shape on the window using - * native window system calls (Arbitrary size/color). - */ - GHOST_TSuccess - setWindowCustomCursorShape( - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - int fg_color, - int bg_color - ); - -private: - - /// Force use of public constructor. - - GHOST_WindowX11( - ); - - GHOST_WindowX11( - const GHOST_WindowX11 & - ); - - Cursor - getStandardCursor( - GHOST_TStandardCursor g_cursor - ); - - Cursor - getEmptyCursor( - ); - - Window m_window; - Display *m_display; - XVisualInfo *m_visualInfo; - void *m_fbconfig; - - GHOST_TWindowState m_normal_state; - - /** A pointer to the typed system class. */ - GHOST_SystemX11 *m_system; - - /** 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; - - /** XCursor to show when cursor is visible */ - Cursor m_visible_cursor; - - /** Cache of XC_* ID's to XCursor structures */ - std::map<unsigned int, Cursor> m_standard_cursors; - - GHOST_TaskBarX11 m_taskbar; + /* + * Need this in case that we want start the window + * in FullScree or Maximized state. + * Check GHOST_WindowX11.cpp + */ + bool m_post_init; + GHOST_TWindowState m_post_state; + + GHOST_TSuccess beginFullScreen() const; + + GHOST_TSuccess endFullScreen() const; + + GHOST_TUns16 getDPIHint(); + + protected: + /** + * \param type The type of rendering context create. + * \return Indication of success. + */ + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); + + /** + * Sets the cursor visibility on the window using + * native window system calls. + */ + GHOST_TSuccess setWindowCursorVisibility(bool visible); + + /** + * Sets the cursor grab on the window using + * native window system calls. + */ + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); + + GHOST_TGrabCursorMode getWindowCursorGrab() const; + + /** + * 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); + + /** + * Sets the cursor shape on the window using + * native window system calls (Arbitrary size/color). + */ + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, + int sizey, + int hotX, + int hotY, + int fg_color, + int bg_color); + + private: + /// Force use of public constructor. + + GHOST_WindowX11(); + + GHOST_WindowX11(const GHOST_WindowX11 &); + + Cursor getStandardCursor(GHOST_TStandardCursor g_cursor); + + Cursor getEmptyCursor(); + + Window m_window; + Display *m_display; + XVisualInfo *m_visualInfo; + void *m_fbconfig; + + GHOST_TWindowState m_normal_state; + + /** A pointer to the typed system class. */ + GHOST_SystemX11 *m_system; + + /** 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; + + /** XCursor to show when cursor is visible */ + Cursor m_visible_cursor; + + /** Cache of XC_* ID's to XCursor structures */ + std::map<unsigned int, Cursor> m_standard_cursors; + + GHOST_TaskBarX11 m_taskbar; #ifdef WITH_XDND - GHOST_DropTargetX11 *m_dropTarget; + GHOST_DropTargetX11 *m_dropTarget; #endif #ifdef WITH_X11_XINPUT - GHOST_TabletData m_tabletData; + GHOST_TabletData m_tabletData; #endif #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) - XIC m_xic; + XIC m_xic; #endif - bool m_valid_setup; - bool m_is_debug_context; + bool m_valid_setup; + bool m_is_debug_context; - void icccmSetState(int state); - int icccmGetState() const; + void icccmSetState(int state); + int icccmGetState() const; - void netwmMaximized(bool set); - bool netwmIsMaximized() const; + void netwmMaximized(bool set); + bool netwmIsMaximized() const; - void netwmFullScreen(bool set); - bool netwmIsFullScreen() const; + void netwmFullScreen(bool set); + bool netwmIsFullScreen() const; - void motifFullScreen(bool set); - bool motifIsFullScreen() const; + void motifFullScreen(bool set); + bool motifIsFullScreen() const; }; -#endif // __GHOST_WINDOWX11_H__ +#endif // __GHOST_WINDOWX11_H__ diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt index 9f714ae4fba..a5a41209603 100644 --- a/intern/ghost/test/CMakeLists.txt +++ b/intern/ghost/test/CMakeLists.txt @@ -14,43 +14,43 @@ set(WITH_GUARDEDALLOC ON) # stub macro, does nothing macro(blender_add_lib - name - sources - includes - includes_sys - ) + name + sources + includes + includes_sys + ) endmacro() # suffix relative paths so we can use external cmake files macro(suffix_relpaths - new_files files prefix) - - set(${new_files}) - foreach(_file ${files}) - if(IS_ABSOLUTE _file) - list(APPEND ${new_files} ${_file}) - else() - list(APPEND ${new_files} "${prefix}${_file}") - endif() - endforeach() - unset(_file) + new_files files prefix) + + set(${new_files}) + foreach(_file ${files}) + if(IS_ABSOLUTE _file) + list(APPEND ${new_files} ${_file}) + else() + list(APPEND ${new_files} "${prefix}${_file}") + endif() + endforeach() + unset(_file) endmacro() macro(data_to_c file_from file_to list_to_add) - list(APPEND ${list_to_add} ${file_to}) + list(APPEND ${list_to_add} ${file_to}) - get_filename_component(_file_to_path ${file_to} PATH) + get_filename_component(_file_to_path ${file_to} PATH) - add_custom_command( - OUTPUT ${file_to} - COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path} - COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to} - DEPENDS ${file_from} datatoc) - unset(_file_to_path) + add_custom_command( + OUTPUT ${file_to} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path} + COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to} + DEPENDS ${file_from} datatoc) + unset(_file_to_path) endmacro() # ----------------------------------------------------------------------------- @@ -58,24 +58,24 @@ endmacro() # set the endian define if(MSVC) - # for some reason this fails on msvc - add_definitions(-D__LITTLE_ENDIAN__) + # for some reason this fails on msvc + add_definitions(-D__LITTLE_ENDIAN__) else() - include(TestBigEndian) - test_big_endian(_SYSTEM_BIG_ENDIAN) - if(_SYSTEM_BIG_ENDIAN) - add_definitions(-D__BIG_ENDIAN__) - else() - add_definitions(-D__LITTLE_ENDIAN__) - endif() - unset(_SYSTEM_BIG_ENDIAN) + include(TestBigEndian) + test_big_endian(_SYSTEM_BIG_ENDIAN) + if(_SYSTEM_BIG_ENDIAN) + add_definitions(-D__BIG_ENDIAN__) + else() + add_definitions(-D__LITTLE_ENDIAN__) + endif() + unset(_SYSTEM_BIG_ENDIAN) endif() # ----------------------------------------------------------------------------- # Libraries if(UNIX AND NOT APPLE) - set(WITH_X11 ON) + set(WITH_X11 ON) endif() # for now... default to this add_definitions(-DWITH_GL_PROFILE_COMPAT) @@ -126,27 +126,27 @@ add_library(glewmx_lib ${SRC_NEW}) # grr, blenfont needs BLI include_directories( - "../../../source/blender/blenlib" - ) + "../../../source/blender/blenlib" + ) add_library(bli_lib - "../../../source/blender/blenlib/intern/fileops.c" - "../../../source/blender/blenlib/intern/gsqueue.c" - "../../../source/blender/blenlib/intern/rct.c" - "../../../source/blender/blenlib/intern/string.c" - "../../../source/blender/blenlib/intern/string_utf8.c" - "../../../source/blender/blenlib/intern/listbase.c" - "../../../source/blender/blenlib/intern/math_color.c" - "../../../source/blender/blenlib/intern/storage.c" - "../../../source/blender/blenlib/intern/task.c" - "../../../source/blender/blenlib/intern/threads.c" - "../../../source/blender/blenlib/intern/time.c" - "../../../source/blender/blenlib/intern/path_util.c" - "../../../source/blender/blenlib/intern/BLI_dynstr.c" - "../../../source/blender/blenlib/intern/BLI_linklist.c" - "../../../source/blender/blenlib/intern/BLI_memarena.c" - "../../../source/blender/blenlib/intern/BLI_mempool.c" - "../../../source/blender/blenlib/intern/system.c" - ) + "../../../source/blender/blenlib/intern/fileops.c" + "../../../source/blender/blenlib/intern/gsqueue.c" + "../../../source/blender/blenlib/intern/rct.c" + "../../../source/blender/blenlib/intern/string.c" + "../../../source/blender/blenlib/intern/string_utf8.c" + "../../../source/blender/blenlib/intern/listbase.c" + "../../../source/blender/blenlib/intern/math_color.c" + "../../../source/blender/blenlib/intern/storage.c" + "../../../source/blender/blenlib/intern/task.c" + "../../../source/blender/blenlib/intern/threads.c" + "../../../source/blender/blenlib/intern/time.c" + "../../../source/blender/blenlib/intern/path_util.c" + "../../../source/blender/blenlib/intern/BLI_dynstr.c" + "../../../source/blender/blenlib/intern/BLI_linklist.c" + "../../../source/blender/blenlib/intern/BLI_memarena.c" + "../../../source/blender/blenlib/intern/BLI_mempool.c" + "../../../source/blender/blenlib/intern/system.c" + ) set(PLATFORM_CGLAGS) @@ -162,26 +162,26 @@ include_directories(${FREETYPE_INCLUDE_DIRS}) include_directories(${CMAKE_SOURCE_DIR}/../../../source/blender/blenfont) if(CMAKE_COMPILER_IS_GNUCC) - set(PLATFORM_CFLAGS "-funsigned-char") + set(PLATFORM_CFLAGS "-funsigned-char") endif() if(UNIX AND NOT APPLE) - find_package(X11 REQUIRED) - find_package(GLEW) - - if(NOT GLEW_FOUND) - message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW") - endif() - - set(PLATFORM_LINKLIBS - ${X11_X11_LIB} - ${X11_Xinput_LIB} - ${GLEW_LIBRARY} - -lpthread - ) + find_package(X11 REQUIRED) + find_package(GLEW) + + if(NOT GLEW_FOUND) + message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW") + endif() + + set(PLATFORM_LINKLIBS + ${X11_X11_LIB} + ${X11_Xinput_LIB} + ${GLEW_LIBRARY} + -lpthread + ) else() - # set(GLEW_LIBRARY "") # unused - set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include") + # set(GLEW_LIBRARY "") # unused + set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}") @@ -192,34 +192,34 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS}") # DataToC add_executable(datatoc - ${CMAKE_SOURCE_DIR}/../../../source/blender/datatoc/datatoc.c) + ${CMAKE_SOURCE_DIR}/../../../source/blender/datatoc/datatoc.c) # Gears (C) add_executable(gears_c - ${CMAKE_SOURCE_DIR}/gears/GHOST_C-Test.c) + ${CMAKE_SOURCE_DIR}/gears/GHOST_C-Test.c) target_link_libraries(gears_c - ghost_lib - glewmx_lib - string_lib - ${OPENGL_gl_LIBRARY} - ${CMAKE_DL_LIBS} - ${PLATFORM_LINKLIBS} - ) + ghost_lib + glewmx_lib + string_lib + ${OPENGL_gl_LIBRARY} + ${CMAKE_DL_LIBS} + ${PLATFORM_LINKLIBS} + ) # Gears (C++) add_executable(gears_cpp - ${CMAKE_SOURCE_DIR}/gears/GHOST_Test.cpp) + ${CMAKE_SOURCE_DIR}/gears/GHOST_Test.cpp) target_link_libraries(gears_cpp - ghost_lib - glewmx_lib - string_lib - ${OPENGL_gl_LIBRARY} - ${CMAKE_DL_LIBS} - ${PLATFORM_LINKLIBS} - ) + ghost_lib + glewmx_lib + string_lib + ${OPENGL_gl_LIBRARY} + ${CMAKE_DL_LIBS} + ${PLATFORM_LINKLIBS} + ) # MultiTest (C) @@ -228,28 +228,28 @@ data_to_c(${CMAKE_SOURCE_DIR}/../../../release/datafiles/bfont.ttf ${CMAKE_CURRENT_BINARY_DIR}/bfont.ttf.c data_to_c_files) add_executable(multitest_c - ${CMAKE_SOURCE_DIR}/multitest/Basic.c - ${CMAKE_SOURCE_DIR}/multitest/EventToBuf.c - ${CMAKE_SOURCE_DIR}/multitest/MultiTest.c - ${CMAKE_SOURCE_DIR}/multitest/ScrollBar.c - ${CMAKE_SOURCE_DIR}/multitest/Util.c - ${CMAKE_SOURCE_DIR}/multitest/WindowData.c - ${CMAKE_SOURCE_DIR}/multitest/stubs.c - ${data_to_c_files} + ${CMAKE_SOURCE_DIR}/multitest/Basic.c + ${CMAKE_SOURCE_DIR}/multitest/EventToBuf.c + ${CMAKE_SOURCE_DIR}/multitest/MultiTest.c + ${CMAKE_SOURCE_DIR}/multitest/ScrollBar.c + ${CMAKE_SOURCE_DIR}/multitest/Util.c + ${CMAKE_SOURCE_DIR}/multitest/WindowData.c + ${CMAKE_SOURCE_DIR}/multitest/stubs.c + ${data_to_c_files} ) target_link_libraries(multitest_c - blenfont_lib - bli_lib - ghost_lib - glewmx_lib - string_lib - guardedalloc_lib - wcwidth_lib - ${OPENGL_gl_LIBRARY} - ${FREETYPE_LIBRARY} - ${ZLIB_LIBRARIES} - ${CMAKE_DL_LIBS} - ${PLATFORM_LINKLIBS} - ) + blenfont_lib + bli_lib + ghost_lib + glewmx_lib + string_lib + guardedalloc_lib + wcwidth_lib + ${OPENGL_gl_LIBRARY} + ${FREETYPE_LIBRARY} + ${ZLIB_LIBRARIES} + ${CMAKE_DL_LIBS} + ${PLATFORM_LINKLIBS} + ) diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c index b308ac61e57..80675ac5e3d 100644 --- a/intern/ghost/test/gears/GHOST_C-Test.c +++ b/intern/ghost/test/gears/GHOST_C-Test.c @@ -39,14 +39,13 @@ # include <windows.h> # include <GL/gl.h> # else /* WIN32 */ - /* __APPLE__ is defined */ +/* __APPLE__ is defined */ # include <AGL/gl.h> # endif /* WIN32 */ -#else /* defined(WIN32) || defined(__APPLE__) */ +#else /* defined(WIN32) || defined(__APPLE__) */ # include <GL/gl.h> #endif /* defined(WIN32) || defined(__APPLE__) */ - static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time); int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData); @@ -63,472 +62,454 @@ static GHOST_TimerTaskHandle sGearsTimer; static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) { - printf("timer1, time=%d\n", (int)time); + printf("timer1, time=%d\n", (int)time); } - -static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth) +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(); + 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 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(); + 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_RectangleHandle hRect = NULL; + GLfloat w, h; - GHOST_ActivateWindowDrawingContext(hWindow); - hRect = GHOST_GetClientBounds(hWindow); + GHOST_ActivateWindowDrawingContext(hWindow); + hRect = GHOST_GetClientBounds(hWindow); - w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect); - h = 1.0; + w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect); + h = 1.0; - glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect)); + 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); + 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); + glClearColor(.2f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); - GHOST_DisposeRectangle(hRect); + GHOST_DisposeRectangle(hRect); } - - int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData) { - int handled = 1; - int cursor; - int visibility; - GHOST_TEventKeyData *keyData = NULL; - GHOST_TEventWheelData *wheelData = NULL; - GHOST_DisplaySetting setting; - GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); - - switch (GHOST_GetEventType(hEvent)) - { + int handled = 1; + int cursor; + int visibility; + GHOST_TEventKeyData *keyData = NULL; + GHOST_TEventWheelData *wheelData = NULL; + GHOST_DisplaySetting setting; + GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); + + switch (GHOST_GetEventType(hEvent)) { #if 0 - case GHOST_kEventUnknown: - break; - case GHOST_kEventCursorButton: - break; - case GHOST_kEventCursorMove: - break; + case GHOST_kEventUnknown: + break; + case GHOST_kEventCursorButton: + break; + case GHOST_kEventCursorMove: + break; #endif - case GHOST_kEventWheel: - { - wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent); - if (wheelData->z > 0) - { - view_rotz += 5.f; - } - else { - view_rotz -= 5.f; - } - } - 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 window2 = GHOST_GetEventWindow(hEvent); - if (window2 == sMainWindow) - { - sExitRequested = 1; - } - else { - if (sGearsTimer) - { - GHOST_RemoveTimer(shSystem, sGearsTimer); - sGearsTimer = 0; - } - GHOST_DisposeWindow(shSystem, window2); - } - } - break; - - case GHOST_kEventWindowActivate: - handled = 0; - break; - case GHOST_kEventWindowDeactivate: - handled = 0; - break; - case GHOST_kEventWindowUpdate: - { - GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent); - if (!GHOST_ValidWindow(shSystem, window2)) - break; - setViewPortGL(window2); - drawGL(); - GHOST_SwapWindowBuffers(window2); - } - break; - - default: - handled = 0; - break; - } - return handled; + case GHOST_kEventWheel: { + wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent); + if (wheelData->z > 0) { + view_rotz += 5.f; + } + else { + view_rotz -= 5.f; + } + } 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 window2 = GHOST_GetEventWindow(hEvent); + if (window2 == sMainWindow) { + sExitRequested = 1; + } + else { + if (sGearsTimer) { + GHOST_RemoveTimer(shSystem, sGearsTimer); + sGearsTimer = 0; + } + GHOST_DisposeWindow(shSystem, window2); + } + } break; + + case GHOST_kEventWindowActivate: + handled = 0; + break; + case GHOST_kEventWindowDeactivate: + handled = 0; + break; + case GHOST_kEventWindowUpdate: { + GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent); + if (!GHOST_ValidWindow(shSystem, window2)) + break; + setViewPortGL(window2); + drawGL(); + GHOST_SwapWindowBuffers(window2); + } break; + + default: + handled = 0; + break; + } + return handled; } - int main(int argc, char **argv) { - GHOST_GLSettings glSettings = {0}; - 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, - glSettings); - 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, - glSettings); - 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)) - { + GHOST_GLSettings glSettings = {0}; + 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, + glSettings); + 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, + glSettings); + 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); + /* 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); - - return 0; + } + 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); + + 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); - } - } + GHOST_WindowHandle hWindow = NULL; + fAngle += 2.0; + view_roty += 1.0; + hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask); + if (GHOST_GetFullScreen(shSystem)) { + /* Running full screen */ + GHOST_InvalidateWindow(sFullScreenWindow); + } + else { + if (GHOST_ValidWindow(shSystem, hWindow)) { + GHOST_InvalidateWindow(hWindow); + } + } } diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp index 23564faf38d..76386fb114a 100644 --- a/intern/ghost/test/gears/GHOST_Test.cpp +++ b/intern/ghost/test/gears/GHOST_Test.cpp @@ -34,13 +34,13 @@ # include <atlbase.h> # include <GL/gl.h> -# else // WIN32 - // __APPLE__ is defined +# else // WIN32 \ + // __APPLE__ is defined # include <AGL/gl.h> -# endif // WIN32 -#else // defined(WIN32) || defined(__APPLE__) +# endif // WIN32 +#else // defined(WIN32) || defined(__APPLE__) # include <GL/gl.h> -#endif // defined(WIN32) || defined(__APPLE__) +#endif // defined(WIN32) || defined(__APPLE__) #include "STR_String.h" #include "GHOST_Rect.h" @@ -49,290 +49,302 @@ #include "GHOST_IEvent.h" #include "GHOST_IEventConsumer.h" - -#define LEFT_EYE 0 +#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 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, +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"; + std::cout << "timer1, time=" << (int)time << "\n"; } - -static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth) +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(); + 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); + 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); + 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(); + 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 = 0; - /* hard coded for testing purposes, display device dependent */ - int verticalBlankingInterval = 32; - float left, right, bottom, top; - float nearplane, farplane, zeroPlane, distance; - float eyeSeparation = 0.62f; - window->getClientBounds(bnds); - - // 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.8f; - top = 4.8f; - 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); + window->activateDrawingContext(); + GHOST_Rect bnds; + int noOfScanlines = 0, lowerScanline = 0; + /* hard coded for testing purposes, display device dependent */ + int verticalBlankingInterval = 32; + float left, right, bottom, top; + float nearplane, farplane, zeroPlane, distance; + float eyeSeparation = 0.62f; + window->getClientBounds(bnds); + + // 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.8f; + top = 4.8f; + 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) +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. * @@ -357,395 +369,380 @@ void StereoProjection(float left, float right, float bottom, float top, float ne * negative for the left eye subfield. */ { - float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, - dx, dy, n_over_d; + float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, dx, dy, n_over_d; - dx = right - left; - dy = top - bottom; + dx = right - left; + dy = top - bottom; - xmid = (right + left) / 2.0; - ymid = (top + bottom) / 2.0; + xmid = (right + left) / 2.0; + ymid = (top + bottom) / 2.0; - clip_near = dist + zero_plane - nearplane; - clip_far = dist + zero_plane - farplane; + clip_near = dist + zero_plane - nearplane; + clip_far = dist + zero_plane - farplane; - n_over_d = clip_near / dist; + 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); + 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); + /* 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; + 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; + 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) + : 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) { - GHOST_GLSettings glSettings = {0}; - 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, - glSettings); - - 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, - glSettings); - if (!m_secondaryWindow) { - std::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); + GHOST_GLSettings glSettings = {0}; + 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, + glSettings); + + 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, + glSettings); + if (!m_secondaryWindow) { + std::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); - } + // 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; + GHOST_IWindow *window = event->getWindow(); + bool handled = true; - switch (event->getType()) { + switch (event->getType()) { #if 0 - case GHOST_kEventUnknown: - break; - case GHOST_kEventCursorButton: - std::cout << "GHOST_kEventCursorButton"; break; - case GHOST_kEventCursorMove: - std::cout << "GHOST_kEventCursorMove"; break; + case GHOST_kEventUnknown: + break; + case GHOST_kEventCursorButton: + std::cout << "GHOST_kEventCursorButton"; break; + case GHOST_kEventCursorMove: + std::cout << "GHOST_kEventCursorMove"; break; #endif - case GHOST_kEventWheel: - { - GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *) event->getData(); - if (wheelData->z > 0) - { - view_rotz += 5.f; - } - else { - view_rotz -= 5.f; - } - } - 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 *window2 = event->getWindow(); - if (window2 == m_mainWindow) { - m_exitRequested = true; - } - else { - m_system->disposeWindow(window2); - } - } - break; - - case GHOST_kEventWindowActivate: - handled = false; - break; - - case GHOST_kEventWindowDeactivate: - handled = false; - break; - - case GHOST_kEventWindowUpdate: - { - GHOST_IWindow *window2 = event->getWindow(); - if (!m_system->validWindow(window2)) - break; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (stereo) - { - View(window2, stereo, LEFT_EYE); - glPushMatrix(); - RenderCamera(); - RenderScene(); - glPopMatrix(); - - View(window2, stereo, RIGHT_EYE); - glPushMatrix(); - RenderCamera(); - RenderScene(); - glPopMatrix(); - } - else { - View(window2, stereo); - glPushMatrix(); - RenderCamera(); - RenderScene(); - glPopMatrix(); - } - window2->swapBuffers(); - } - break; - - default: - handled = false; - break; - } - return handled; + case GHOST_kEventWheel: { + GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *)event->getData(); + if (wheelData->z > 0) { + view_rotz += 5.f; + } + else { + view_rotz -= 5.f; + } + } 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 *window2 = event->getWindow(); + if (window2 == m_mainWindow) { + m_exitRequested = true; + } + else { + m_system->disposeWindow(window2); + } + } break; + + case GHOST_kEventWindowActivate: + handled = false; + break; + + case GHOST_kEventWindowDeactivate: + handled = false; + break; + + case GHOST_kEventWindowUpdate: { + GHOST_IWindow *window2 = event->getWindow(); + if (!m_system->validWindow(window2)) + break; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (stereo) { + View(window2, stereo, LEFT_EYE); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + + View(window2, stereo, RIGHT_EYE); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + } + else { + View(window2, stereo); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + } + window2->swapBuffers(); + } break; + + default: + handled = false; + break; + } + return handled; } - int main(int /*argc*/, char ** /*argv*/) { - nVidiaWindows = false; -// nVidiaWindows = true; + 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("Successfully opened key\n"); -#if 0 - lresult = regkey.QueryValue(&keyValue, "StereoEnable"); - if (lresult == ERROR_SUCCESS) - printf("Successfully queried key\n"); -#endif - lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", - "1"); - if (lresult == ERROR_SUCCESS) - printf("Successfully set value for key\n"); - regkey.Close(); - if (lresult == ERROR_SUCCESS) - printf("Successfully closed key\n"); -// regkey.Write("2"); - } + /* 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("Successfully opened key\n"); +# if 0 + lresult = regkey.QueryValue(&keyValue, "StereoEnable"); + if (lresult == ERROR_SUCCESS) + printf("Successfully queried key\n"); +# endif + lresult = regkey.SetValue( + HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", "1"); + if (lresult == ERROR_SUCCESS) + printf("Successfully set value for key\n"); + regkey.Close(); + if (lresult == ERROR_SUCCESS) + printf("Successfully closed key\n"); + // regkey.Write("2"); + } #endif // WIN32 - // Create the system - GHOST_ISystem::createSystem(); - fSystem = GHOST_ISystem::getSystem(); + // Create the system + GHOST_ISystem::createSystem(); + fSystem = GHOST_ISystem::getSystem(); - if (fSystem) { - // Create an application object - Application app(fSystem); + if (fSystem) { + // Create an application object + Application app(fSystem); - // Add the application as event consumer - fSystem->addEventConsumer(&app); + // 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(); - } + // Enter main loop + while (!app.m_exitRequested) { + //printf("main: loop\n"); + fSystem->processEvents(true); + fSystem->dispatchEvents(); + } - // Remove so ghost doesn't do a double free - fSystem->removeEventConsumer(&app); - } + // Remove so ghost doesn't do a double free + fSystem->removeEventConsumer(&app); + } - // Dispose the system - GHOST_ISystem::disposeSystem(); + // Dispose the system + GHOST_ISystem::disposeSystem(); - return 0; + 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(); - } - } + fAngle += 2.0; + view_roty += 1.0; + GHOST_IWindow *window = (GHOST_IWindow *)task->getUserData(); + if (fApp->m_fullScreenWindow) { + // Running full screen + fApp->m_fullScreenWindow->invalidate(); + } + else { + if (fSystem->validWindow(window)) { + window->invalidate(); + } + } } diff --git a/intern/ghost/test/multitest/Basic.c b/intern/ghost/test/multitest/Basic.c index 17f1fc0de48..670c7583fe5 100644 --- a/intern/ghost/test/multitest/Basic.c +++ b/intern/ghost/test/multitest/Basic.c @@ -21,45 +21,45 @@ int min_i(int a, int b) { - return (a < b) ? a : b; + return (a < b) ? a : b; } int max_i(int a, int b) { - return (b < a) ? a : b; + return (b < a) ? a : b; } int clamp_i(int val, int min, int max) { - return min_i(max_i(val, min), max); + return min_i(max_i(val, min), max); } float min_f(float a, float b) { - return (a < b) ? a : b; + return (a < b) ? a : b; } float max_f(float a, float b) { - return (b < a) ? a : b; + return (b < a) ? a : b; } float clamp_f(float val, float min, float max) { - return min_f(max_f(val, min), 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]; + 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])); + 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]); + return (rect[1][0] - rect[0][0]); } int rect_height(int rect[2][2]) { - return (rect[1][1] - rect[0][1]); + return (rect[1][1] - rect[0][1]); } diff --git a/intern/ghost/test/multitest/Basic.h b/intern/ghost/test/multitest/Basic.h index 16af83be8dd..1557be8433e 100644 --- a/intern/ghost/test/multitest/Basic.h +++ b/intern/ghost/test/multitest/Basic.h @@ -17,16 +17,16 @@ * All rights reserved. */ -int min_i (int a, int b); +int min_i(int a, int b); -int max_i (int a, int b); -int clamp_i (int val, int min, int max); +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); +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]); +void rect_copy(int dst[2][2], int src[2][2]); +int rect_contains_pt(int rect[2][2], int pt[2]); +int rect_width(int rect[2][2]); +int rect_height(int rect[2][2]); diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c index 4edebec8066..5aee8a50a8d 100644 --- a/intern/ghost/test/multitest/EventToBuf.c +++ b/intern/ghost/test/multitest/EventToBuf.c @@ -28,204 +28,215 @@ 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>"; - } + 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(KeyOS); - - 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"; - } +#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(KeyOS); + + 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; - } - } + GHOST_TEventType type = GHOST_GetEventType(evt); + double time = (double)((GHOST_TInt64)GHOST_GetEventTime(evt)) / 1000; + GHOST_WindowHandle win = GHOST_GetEventWindow(evt); + void *data = GHOST_GetEventData(evt); + char *pos = buf; + + pos += sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type)); + if (win) { + char *s = GHOST_GetTitle(win); + pos += sprintf(pos, " - win: %s", s); + free(s); + } + else { + pos += sprintf(pos, " - sys evt"); + } + switch (type) { + case GHOST_kEventCursorMove: { + GHOST_TEventCursorData *cd = data; + pos += sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y); + break; + } + case GHOST_kEventButtonDown: + case GHOST_kEventButtonUp: { + GHOST_TEventButtonData *bd = data; + pos += sprintf(pos, " - but: %d", bd->button); + break; + } + + case GHOST_kEventKeyDown: + case GHOST_kEventKeyUp: { + GHOST_TEventKeyData *kd = data; + pos += sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key); + if (kd->ascii) + pos += sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii); + break; + } + } } diff --git a/intern/ghost/test/multitest/GL.h b/intern/ghost/test/multitest/GL.h index 9afa4e22fdb..2a7d95212e1 100644 --- a/intern/ghost/test/multitest/GL.h +++ b/intern/ghost/test/multitest/GL.h @@ -19,13 +19,13 @@ #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__) +# ifdef WIN32 +# include <windows.h> +# include <GL/gl.h> +# else // WIN32 +// __APPLE__ is defined +# include <AGL/gl.h> +# endif // WIN32 +#else // defined(WIN32) || defined(__APPLE__) +# include <GL/gl.h> +#endif // defined(WIN32) || defined(__APPLE__) diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index 8d6a3e94fb7..25e9f6b2bf1 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -19,7 +19,7 @@ #define FALSE 0 #ifdef _MSC_VER -# pragma warning(disable: 4244 4305) +# pragma warning(disable : 4244 4305) #endif #include <stdlib.h> @@ -68,56 +68,56 @@ void multitestapp_exit(MultiTestApp *app); void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float col[3], int width) { - int ltidx = (side / 2) % 4; - int dkidx = (ltidx + 1 + (side & 1)) % 4; - int i, corner; + 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; + 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); + 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); + 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(); + 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); + 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; + 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; - } + 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); + glGetFloatv(GL_CURRENT_COLOR, col); - rect_bevel_side(rect, 3, lt, dk, col, width); + rect_bevel_side(rect, 3, lt, dk, col, width); - free(lt); - free(dk); + free(lt); + free(dk); } /* @@ -125,218 +125,219 @@ void rect_bevel_smooth(int rect[2][2], int width) */ typedef struct { - MultiTestApp *app; + MultiTestApp *app; - GHOST_WindowHandle win; + GHOST_WindowHandle win; - int size[2]; + int size[2]; - int lmouse[2], lmbut[3]; + int lmouse[2], lmbut[3]; - int tmouse[2]; + int tmouse[2]; } MainWindow; static void mainwindow_log(MainWindow *mw, char *str) { - loggerwindow_log(multitestapp_get_logger(mw->app), str); + loggerwindow_log(multitestapp_get_logger(mw->app), str); } static void mainwindow_do_draw(MainWindow *mw) { - GHOST_ActivateWindowDrawingContext(mw->win); + 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); + 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); + 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); + GHOST_SwapWindowBuffers(mw->win); } static void mainwindow_do_reshape(MainWindow *mw) { - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(mw->win); + GHOST_RectangleHandle bounds = GHOST_GetClientBounds(mw->win); - GHOST_ActivateWindowDrawingContext(mw->win); + GHOST_ActivateWindowDrawingContext(mw->win); - mw->size[0] = GHOST_GetWidthRectangle(bounds); - mw->size[1] = GHOST_GetHeightRectangle(bounds); + mw->size[0] = GHOST_GetWidthRectangle(bounds); + mw->size[1] = GHOST_GetHeightRectangle(bounds); - glViewport(0, 0, mw->size[0], mw->size[1]); + 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_PROJECTION); + glLoadIdentity(); + glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1); + glTranslatef(0.375, 0.375, 0.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + 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; - } + 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; + mw->lmouse[0] = x, mw->lmouse[1] = y; - if (mw->lmbut[0]) { - mw->tmouse[0] = x, mw->tmouse[1] = y; - GHOST_InvalidateWindow(mw->win); - } + 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; - } + 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; - } + 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]; + MainWindow *mw = GHOST_GetTimerTaskUserData(task); + char buf[64]; - sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time) / 1000); - mainwindow_log(mw, buf); + 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; - GHOST_GLSettings glSettings = {0}; + GHOST_SystemHandle sys = multitestapp_get_system(app); + GHOST_WindowHandle win; + GHOST_GLSettings glSettings = {0}; - win = GHOST_CreateWindow( - sys, "MultiTest:Main", - 40, 40, 400, 400, - GHOST_kWindowStateNormal, - GHOST_kDrawingContextTypeOpenGL, - glSettings); + win = GHOST_CreateWindow(sys, + "MultiTest:Main", + 40, + 40, + 400, + 400, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, + glSettings); - if (win) { - MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new"); - mw->app = app; - mw->win = win; + 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_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle)); - GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw); + GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw); - return mw; - } - else { - return NULL; - } + return mw; + } + else { + return NULL; + } } void mainwindow_free(MainWindow *mw) { - GHOST_SystemHandle sys = multitestapp_get_system(mw->app); + GHOST_SystemHandle sys = multitestapp_get_system(mw->app); - windowdata_free(GHOST_GetWindowUserData(mw->win)); - GHOST_DisposeWindow(sys, mw->win); - MEM_freeN(mw); + windowdata_free(GHOST_GetWindowUserData(mw->win)); + GHOST_DisposeWindow(sys, mw->win); + MEM_freeN(mw); } /* @@ -344,29 +345,29 @@ void mainwindow_free(MainWindow *mw) */ struct _LoggerWindow { - MultiTestApp *app; + MultiTestApp *app; - GHOST_WindowHandle win; + GHOST_WindowHandle win; #ifdef USE_BMF - BMF_Font *font; + BMF_Font *font; #else - int font; + int font; #endif - int fonttexid; - int fontheight; + int fonttexid; + int fontheight; - int size[2]; + int size[2]; - int ndisplines; - int textarea[2][2]; - ScrollBar *scroll; + int ndisplines; + int textarea[2][2]; + ScrollBar *scroll; - char **loglines; - int nloglines, logsize; + char **loglines; + int nloglines, logsize; - int lmbut[3]; - int lmouse[2]; + int lmbut[3]; + int lmouse[2]; }; #define SCROLLBAR_PAD 2 @@ -374,443 +375,443 @@ struct _LoggerWindow { #define TEXTAREA_PAD 2 static void loggerwindow_recalc_regions(LoggerWindow *lw) { - int nscroll[2][2]; + 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; + 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->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; + 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); + 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]); + 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_PROJECTION); + glLoadIdentity(); + glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1); + glTranslatef(0.375, 0.375, 0.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); } static void loggerwindow_do_reshape(LoggerWindow *lw) { - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win); + GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win); - GHOST_ActivateWindowDrawingContext(lw->win); + GHOST_ActivateWindowDrawingContext(lw->win); - lw->size[0] = GHOST_GetWidthRectangle(bounds); - lw->size[1] = GHOST_GetHeightRectangle(bounds); + lw->size[0] = GHOST_GetWidthRectangle(bounds); + lw->size[1] = GHOST_GetHeightRectangle(bounds); - loggerwindow_recalc_regions(lw); - loggerwindow_setup_window_gl(lw); + 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]; + int i, ndisplines, startline; + int sb_rect[2][2], sb_thumb[2][2]; - GHOST_ActivateWindowDrawingContext(lw->win); + GHOST_ActivateWindowDrawingContext(lw->win); - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - glColor3f(0.8, 0.8, 0.8); - rect_bevel_smooth(lw->textarea, 4); + 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); + 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); + 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); + 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); + 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); + 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; + 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; #ifdef USE_BMF - 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) { + glRasterPos2i(x_pos, y_pos); + BMF_DrawString(lw->font, line); + } + else { + BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0); + } #else - BLF_position(lw->font, x_pos, y_pos, 0.0); - BLF_draw(lw->font, line, 256); // XXX + BLF_position(lw->font, x_pos, y_pos, 0.0); + BLF_draw(lw->font, line, 256); // XXX #endif - } + } #ifdef USE_BMF - if (lw->fonttexid != -1) { - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - } + if (lw->fonttexid != -1) { + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + } #endif - GHOST_SwapWindowBuffers(lw->win); + GHOST_SwapWindowBuffers(lw->win); } static void loggerwindow_do_move(LoggerWindow *lw, int x, int y) { - lw->lmouse[0] = x, lw->lmouse[1] = 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); - } + 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; - } + 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; - } + 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 *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_GLSettings glSettings = {0}; - 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, - glSettings); - - if (win) { - LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new"); - int bbox[2][2]; - lw->app = app; - lw->win = win; + GHOST_GLSettings glSettings = {0}; + 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, + glSettings); + + if (win) { + LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new"); + int bbox[2][2]; + lw->app = app; + lw->win = win; #ifdef USE_BMF - lw->font = BMF_GetFont(BMF_kScreen12); - lw->fonttexid = BMF_GetFontTexture(lw->font); + 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); + BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]); + lw->fontheight = rect_height(bbox); #else - lw->font = BLF_load_mem("default", (unsigned char *)datatoc_bfont_ttf, datatoc_bfont_ttf_size); - BLF_size(lw->font, 11, 72); - lw->fontheight = BLF_height(lw->font, "A_", 2); + lw->font = BLF_load_mem("default", (unsigned char *)datatoc_bfont_ttf, datatoc_bfont_ttf_size); + BLF_size(lw->font, 11, 72); + lw->fontheight = BLF_height(lw->font, "A_", 2); #endif - lw->nloglines = lw->logsize = 0; - lw->loglines = MEM_mallocN(sizeof(*lw->loglines) * lw->nloglines, "loglines"); + lw->nloglines = lw->logsize = 0; + lw->loglines = MEM_mallocN(sizeof(*lw->loglines) * lw->nloglines, "loglines"); - lw->scroll = scrollbar_new(2, 40); + lw->scroll = scrollbar_new(2, 40); - GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle)); + GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle)); - loggerwindow_do_reshape(lw); + loggerwindow_do_reshape(lw); - return lw; - } - else { - return NULL; - } + 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)); - } + 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); + lw->loglines[lw->nloglines++] = string_dup(line); + scrollbar_set_thumbpct(lw->scroll, (float)lw->ndisplines / lw->nloglines); - GHOST_InvalidateWindow(lw->win); + GHOST_InvalidateWindow(lw->win); } void loggerwindow_free(LoggerWindow *lw) { - GHOST_SystemHandle sys = multitestapp_get_system(lw->app); - int i; + 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); + 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); + windowdata_free(GHOST_GetWindowUserData(lw->win)); + GHOST_DisposeWindow(sys, lw->win); + MEM_freeN(lw); } /* * ExtraWindow */ - typedef struct { - MultiTestApp *app; + MultiTestApp *app; - GHOST_WindowHandle win; + GHOST_WindowHandle win; - int size[2]; + int size[2]; } ExtraWindow; static void extrawindow_do_draw(ExtraWindow *ew) { - GHOST_ActivateWindowDrawingContext(ew->win); + GHOST_ActivateWindowDrawingContext(ew->win); - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + 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); + glColor3f(0.8, 0.8, 0.8); + glRecti(10, 10, ew->size[0] - 10, ew->size[1] - 10); - GHOST_SwapWindowBuffers(ew->win); + GHOST_SwapWindowBuffers(ew->win); } static void extrawindow_do_reshape(ExtraWindow *ew) { - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(ew->win); + GHOST_RectangleHandle bounds = GHOST_GetClientBounds(ew->win); - GHOST_ActivateWindowDrawingContext(ew->win); + GHOST_ActivateWindowDrawingContext(ew->win); - ew->size[0] = GHOST_GetWidthRectangle(bounds); - ew->size[1] = GHOST_GetHeightRectangle(bounds); + ew->size[0] = GHOST_GetWidthRectangle(bounds); + ew->size[1] = GHOST_GetHeightRectangle(bounds); - glViewport(0, 0, ew->size[0], ew->size[1]); + 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_PROJECTION); + glLoadIdentity(); + glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1); + glTranslatef(0.375, 0.375, 0.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + 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; - } + 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; + 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)); + 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; + 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; + 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)); + } + 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)); - } + mask[y][x / 8] |= (1 << (x % 8)); + } - GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0); + 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 *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_GLSettings glSettings = {0}; - GHOST_SystemHandle sys = multitestapp_get_system(app); - GHOST_WindowHandle win; + GHOST_GLSettings glSettings = {0}; + GHOST_SystemHandle sys = multitestapp_get_system(app); + GHOST_WindowHandle win; - win = GHOST_CreateWindow( - sys, "MultiTest:Extra", - 500, 40, 400, 400, - GHOST_kWindowStateNormal, - GHOST_kDrawingContextTypeOpenGL, - glSettings); + win = GHOST_CreateWindow(sys, + "MultiTest:Extra", + 500, + 40, + 400, + 400, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, + glSettings); - if (win) { - ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new"); - ew->app = app; - ew->win = win; + 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)); + GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle)); - return ew; - } - else { - return NULL; - } + return ew; + } + else { + return NULL; + } } void extrawindow_free(ExtraWindow *ew) { - GHOST_SystemHandle sys = multitestapp_get_system(ew->app); + GHOST_SystemHandle sys = multitestapp_get_system(ew->app); - windowdata_free(GHOST_GetWindowUserData(ew->win)); - GHOST_DisposeWindow(sys, ew->win); - MEM_freeN(ew); + windowdata_free(GHOST_GetWindowUserData(ew->win)); + GHOST_DisposeWindow(sys, ew->win); + MEM_freeN(ew); } /* @@ -818,136 +819,139 @@ void extrawindow_free(ExtraWindow *ew) */ struct _MultiTestApp { - GHOST_SystemHandle sys; - MainWindow *main; - LoggerWindow *logger; - ExtraWindow *extra; + GHOST_SystemHandle sys; + MainWindow *main; + LoggerWindow *logger; + ExtraWindow *extra; - int exit; + int exit; }; static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data) { - MultiTestApp *app = data; - GHOST_WindowHandle win; + 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; - } + 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); + if (win) { + WindowData *wb = GHOST_GetWindowUserData(win); - windowdata_handle(wb, evt); - } - else { - GHOST_TEventType type = GHOST_GetEventType(evt); + 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; + /* 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; - } - } + default: + fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type)); + break; + } + } - return 1; + return 1; } /**/ -MultiTestApp *multitestapp_new(void) { - MultiTestApp *app = MEM_mallocN(sizeof(*app), "multitestapp_new"); - GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(multitest_event_handler, app); +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"); + 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 "); + 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->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->logger = loggerwindow_new(app); + if (!app->logger) + fatal("Unable to create logger window"); - app->extra = NULL; - app->exit = 0; + app->extra = NULL; + app->exit = 0; - return app; + return app; } -LoggerWindow *multitestapp_get_logger(MultiTestApp *app) { - return app->logger; +LoggerWindow *multitestapp_get_logger(MultiTestApp *app) +{ + return app->logger; } -GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) { - return app->sys; +GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) +{ + return app->sys; } void multitestapp_free_extrawindow(MultiTestApp *app) { - extrawindow_free(app->extra); - app->extra = NULL; + 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); - } + if (app->extra) { + multitestapp_free_extrawindow(app); + } + else { + app->extra = extrawindow_new(app); + } } void multitestapp_exit(MultiTestApp *app) { - app->exit = 1; + app->exit = 1; } void multitestapp_run(MultiTestApp *app) { - while (!app->exit) { - GHOST_ProcessEvents(app->sys, 1); - GHOST_DispatchEvents(app->sys); - } + 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); + mainwindow_free(app->main); + loggerwindow_free(app->logger); + GHOST_DisposeSystem(app->sys); + MEM_freeN(app); } /***/ int main(int argc, char **argv) { - MultiTestApp *app; + MultiTestApp *app; #ifndef USE_BMF - BLF_init(); + BLF_init(); #endif - app = multitestapp_new(); + app = multitestapp_new(); - multitestapp_run(app); - multitestapp_free(app); + multitestapp_run(app); + multitestapp_free(app); - return 0; + return 0; } diff --git a/intern/ghost/test/multitest/ScrollBar.c b/intern/ghost/test/multitest/ScrollBar.c index fbc3ab2f967..f14e726a077 100644 --- a/intern/ghost/test/multitest/ScrollBar.c +++ b/intern/ghost/test/multitest/ScrollBar.c @@ -27,125 +27,125 @@ #include "ScrollBar.h" struct _ScrollBar { - int rect[2][2]; - float thumbpos, thumbpct; + int rect[2][2]; + float thumbpos, thumbpct; - int inset; - int minthumb; + int inset; + int minthumb; - int scrolling; - float scrolloffs; + int scrolling; + float scrolloffs; }; static int scrollbar_get_thumbH(ScrollBar *sb) { - int scrollable_h = rect_height(sb->rect) - 2 * sb->inset; + int scrollable_h = rect_height(sb->rect) - 2 * sb->inset; - return clamp_i(sb->thumbpct * scrollable_h, sb->minthumb, scrollable_h); + 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); + int scrollable_h = rect_height(sb->rect) - 2 * sb->inset; + int thumb_h = scrollbar_get_thumbH(sb); - return scrollable_h - thumb_h; + 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; + 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; + 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; + ScrollBar *sb = MEM_callocN(sizeof(*sb), "scrollbar_new"); + sb->inset = inset; + sb->minthumb = minthumb; - return sb; + 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); + 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][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; + 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; + return sb->scrolling; } int scrollbar_contains_pt(ScrollBar *sb, int pt[2]) { - return rect_contains_pt(sb->rect, pt); + 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); + 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->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); + 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); + float npos = scrollbar_co_to_pos(sb, yco); - sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0); + sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0); } void scrollbar_stop_scrolling(ScrollBar *sb) { - sb->scrolling = 0; - sb->scrolloffs = 0.0; + sb->scrolling = 0; + sb->scrolloffs = 0.0; } void scrollbar_set_thumbpct(ScrollBar *sb, float pct) { - sb->thumbpct = pct; + sb->thumbpct = pct; } void scrollbar_set_thumbpos(ScrollBar *sb, float pos) { - sb->thumbpos = clamp_f(pos, 0.0, 1.0); + sb->thumbpos = clamp_f(pos, 0.0, 1.0); } void scrollbar_set_rect(ScrollBar *sb, int rect[2][2]) { - rect_copy(sb->rect, rect); + rect_copy(sb->rect, rect); } float scrollbar_get_thumbpct(ScrollBar *sb) { - return sb->thumbpct; + return sb->thumbpct; } float scrollbar_get_thumbpos(ScrollBar *sb) { - return sb->thumbpos; + return sb->thumbpos; } void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2]) { - rect_copy(rect_r, sb->rect); + rect_copy(rect_r, sb->rect); } void scrollbar_free(ScrollBar *sb) { - MEM_freeN(sb); + MEM_freeN(sb); } diff --git a/intern/ghost/test/multitest/ScrollBar.h b/intern/ghost/test/multitest/ScrollBar.h index 015af7a1e07..7108f9ce2df 100644 --- a/intern/ghost/test/multitest/ScrollBar.h +++ b/intern/ghost/test/multitest/ScrollBar.h @@ -19,26 +19,25 @@ typedef struct _ScrollBar ScrollBar; +/***/ - /***/ +ScrollBar *scrollbar_new(int inset, int minthumb); -ScrollBar* scrollbar_new (int inset, int minthumb); +int scrollbar_is_scrolling(ScrollBar *sb); +int scrollbar_contains_pt(ScrollBar *sb, int pt[2]); -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_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]); -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]); -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_get_thumb (ScrollBar *sb, int thumb_r[2][2]); - -void scrollbar_free (ScrollBar *sb); +void scrollbar_free(ScrollBar *sb); diff --git a/intern/ghost/test/multitest/Util.c b/intern/ghost/test/multitest/Util.c index abaeb4407dc..c6cdebd39ce 100644 --- a/intern/ghost/test/multitest/Util.c +++ b/intern/ghost/test/multitest/Util.c @@ -29,36 +29,36 @@ 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"); + 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); + memcpy(nmem, mem, cur_size * item_size); + MEM_freeN(mem); - *size_pr = new_size; - return nmem; + *size_pr = new_size; + return nmem; } char *string_dup(char *str) { - int len = strlen(str); - char *nstr = MEM_mallocN(len + 1, "string_dup"); + int len = strlen(str); + char *nstr = MEM_mallocN(len + 1, "string_dup"); - memcpy(nstr, str, len + 1); + memcpy(nstr, str, len + 1); - return nstr; + return nstr; } void fatal(char *fmt, ...) { - va_list ap; + va_list ap; - fprintf(stderr, "FATAL: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); + fprintf(stderr, "FATAL: "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); - exit(1); + exit(1); } diff --git a/intern/ghost/test/multitest/Util.h b/intern/ghost/test/multitest/Util.h index 5bd8f84b35f..24f963a6d89 100644 --- a/intern/ghost/test/multitest/Util.h +++ b/intern/ghost/test/multitest/Util.h @@ -17,7 +17,7 @@ * All rights reserved. */ -void* memdbl (void *mem, int *size_pr, int item_size); +void *memdbl(void *mem, int *size_pr, int item_size); -char* string_dup (char *str); -void fatal (char *fmt, ...); +char *string_dup(char *str); +void fatal(char *fmt, ...); diff --git a/intern/ghost/test/multitest/WindowData.c b/intern/ghost/test/multitest/WindowData.c index ea341ffa3be..7d3cbec43f3 100644 --- a/intern/ghost/test/multitest/WindowData.c +++ b/intern/ghost/test/multitest/WindowData.c @@ -26,25 +26,25 @@ #include "WindowData.h" struct _WindowData { - void *data; - WindowDataHandler handler; + 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; + WindowData *wb = MEM_mallocN(sizeof(*wb), "windowdata_new"); + wb->data = data; + wb->handler = handler; - return wb; + return wb; } void windowdata_handle(WindowData *wb, GHOST_EventHandle evt) { - wb->handler(wb->data, evt); + wb->handler(wb->data, evt); } void windowdata_free(WindowData *wb) { - MEM_freeN(wb); + MEM_freeN(wb); } diff --git a/intern/ghost/test/multitest/WindowData.h b/intern/ghost/test/multitest/WindowData.h index 073da0dad2b..9d39377bb0a 100644 --- a/intern/ghost/test/multitest/WindowData.h +++ b/intern/ghost/test/multitest/WindowData.h @@ -20,8 +20,8 @@ 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); +WindowData *windowdata_new(void *data, WindowDataHandler handler); +void windowdata_handle(WindowData *wb, GHOST_EventHandle evt); +void windowdata_free(WindowData *wb); diff --git a/intern/ghost/test/multitest/stubs.c b/intern/ghost/test/multitest/stubs.c index ad4b9812e98..f0b076eeba0 100644 --- a/intern/ghost/test/multitest/stubs.c +++ b/intern/ghost/test/multitest/stubs.c @@ -24,5 +24,10 @@ struct ImBuf; -void IMB_freeImBuf(struct ImBuf *UNUSED(ibuf)) {} -void IMB_colormanagement_display_to_scene_linear_v3(float UNUSED(pixel[3]), struct ColorManagedDisplay *UNUSED(display)) {} +void IMB_freeImBuf(struct ImBuf *UNUSED(ibuf)) +{ +} +void IMB_colormanagement_display_to_scene_linear_v3(float UNUSED(pixel[3]), + struct ColorManagedDisplay *UNUSED(display)) +{ +} |