From 4a8877bdf2526a0525faa7918b628d7905409352 Mon Sep 17 00:00:00 2001 From: Ben Cottrell Date: Wed, 11 Nov 2015 16:59:40 +1300 Subject: [PATCH] Added WM_COMMAND event handling --- include/GLFW/glfw3.h | 252 ++++---------------- src/input.c | 50 ++-- src/internal.h | 217 ++++++++--------- src/win32_window.c | 540 ++++++++++++++++++------------------------- 4 files changed, 391 insertions(+), 668 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 81acecdce..66d3ee1af 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1,5 +1,5 @@ /************************************************************************* - * GLFW 3.2 - www.glfw.org + * GLFW 3.1 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard @@ -38,14 +38,6 @@ extern "C" { * Doxygen documentation *************************************************************************/ -/*! @file glfw3.h - * @brief The header of the GLFW 3 API. - * - * This is the header file of the GLFW 3 API. It defines all its types and - * declares all its functions. - * - * For more information about how to use this file, see @ref build_include. - */ /*! @defgroup context Context handling * * This is the reference documentation for context related functions. For more @@ -212,32 +204,14 @@ extern "C" { * backward-compatible. * @ingroup init */ -#define GLFW_VERSION_MINOR 2 +#define GLFW_VERSION_MINOR 1 /*! @brief The revision number of the GLFW library. * * This is incremented when a bug fix release is made that does not contain any * API changes. * @ingroup init */ -#define GLFW_VERSION_REVISION 0 -/*! @} */ - -/*! @name Boolean values - * @{ */ -/*! @brief One. - * - * One. Seriously. You don't _need_ to use this symbol in your code. It's - * just semantic sugar for the number 1. You can use `1` or `true` or `_True` - * or `GL_TRUE` or whatever you want. - */ -#define GLFW_TRUE 1 -/*! @brief Zero. - * - * Zero. Seriously. You don't _need_ to use this symbol in your code. It's - * just just semantic sugar for the number 0. You can use `0` or `false` or - * `_False` or `GL_FALSE` or whatever you want. - */ -#define GLFW_FALSE 0 +#define GLFW_VERSION_REVISION 2 /*! @} */ /*! @name Key and button actions @@ -414,7 +388,6 @@ extern "C" { #define GLFW_KEY_RIGHT_ALT 346 #define GLFW_KEY_RIGHT_SUPER 347 #define GLFW_KEY_MENU 348 - #define GLFW_KEY_LAST GLFW_KEY_MENU /*! @} */ @@ -614,15 +587,6 @@ extern "C" { * the user, as appropriate. */ #define GLFW_FORMAT_UNAVAILABLE 0x00010009 -/*! @brief The specified window does not have an OpenGL or OpenGL ES context. - * - * A window that does not have an OpenGL or OpenGL ES context was passed to - * a function that requires it to have one. - * - * @par Analysis - * Application programmer error. Fix the offending call. - */ -#define GLFW_NO_WINDOW_CONTEXT 0x0001000A /*! @} */ #define GLFW_FOCUSED 0x00020001 @@ -659,9 +623,7 @@ extern "C" { #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 #define GLFW_OPENGL_PROFILE 0x00022008 #define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 -#define GLFW_CONTEXT_NO_ERROR 0x0002200A -#define GLFW_NO_API 0 #define GLFW_OPENGL_API 0x00030001 #define GLFW_OPENGL_ES_API 0x00030002 @@ -739,9 +701,6 @@ extern "C" { * Generic function pointer used for returning client API function pointers * without forcing a cast from a regular pointer. * - * @sa @ref context_glext - * @sa glfwGetProcAddress - * * @ingroup context */ typedef void (*GLFWglproc)(void); @@ -750,8 +709,6 @@ typedef void (*GLFWglproc)(void); * * Opaque monitor object. * - * @see @ref monitor_object - * * @ingroup monitor */ typedef struct GLFWmonitor GLFWmonitor; @@ -760,8 +717,6 @@ typedef struct GLFWmonitor GLFWmonitor; * * Opaque window object. * - * @see @ref window_object - * * @ingroup window */ typedef struct GLFWwindow GLFWwindow; @@ -770,8 +725,6 @@ typedef struct GLFWwindow GLFWwindow; * * Opaque cursor object. * - * @see @ref cursor_object - * * @ingroup cursor */ typedef struct GLFWcursor GLFWcursor; @@ -783,7 +736,6 @@ typedef struct GLFWcursor GLFWcursor; * @param[in] error An [error code](@ref errors). * @param[in] description A UTF-8 encoded string describing the error. * - * @sa @ref error_handling * @sa glfwSetErrorCallback * * @ingroup init @@ -800,7 +752,6 @@ typedef void (* GLFWerrorfun)(int,const char*); * @param[in] ypos The new y-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * - * @sa @ref window_pos * @sa glfwSetWindowPosCallback * * @ingroup window @@ -815,7 +766,6 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); * @param[in] width The new width, in screen coordinates, of the window. * @param[in] height The new height, in screen coordinates, of the window. * - * @sa @ref window_size * @sa glfwSetWindowSizeCallback * * @ingroup window @@ -828,7 +778,6 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); * * @param[in] window The window that the user attempted to close. * - * @sa @ref window_close * @sa glfwSetWindowCloseCallback * * @ingroup window @@ -841,7 +790,6 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); * * @param[in] window The window whose content needs to be refreshed. * - * @sa @ref window_refresh * @sa glfwSetWindowRefreshCallback * * @ingroup window @@ -853,10 +801,9 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); * This is the function signature for window focus callback functions. * * @param[in] window The window that gained or lost input focus. - * @param[in] focused `GLFW_TRUE` if the window was given input focus, or - * `GLFW_FALSE` if it lost it. + * @param[in] focused `GL_TRUE` if the window was given input focus, or + * `GL_FALSE` if it lost it. * - * @sa @ref window_focus * @sa glfwSetWindowFocusCallback * * @ingroup window @@ -869,10 +816,9 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); * functions. * * @param[in] window The window that was iconified or restored. - * @param[in] iconified `GLFW_TRUE` if the window was iconified, or - * `GLFW_FALSE` if it was restored. + * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` + * if it was restored. * - * @sa @ref window_iconify * @sa glfwSetWindowIconifyCallback * * @ingroup window @@ -888,7 +834,6 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); * @param[in] width The new width, in pixels, of the framebuffer. * @param[in] height The new height, in pixels, of the framebuffer. * - * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * * @ingroup window @@ -906,7 +851,6 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * - * @sa @ref input_mouse_button * @sa glfwSetMouseButtonCallback * * @ingroup input @@ -921,7 +865,6 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); * @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor. * @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor. * - * @sa @ref cursor_pos * @sa glfwSetCursorPosCallback * * @ingroup input @@ -933,10 +876,9 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); * This is the function signature for cursor enter/leave callback functions. * * @param[in] window The window that received the event. - * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client - * area, or `GLFW_FALSE` if it left it. + * @param[in] entered `GL_TRUE` if the cursor entered the window's client + * area, or `GL_FALSE` if it left it. * - * @sa @ref cursor_enter * @sa glfwSetCursorEnterCallback * * @ingroup input @@ -951,13 +893,23 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); * @param[in] xoffset The scroll offset along the x-axis. * @param[in] yoffset The scroll offset along the y-axis. * - * @sa @ref scrolling * @sa glfwSetScrollCallback * * @ingroup input */ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); +/*! @brief The function signature for menu item callbacks +* +* This is the function signature for menu item callbacks +* +* @param[in] window The window that received the event. +* @param[in] id The menu item ID that was selected +* +*/ +typedef void (* GLFWmenufun)(GLFWwindow*,int); + + /*! @brief The function signature for keyboard key callbacks. * * This is the function signature for keyboard key callback functions. @@ -969,7 +921,6 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * - * @sa @ref input_key * @sa glfwSetKeyCallback * * @ingroup input @@ -983,7 +934,6 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * - * @sa @ref input_char * @sa glfwSetCharCallback * * @ingroup input @@ -1002,7 +952,6 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * - * @sa @ref input_char * @sa glfwSetCharModsCallback * * @ingroup input @@ -1017,7 +966,6 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); * @param[in] count The number of dropped files. * @param[in] paths The UTF-8 encoded file and/or directory path names. * - * @sa @ref path_drop * @sa glfwSetDropCallback * * @ingroup input @@ -1031,7 +979,6 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); * @param[in] monitor The monitor that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * - * @sa @ref monitor_event * @sa glfwSetMonitorCallback * * @ingroup monitor @@ -1042,9 +989,6 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); * * This describes a single video mode. * - * @sa @ref monitor_modes - * @sa glfwGetVideoMode glfwGetVideoModes - * * @ingroup monitor */ typedef struct GLFWvidmode @@ -1073,7 +1017,6 @@ typedef struct GLFWvidmode * * This describes the gamma ramp for a monitor. * - * @sa @ref monitor_gamma * @sa glfwGetGammaRamp glfwSetGammaRamp * * @ingroup monitor @@ -1095,8 +1038,6 @@ typedef struct GLFWgammaramp } GLFWgammaramp; /*! @brief Image data. - * - * @sa @ref cursor_custom */ typedef struct GLFWimage { @@ -1127,9 +1068,9 @@ typedef struct GLFWimage * succeeds, you should call @ref glfwTerminate before the application exits. * * Additional calls to this function after successful initialization but before - * termination will return `GLFW_TRUE` immediately. + * termination will return `GL_TRUE` immediately. * - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * @return `GL_TRUE` if successful, or `GL_FALSE` if an * [error](@ref error_handling) occurred. * * @remarks __OS X:__ This function will change the current directory of the @@ -1418,6 +1359,9 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @bug __X11:__ This callback is not yet called on monitor configuration + * changes. + * * @par Thread Safety * This function may only be called from the main thread. * @@ -1894,77 +1838,6 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); */ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); -/*! @brief Sets the size limits of the specified window. - * - * This function sets the size limits of the client area of the specified - * window. If the window is full screen or not resizable, this function does - * nothing. - * - * The size limits are applied immediately and may cause the window to be - * resized. - * - * @param[in] window The window to set limits for. - * @param[in] minwidth The minimum width, in screen coordinates, of the client - * area, or `GLFW_DONT_CARE`. - * @param[in] minheight The minimum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. - * @param[in] maxwidth The maximum width, in screen coordinates, of the client - * area, or `GLFW_DONT_CARE`. - * @param[in] maxheight The maximum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. - * - * @remarks If you set size limits and an aspect ratio that conflict, the - * results are undefined. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_sizelimits - * @sa glfwSetWindowAspectRatio - * - * @since Added in GLFW 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); - -/*! @brief Sets the aspect ratio of the specified window. - * - * This function sets the required aspect ratio of the client area of the - * specified window. If the window is full screen or not resizable, this - * function does nothing. - * - * The aspect ratio is specified as a numerator and a denominator and both - * values must be greater than zero. For example, the common 16:9 aspect ratio - * is specified as 16 and 9, respectively. - * - * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect - * ratio limit is disabled. - * - * The aspect ratio is applied immediately and may cause the window to be - * resized. - * - * @param[in] window The window to set limits for. - * @param[in] numer The numerator of the desired aspect ratio, or - * `GLFW_DONT_CARE`. - * @param[in] denom The denominator of the desired aspect ratio, or - * `GLFW_DONT_CARE`. - * - * @remarks If you set size limits and an aspect ratio that conflict, the - * results are undefined. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_sizelimits - * @sa glfwSetWindowSizeLimits - * - * @since Added in GLFW 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); - /*! @brief Sets the size of the client area of the specified window. * * This function sets the size, in screen coordinates, of the client area of @@ -2558,20 +2431,20 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. * - * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to - * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are + * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to + * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` * the next time it is called even if the key had been released before the * call. This is useful when you are only interested in whether keys have been * pressed but not when or in which order. * * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either - * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. - * If sticky mouse buttons are enabled, a mouse button press will ensure that - * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even - * if the mouse button had been released before the call. This is useful when - * you are only interested in whether mouse buttons have been pressed but not - * when or in which order. + * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If + * sticky mouse buttons are enabled, a mouse button press will ensure that @ref + * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if + * the mouse button had been released before the call. This is useful when you + * are only interested in whether mouse buttons have been pressed but not when + * or in which order. * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or @@ -2589,33 +2462,6 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); -/*! @brief Returns the localized name of the specified printable key. - * - * This function returns the localized name of the specified printable key. - * - * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used, otherwise the - * scancode is ignored. - * - * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. - * @param[in] scancode The scancode of the key to query. - * @return The localized name of the key. - * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the next call to @ref glfwGetKeyName, or until - * the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_key_name - * - * @since Added in GLFW 3.2. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetKeyName(int key, int scancode); - /*! @brief Returns the last reported state of a keyboard key for the specified * window. * @@ -2635,8 +2481,6 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * The [modifier key bit masks](@ref mods) are not key tokens and cannot be * used with this function. * - * __Do not use this function__ to implement [text input](@ref input_char). - * * @param[in] window The desired window. * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is * not a valid key for this function. @@ -2873,6 +2717,19 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); */ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); + +/*! @brief Sets the menu item callback + * + * This function sets the menu item callback of the specified window, + * which is called when a menu item is selected. + * + * @param[in] window The window whose callback to set + * @param[in] cbfun The new menu item callback +*/ + +GLFWAPI GLFWmenufun glfwSetMenuCallback(GLFWwindow* window, GLFWmenufun cbfun); + + /*! @brief Sets the key callback. * * This function sets the key callback of the specified window, which is called @@ -3124,7 +2981,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); * This function returns whether the specified joystick is present. * * @param[in] joy The [joystick](@ref joysticks) to query. - * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. + * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise. * * @par Thread Safety * This function may only be called from the main thread. @@ -3330,10 +3187,6 @@ GLFWAPI void glfwSetTime(double time); * whether a context performs this flush by setting the * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. * - * The specified window must have an OpenGL or OpenGL ES context. Specifying - * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT - * error. - * * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * @@ -3375,10 +3228,6 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); * the swap interval is greater than zero, the GPU driver waits the specified * number of screen updates before swapping the buffers. * - * The specified window must have an OpenGL or OpenGL ES context. Specifying - * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT - * error. - * * @param[in] window The window whose buffers to swap. * * @par Thread Safety @@ -3454,8 +3303,7 @@ GLFWAPI void glfwSwapInterval(int interval); * a context, so there is no danger in doing this. * * @param[in] extension The ASCII encoded name of the extension. - * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` - * otherwise. + * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise. * * @par Thread Safety * This function may be called from any thread. @@ -3480,8 +3328,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension); * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * @param[in] procname The ASCII encoded name of the function. - * @return The address of the function, or `NULL` if an - * [error](@ref error_handling) occurred. + * @return The address of the function, or `NULL` if an [error](@ref + * error_handling) occurred. * * @remarks The address of a given function is not guaranteed to be the same * between contexts. diff --git a/src/input.c b/src/input.c index 6eac88055..63f3f4038 100644 --- a/src/input.c +++ b/src/input.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.2 - www.glfw.org +// GLFW 3.1 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2010 Camilla Berglund @@ -78,7 +78,7 @@ static void setCursorMode(_GLFWwindow* window, int newMode) _glfwPlatformSetCursorPos(window, width / 2, height / 2); } - _glfwPlatformSetCursorMode(window, window->cursorMode); + _glfwPlatformApplyCursorMode(window); } } @@ -135,13 +135,13 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m { if (key >= 0 && key <= GLFW_KEY_LAST) { - GLFWbool repeated = GLFW_FALSE; + GLboolean repeated = GL_FALSE; if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE) return; if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS) - repeated = GLFW_TRUE; + repeated = GL_TRUE; if (action == GLFW_RELEASE && window->stickyKeys) window->keys[key] = _GLFW_STICK; @@ -156,7 +156,14 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods); } -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain) +//EDIT +void _glfwInputMenuItem(_GLFWwindow* window, int id) +{ + if (window->callbacks.menuitem) + window->callbacks.menuitem((GLFWwindow*)window, id); +} + +void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain) { if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) return; @@ -210,7 +217,7 @@ void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y) window->callbacks.cursorPos((GLFWwindow*) window, x, y); } -void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) +void _glfwInputCursorEnter(_GLFWwindow* window, int entered) { if (window->callbacks.cursorEnter) window->callbacks.cursorEnter((GLFWwindow*) window, entered); @@ -223,18 +230,6 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) } -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWbool _glfwIsPrintable(int key) -{ - return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) || - (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) || - key == GLFW_KEY_KP_EQUAL; -} - - ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// ////////////////////////////////////////////////////////////////////////// @@ -271,10 +266,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) setCursorMode(window, value); break; case GLFW_STICKY_KEYS: - setStickyKeys(window, value ? GLFW_TRUE : GLFW_FALSE); + setStickyKeys(window, value ? GL_TRUE : GL_FALSE); break; case GLFW_STICKY_MOUSE_BUTTONS: - setStickyMouseButtons(window, value ? GLFW_TRUE : GLFW_FALSE); + setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE); break; default: _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode"); @@ -282,12 +277,6 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) } } -GLFWAPI const char* glfwGetKeyName(int key, int scancode) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfwPlatformGetKeyName(key, scancode); -} - GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) { _GLFWwindow* window = (_GLFWwindow*) handle; @@ -473,6 +462,15 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) window->cursor = cursor; } +//EDIT +GLFWAPI GLFWmenufun glfwSetMenuCallback(GLFWwindow* handle, GLFWmenufun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*)handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.menuitem, cbfun); + return cbfun; +} + GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; diff --git a/src/internal.h b/src/internal.h index daa573bab..dbca851cc 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.2 - www.glfw.org +// GLFW 3.1 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2010 Camilla Berglund @@ -33,6 +33,8 @@ #include "glfw_config.h" #endif +#define _GLFW_VERSION_NUMBER "3.1.2" + #if defined(GLFW_INCLUDE_GLCOREARB) || \ defined(GLFW_INCLUDE_ES1) || \ defined(GLFW_INCLUDE_ES2) || \ @@ -44,49 +46,41 @@ #error "You may not define any header option macros when compiling GLFW" #endif -#define GLFW_INCLUDE_NONE +#if defined(_GLFW_USE_OPENGL) + // This is the default for glfw3.h +#elif defined(_GLFW_USE_GLESV1) + #define GLFW_INCLUDE_ES1 +#elif defined(_GLFW_USE_GLESV2) + #define GLFW_INCLUDE_ES2 +#else + #error "No supported client library selected" +#endif + +// Disable the inclusion of the platform glext.h by gl.h to allow proper +// inclusion of our own, newer glext.h below +#define GL_GLEXT_LEGACY + #include "../include/GLFW/glfw3.h" -#define GL_VERSION 0x1f02 -#define GL_NONE 0 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_EXTENSIONS 0x1f03 -#define GL_NUM_EXTENSIONS 0x821d -#define GL_CONTEXT_FLAGS 0x821e -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc -#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 - -typedef int GLint; -typedef unsigned int GLuint; -typedef unsigned int GLenum; -typedef unsigned int GLbitfield; -typedef unsigned char GLubyte; +#if defined(_GLFW_USE_OPENGL) + // This path may need to be changed if you build GLFW using your own setup + // GLFW comes with its own copy of glext.h since it uses fairly new extensions + // and not all development environments come with an up-to-date version + #include "../deps/GL/glext.h" +#endif typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); -typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); typedef struct _GLFWwndconfig _GLFWwndconfig; typedef struct _GLFWctxconfig _GLFWctxconfig; typedef struct _GLFWfbconfig _GLFWfbconfig; -typedef struct _GLFWcontext _GLFWcontext; typedef struct _GLFWwindow _GLFWwindow; typedef struct _GLFWlibrary _GLFWlibrary; typedef struct _GLFWmonitor _GLFWmonitor; typedef struct _GLFWcursor _GLFWcursor; -typedef int GLFWbool; - #if defined(_GLFW_COCOA) #include "cocoa_platform.h" #elif defined(_GLFW_WIN32) @@ -133,13 +127,6 @@ typedef int GLFWbool; // Helper macros //======================================================================== -// Constructs a version number string from the public header macros -#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r -#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) -#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \ - GLFW_VERSION_MINOR, \ - GLFW_VERSION_REVISION) - // Checks for whether the library has been initialized #define _GLFW_REQUIRE_INIT() \ if (!_glfwInitialized) \ @@ -179,12 +166,12 @@ struct _GLFWwndconfig int width; int height; const char* title; - GLFWbool resizable; - GLFWbool visible; - GLFWbool decorated; - GLFWbool focused; - GLFWbool autoIconify; - GLFWbool floating; + GLboolean resizable; + GLboolean visible; + GLboolean decorated; + GLboolean focused; + GLboolean autoIconify; + GLboolean floating; _GLFWmonitor* monitor; }; @@ -200,9 +187,8 @@ struct _GLFWctxconfig int api; int major; int minor; - GLFWbool forward; - GLFWbool debug; - GLFWbool noerror; + GLboolean forward; + GLboolean debug; int profile; int robustness; int release; @@ -241,26 +227,6 @@ struct _GLFWfbconfig }; -/*! @brief Context structure. - */ -struct _GLFWcontext -{ - int api; - int major, minor, revision; - GLFWbool forward, debug, noerror; - int profile; - int robustness; - int release; - - PFNGLGETSTRINGIPROC GetStringi; - PFNGLGETINTEGERVPROC GetIntegerv; - PFNGLGETSTRINGPROC GetString; - - // This is defined in the context API's context.h - _GLFW_PLATFORM_CONTEXT_STATE; -}; - - /*! @brief Window and context structure. */ struct _GLFWwindow @@ -268,25 +234,40 @@ struct _GLFWwindow struct _GLFWwindow* next; // Window settings and state - GLFWbool resizable; - GLFWbool decorated; - GLFWbool autoIconify; - GLFWbool floating; - GLFWbool closed; + GLboolean resizable; + GLboolean decorated; + GLboolean autoIconify; + GLboolean floating; + GLboolean closed; void* userPointer; GLFWvidmode videoMode; _GLFWmonitor* monitor; _GLFWcursor* cursor; // Window input state - GLFWbool stickyKeys; - GLFWbool stickyMouseButtons; + GLboolean stickyKeys; + GLboolean stickyMouseButtons; double cursorPosX, cursorPosY; int cursorMode; char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; char keys[GLFW_KEY_LAST + 1]; - _GLFWcontext context; + // OpenGL extensions and context attributes + struct { + int api; + int major, minor, revision; + GLboolean forward, debug; + int profile; + int robustness; + int release; + } context; + +#if defined(_GLFW_USE_OPENGL) + PFNGLGETSTRINGIPROC GetStringi; +#endif + PFNGLGETINTEGERVPROC GetIntegerv; + PFNGLGETSTRINGPROC GetString; + PFNGLCLEARPROC Clear; struct { GLFWwindowposfun pos; @@ -301,6 +282,7 @@ struct _GLFWwindow GLFWcursorenterfun cursorEnter; GLFWscrollfun scroll; GLFWkeyfun key; + GLFWmenufun menuitem; GLFWcharfun character; GLFWcharmodsfun charmods; GLFWdropfun drop; @@ -308,6 +290,8 @@ struct _GLFWwindow // This is defined in the window API's platform.h _GLFW_PLATFORM_WINDOW_STATE; + // This is defined in the context API's context.h + _GLFW_PLATFORM_CONTEXT_STATE; }; @@ -386,7 +370,7 @@ struct _GLFWlibrary /*! @brief Flag indicating whether GLFW has been successfully initialized. */ -extern GLFWbool _glfwInitialized; +extern GLboolean _glfwInitialized; /*! @brief All global data protected by @ref _glfwInitialized. * This should only be touched after a call to @ref glfwInit that has not been @@ -400,7 +384,7 @@ extern _GLFWlibrary _glfw; //======================================================================== /*! @brief Initializes the platform-specific part of the library. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an error occurred. + * @return `GL_TRUE` if successful, or `GL_FALSE` if an error occurred. * @ingroup platform */ int _glfwPlatformInit(void); @@ -429,16 +413,11 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); */ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); -/*! @brief Sets the specified cursor mode of the specified window. - * @param[in] window The window whose cursor mode to set. +/*! @brief Applies the cursor mode of the specified window to the system. + * @param[in] window The window whose cursor mode to apply. * @ingroup platform */ -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); - -/*! @copydoc glfwGetKeyName - * @ingroup platform - */ -const char* _glfwPlatformGetKeyName(int key, int scancode); +void _glfwPlatformApplyCursorMode(_GLFWwindow* window); /*! @copydoc glfwGetMonitors * @ingroup platform @@ -449,11 +428,11 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count); * * @param[in] first The first monitor. * @param[in] second The second monitor. - * @return @c GLFW_TRUE if the monitor objects represent the same monitor, or - * @c GLFW_FALSE otherwise. + * @return @c GL_TRUE if the monitor objects represent the same monitor, or @c + * GL_FALSE otherwise. * @ingroup platform */ -GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second); +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second); /*! @copydoc glfwGetMonitorPos * @ingroup platform @@ -558,16 +537,6 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); */ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); -/*! @copydoc glfwSetWindowSizeLimits - * @ingroup platform - */ -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); - -/*! @copydoc glfwSetWindowAspectRatio - * @ingroup platform - */ -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom); - /*! @copydoc glfwGetFramebufferSize * @ingroup platform */ @@ -689,11 +658,11 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); /*! @brief Notifies shared code of a window focus event. * @param[in] window The window that received the event. - * @param[in] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE` + * @param[in] focused `GL_TRUE` if the window received focus, or `GL_FALSE` * if it lost focus. * @ingroup event */ -void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused); +void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused); /*! @brief Notifies shared code of a window movement event. * @param[in] window The window that received the event. @@ -721,11 +690,11 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height); /*! @brief Notifies shared code of a window iconification event. * @param[in] window The window that received the event. - * @param[in] iconified `GLFW_TRUE` if the window was iconified, or - * `GLFW_FALSE` if it was restored. + * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` + * if it was restored. * @ingroup event */ -void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified); +void _glfwInputWindowIconify(_GLFWwindow* window, int iconified); /*! @brief Notifies shared code of a window damage event. * @param[in] window The window that received the event. @@ -738,6 +707,13 @@ void _glfwInputWindowDamage(_GLFWwindow* window); */ void _glfwInputWindowCloseRequest(_GLFWwindow* window); +/*! @brief Notifies shared code of a menu item event. + * @param[in] window The Window that received the event. + * @param[in] id The ID of the menu item + * @ingroup event +*/ +void _glfwInputMenuItem(_GLFWwindow* window, int id); + /*! @brief Notifies shared code of a physical key event. * @param[in] window The window that received the event. * @param[in] key The key that was pressed or released. @@ -752,11 +728,11 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the input character. * @param[in] mods Bit field describing which modifier keys were held down. - * @param[in] plain `GLFW_TRUE` if the character is regular text input, or - * `GLFW_FALSE` otherwise. + * @param[in] plain `GL_TRUE` if the character is regular text input, or + * `GL_FALSE` otherwise. * @ingroup event */ -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain); +void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain); /*! @brief Notifies shared code of a scroll event. * @param[in] window The window that received the event. @@ -786,11 +762,11 @@ void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y); /*! @brief Notifies shared code of a cursor enter/leave event. * @param[in] window The window that received the event. - * @param[in] entered `GLFW_TRUE` if the cursor entered the client area of the - * window, or `GLFW_FALSE` if it left it. + * @param[in] entered `GL_TRUE` if the cursor entered the client area of the + * window, or `GL_FALSE` if it left it. * @ingroup event */ -void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered); +void _glfwInputCursorEnter(_GLFWwindow* window, int entered); /*! @ingroup event */ @@ -802,11 +778,7 @@ void _glfwInputMonitorChange(void); * description. * @ingroup event */ -#if defined(__GNUC__) -void _glfwInputError(int error, const char* format, ...) __attribute__((format(printf, 2, 3))); -#else void _glfwInputError(int error, const char* format, ...); -#endif /*! @brief Notifies dropped object over window. * @param[in] window The window that received the event. @@ -839,10 +811,10 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); /*! @brief Searches an extension string for the specified extension. * @param[in] string The extension string to search. * @param[in] extensions The extension to search for. - * @return `GLFW_TRUE` if the extension was found, or `GLFW_FALSE` otherwise. + * @return `GL_TRUE` if the extension was found, or `GL_FALSE` otherwise. * @ingroup utility */ -GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions); +int _glfwStringInExtensionString(const char* string, const char* extensions); /*! @brief Chooses the framebuffer config that best matches the desired one. * @param[in] desired The desired framebuffer config. @@ -858,15 +830,14 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, /*! @brief Retrieves the attributes of the current context. * @param[in] ctxconfig The desired context attributes. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if the context is - * unusable. + * @return `GL_TRUE` if successful, or `GL_FALSE` if the context is unusable. * @ingroup utility */ -GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig); +GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig); /*! @brief Checks whether the desired context attributes are valid. * @param[in] ctxconfig The context attributes to check. - * @return `GLFW_TRUE` if the context attributes are valid, or `GLFW_FALSE` + * @return `GL_TRUE` if the context attributes are valid, or `GL_FALSE` * otherwise. * @ingroup utility * @@ -874,16 +845,16 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig); * exists and whether all relevant options have supported and non-conflicting * values. */ -GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig); +GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig); /*! @brief Checks whether the current context fulfils the specified hard * constraints. * @param[in] ctxconfig The desired context attributes. - * @return `GLFW_TRUE` if the context fulfils the hard constraints, or - * `GLFW_FALSE` otherwise. + * @return `GL_TRUE` if the context fulfils the hard constraints, or `GL_FALSE` + * otherwise. * @ingroup utility */ -GLFWbool _glfwIsValidContext(const _GLFWctxconfig* ctxconfig); +GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig); /*! @ingroup utility */ @@ -912,8 +883,4 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor); */ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); -/*! @ingroup utility - */ -int _glfwIsPrintable(int key); - #endif // _glfw3_internal_h_ diff --git a/src/win32_window.c b/src/win32_window.c index 2b34a1ce6..806cb7052 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.2 Win32 - www.glfw.org +// GLFW 3.1 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2010 Camilla Berglund @@ -37,6 +37,7 @@ #define _GLFW_WNDCLASSNAME L"GLFW30" + // Returns the window style for the specified window // static DWORD getWindowStyle(const _GLFWwindow* window) @@ -68,47 +69,6 @@ static DWORD getWindowExStyle(const _GLFWwindow* window) return style; } -// Translate client window size to full window size according to styles -// -static void getFullWindowSize(DWORD style, DWORD exStyle, - int clientWidth, int clientHeight, - int* fullWidth, int* fullHeight) -{ - RECT rect = { 0, 0, clientWidth, clientHeight }; - AdjustWindowRectEx(&rect, style, FALSE, exStyle); - *fullWidth = rect.right - rect.left; - *fullHeight = rect.bottom - rect.top; -} - -// Enforce the client rect aspect ratio based on which edge is being dragged -// -static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) -{ - int xoff, yoff; - const float ratio = (float) window->win32.numer / - (float) window->win32.denom; - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff); - - if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || - edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) - { - area->bottom = area->top + yoff + - (int) ((area->right - area->left - xoff) / ratio); - } - else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) - { - area->top = area->bottom - yoff - - (int) ((area->right - area->left - xoff) / ratio); - } - else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) - { - area->right = area->left + xoff + - (int) ((area->bottom - area->top - yoff) * ratio); - } -} - // Updates the cursor clip rect // static void updateClipRect(_GLFWwindow* window) @@ -120,6 +80,56 @@ static void updateClipRect(_GLFWwindow* window) ClipCursor(&clipRect); } +// Hide the mouse cursor +// +static void hideCursor(_GLFWwindow* window) +{ + POINT pos; + + ClipCursor(NULL); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + SetCursor(NULL); + } +} + +// Disable the mouse cursor +// +static void disableCursor(_GLFWwindow* window) +{ + POINT pos; + + updateClipRect(window); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + SetCursor(NULL); + } +} + +// Restores the mouse cursor +// +static void restoreCursor(_GLFWwindow* window) +{ + POINT pos; + + ClipCursor(NULL); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + { + if (window->cursor) + SetCursor(window->cursor->win32.handle); + else + SetCursor(LoadCursorW(NULL, IDC_ARROW)); + } + } +} + // Translates a GLFW standard cursor to a resource ID // static LPWSTR translateCursorShape(int shape) @@ -225,10 +235,10 @@ static int translateKey(WPARAM wParam, LPARAM lParam) // Enter full screen mode // -static GLFWbool enterFullscreenMode(_GLFWwindow* window) +static GLboolean enterFullscreenMode(_GLFWwindow* window) { GLFWvidmode mode; - GLFWbool status; + GLboolean status; int xpos, ypos; status = _glfwSetVideoMode(window->monitor, &window->videoMode); @@ -249,7 +259,7 @@ static void leaveFullscreenMode(_GLFWwindow* window) _glfwRestoreVideoMode(window->monitor); } -// Window callback function (handles window messages) +// Window callback function (handles window events) // static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -267,25 +277,29 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_SETFOCUS: { - if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + if (window->cursorMode != GLFW_CURSOR_NORMAL) + _glfwPlatformApplyCursorMode(window); - _glfwInputWindowFocus(window, GLFW_TRUE); + _glfwInputWindowFocus(window, GL_TRUE); return 0; } case WM_KILLFOCUS: { - if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); + if (window->cursorMode != GLFW_CURSOR_NORMAL) + restoreCursor(window); if (window->monitor && window->autoIconify) _glfwPlatformIconifyWindow(window); - _glfwInputWindowFocus(window, GLFW_FALSE); + _glfwInputWindowFocus(window, GL_FALSE); return 0; } - + case WM_COMMAND: + { + _glfwInputMenuItem(window, LOWORD(wParam)); + break; + } case WM_SYSCOMMAND: { switch (wParam & 0xfff0) @@ -316,52 +330,69 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return 0; } + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + const int scancode = (lParam >> 16) & 0x1ff; + const int key = translateKey(wParam, lParam); + if (key == _GLFW_KEY_INVALID) + break; + + _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods()); + break; + } + case WM_CHAR: + { + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); + return 0; + } + case WM_SYSCHAR: + { + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE); + return 0; + } + case WM_UNICHAR: { - const GLFWbool plain = (uMsg != WM_SYSCHAR); + // This message is not sent by Windows, but is sent by some + // third-party input method engines - if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR) + if (wParam == UNICODE_NOCHAR) { - // WM_UNICHAR is not sent by Windows, but is sent by some - // third-party input method engine // Returning TRUE here announces support for this message return TRUE; } - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); - return 0; + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); + return FALSE; } - case WM_KEYDOWN: - case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: { - const int key = translateKey(wParam, lParam); - const int scancode = (lParam >> 16) & 0x1ff; - const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS; const int mods = getKeyMods(); - + const int scancode = (lParam >> 16) & 0x1ff; + const int key = translateKey(wParam, lParam); if (key == _GLFW_KEY_INVALID) break; - if (action == GLFW_RELEASE && wParam == VK_SHIFT) + if (wParam == VK_SHIFT) { // Release both Shift keys on Shift up event, as only one event // is sent even if both keys are released - _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods); - _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods); + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods); + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods); } else if (wParam == VK_SNAPSHOT) { - // Key down is not reported for the Print Screen key + // Key down is not reported for the print screen key _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); } else - _glfwInputKey(window, key, scancode, action, mods); + _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); break; } @@ -370,40 +401,54 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_XBUTTONDOWN: + { + const int mods = getKeyMods(); + + SetCapture(hWnd); + + if (uMsg == WM_LBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); + else if (uMsg == WM_RBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); + else if (uMsg == WM_MBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); + else + { + if (HIWORD(wParam) == XBUTTON1) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods); + else if (HIWORD(wParam) == XBUTTON2) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods); + + return TRUE; + } + + return 0; + } + case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_XBUTTONUP: { - int button, action; + const int mods = getKeyMods(); - if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) - button = GLFW_MOUSE_BUTTON_LEFT; - else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) - button = GLFW_MOUSE_BUTTON_RIGHT; - else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) - button = GLFW_MOUSE_BUTTON_MIDDLE; - else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) - button = GLFW_MOUSE_BUTTON_4; - else - button = GLFW_MOUSE_BUTTON_5; + ReleaseCapture(); - if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || - uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN) - { - action = GLFW_PRESS; - SetCapture(hWnd); - } + if (uMsg == WM_LBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); + else if (uMsg == WM_RBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); + else if (uMsg == WM_MBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); else { - action = GLFW_RELEASE; - ReleaseCapture(); - } + if (HIWORD(wParam) == XBUTTON1) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods); + else if (HIWORD(wParam) == XBUTTON2) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods); - _glfwInputMouseClick(window, button, action, getKeyMods()); - - if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) return TRUE; + } return 0; } @@ -437,8 +482,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, tme.hwndTrack = window->win32.handle; TrackMouseEvent(&tme); - window->win32.cursorTracked = GLFW_TRUE; - _glfwInputCursorEnter(window, GLFW_TRUE); + window->win32.cursorTracked = GL_TRUE; + _glfwInputCursorEnter(window, GL_TRUE); } return 0; @@ -446,8 +491,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_MOUSELEAVE: { - window->win32.cursorTracked = GLFW_FALSE; - _glfwInputCursorEnter(window, GLFW_FALSE); + window->win32.cursorTracked = GL_FALSE; + _glfwInputCursorEnter(window, GL_FALSE); return 0; } @@ -475,20 +520,20 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (!window->win32.iconified && wParam == SIZE_MINIMIZED) { - window->win32.iconified = GLFW_TRUE; + window->win32.iconified = GL_TRUE; if (window->monitor) leaveFullscreenMode(window); - _glfwInputWindowIconify(window, GLFW_TRUE); + _glfwInputWindowIconify(window, GL_TRUE); } else if (window->win32.iconified && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) { - window->win32.iconified = GLFW_FALSE; + window->win32.iconified = GL_FALSE; if (window->monitor) enterFullscreenMode(window); - _glfwInputWindowIconify(window, GLFW_FALSE); + _glfwInputWindowIconify(window, GL_FALSE); } _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); @@ -512,46 +557,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return 0; } - case WM_SIZING: - { - if (window->win32.numer == GLFW_DONT_CARE || - window->win32.denom == GLFW_DONT_CARE) - { - break; - } - - applyAspectRatio(window, (int) wParam, (RECT*) lParam); - return TRUE; - } - - case WM_GETMINMAXINFO: - { - int xoff, yoff; - MINMAXINFO* mmi = (MINMAXINFO*) lParam; - - if (!window) - break; - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff); - - if (window->win32.minwidth != GLFW_DONT_CARE && - window->win32.minheight != GLFW_DONT_CARE) - { - mmi->ptMinTrackSize.x = window->win32.minwidth + xoff; - mmi->ptMinTrackSize.y = window->win32.minheight + yoff; - } - - if (window->win32.maxwidth != GLFW_DONT_CARE && - window->win32.maxheight != GLFW_DONT_CARE) - { - mmi->ptMaxTrackSize.x = window->win32.maxwidth + xoff; - mmi->ptMaxTrackSize.y = window->win32.maxheight + yoff; - } - - return 0; - } - case WM_PAINT: { _glfwInputWindowDamage(window); @@ -583,19 +588,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, break; } - case WM_DPICHANGED: - { - RECT* rect = (RECT*) lParam; - SetWindowPos(window->win32.handle, - HWND_TOP, - rect->left, - rect->top, - rect->right - rect->left, - rect->bottom - rect->top, - SWP_NOACTIVATE | SWP_NOZORDER); - break; - } - case WM_DEVICECHANGE: { if (DBT_DEVNODES_CHANGED == wParam) @@ -641,12 +633,28 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, } } - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +// Translate client window size to full window size (including window borders) +// +static void getFullWindowSize(_GLFWwindow* window, + int clientWidth, int clientHeight, + int* fullWidth, int* fullHeight) +{ + RECT rect = { 0, 0, clientWidth, clientHeight }; + AdjustWindowRectEx(&rect, getWindowStyle(window), + FALSE, getWindowExStyle(window)); + *fullWidth = rect.right - rect.left; + *fullHeight = rect.bottom - rect.top; } // Creates the GLFW window and rendering context // -static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) +static int createWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { int xpos, ypos, fullWidth, fullHeight; WCHAR* wideTitle; @@ -668,7 +676,7 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) xpos = CW_USEDEFAULT; ypos = CW_USEDEFAULT; - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), + getFullWindowSize(window, wndconfig->width, wndconfig->height, &fullWidth, &fullHeight); } @@ -678,7 +686,7 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to convert window title to UTF-16"); - return GLFW_FALSE; + return GL_FALSE; } window->win32.handle = CreateWindowExW(getWindowExStyle(window), @@ -697,7 +705,7 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) if (!window->win32.handle) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window"); - return GLFW_FALSE; + return GL_FALSE; } if (_glfw_ChangeWindowMessageFilterEx) @@ -720,20 +728,18 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) DragAcceptFiles(window->win32.handle, TRUE); - window->win32.minwidth = GLFW_DONT_CARE; - window->win32.minheight = GLFW_DONT_CARE; - window->win32.maxwidth = GLFW_DONT_CARE; - window->win32.maxheight = GLFW_DONT_CARE; - window->win32.numer = GLFW_DONT_CARE; - window->win32.denom = GLFW_DONT_CARE; + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; - return GLFW_TRUE; + return GL_TRUE; } // Destroys the GLFW window and rendering context // static void destroyWindow(_GLFWwindow* window) { + _glfwDestroyContext(window); + if (window->win32.handle) { DestroyWindow(window->win32.handle); @@ -748,7 +754,7 @@ static void destroyWindow(_GLFWwindow* window) // Registers the GLFW window class // -GLFWbool _glfwRegisterWindowClass(void) +GLboolean _glfwRegisterWindowClass(void) { WNDCLASSW wc; @@ -763,25 +769,21 @@ GLFWbool _glfwRegisterWindowClass(void) wc.lpszClassName = _GLFW_WNDCLASSNAME; // Load user-provided icon if available - wc.hIcon = LoadImageW(GetModuleHandleW(NULL), - L"GLFW_ICON", IMAGE_ICON, - 0, 0, LR_DEFAULTSIZE | LR_SHARED); + wc.hIcon = LoadIconW(GetModuleHandleW(NULL), L"GLFW_ICON"); if (!wc.hIcon) { // No user-provided icon found, load default icon - wc.hIcon = LoadImageW(NULL, - IDI_APPLICATION, IMAGE_ICON, - 0, 0, LR_DEFAULTSIZE | LR_SHARED); + wc.hIcon = LoadIconW(NULL, IDI_WINLOGO); } if (!RegisterClassW(&wc)) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to register window class"); - return GLFW_FALSE; + return GL_FALSE; } - return GLFW_TRUE; + return GL_TRUE; } // Unregisters the GLFW window class @@ -803,65 +805,53 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { int status; - if (!createWindow(window, wndconfig)) - return GLFW_FALSE; + if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) + return GL_FALSE; - if (ctxconfig->api != GLFW_NO_API) + status = _glfwAnalyzeContext(window, ctxconfig, fbconfig); + + if (status == _GLFW_RECREATION_IMPOSSIBLE) + return GL_FALSE; + + if (status == _GLFW_RECREATION_REQUIRED) { - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GLFW_FALSE; + // Some window hints require us to re-create the context using WGL + // extensions retrieved through the current context, as we cannot check + // for WGL extensions or retrieve WGL entry points before we have a + // current context (actually until we have implicitly loaded the ICD) -#if defined(_GLFW_WGL) - status = _glfwAnalyzeContext(window, ctxconfig, fbconfig); + // Yes, this is strange, and yes, this is the proper way on Win32 - if (status == _GLFW_RECREATION_IMPOSSIBLE) - return GLFW_FALSE; + // As Windows only allows you to set the pixel format once for a + // window, we need to destroy the current window and create a new one + // to be able to use the new pixel format - if (status == _GLFW_RECREATION_REQUIRED) - { - // Some window hints require us to re-create the context using WGL - // extensions retrieved through the current context, as we cannot - // check for WGL extensions or retrieve WGL entry points before we - // have a current context (actually until we have implicitly loaded - // the vendor ICD) + // Technically, it may be possible to keep the old window around if + // we're just creating an OpenGL 3.0+ context with the same pixel + // format, but it's not worth the added code complexity - // Yes, this is strange, and yes, this is the proper way on WGL + // First we clear the current context (the one we just created) + // This is usually done by glfwDestroyWindow, but as we're not doing + // full GLFW window destruction, it's duplicated here + _glfwPlatformMakeContextCurrent(NULL); - // As Windows only allows you to set the pixel format once for - // a window, we need to destroy the current window and create a new - // one to be able to use the new pixel format + // Next destroy the Win32 window and WGL context (without resetting or + // destroying the GLFW window object) + destroyWindow(window); - // Technically, it may be possible to keep the old window around if - // we're just creating an OpenGL 3.0+ context with the same pixel - // format, but it's not worth the added code complexity - - // First we clear the current context (the one we just created) - // This is usually done by glfwDestroyWindow, but as we're not doing - // full GLFW window destruction, it's duplicated here - _glfwPlatformMakeContextCurrent(NULL); - - // Next destroy the Win32 window and WGL context (without resetting - // or destroying the GLFW window object) - _glfwDestroyContext(window); - destroyWindow(window); - - // ...and then create them again, this time with better APIs - if (!createWindow(window, wndconfig)) - return GLFW_FALSE; - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GLFW_FALSE; - } -#endif // _GLFW_WGL + // ...and then create them again, this time with better APIs + if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) + return GL_FALSE; } if (window->monitor) { _glfwPlatformShowWindow(window); if (!enterFullscreenMode(window)) - return GLFW_FALSE; + return GL_FALSE; } - return GLFW_TRUE; + return GL_TRUE; } void _glfwPlatformDestroyWindow(_GLFWwindow* window) @@ -869,9 +859,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->monitor) leaveFullscreenMode(window); - if (window->context.api != GLFW_NO_API) - _glfwDestroyContext(window); - destroyWindow(window); } @@ -927,8 +914,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) else { int fullWidth, fullHeight; - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - width, height, &fullWidth, &fullHeight); + getFullWindowSize(window, width, height, &fullWidth, &fullHeight); SetWindowPos(window->win32.handle, HWND_TOP, 0, 0, fullWidth, fullHeight, @@ -936,48 +922,6 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) } } -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight) -{ - RECT area; - - window->win32.minwidth = minwidth; - window->win32.minheight = minheight; - window->win32.maxwidth = maxwidth; - window->win32.maxheight = maxheight; - - if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) && - (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)) - { - return; - } - - GetWindowRect(window->win32.handle, &area); - MoveWindow(window->win32.handle, - area.left, area.top, - area.right - area.left, - area.bottom - area.top, TRUE); -} - -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) -{ - RECT area; - - window->win32.numer = numer; - window->win32.denom = denom; - - if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) - return; - - GetWindowRect(window->win32.handle, &area); - applyAspectRatio(window, WMSZ_BOTTOMRIGHT, &area); - MoveWindow(window->win32.handle, - area.left, area.top, - area.right - area.left, - area.bottom - area.top, TRUE); -} - void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { _glfwPlatformGetWindowSize(window, width, height); @@ -1153,54 +1097,20 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) SetCursorPos(pos.x, pos.y); } -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) { - POINT pos; - - if (mode == GLFW_CURSOR_DISABLED) - updateClipRect(window); - else - ClipCursor(NULL); - - if (!GetCursorPos(&pos)) - return; - - if (WindowFromPoint(pos) != window->win32.handle) - return; - - if (mode == GLFW_CURSOR_NORMAL) + switch (window->cursorMode) { - if (window->cursor) - SetCursor(window->cursor->win32.handle); - else - SetCursor(LoadCursorW(NULL, IDC_ARROW)); + case GLFW_CURSOR_NORMAL: + restoreCursor(window); + break; + case GLFW_CURSOR_HIDDEN: + hideCursor(window); + break; + case GLFW_CURSOR_DISABLED: + disableCursor(window); + break; } - else - SetCursor(NULL); -} - -const char* _glfwPlatformGetKeyName(int key, int scancode) -{ - WCHAR name[16]; - - if (key != GLFW_KEY_UNKNOWN) - scancode = _glfw.win32.nativeKeys[key]; - - if (!_glfwIsPrintable(_glfw.win32.publicKeys[scancode])) - return NULL; - - if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR))) - return NULL; - - if (!WideCharToMultiByte(CP_UTF8, 0, name, -1, - _glfw.win32.keyName, - sizeof(_glfw.win32.keyName), - NULL, NULL)) - { - return NULL; - } - - return _glfw.win32.keyName; } int _glfwPlatformCreateCursor(_GLFWcursor* cursor, @@ -1233,13 +1143,13 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, ReleaseDC(NULL, dc); if (!bitmap) - return GLFW_FALSE; + return GL_FALSE; mask = CreateBitmap(image->width, image->height, 1, 1, NULL); if (!mask) { DeleteObject(bitmap); - return GLFW_FALSE; + return GL_FALSE; } for (i = 0; i < image->width * image->height; i++, target++, source += 4) @@ -1263,9 +1173,9 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, DeleteObject(mask); if (!cursor->win32.handle) - return GLFW_FALSE; + return GL_FALSE; - return GLFW_TRUE; + return GL_TRUE; } int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) @@ -1276,10 +1186,10 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create standard cursor"); - return GLFW_FALSE; + return GL_FALSE; } - return GLFW_TRUE; + return GL_TRUE; } void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)