diff --git a/CMakeLists.txt b/CMakeLists.txt index a698baa9..0a809003 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib option(BUILD_SHARED_LIBS "Build shared libraries" OFF) option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) +option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) option(GLFW_INSTALL "Generate installation target" ON) option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) @@ -73,11 +74,13 @@ endif() find_package(Threads REQUIRED) -set(DOXYGEN_SKIP_DOT TRUE) -find_package(Doxygen) +if (GLFW_BUILD_DOCS) + set(DOXYGEN_SKIP_DOT TRUE) + find_package(Doxygen) -if (GLFW_DOCUMENT_INTERNALS) - set(GLFW_INTERNAL_DOCS "${GLFW_SOURCE_DIR}/src/internal.h ${GLFW_SOURCE_DIR}/docs/internal.dox") + if (GLFW_DOCUMENT_INTERNALS) + set(GLFW_INTERNAL_DOCS "${GLFW_SOURCE_DIR}/src/internal.h ${GLFW_SOURCE_DIR}/docs/internal.dox") + endif() endif() #-------------------------------------------------------------------- @@ -407,7 +410,7 @@ if (GLFW_BUILD_TESTS) add_subdirectory(tests) endif() -if (DOXYGEN_FOUND) +if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS) add_subdirectory(docs) endif() diff --git a/README.md b/README.md index 848bc303..7d30fa2c 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,27 @@ guide in the GLFW documentation. ## Changelog + - Added the `GLFW_BUILD_DOCS` CMake option for controlling whether the + documentation is built + - Added the `_GLFW_USE_CONFIG_H` configuration macro for controlling whether to + include the configuration header + - Moved version number macro to `internal.h` for easier manual compilation - Renamed configuration header to `glfw_config.h` to avoid conflicts - Bugfix: The `glfw3.pc` file did not respect the `LIB_SUFFIX` CMake option + - Bugfix: The `joysticks` test would segfault if a controller had no axes + - [Win32] Allowed swap interval to be explicitly set to zero on DWM systems - [Win32] Bugfix: Removed joystick axis value negation left over from GLFW 2 - [Win32] Bugfix: Restoring windows using the Win+D hot key did not trigger the focus callback - [Win32] Bugfix: The disabled cursor mode clip rectangle was updated for unfocused windows + - [Win32] Bugfix: Cursor was not properly re-centered over odd-sized windows + - [Win32] Bugfix: Negative window positions were reported incorrectly + - [Win32] Bugfix: The iconify callback was not triggered when switching away + from a full screen window using Alt+Tab - [Cocoa] Added dependency on CoreVideo framework for refresh rate retrieval - [Cocoa] Enabled Lion full screen for resizable windowed mode windows + - [Cocoa] Moved to Cocoa API for application transformation and activation - [Cocoa] Bugfix: The `GLFW_KEY_GRAVE_ACCENT` key was reported as `GLFW_KEY_WORLD_1` and vice versa - [Cocoa] Bugfix: The `GLFW_KEY_F13` key was reported as @@ -55,10 +67,19 @@ guide in the GLFW documentation. - [Cocoa] Bugfix: Full screen windows were never reported as having focus - [Cocoa] Bugfix: A superfluous I/O flag test prevented video modes from being listed for Thunderbolt monitor + - [Cocoa] Bugfix: Retrieving the name of some external displays caused segfault + - [Cocoa] Bugfix: The 10.9 SDK defines `GLintptrARB` and `GLsizeiptrARB` + differently from the Khronos `glext.h` + - [Cocoa] Bugfix: Creating hidden windows would steal application focus + - [Cocoa] Bugfix: Controllers were reported as having zero buttons and axes + - [Cocoa] Bugfix: Removed joystick axis value negation left over from GLFW 2 - [X11] Added setting of the `WM_CLASS` property to the initial window title + - [X11] Added support for `_NET_WM_BYPASS_COMPOSITOR` - [X11] Bugfix: Removed joystick axis value negation left over from GLFW 2 - [X11] Bugfix: The position of hidden windows was ignored by Metacity and Compiz + - [X11] Bugfix: The `pthread.h` header was not included by the GLX platform + header. ## Contact @@ -104,6 +125,7 @@ skills. - Paul R. Deppe - Jonathan Dummer - Ralph Eastwood + - Michael Fogleman - Gerald Franz - GeO4d - Marcus Geelnard @@ -133,6 +155,7 @@ skills. - Jon Morton - Pierre Moulon - Julian Møller + - Kamil Nowakowski - Ozzy - Andri Pálsson - Peoro diff --git a/deps/GL/glext.h b/deps/GL/glext.h index 6cd79a20..4edeae9f 100644 --- a/deps/GL/glext.h +++ b/deps/GL/glext.h @@ -4130,8 +4130,16 @@ GLAPI void APIENTRY glVertexBlendARB (GLint count); #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 +/* HACK: This is a workaround for gltypes.h on OS X 10.9 defining these types as + * long instead of ptrdiff_t + */ +#if defined(__APPLE__) +typedef long GLsizeiptrARB; +typedef long GLintptrARB; +#else typedef ptrdiff_t GLsizeiptrARB; typedef ptrdiff_t GLintptrARB; +#endif #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 diff --git a/docs/build.dox b/docs/build.dox index 86ec1e5f..c4594cda 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -50,7 +50,9 @@ header that the GLFW header includes and GLEW will work as expected. @subsection build_macros GLFW header option macros These macros may be defined before the inclusion of the GLFW header and affect -how that header behaves. +the behavior of the header. Note that GLFW does not provide any of the OpenGL +or OpenGL ES headers mentioned below. These are provided by your development +environment or your OpenGL or OpenGL ES SDK. `GLFW_INCLUDE_GLCOREARB` makes the header include the modern `GL/glcorearb.h` header (`OpenGL/gl3.h` on OS X) instead of the regular OpenGL header. @@ -83,8 +85,10 @@ The static version of the GLFW library is named `glfw3`. When using this version, it is also necessary to link with some libraries that GLFW uses. When linking a program under Windows that uses the static version of GLFW, you -must link with `opengl32`. If you are using GLU, you must also link with -`glu32`. +must link with `opengl32`. On some versions of MinGW, you must also explicitly +link with `gdi32`, while other versions of MinGW include it in the set of +default libraries along with other dependencies like `user32` and `kernel32`. +If you are using GLU, you must also link with `glu32`. The link library for the GLFW DLL is named `glfw3dll`. When compiling a program that uses the DLL version of GLFW, you need to define the `GLFW_DLL` macro diff --git a/docs/compat.dox b/docs/compat.dox index 9f78f476..e14263f6 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -123,15 +123,15 @@ version 2.1. Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if -given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` is required for -creating contexts for OpenGL 3.2 and later, the `GLFW_OPENGL_DEBUG_CONTEXT` hint -is ignored and setting the `GLFW_OPENGL_PROFILE` hint to anything except -`GLFW_OPENGL_CORE_PROFILE` will cause @ref glfwCreateWindow to fail. +given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to +non-zero and the `GLFW_OPENGL_PROFILE` hint must be set to +`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and -`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, the -`GLFW_OPENGL_DEBUG_CONTEXT` hint will have no effect, and setting the -`GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to a non-zero value -will cause @ref glfwCreateWindow to fail. +`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, +setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to +a non-default value will cause @ref glfwCreateWindow to fail and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. */ diff --git a/docs/compile.dox b/docs/compile.dox index 579f10a2..ef6c3b93 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -19,6 +19,8 @@ Windows and OS X from the [CMake website](http://www.cmake.org/). Additional dependencies are listed below. +If you wish to compile GLFW without CMake, see @ref compile_manual. + @subsection compile_deps_msvc Dependencies using Visual C++ on Windows @@ -81,9 +83,10 @@ not* tie your binaries to the Mesa implementation of OpenGL. Once you have all necessary dependencies it is time to generate the project files or makefiles for your development environment. CMake needs to know two -paths for this: the path to the source directory and the target path for the -generated files and compiled binaries. If these are the same, it is called an -in-tree build, otherwise it is called an out-of-tree build. +paths for this: the path to the *root* directory of the GLFW source tree (i.e. +*not* the `src` subdirectory) and the target path for the generated files and +compiled binaries. If these are the same, it is called an in-tree build, +otherwise it is called an out-of-tree build. One of several advantages of out-of-tree builds is that you can generate files and compile for different development environments using a single source tree. @@ -91,9 +94,10 @@ and compile for different development environments using a single source tree. @subsection compile_cmake_cli Generating files with the CMake command-line tool -To make an in-tree build, enter the root directory of the GLFW source tree and -run CMake. The current directory is used as target path, while the path -provided as an argument is used to find the source tree. +To make an in-tree build, enter the *root* directory of the GLFW source tree +(i.e. *not* the `src` subdirectory) and run CMake. The current directory is +used as target path, while the path provided as an argument is used to find the +source tree. cd cmake . @@ -133,9 +137,9 @@ GNU/Linux have this tool in a separate `cmake-curses-gui` package. `BUILD_SHARED_LIBS` determines whether GLFW is built as a static library or as a DLL / shared library / dynamic library. -`LIB_SUFFIX` affects where the GLFW shared /dynamic library is -installed. If it is empty, it is installed to `$PREFIX/lib`. If it is set to -`64`, it is installed to `$PREFIX/lib64`. +`LIB_SUFFIX` affects where the GLFW shared /dynamic library is installed. If it +is empty, it is installed to `${CMAKE_INSTALL_PREFIX}/lib`. If it is set to +`64`, it is installed to `${CMAKE_INSTALL_PREFIX}/lib64`. `GLFW_CLIENT_LIBRARY` determines which client API library to use. If set to `opengl` the OpenGL library is used, if set to `glesv1` for the OpenGL ES 1.x @@ -149,6 +153,9 @@ along with the library. `GLFW_BUILD_TESTS` determines whether the GLFW test programs are built along with the library. +`GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with +the library. + @subsection compile_options_osx OS X specific CMake options @@ -185,4 +192,70 @@ systems. context creation API. Note that EGL is not yet provided on all supported platforms. + +@section compile_manual Compiling GLFW manually + +If you wish to compile GLFW without its CMake build environment then you will +have to do at least some of the platform detection yourself. GLFW needs +a number of configuration macros to be defined in order to know what it's being +compiled for and has many optional, platform-specific ones for various features. + +When building with CMake, the `glfw_config.h` configuration header is generated +based on the current platform and CMake options. The GLFW CMake environment +defines `_GLFW_USE_CONFIG_H`, which causes this header to be included by +`internal.h`. Without this macro, GLFW will expect the necessary configuration +macros to be defined on the command-line. + +Three macros *must* be defined when compiling GLFW: one for selecting the window +creation API, one selecting the context creation API and one client library. +Exactly one of each kind must be defined for GLFW to compile and link. + +The window creation API is used to create windows, handle input, monitors, gamma +ramps and clipboard. The options are: + + - `_GLFW_COCOA` to use the Cocoa frameworks + - `_GLFW_WIN32` to use the Win32 API + - `_GLFW_X11` to use the X Window System + +The context creation API is used to enumerate pixel formats / framebuffer +configurations and to create contexts. The options are: + + - `_GLFW_NSGL` to use the Cocoa OpenGL framework + - `_GLFW_WGL` to use the Win32 WGL API + - `_GLFW_GLX` to use the X11 GLX API + - `_GLFW_EGL` to use the EGL API (experimental) + +The client library is the one providing the OpenGL or OpenGL ES API, which is +used by GLFW to probe the created context. This is not the same thing as the +client API, as many desktop OpenGL client libraries now expose the OpenGL ES API +through extensions. The options are: + + - `_GLFW_USE_OPENGL` for the desktop OpenGL (opengl32.dll, libGL.so or + OpenGL.framework) + - `_GLFW_USE_GLESV1` for OpenGL ES 1.x (experimental) + - `_GLFW_USE_GLESV2` for OpenGL ES 2.x (experimental) + +Note that `_GLFW_USE_GLESV1` and `_GLFW_USE_GLESV2` may only be used with EGL, +as the other context creation APIs do not interface with OpenGL ES client +libraries. + +If you are building GLFW as a shared library / dynamic library / DLL then you +must also define `_GLFW_BUILD_DLL`. Otherwise, you may not define it. + +If you are using the X11 window creation API then you *must* also select an entry +point retrieval mechanism. + + - `_GLFW_HAS_GLXGETPROCADDRESS` to use `glXGetProcAddress` (recommended) + - `_GLFW_HAS_GLXGETPROCADDRESSARB` to use `glXGetProcAddressARB` (legacy) + - `_GLFW_HAS_GLXGETPROCADDRESSEXT` to use `glXGetProcAddressEXT` (legacy) + - `_GLFW_HAS_DLOPEN` to do manual retrieval with `dlopen` (fallback) + +If you are using the Cocoa window creation API, the following options are +available: + + - `_GLFW_USE_CHDIR` to `chdir` to the `Resources` subdirectory of the + application bundle during @ref glfwInit (recommended) + - `_GLFW_USE_MENUBAR` to create and populate the menu bar when the first window + is created (recommended) + */ diff --git a/docs/context.dox b/docs/context.dox index 56d1de76..8057cc70 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -24,6 +24,15 @@ what kind of context is created. See [context related hints](@ref window_hints_ctx) in the window handling guide. +@section context_sharing Context object sharing + +When creating a window and context with @ref glfwCreateWindow, you can specify +another window whose context the new one should share its objects with. OpenGL +object sharing is implemented by the operating system and graphics driver and is +described in the OpenGL documentation. On platforms where it is possible to +choose which types of objects are shared, GLFW requests that all are shared. + + @section context_current Current context Before you can use the OpenGL or OpenGL ES APIs, you need to have a current diff --git a/docs/news.dox b/docs/news.dox index 6f97afc8..bbce25fd 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -18,7 +18,7 @@ For more information on how to use CMake, see the [CMake manual](http://cmake.org/cmake/help/documentation.html). -@subsection new_30_multiwnd Multi-window support +@subsection news_30_multiwnd Multi-window support GLFW now supports the creation of multiple windows, each with their own OpenGL or OpenGL ES context, and all window functions now take a window handle. Event @@ -79,7 +79,7 @@ through CMake options. GLFW now supports high-DPI monitors on both Windows and OS X, giving windows full resolution framebuffers where other UI elements are scaled up. To achieve this, @ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have been -added. These work with pixels, while the rest of the GLFW API work with screen +added. These work with pixels, while the rest of the GLFW API works with screen coordinates. diff --git a/docs/window.dox b/docs/window.dox index 8a28958a..ab83e505 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -448,7 +448,9 @@ context is an OpenGL debug context, or `GL_FALSE` otherwise. The `GLFW_OPENGL_PROFILE` attribute indicates the OpenGL profile used by the context. This is `GLFW_OPENGL_CORE_PROFILE` or `GLFW_OPENGL_COMPAT_PROFILE` if the context uses a known profile, or `GLFW_OPENGL_ANY_PROFILE` if the -OpenGL profile is unknown or the context is for another client API. +OpenGL profile is unknown or the context is for another client API. Note that +the returned profile may not match the profile bits of the context flags, as +GLFW will try other means of detecting the profile when no bits are set. The `GLFW_CONTEXT_ROBUSTNESS` attribute indicates the robustness strategy used by the context. This is `GLFW_LOSE_CONTEXT_ON_RESET` or @@ -485,8 +487,10 @@ zero can be useful for benchmarking purposes, when it is not desirable to measure the time it takes to wait for the vertical retrace. However, a swap interval of one lets you avoid tearing. -Note that not all OpenGL implementations properly implement this function, in -which case @ref glfwSwapInterval will have no effect. Some drivers also have -user settings that override requests by GLFW. +Note that this may not work on all machines, as some drivers have +user-controlled settings that override any swap interval the application +requests. It is also by default disabled on Windows Vista and later when using +DWM (Aero), as using it there sometimes leads to severe jitter. You can +forcibly enable it for machines using DWM using @ref compile_options_win32. */ diff --git a/examples/heightmap.c b/examples/heightmap.c index 5ae50bfd..c39e6b80 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c @@ -644,7 +644,7 @@ int main(int argc, char** argv) /* main loop */ frame = 0; iter = 0; - dt = last_update_time = glfwGetTime(); + last_update_time = glfwGetTime(); while (!glfwWindowShouldClose(window)) { diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 4bf47ded..0f97738c 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -863,9 +863,6 @@ typedef struct GLFWgammaramp * * @note This function may only be called from the main thread. * - * @note This function may take several seconds to complete on some systems, - * while on other systems it may take only a fraction of a second to complete. - * * @note **OS X:** This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. @@ -1694,6 +1691,12 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * This function is no longer called by @ref glfwSwapBuffers. You need to call * it or @ref glfwWaitEvents yourself. * + * @remarks On some platforms, a window move, resize or menu operation will + * cause event processing to block. This is due to how event processing is + * designed on those platforms. You can use the + * [window refresh callback](@ref GLFWwindowrefreshfun) to redraw the contents + * of your window when necessary during the operation. + * * @note This function may only be called from the main thread. * * @note This function may not be called from a callback. @@ -1721,6 +1724,12 @@ GLFWAPI void glfwPollEvents(void); * * This function is not required for joystick input to work. * + * @remarks On some platforms, a window move, resize or menu operation will + * cause event processing to block. This is due to how event processing is + * designed on those platforms. You can use the + * [window refresh callback](@ref GLFWwindowrefreshfun) to redraw the contents + * of your window when necessary during the operation. + * * @note This function may only be called from the main thread. * * @note This function may not be called from a callback. @@ -1756,9 +1765,12 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * modes: * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client - * area of the window. - * - `GLFW_CURSOR_DISABLED` disables the cursor and removes any limitations on - * cursor movement. + * area of the window but does not restrict the cursor from leaving. This is + * useful if you wish to render your own cursor or have no visible cursor at + * all. + * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual + * and unlimited cursor movement. This is useful for implementing for + * example 3D camera controls. * * If `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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c78ad20..cd699efd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,8 @@ include_directories(${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${glfw_INCLUDE_DIRS}) +add_definitions(-D_GLFW_USE_CONFIG_H) + set(common_HEADERS ${GLFW_BINARY_DIR}/src/glfw_config.h internal.h ${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h ${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 9c2813f8..42b31c54 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -122,7 +122,7 @@ void _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = _GLFW_VERSION_FULL " Cocoa" + const char* version = _GLFW_VERSION_NUMBER " Cocoa" #if defined(_GLFW_NSGL) " NSGL" #endif diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 6824726f..7af1042b 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -251,9 +251,6 @@ static void pollJoystickEvents(void) joystick->axes[i] = value; else joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f; - - if (i & 1) - joystick->axes[i] = -joystick->axes[i]; } for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++) @@ -319,8 +316,9 @@ void _glfwInitJoysticks(void) while ((ioHIDDeviceObject = IOIteratorNext(objectIterator))) { + CFMutableDictionaryRef propsRef = NULL; + CFTypeRef valueRef = NULL; kern_return_t result; - CFTypeRef valueRef = 0; IOCFPlugInInterface** ppPlugInInterface = NULL; HRESULT plugInResult = S_OK; @@ -329,26 +327,29 @@ void _glfwInitJoysticks(void) long usagePage, usage; // Check device type - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDPrimaryUsagePageKey), + result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, + &propsRef, kCFAllocatorDefault, kNilOptions); + + if (result != kIOReturnSuccess) + continue; + + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsagePageKey)); if (valueRef) { CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage); if (usagePage != kHIDPage_GenericDesktop) { // This device is not relevant to GLFW + CFRelease(valueRef); continue; } CFRelease(valueRef); } - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDPrimaryUsageKey), - kCFAllocatorDefault, - kNilOptions); + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsageKey)); if (valueRef) { CFNumberGetValue(valueRef, kCFNumberLongType, &usage); @@ -358,6 +359,7 @@ void _glfwInitJoysticks(void) usage != kHIDUsage_GD_MultiAxisController)) { // This device is not relevant to GLFW + CFRelease(valueRef); continue; } @@ -393,10 +395,7 @@ void _glfwInitJoysticks(void) joystick); // Get product string - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDProductKey), - kCFAllocatorDefault, - kNilOptions); + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDProductKey)); if (valueRef) { CFStringGetCString(valueRef, @@ -410,10 +409,7 @@ void _glfwInitJoysticks(void) joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); joystick->hatElements = CFArrayCreateMutable(NULL, 0, NULL); - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDElementKey), - kCFAllocatorDefault, - kNilOptions); + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDElementKey)); if (CFGetTypeID(valueRef) == CFArrayGetTypeID()) { CFRange range = { 0, CFArrayGetCount(valueRef) }; diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 504a5fc9..caddde40 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -49,9 +49,11 @@ static const char* getDisplayName(CGDirectDisplayID displayID) kIODisplayOnlyPreferredName); names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); - if (!CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), - (const void**) &value)) + if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), + (const void**) &value)) { + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name"); + CFRelease(info); return strdup("Unknown"); } diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 5010a19a..81701941 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -67,7 +67,7 @@ static void enterFullscreenMode(_GLFWwindow* window) withOptions:options]; // HACK: Synthesize focus event as window does not become key when the view - // is made full screen + // is made full screen // TODO: Remove this when moving to a full screen window _glfwInputWindowFocus(window, GL_TRUE); } @@ -80,7 +80,7 @@ static void leaveFullscreenMode(_GLFWwindow* window) return; // HACK: Synthesize focus event as window does not become key when the view - // is made full screen + // is made full screen // TODO: Remove this when moving to a full screen window _glfwInputWindowFocus(window, GL_FALSE); @@ -266,7 +266,6 @@ static int translateFlags(NSUInteger flags) static int translateKey(unsigned int key) { // Keyboard symbol translation table - // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. static const unsigned int table[128] = { /* 00 */ GLFW_KEY_A, @@ -827,13 +826,8 @@ static GLboolean initializeAppKit(void) // Implicitly create shared NSApplication instance [GLFWApplication sharedApplication]; - // If we get here, the application is unbundled - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - - // Having the app in front of the terminal window is also generally - // handy. There is an NSApplication API to do this, but... - SetFrontProcess(&psn); + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; #if defined(_GLFW_USE_MENUBAR) // Menu bar setup must go between sharedApplication above and @@ -1040,6 +1034,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window) { + // Make us the active application + // HACK: This has been moved here from initializeAppKit to prevent + // applications using only hidden windows from being activated, but + // should probably not be done every time any window is shown + [NSApp activateIgnoringOtherApps:YES]; + [window->ns.object makeKeyAndOrderFront:nil]; _glfwInputWindowVisibility(window, GL_TRUE); } diff --git a/src/context.c b/src/context.c index ca7b8d61..3bc86bc5 100644 --- a/src/context.c +++ b/src/context.c @@ -98,7 +98,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) if (wndconfig->clientAPI == GLFW_OPENGL_API) { - if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0 || + if ((wndconfig->glMajor < 1 || wndconfig->glMinor < 0) || (wndconfig->glMajor == 1 && wndconfig->glMinor > 5) || (wndconfig->glMajor == 2 && wndconfig->glMinor > 1) || (wndconfig->glMajor == 3 && wndconfig->glMinor > 3)) @@ -402,8 +402,8 @@ GLboolean _glfwRefreshContextAttribs(void) else if (glfwExtensionSupported("GL_ARB_debug_output")) { // HACK: This is a workaround for older drivers (pre KHR_debug) - // not setting the debug bit in the context flags for debug - // contexts + // not setting the debug bit in the context flags for + // debug contexts window->glDebug = GL_TRUE; } } @@ -419,13 +419,21 @@ GLboolean _glfwRefreshContextAttribs(void) window->glProfile = GLFW_OPENGL_COMPAT_PROFILE; else if (mask & GL_CONTEXT_CORE_PROFILE_BIT) window->glProfile = GLFW_OPENGL_CORE_PROFILE; + else if (glfwExtensionSupported("GL_ARB_compatibility")) + { + // HACK: This is a workaround for the compatibility profile bit + // not being set in the context flags if an OpenGL 3.2+ + // context was created without having requested a specific + // version + window->glProfile = GLFW_OPENGL_COMPAT_PROFILE; + } } // Read back robustness strategy if (glfwExtensionSupported("GL_ARB_robustness")) { // NOTE: We avoid using the context flags for detection, as they are - // only present from 3.0 while the extension applies from 1.1 + // only present from 3.0 while the extension applies from 1.1 GLint strategy; glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); @@ -442,7 +450,7 @@ GLboolean _glfwRefreshContextAttribs(void) if (glfwExtensionSupported("GL_EXT_robustness")) { // NOTE: The values of these constants match those of the OpenGL ARB - // one, so we can reuse them here + // one, so we can reuse them here GLint strategy; glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); @@ -566,7 +574,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension) return GL_FALSE; } - if (extension == NULL || *extension == '\0') + if (!extension || *extension == '\0') { _glfwInputError(GLFW_INVALID_VALUE, NULL); return GL_FALSE; @@ -577,11 +585,15 @@ GLFWAPI int glfwExtensionSupported(const char* extension) // Check if extension is in the old style OpenGL extensions string extensions = glGetString(GL_EXTENSIONS); - if (extensions != NULL) + if (!extensions) { - if (_glfwStringInExtensionString(extension, extensions)) - return GL_TRUE; + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve extension string"); + return GL_FALSE; } + + if (_glfwStringInExtensionString(extension, extensions)) + return GL_TRUE; } #if defined(_GLFW_USE_OPENGL) else @@ -596,11 +608,15 @@ GLFWAPI int glfwExtensionSupported(const char* extension) for (i = 0; i < count; i++) { const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i); - if (en != NULL) + if (!en) { - if (strcmp(en, extension) == 0) - return GL_TRUE; + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve extension string %i", i); + return GL_FALSE; } + + if (strcmp(en, extension) == 0) + return GL_TRUE; } } #endif // _GLFW_USE_OPENGL diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index ea65a943..a7318602 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -81,6 +81,3 @@ // Define this to 1 if using OpenGL ES 2.0 as the client library #cmakedefine _GLFW_USE_GLESV2 -// The GLFW version as used by glfwGetVersionString -#define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@" - diff --git a/src/glx_context.c b/src/glx_context.c index 58c25757..6b87000d 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -30,7 +30,6 @@ #include #include #include -#include // This is the only glXGetProcAddress variant not declared by glxext.h @@ -75,7 +74,7 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul if (strcmp(vendor, "Chromium") == 0) { // HACK: This is a (hopefully temporary) workaround for Chromium - // (VirtualBox GL) not setting the window bit on any GLXFBConfigs + // (VirtualBox GL) not setting the window bit on any GLXFBConfigs trustWindowBit = GL_FALSE; } @@ -457,8 +456,8 @@ int _glfwCreateContext(_GLFWwindow* window, if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) { // NOTE: Only request an explicitly versioned context when - // necessary, as explicitly requesting version 1.0 does not always - // return the highest available version + // necessary, as explicitly requesting version 1.0 does not + // always return the highest available version setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor); setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor); @@ -485,8 +484,9 @@ int _glfwCreateContext(_GLFWwindow* window, if (window->glx.context == NULL) { // HACK: This is a fallback for the broken Mesa implementation of - // GLX_ARB_create_context_profile, which fails default 1.0 context - // creation with a GLXBadProfileARB error in violation of the spec + // GLX_ARB_create_context_profile, which fails default 1.0 + // context creation with a GLXBadProfileARB error in violation + // of the extension spec if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && wndconfig->clientAPI == GLFW_OPENGL_API && wndconfig->glProfile == GLFW_OPENGL_ANY_PROFILE && diff --git a/src/glx_platform.h b/src/glx_platform.h index 74e60a81..4b133a2d 100644 --- a/src/glx_platform.h +++ b/src/glx_platform.h @@ -41,6 +41,8 @@ #include #endif +#include + // We support four different ways for getting addresses for GL/GLX // extension functions: glXGetProcAddress, glXGetProcAddressARB, // glXGetProcAddressEXT, and dlsym diff --git a/src/internal.h b/src/internal.h index 357277eb..8a24959a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -29,7 +29,11 @@ #define _internal_h_ -#include "glfw_config.h" +#if defined(_GLFW_USE_CONFIG_H) + #include "glfw_config.h" +#endif + +#define _GLFW_VERSION_NUMBER "3.0.4" #if defined(_GLFW_USE_OPENGL) // This is the default for glfw3.h @@ -750,11 +754,18 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size); */ void _glfwFreeGammaArrays(GLFWgammaramp* ramp); -/*! @ingroup utility +/*! @brief Allocates and returns a monitor object with the specified name + * and dimensions. + * @param[in] name The name of the monitor. + * @param[in] widthMM The width, in mm, of the monitor's display area. + * @param[in] heightMM The height, in mm, of the monitor's display area. + * @return The newly created object. + * @ingroup utility */ _GLFWmonitor* _glfwCreateMonitor(const char* name, int widthMM, int heightMM); -/*! @ingroup utility +/*! @brief Frees a monitor object and any data associated with it. + * @ingroup utility */ void _glfwDestroyMonitor(_GLFWmonitor* monitor); diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 1051fe7d..71638ad1 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -178,7 +178,7 @@ int _glfwCreateContext(_GLFWwindow* window, } // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB - // frambuffer, so there's no need (and no way) to request it + // frambuffer, so there's no need (and no way) to request it ADD_ATTR(0); diff --git a/src/wgl_context.c b/src/wgl_context.c index ccd7f574..0b3610bd 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -272,9 +272,21 @@ static GLboolean choosePixelFormat(_GLFWwindow* window, usableCount++; } + if (!usableCount) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "WGL: The driver does not appear to support OpenGL"); + + free(usableConfigs); + return GL_FALSE; + } + closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (!closest) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to find a suitable pixel format"); + free(usableConfigs); return GL_FALSE; } @@ -355,11 +367,7 @@ int _glfwCreateContext(_GLFWwindow* window, } if (!choosePixelFormat(window, fbconfig, &pixelFormat)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "WGL: Failed to find a suitable pixel format"); return GL_FALSE; - } if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) { @@ -598,7 +606,7 @@ void _glfwPlatformSwapInterval(int interval) _GLFWwindow* window = _glfwPlatformGetCurrentContext(); #if !defined(_GLFW_USE_DWM_SWAP_INTERVAL) - if (_glfwIsCompositionEnabled()) + if (_glfwIsCompositionEnabled() && interval) { // Don't enabled vsync when desktop compositing is enabled, as it leads // to frame jitter diff --git a/src/win32_init.c b/src/win32_init.c index 8e0c19b0..aae46a9b 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -243,7 +243,7 @@ void _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = _GLFW_VERSION_FULL " Win32" + const char* version = _GLFW_VERSION_NUMBER " Win32" #if defined(_GLFW_WGL) " WGL" #elif defined(_GLFW_EGL) @@ -252,7 +252,7 @@ const char* _glfwPlatformGetVersionString(void) #if defined(__MINGW32__) " MinGW" #elif defined(_MSC_VER) - " VisualC " + " VisualC" #elif defined(__BORLANDC__) " BorlandC" #endif diff --git a/src/win32_platform.h b/src/win32_platform.h index 69038651..11d774b7 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -157,7 +157,7 @@ typedef struct _GLFWwindowWin32 GLboolean cursorCentered; GLboolean cursorInside; GLboolean cursorHidden; - double oldCursorX, oldCursorY; + int oldCursorX, oldCursorY; } _GLFWwindowWin32; diff --git a/src/win32_window.c b/src/win32_window.c index 7480f70c..32b6ff21 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -145,7 +145,7 @@ static int translateKey(WPARAM wParam, LPARAM lParam) { // Check for numeric keypad keys // NOTE: This way we always force "NumLock = ON", which is intentional since - // the returned key code should correspond to a physical location. + // the returned key code should correspond to a physical location. if ((HIWORD(lParam) & 0x100) == 0) { switch (MapVirtualKey(HIWORD(lParam) & 0xFF, 1)) @@ -442,6 +442,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return 0; } + case WM_ACTIVATEAPP: + { + if (!wParam && IsIconic(hWnd)) + { + // This is a workaround for full screen windows losing focus + // through Alt+Tab leading to windows being told they're + // unfocused and restored and then never told they're iconified + _glfwInputWindowIconify(window, GL_TRUE); + } + + return 0; + } + case WM_SHOWWINDOW: { _glfwInputWindowVisibility(window, wParam ? GL_TRUE : GL_FALSE); @@ -604,7 +617,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (newCursorX != window->win32.oldCursorX || newCursorY != window->win32.oldCursorY) { - double x, y; + int x, y; if (window->cursorMode == GLFW_CURSOR_DISABLED) { @@ -684,7 +697,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, updateClipRect(window); } - _glfwInputWindowPos(window, LOWORD(lParam), HIWORD(lParam)); + // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as + // those macros do not handle negative window positions correctly + _glfwInputWindowPos(window, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam)); return 0; } @@ -1121,8 +1138,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) ClientToScreen(window->win32.handle, &pos); SetCursorPos(pos.x, pos.y); - window->win32.oldCursorX = xpos; - window->win32.oldCursorY = ypos; + window->win32.oldCursorX = (int) xpos; + window->win32.oldCursorY = (int) ypos; } void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) diff --git a/src/window.c b/src/window.c index de75952b..4e2b2770 100644 --- a/src/window.c +++ b/src/window.c @@ -213,10 +213,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->videoMode.refreshRate = Max(_glfw.hints.refreshRate, 0); } - window->monitor = wndconfig.monitor; - window->resizable = wndconfig.resizable; - window->decorated = wndconfig.decorated; - window->cursorMode = GLFW_CURSOR_NORMAL; + window->monitor = wndconfig.monitor; + window->resizable = wndconfig.resizable; + window->decorated = wndconfig.decorated; + window->cursorMode = GLFW_CURSOR_NORMAL; // Save the currently current context so it can be restored later previous = (_GLFWwindow*) glfwGetCurrentContext(); diff --git a/src/x11_init.c b/src/x11_init.c index 3d94ff5e..5b477f04 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -409,6 +409,8 @@ static void detectEWMH(void) getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING"); _glfw.x11.NET_ACTIVE_WINDOW = getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); + _glfw.x11.NET_WM_BYPASS_COMPOSITOR = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_BYPASS_COMPOSITOR"); XFree(supportedAtoms); @@ -680,7 +682,7 @@ void _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = _GLFW_VERSION_FULL " X11" + const char* version = _GLFW_VERSION_NUMBER " X11" #if defined(_GLFW_GLX) " GLX" #elif defined(_GLFW_EGL) diff --git a/src/x11_monitor.c b/src/x11_monitor.c index de3287cd..48d47b4a 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -111,6 +111,9 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) } } + if (bestMode == ci->mode) + return; + if (monitor->x11.oldMode == None) monitor->x11.oldMode = ci->mode; diff --git a/src/x11_platform.h b/src/x11_platform.h index 868429fa..f8129385 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -117,6 +117,7 @@ typedef struct _GLFWlibraryX11 Atom NET_WM_PING; Atom NET_WM_STATE; Atom NET_WM_STATE_FULLSCREEN; + Atom NET_WM_BYPASS_COMPOSITOR; Atom NET_ACTIVE_WINDOW; Atom MOTIF_WM_HINTS; diff --git a/src/x11_window.c b/src/x11_window.c index ac78a154..7f756950 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -129,13 +129,15 @@ static GLboolean createWindow(_GLFWwindow* window, if (wndconfig->monitor == NULL) { // HACK: This is a workaround for windows without a background pixel - // not getting any decorations on certain older versions of Compiz - // running on Intel hardware + // not getting any decorations on certain older versions of + // Compiz running on Intel hardware wa.background_pixel = BlackPixel(_glfw.x11.display, _glfw.x11.screen); wamask |= CWBackPixel; } + _glfwGrabXErrorHandler(); + window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, 0, 0, @@ -147,12 +149,12 @@ static GLboolean createWindow(_GLFWwindow* window, wamask, &wa); + _glfwReleaseXErrorHandler(); + if (!window->x11.handle) { - // TODO: Handle all the various error codes here and translate them - // to GLFW errors - - _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); + _glfwInputXError(GLFW_PLATFORM_ERROR, + "X11: Failed to create window"); return GL_FALSE; } @@ -203,13 +205,13 @@ static GLboolean createWindow(_GLFWwindow* window, // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol - if (_glfw.x11.WM_DELETE_WINDOW != None) + if (_glfw.x11.WM_DELETE_WINDOW) protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; // The _NET_WM_PING EWMH protocol // Tells the WM to ping the GLFW window and flag the application as // unresponsive if the WM doesn't get a reply within a few seconds - if (_glfw.x11.NET_WM_PING != None) + if (_glfw.x11.NET_WM_PING) protocols[count++] = _glfw.x11.NET_WM_PING; if (count > 0) @@ -219,7 +221,7 @@ static GLboolean createWindow(_GLFWwindow* window, } } - if (_glfw.x11.NET_WM_PID != None) + if (_glfw.x11.NET_WM_PID) { const pid_t pid = getpid(); @@ -258,6 +260,9 @@ static GLboolean createWindow(_GLFWwindow* window, } else { + // HACK: Explicitly setting PPosition to any value causes some WMs, + // notably Compiz and Metacity, to honor the position of + // unmapped windows set by XMoveWindow hints->flags |= PPosition; hints->x = hints->y = 0; } @@ -275,7 +280,7 @@ static GLboolean createWindow(_GLFWwindow* window, // Set ICCCM WM_CLASS property // HACK: Until a mechanism for specifying the application name is added, the - // initial window title is used as the window class name + // initial window title is used as the window class name if (strlen(wndconfig->title)) { XClassHint* hint = XAllocClassHint(); @@ -394,15 +399,22 @@ static void enterFullscreenMode(_GLFWwindow* window) _glfwSetVideoMode(window->monitor, &window->videoMode); - if (_glfw.x11.hasEWMH && - _glfw.x11.NET_WM_STATE != None && - _glfw.x11.NET_WM_STATE_FULLSCREEN != None) + if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) + { + const unsigned long value = 1; + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, + PropModeReplace, (unsigned char*) &value, 1); + } + + if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) { int x, y; _glfwPlatformGetMonitorPos(window->monitor, &x, &y); _glfwPlatformSetWindowPos(window, x, y); - if (_glfw.x11.NET_ACTIVE_WINDOW != None) + if (_glfw.x11.NET_ACTIVE_WINDOW) { // Ask the window manager to raise and focus the GLFW window // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end @@ -482,9 +494,16 @@ static void leaveFullscreenMode(_GLFWwindow* window) _glfw.x11.saver.exposure); } - if (_glfw.x11.hasEWMH && - _glfw.x11.NET_WM_STATE != None && - _glfw.x11.NET_WM_STATE_FULLSCREEN != None) + if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) + { + const unsigned long value = 0; + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, + PropModeReplace, (unsigned char*) &value, 1); + } + + if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) { // Ask the window manager to make the GLFW window a normal window // Normal windows usually have frames and other decorations @@ -712,7 +731,7 @@ static void processEvent(XEvent *event) _glfwInputWindowCloseRequest(window); } - else if (_glfw.x11.NET_WM_PING != None && + else if (_glfw.x11.NET_WM_PING && (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) { // The window manager is pinging the application to ensure it's @@ -994,7 +1013,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) NULL, NULL, NULL); #endif - if (_glfw.x11.NET_WM_NAME != None) + if (_glfw.x11.NET_WM_NAME) { XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8, @@ -1002,7 +1021,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) (unsigned char*) title, strlen(title)); } - if (_glfw.x11.NET_WM_ICON_NAME != None) + if (_glfw.x11.NET_WM_ICON_NAME) { XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8, @@ -1019,7 +1038,7 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, 0, 0, &x, &y, &child); - if (child != None) + if (child) { int left, top; @@ -1100,6 +1119,9 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window) { // Override-redirect windows cannot be iconified or restored, as those // tasks are performed by the window manager + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Iconification of full screen windows requires " + "a WM that supports EWMH"); return; } @@ -1112,6 +1134,9 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) { // Override-redirect windows cannot be iconified or restored, as those // tasks are performed by the window manager + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Iconification of full screen windows requires " + "a WM that supports EWMH"); return; } @@ -1153,10 +1178,8 @@ void _glfwPlatformWaitEvents(void) { if (!XPending(_glfw.x11.display)) { - int fd; fd_set fds; - - fd = ConnectionNumber(_glfw.x11.display); + const int fd = ConnectionNumber(_glfw.x11.display); FD_ZERO(&fds); FD_SET(fd, &fds); diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index ed7b9df6..fc312dee 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -253,9 +253,6 @@ int main(int argc, char** argv) } } - argc -= optind; - argv += optind; - // Initialize GLFW and create window if (!valid_version()) diff --git a/tests/joysticks.c b/tests/joysticks.c index cd49cd46..a3a5cd7e 100644 --- a/tests/joysticks.c +++ b/tests/joysticks.c @@ -64,43 +64,47 @@ static void framebuffer_size_callback(GLFWwindow* window, int width, int height) static void draw_joystick(Joystick* j, int x, int y, int width, int height) { int i; - int axis_width, axis_height; - int button_width, button_height; + const int axis_height = 3 * height / 4; + const int button_height = height / 4; - axis_width = width / j->axis_count; - axis_height = 3 * height / 4; - - button_width = width / j->button_count; - button_height = height / 4; - - for (i = 0; i < j->axis_count; i++) + if (j->axis_count) { - float value = j->axes[i] / 2.f + 0.5f; + const int axis_width = width / j->axis_count; - glColor3f(0.3f, 0.3f, 0.3f); - glRecti(x + i * axis_width, - y, - x + (i + 1) * axis_width, - y + axis_height); + for (i = 0; i < j->axis_count; i++) + { + float value = j->axes[i] / 2.f + 0.5f; - glColor3f(1.f, 1.f, 1.f); - glRecti(x + i * axis_width, - y + (int) (value * (axis_height - 5)), - x + (i + 1) * axis_width, - y + 5 + (int) (value * (axis_height - 5))); + glColor3f(0.3f, 0.3f, 0.3f); + glRecti(x + i * axis_width, + y, + x + (i + 1) * axis_width, + y + axis_height); + + glColor3f(1.f, 1.f, 1.f); + glRecti(x + i * axis_width, + y + (int) (value * (axis_height - 5)), + x + (i + 1) * axis_width, + y + 5 + (int) (value * (axis_height - 5))); + } } - for (i = 0; i < j->button_count; i++) + if (j->button_count) { - if (j->buttons[i]) - glColor3f(1.f, 1.f, 1.f); - else - glColor3f(0.3f, 0.3f, 0.3f); + const int button_width = width / j->button_count; - glRecti(x + i * button_width, - y + axis_height, - x + (i + 1) * button_width, - y + axis_height + button_height); + for (i = 0; i < j->button_count; i++) + { + if (j->buttons[i]) + glColor3f(1.f, 1.f, 1.f); + else + glColor3f(0.3f, 0.3f, 0.3f); + + glRecti(x + i * button_width, + y + axis_height, + x + (i + 1) * button_width, + y + axis_height + button_height); + } } } diff --git a/tests/modes.c b/tests/modes.c index 37e9a675..76353685 100644 --- a/tests/modes.c +++ b/tests/modes.c @@ -218,9 +218,6 @@ int main(int argc, char** argv) } } - argc -= optind; - argv += optind; - glfwSetErrorCallback(error_callback); if (!glfwInit())