Compare commits

..

4 Commits

Author SHA1 Message Date
Camilla Löwy cad8f2f7d5 Cocoa: Initial implementation of glfwDragWindow 2017-09-28 19:14:51 +02:00
Camilla Löwy ea46ea0929 Cleanup 2017-08-04 02:41:52 +02:00
Camilla Löwy ce87a1142e Move glfwDragWindow demo to windows test 2017-08-04 02:40:09 +02:00
Felipe Ferreira da Silva a4c76fbeed Add glfwDragWindow
This is the initial implementation of glfwDragWindow, with support for
X11. The function glfwDragWindow requires only the target window to be
dragged. To make the function easier and more portable, the position of
the window and of the cursor are grabbed internally, so the end-user do
not need to pass them manually.

The example 'simple.c' was updated to include this functionality when
clicking on the client area of the window.
2017-08-04 02:38:35 +02:00
46 changed files with 565 additions and 1509 deletions
+2 -2
View File
@@ -19,5 +19,5 @@ notifications:
- provider: Email
to:
- ci@glfw.org
on_build_failure: true
on_build_success: false
- on_build_failure: true
- on_build_success: false
-33
View File
@@ -1,33 +0,0 @@
# Usage:
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
set(template_path "${CMAKE_ARGV3}")
set(target_path "${CMAKE_ARGV4}")
if (NOT EXISTS "${template_path}")
message(FATAL_ERROR "Failed to find template file ${template_path}")
endif()
file(DOWNLOAD "${source_url}" "${source_path}"
STATUS download_status
TLS_VERIFY on)
list(GET download_status 0 status_code)
list(GET download_status 1 status_message)
if (status_code)
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
endif()
file(STRINGS "${source_path}" lines)
foreach(line ${lines})
if ("${line}" MATCHES "^[0-9a-fA-F].*$")
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\\n\"\n")
endif()
endforeach()
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
file(REMOVE "${source_path}")
+20 -10
View File
@@ -181,7 +181,7 @@ endif()
#--------------------------------------------------------------------
if (GLFW_VULKAN_STATIC)
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
list(APPEND glfw_LIBRARIES "${VULKAN_STATIC_LIBRARY}" ${GLFW_VULKAN_DEPS})
list(APPEND glfw_LIBRARIES ${VULKAN_STATIC_LIBRARY} ${GLFW_VULKAN_DEPS})
if (BUILD_SHARED_LIBS)
message(WARNING "Linking Vulkan loader static library into GLFW")
endif()
@@ -245,28 +245,38 @@ if (_GLFW_X11)
# Check for XRandR (modern resolution switching and gamma control)
if (NOT X11_Xrandr_FOUND)
message(FATAL_ERROR "The RandR headers were not found")
message(FATAL_ERROR "The RandR library and headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}")
list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}")
list(APPEND glfw_PKG_DEPS "xrandr")
# Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_FOUND)
message(FATAL_ERROR "The Xinerama headers were not found")
message(FATAL_ERROR "The Xinerama library and headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}")
list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}")
list(APPEND glfw_PKG_DEPS "xinerama")
# Check for Xkb (X keyboard extension)
if (NOT X11_Xkb_FOUND)
message(FATAL_ERROR "The X keyboard extension headers were not found")
endif()
# Check for Xcursor (cursor creation from RGBA images)
list(APPEND glfw_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}")
# Check for Xcursor
if (NOT X11_Xcursor_FOUND)
message(FATAL_ERROR "The Xcursor headers were not found")
message(FATAL_ERROR "The Xcursor libraries and headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
"${X11_Xinerama_INCLUDE_PATH}"
"${X11_Xkb_INCLUDE_PATH}"
"${X11_Xcursor_INCLUDE_PATH}")
list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}")
list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}")
list(APPEND glfw_PKG_DEPS "xcursor")
endif()
#--------------------------------------------------------------------
@@ -274,7 +284,7 @@ endif()
#--------------------------------------------------------------------
if (_GLFW_WAYLAND)
find_package(ECM REQUIRED NO_MODULE)
list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
find_package(Wayland REQUIRED)
find_package(WaylandScanner REQUIRED)
+10 -46
View File
@@ -138,8 +138,8 @@ information on what to include when reporting a bug.
for retrieving gamepad input state (#900)
- Added `glfwRequestWindowAttention` function for requesting attention from the
user (#732,#988)
- Added `glfwGetEventTime` function for querying the time of the last input
event (#1012)
- Added `glfwDragWindow` function for starting a drag operation on a window
(#987)
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
scancodes for keys (#830)
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
@@ -148,8 +148,6 @@ information on what to include when reporting a bug.
- Added `glfwGetJoystickHats` function for querying joystick hats
(#889,#906,#934)
- Added `glfwInitHint` and `glfwInitHintString` for setting initialization hints
- Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString`
functions for accessing X11 primary selection (#894,#1056)
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
- Added definition of `GLAPIENTRY` to public header
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
@@ -165,7 +163,6 @@ information on what to include when reporting a bug.
- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
- Added `GenerateMappings.cmake` script for updating gamepad mappings
- Removed `GLFW_USE_RETINA` compile-time option
- Removed `GLFW_USE_CHDIR` compile-time option
- Removed `GLFW_USE_MENUBAR` compile-time option
@@ -178,7 +175,6 @@ information on what to include when reporting a bug.
- Bugfix: The scancode for synthetic key release events was always zero
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
- [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928)
@@ -192,11 +188,6 @@ information on what to include when reporting a bug.
- [Win32] Bugfix: Monitors with no display devices were not enumerated (#960)
- [Win32] Bugfix: Monitor events were not emitted (#784)
- [Win32] Bugfix: The Cygwin DLL was installed to the wrong directory (#1035)
- [Win32] Bugfix: Normalization of axis data via XInput was incorrect (#1045)
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
(#650,#1071)
- [Win32] Bugfix: Returned key names did not match other platforms (#943)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
@@ -210,8 +201,6 @@ information on what to include when reporting a bug.
- [Linux] Moved to evdev for joystick input (#906,#1005)
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
- [Linux] Bugfix: `glfwInit` would fail if inotify creation failed (#833)
- [Linux] Bugfix: `strdup` was used without any required feature macro (#1055)
- [Cocoa] Added support for Vulkan window surface creation via
[MoltenVK](https://moltengl.com/moltenvk/) (#870)
- [Cocoa] Added support for loading a `MainMenu.nib` when available
@@ -229,10 +218,6 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: Value range was ignored for joystick hats and buttons (#888)
- [Cocoa] Bugfix: Full screen framebuffer was incorrectly sized for some video
modes (#682)
- [Cocoa] Bugfix: A string object for IME was updated non-idiomatically (#1050)
- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
notification was shown (#971,#1028)
- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
- [WGL] Added support for `WGL_ARB_create_context_no_error`
- [GLX] Added support for `GLX_ARB_create_context_no_error`
@@ -266,8 +251,9 @@ GLFW exists because people around the world donated their time and lent their
skills.
- Bobyshev Alexander
- artblanc
- arturo
- Matt Arsenault
- David Avedissian
- Keith Bauer
- John Bartholomew
- Niklas Behrens
@@ -276,16 +262,11 @@ skills.
- Doug Binks
- blanco
- Kyle Brenneman
- Rok Breulj
- Martin Capitanio
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Noel Cower
- Jason Daly
@@ -297,8 +278,6 @@ skills.
- Mario Dorn
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
- Robin Eklind
- Siavash Eliasi
- Felipe Ferreira
- Michael Fogleman
@@ -308,7 +287,6 @@ skills.
- Marcus Geelnard
- Eloi Marín Gratacós
- Stefan Gustavson
- Jonathan Hale
- Sylvain Hellegouarch
- Matthew Henry
- heromyth
@@ -321,22 +299,20 @@ skills.
- Toni Jovanoski
- Arseny Kapoulkine
- Osman Keskin
- Josh Kilmer
- Cameron King
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
- Konstantin Käfer
- Eric Larson
- Robin Leffmann
- Glenn Lewis
- Shane Liesegang
- Eyal Lotem
- Дмитри Малышев
- Martins Mozeiko
- Tristam MacDonald
- Hans Mackowiak
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Célestin Marot
- Kyle McDonald
- David Medlock
- Bryce Mehring
@@ -348,15 +324,10 @@ skills.
- Bruce Mitchener
- Jack Moffitt
- Jeff Molofee
- Pierre Morel
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Julian Møller
- ndogxj
- Kristian Nielsen
- Kamil Nowakowski
- Denis Ovod
- Ozzy
- Andri Pálsson
- Peoro
@@ -366,34 +337,28 @@ skills.
- Orson Peters
- Emmanuel Gil Peyrot
- Cyril Pichard
- Keith Pitt
- Stanislav Podgorskiy
- Alexandre Pretyman
- Pieroman
- Philip Rideout
- Eddie Ringle
- Jorge Rodriguez
- Ed Ropple
- Aleksey Rybalkin
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- SephiRok
- Steve Sexton
- Arkady Shapkin
- Systemcluster
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Daniel Skorupski
- Bradley Smith
- Patrick Snape
- Erlend Sogge Heggen
- Julian Squires
- Johannes Stein
- Pontus Stenetorp
- Michael Stocker
- Justin Stoecker
- Elviss Strazdins
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Sergey Tikhomirov
@@ -403,7 +368,6 @@ skills.
- Matthew Turner
- urraka
- Elias Vanderstuyft
- Stef Velzel
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
@@ -413,8 +377,8 @@ skills.
- Xo Wang
- Jay Weisskopf
- Frank Wille
- yuriks
- Ryogo Yoshimura
- Andrey Zholos
- Santi Zupancic
- Jonas Ådahl
- Lasse Öörni
-6
View File
@@ -265,12 +265,6 @@ If you are linking the Vulkan loader statically into your application then you
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
external version.
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
or GLESv2 library, you can override the default names by defining those you need
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
_GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names.
For the EGL context creation API, the following options are available:
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
+1
View File
@@ -25,6 +25,7 @@ $extrastylesheet
<ul class="glfwnavbar">
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
<li><a href="http://www.glfw.org/download.html">Download</a></li>
<li><a href="http://www.glfw.org/media.html">Media</a></li>
<li><a href="http://www.glfw.org/community.html">Community</a></li>
</ul>
</div>
+28 -32
View File
@@ -82,9 +82,6 @@ Some hints are platform specific. These may be set on any platform but they
will only affect their specific platform. Other platforms will simply ignore
them. Setting these hints requires no platform specific headers or functions.
@subsubsection init_hints_shared Shared init hints
@anchor GLFW_JOYSTICK_HAT_BUTTONS
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of GLFW that did not have @ref
@@ -115,7 +112,7 @@ Set this with @ref glfwInitHintString.
@subsubsection init_hints_values Supported and default values
Initialization hint | Default value | Supported values
Init hint | Default value | Supported values
------------------------------- | ------------- | ----------------
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@@ -302,39 +299,35 @@ functions not on this list will not be made non-reentrant.
@subsection thread_safety Thread safety
Most GLFW functions must only be called from the main thread (the thread that
calls main), but some may be called from any thread once the library has been
initialized. Before initialization the whole library is thread-unsafe.
Most GLFW functions must only be called from the main thread, but some may be
called from any thread. However, no GLFW function may be called from any thread
but the main thread until GLFW has been successfully initialized, including
functions that may called before initialization.
The reference documentation for every GLFW function states whether it is limited
to the main thread.
Initialization, termination, event processing and the creation and
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
restricted to the main thread due to limitations of one or several platforms.
Initialization and termination, event processing and the creation and
destruction of windows, contexts and cursors are all limited to the main thread
due to limitations of one or several platforms.
Because event processing must be performed on the main thread, all callbacks
except for the error callback will only be called on that thread. The error
callback may be called on any thread, as any GLFW function may generate errors.
The error code and description may be queried from any thread.
- @ref glfwGetError
Empty events may be posted from any thread.
The posting of empty events may be done from any thread. The window user
pointer and close flag may also be accessed and modified from any thread, but
this is not synchronized by GLFW. The following window related functions may
be called from any thread:
- @ref glfwPostEmptyEvent
The window user pointer and close flag may be read and written from any thread,
but this is not synchronized by GLFW.
- @ref glfwGetWindowUserPointer
- @ref glfwSetWindowUserPointer
- @ref glfwWindowShouldClose
- @ref glfwSetWindowShouldClose
These functions for working with OpenGL and OpenGL ES contexts may be called
from any thread, but the window object is not synchronized by GLFW.
Rendering may be done on any thread. The following context related functions
may be called from any thread:
- @ref glfwMakeContextCurrent
- @ref glfwGetCurrentContext
@@ -343,23 +336,27 @@ from any thread, but the window object is not synchronized by GLFW.
- @ref glfwExtensionSupported
- @ref glfwGetProcAddress
The raw timer functions may be called from any thread.
The raw timer may be queried from any thread. The following raw timer related
functions may be called from any thread:
- @ref glfwGetTimerFrequency
- @ref glfwGetTimerValue
The regular timer may be used from any thread, but reading and writing the timer
offset is not synchronized by GLFW.
The regular timer may be used from any thread, but the reading and writing of
the timer offset is not synchronized by GLFW. The following timer related
functions may be called from any thread:
- @ref glfwGetTime
- @ref glfwSetTime
Library version information may be queried from any thread.
Library version information may be queried from any thread. The following
version related functions may be called from any thread:
- @ref glfwGetVersion
- @ref glfwGetVersionString
All Vulkan related functions may be called from any thread.
Vulkan objects may be created and information queried from any thread. The
following Vulkan related functions may be called from any thread:
- @ref glfwVulkanSupported
- @ref glfwGetRequiredInstanceExtensions
@@ -367,9 +364,9 @@ All Vulkan related functions may be called from any thread.
- @ref glfwGetPhysicalDevicePresentationSupport
- @ref glfwCreateWindowSurface
GLFW uses synchronization objects internally only to manage the per-thread
context and error states. Additional synchronization is left to the
application.
GLFW uses no synchronization objects internally except for thread-local storage
to keep track of the current context for each thread. Synchronization is left
to the application.
Functions that may currently be called from any thread will always remain so,
but functions that are currently limited to the main thread may be updated to
@@ -391,9 +388,8 @@ Undocumented behavior, i.e. behavior that is not described in the documentation,
may change at any time until it is documented.
If the reference documentation and the implementation differ, the reference
documentation will almost always take precedence and the implementation will be
fixed in the next release. The reference documentation will also take
precedence over anything stated in a guide.
documentation is correct and the implementation will be fixed in the next
release.
@subsection event_order Event order
-7
View File
@@ -118,13 +118,6 @@ creation API, intended for automated testing. This backend does not provide
input.
@subsection news_33_primary X11 primary selection access
GLFW now supports querying and setting the X11 primary selection via the native
access functions @ref glfwGetX11SelectionString and @ref
glfwSetX11SelectionString.
@section news_32 Release notes for 3.2
+32 -53
View File
@@ -105,7 +105,6 @@ extern "C" {
#else
#define APIENTRY
#endif
#define GLFW_APIENTRY_DEFINED
#endif /* APIENTRY */
/* Some Windows OpenGL headers need this.
@@ -2930,6 +2929,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
*/
GLFWAPI void glfwFocusWindow(GLFWwindow* window);
/*! @brief Starts drag operation to the specified window.
*
* This function starts the drag operation of the specified window.
*
* @param[in] window The window to start the dragging operation.
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_drag
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI void glfwDragWindow(GLFWwindow* handle);
/*! @brief Requests user attention to the specified window.
*
* This function requests user attention to the specified window. On
@@ -3366,31 +3380,6 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window,
*/
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
/*! @brief Returns the time of the last input event.
*
* This function returns the time, in seconds, that the last input event
* occurred. The time is collected for key, mouse button, scrolling and cursor
* position events including enter and leave. The function is intended to be
* called from the relevant event callback.
*
* @return The time of the input event, in seconds, or zero if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remarks The event timestamps provided by most platforms have much lower
* resolution than the GLFW timer.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI double glfwGetEventTime(void);
/*! @brief Processes all pending events.
*
* This function processes only those events that are already in the event
@@ -4229,10 +4218,6 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
*
* This function returns whether the specified joystick is present.
*
* There is no need to call this function before other functions that accept
* a joystick ID, as they all check for presence before performing any other
* work.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
*
@@ -4255,8 +4240,8 @@ GLFWAPI int glfwJoystickPresent(int jid);
* Each element in the array is a value between -1.0 and 1.0.
*
* If the specified joystick is not present this function will return `NULL`
* but will not generate an error. This can be used instead of first calling
* @ref glfwJoystickPresent.
* but will not generate an error. Call @ref glfwJoystickPresent to check
* device presence.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of axis values in the returned
@@ -4295,8 +4280,8 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
* GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.
*
* If the specified joystick is not present this function will return `NULL`
* but will not generate an error. This can be used instead of first calling
* @ref glfwJoystickPresent.
* but will not generate an error. Call @ref glfwJoystickPresent to check
* device presence.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of button states in the returned
@@ -4352,8 +4337,8 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
* @endcode
*
* If the specified joystick is not present this function will return `NULL`
* but will not generate an error. This can be used instead of first calling
* @ref glfwJoystickPresent.
* but will not generate an error. Call @ref glfwJoystickPresent to check
* device presence.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of hat states in the returned
@@ -4387,8 +4372,8 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
* yourself.
*
* If the specified joystick is not present this function will return `NULL`
* but will not generate an error. This can be used instead of first calling
* @ref glfwJoystickPresent.
* but will not generate an error. Call @ref glfwJoystickPresent to check
* device presence.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
@@ -4417,13 +4402,9 @@ GLFWAPI const char* glfwGetJoystickName(int jid);
* hexadecimal string, of the specified joystick. The returned string is
* allocated and freed by GLFW. You should not free it yourself.
*
* The GUID is what connects a joystick to a gamepad mapping. A connected
* joystick will always have a GUID even if there is no gamepad mapping
* assigned to it.
*
* If the specified joystick is not present this function will return `NULL`
* but will not generate an error. This can be used instead of first calling
* @ref glfwJoystickPresent.
* but will not generate an error. Call @ref glfwJoystickPresent to check
* device presence.
*
* The GUID uses the format introduced in SDL 2.0.5. This GUID tries to
* uniquely identify the make and model of a joystick but does not identify
@@ -4459,8 +4440,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid);
*
* If the specified joystick is present but does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* @ref glfwJoystickPresent to check if a joystick is present regardless of
* whether it has a mapping.
* @ref glfwJoystickPresent to only check device presence.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
@@ -4549,9 +4529,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string);
* gamepad mapping assigned to the specified joystick.
*
* If the specified joystick is not present or does not have a gamepad mapping
* this function will return `NULL` but will not generate an error. Call
* @ref glfwJoystickPresent to check whether it is present regardless of
* whether it has a mapping.
* this function will return `NULL` but will not generate an error. Call @ref
* glfwJoystickIsGamepad to check whether it is present and has a gamepad mapping.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return The UTF-8 encoded name of the gamepad, or `NULL` if the
@@ -4578,10 +4557,10 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
* This function retrives the state of the specified joystick remapped to
* an Xbox-like gamepad.
*
* If the specified joystick is not present or does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* @ref glfwJoystickPresent to check whether it is present regardless of
* whether it has a mapping.
* If the specified joystick is not present this function will return
* `GLFW_FALSE` but will not generate an error. Call @ref
* glfwJoystickIsGamepad to check whether it is present and has a gamepad
* mapping.
*
* The Guide button may not be available for input as it is often hooked by the
* system or the Steam client.
+1 -54
View File
@@ -86,10 +86,7 @@ extern "C" {
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_ARB_debug_output
// callback) but windows.h assumes no one will define APIENTRY before it does
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#undef APIENTRY
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
#include <ApplicationServices/ApplicationServices.h>
@@ -292,56 +289,6 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwGetX11SelectionString
* @sa glfwSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI void glfwSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @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
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwSetX11SelectionString
* @sa glfwGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
+7 -21
View File
@@ -7,7 +7,7 @@ set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
posix_thread.h nsgl_context.h egl_context.h osmesa_context.c)
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
nsgl_context.m egl_context.c osmesa_context.c)
@@ -41,11 +41,11 @@ elseif (_GLFW_WAYLAND)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml
BASENAME relative-pointer-unstable-v1)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
BASENAME pointer-constraints-unstable-v1)
elseif (_GLFW_MIR)
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
@@ -66,18 +66,6 @@ if (APPLE)
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
endif()
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't accept
# for all source files that VS will build
if (${CMAKE_C_COMPILER_ID} STREQUAL GNU OR ${CMAKE_C_COMPILER_ID} STREQUAL Clang)
if (WIN32)
set(windows_SOURCES ${glfw_SOURCES})
else()
set(windows_SOURCES ${common_SOURCES})
endif()
set_source_files_properties(${windows_SOURCES} PROPERTIES
COMPILE_FLAGS -Wdeclaration-after-statement)
endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
set_target_properties(glfw PROPERTIES
OUTPUT_NAME ${GLFW_LIB_NAME}
@@ -86,12 +74,10 @@ set_target_properties(glfw PROPERTIES
POSITION_INDEPENDENT_CODE ON
FOLDER "GLFW3")
target_compile_definitions(glfw PRIVATE
_GLFW_USE_CONFIG_H
$<$<BOOL:${UNIX}>:_XOPEN_SOURCE=600>)
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H)
target_include_directories(glfw PUBLIC
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src"
@@ -132,7 +118,7 @@ if (BUILD_SHARED_LIBS)
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
endif()
target_compile_definitions(glfw INTERFACE GLFW_DLL)
target_compile_definitions(glfw INTERFACE -DGLFW_DLL)
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
else()
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
+3
View File
@@ -352,6 +352,9 @@ void _glfwPlatformTerminate(void)
_glfw.ns.listener = nil;
}
[_glfw.ns.cursor release];
_glfw.ns.cursor = nil;
free(_glfw.ns.clipboardString);
_glfwTerminateNSGL();
+1 -4
View File
@@ -102,7 +102,7 @@ typedef struct _GLFWlibraryNS
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
GLFWbool cursorHidden;
id cursor;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
@@ -118,9 +118,6 @@ typedef struct _GLFWlibraryNS
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The time of the last event
double lastEventTime;
struct {
CFBundleRef bundle;
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
+22 -72
View File
@@ -88,43 +88,19 @@ static GLFWbool cursorInClientArea(_GLFWwindow* window)
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
}
// Hides the cursor if not already hidden
//
static void hideCursor(_GLFWwindow* window)
{
if (!_glfw.ns.cursorHidden)
{
[NSCursor hide];
_glfw.ns.cursorHidden = GLFW_TRUE;
}
}
// Shows the cursor if not already shown
//
static void showCursor(_GLFWwindow* window)
{
if (_glfw.ns.cursorHidden)
{
[NSCursor unhide];
_glfw.ns.cursorHidden = GLFW_FALSE;
}
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
showCursor(window);
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
hideCursor(window);
[(NSCursor*) _glfw.ns.cursor set];
}
// Transforms the specified y-coordinate between the CG display and NS screen
@@ -387,6 +363,20 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
@implementation GLFWContentView
+ (void)initialize
{
if (self == [GLFWContentView class])
{
if (_glfw.ns.cursor == nil)
{
NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)];
_glfw.ns.cursor = [[NSCursor alloc] initWithImage:data
hotSpot:NSZeroPoint];
[data release];
}
}
}
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
{
self = [super init];
@@ -446,8 +436,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_PRESS,
@@ -456,15 +444,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)mouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_RELEASE,
@@ -473,8 +457,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseMoved:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
@@ -498,8 +480,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)rightMouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_PRESS,
@@ -508,15 +488,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)rightMouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)rightMouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_RELEASE,
@@ -525,8 +501,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)otherMouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_PRESS,
@@ -535,15 +509,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)otherMouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)otherMouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_RELEASE,
@@ -552,17 +522,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseExited:(NSEvent *)event
{
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
showCursor(window);
_glfwInputCursorEnter(window, GLFW_FALSE);
}
- (void)mouseEntered:(NSEvent *)event
{
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
hideCursor(window);
_glfwInputCursorEnter(window, GLFW_TRUE);
}
@@ -608,8 +572,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
@@ -641,9 +603,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
{
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
}
@@ -739,11 +698,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
selectedRange:(NSRange)selectedRange
replacementRange:(NSRange)replacementRange
{
[markedText release];
if ([string isKindOfClass:[NSAttributedString class]])
markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
[markedText initWithAttributedString:string];
else
markedText = [[NSMutableAttributedString alloc] initWithString:string];
[markedText initWithString:string];
}
- (void)unmarkText
@@ -1024,13 +982,6 @@ static GLFWbool initializeAppKit(void)
[NSApp setDelegate:_glfw.ns.delegate];
[NSApp run];
// Press and Hold prevents some keys from emitting repeated characters
NSDictionary* defaults =
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
@"ApplePressAndHoldEnabled",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
return GLFW_TRUE;
}
@@ -1347,6 +1298,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
[window->ns.object makeKeyAndOrderFront:nil];
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
[window->ns.object performWindowDragWithEvent:[NSApp currentEvent]];
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
@@ -1487,12 +1443,6 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
[window->ns.object setLevel:NSNormalWindowLevel];
}
double _glfwPlatformGetEventTime(void)
{
/* Windows events are stored in seconds */
return _glfw.ns.lastEventTime;
}
void _glfwPlatformPollEvents(void)
{
for (;;)
+4 -12
View File
@@ -286,9 +286,7 @@ GLFWbool _glfwInitEGL(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
@@ -603,9 +601,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const char** sonames;
const char* es1sonames[] =
{
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
@@ -618,9 +614,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* es2sonames[] =
{
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
@@ -634,9 +628,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* glsonames[] =
{
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#else
"libGL.so.1",
+1 -3
View File
@@ -244,9 +244,7 @@ GLFWbool _glfwInitGLX(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__)
#if defined(__CYGWIN__)
"libGL-1.so",
#else
"libGL.so.1",
+1 -1
View File
@@ -148,7 +148,7 @@ static void terminate(void)
void _glfwInputError(int code, const char* format, ...)
{
_GLFWerror* error;
char description[_GLFW_MESSAGE_SIZE];
char description[1024];
if (format)
{
+67 -60
View File
@@ -354,10 +354,10 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->stickyKeys;
case GLFW_STICKY_MOUSE_BUTTONS:
return window->stickyMouseButtons;
default:
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
return 0;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
return 0;
}
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
@@ -367,72 +367,79 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_GLFW_REQUIRE_INIT();
if (mode == GLFW_CURSOR)
switch (mode)
{
if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
case GLFW_CURSOR:
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X",
value);
return;
}
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
}
else if (mode == GLFW_STICKY_KEYS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X",
value);
return;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyMouseButtons == value)
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
case GLFW_STICKY_KEYS:
{
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
case GLFW_STICKY_MOUSE_BUTTONS:
{
if (window->stickyMouseButtons == value)
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)
+2 -4
View File
@@ -54,8 +54,6 @@
#define _GLFW_POLL_BUTTONS 2
#define _GLFW_POLL_ALL (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS)
#define _GLFW_MESSAGE_SIZE 1024
typedef int GLFWbool;
typedef struct _GLFWerror _GLFWerror;
@@ -265,7 +263,7 @@ struct _GLFWerror
{
_GLFWerror* next;
int code;
char description[_GLFW_MESSAGE_SIZE];
char description[1024];
};
/*! @brief Initialization configuration.
@@ -676,6 +674,7 @@ void _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformDragWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
int _glfwPlatformWindowFocused(_GLFWwindow* window);
int _glfwPlatformWindowIconified(_GLFWwindow* window);
@@ -685,7 +684,6 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
double _glfwPlatformGetEventTime(void);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
+26 -13
View File
@@ -266,17 +266,28 @@ GLFWbool _glfwInitJoysticksLinux(void)
const char* dirname = "/dev/input";
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linjs.inotify > 0)
if (_glfw.linjs.inotify == -1)
{
// HACK: Register for IN_ATTRIB to get notified when udev is done
// This works well in practice but the true way is libudev
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to initialize inotify: %s",
strerror(errno));
return GLFW_FALSE;
}
// Continue without device connection notifications if inotify fails
// HACK: Register for IN_ATTRIB as well to get notified when udev is done
// This works well in practice but the true way is libudev
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
if (_glfw.linjs.watch == -1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to watch for joystick connections in %s: %s",
dirname,
strerror(errno));
// Continue without device connection notifications
}
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
{
@@ -307,8 +318,13 @@ GLFWbool _glfwInitJoysticksLinux(void)
closedir(dir);
}
else
// Continue with no joysticks if enumeration fails
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to open joystick device directory %s: %s",
dirname,
strerror(errno));
// Continue with no joysticks detected
}
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
return GLFW_TRUE;
@@ -343,9 +359,6 @@ void _glfwDetectJoystickConnectionLinux(void)
ssize_t offset = 0;
char buffer[16384];
if (_glfw.linjs.inotify <= 0)
return;
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
-11
View File
@@ -23,16 +23,6 @@
// distribution.
//
//========================================================================
// As mappings.h.in, this file is used by CMake to produce the mappings.h
// header file. If you are adding a GLFW specific gamepad mapping, this is
// where to put it.
//========================================================================
// As mappings.h, this provides all pre-defined gamepad mappings, including
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
// This file can be re-generated from mappings.h.in and the upstream
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
//========================================================================
// All gamepad mappings not labeled GLFW are copied from the
// SDL_GameControllerDB project under the following license:
@@ -230,7 +220,6 @@ const char* _glfwDefaultMappings =
"03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
"05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
"03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,\n"
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
-70
View File
@@ -1,70 +0,0 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// As mappings.h.in, this file is used by CMake to produce the mappings.h
// header file. If you are adding a GLFW specific gamepad mapping, this is
// where to put it.
//========================================================================
// As mappings.h, this provides all pre-defined gamepad mappings, including
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
// This file can be re-generated from mappings.h.in and the upstream
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
//========================================================================
// All gamepad mappings not labeled GLFW are copied from the
// SDL_GameControllerDB project under the following license:
//
// Simple DirectMedia Layer
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
const char* _glfwDefaultMappings =
@GLFW_GAMEPAD_MAPPINGS@
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n";
+1 -1
View File
@@ -231,7 +231,7 @@ const char* _glfwPlatformGetVersionString(void)
#else
" gettimeofday"
#endif
" evdev"
" /dev/js"
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
-3
View File
@@ -114,9 +114,6 @@ typedef struct _GLFWlibraryMir
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The time of the last event
int64_t lastEventTime;
} _GLFWlibraryMir;
// Mir-specific per-cursor data
+4 -12
View File
@@ -147,8 +147,6 @@ static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* windo
const long text = _glfwKeySym2Unicode(key_code);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirInputEvent *) key_event);
_glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);
if (text != -1)
@@ -166,8 +164,6 @@ static void handlePointerButton(_GLFWwindow* window,
uint32_t newButtonStates = mir_pointer_event_buttons(pointer_event);
int publicButton = GLFW_MOUSE_BUTTON_LEFT;
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirEvent *) pointer_event);
// XOR our old button states our new states to figure out what was added or removed
button = newButtonStates ^ oldButtonStates;
@@ -205,8 +201,6 @@ static void handlePointerMotion(_GLFWwindow* window,
const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirEvent *) pointer_event);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.mir.disabledCursorWindow != window)
@@ -588,6 +582,10 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
@@ -638,12 +636,6 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
double _glfwPlatformGetEventTime(void)
{
/* Mir events are stored in nanoseconds */
return (double) _glfw.mir.lastEventTime / 1000000000.0;
}
void _glfwPlatformPollEvents(void)
{
EventNode* node = NULL;
+4 -5
View File
@@ -189,6 +189,10 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return GLFW_FALSE;
@@ -204,11 +208,6 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
return GLFW_FALSE;
}
double _glfwPlatformGetEventTime(void)
{
return 0.0;
}
void _glfwPlatformPollEvents(void)
{
}
+1 -3
View File
@@ -113,9 +113,7 @@ GLFWbool _glfwInitOSMesa(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_OSMESA_LIBRARY)
_GLFW_OSMESA_LIBRARY,
#elif defined(_WIN32)
#if defined(_WIN32)
"libOSMesa.dll",
"OSMesa.dll",
#elif defined(__APPLE__)
+1 -3
View File
@@ -49,9 +49,7 @@ GLFWbool _glfwInitVulkan(int mode)
return GLFW_TRUE;
#if !defined(_GLFW_VULKAN_STATIC)
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
#elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");
+8 -8
View File
@@ -233,15 +233,15 @@ static int choosePixelFormat(_GLFWwindow* window,
//
static GLFWbool isCompositionEnabled(void)
{
if (_glfw.win32.dwmapi.instance)
{
BOOL enabled;
BOOL enabled;
if (DwmIsCompositionEnabled(&enabled) == S_OK)
return enabled;
}
if (!_glfw_DwmIsCompositionEnabled)
return FALSE;
return FALSE;
if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)
return FALSE;
return enabled;
}
static void makeContextCurrentWGL(_GLFWwindow* window)
@@ -276,7 +276,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
{
int count = abs(window->context.wgl.interval);
while (count--)
DwmFlush();
_glfw_DwmFlush();
}
SwapBuffers(window->context.wgl.dc);
+14 -69
View File
@@ -124,9 +124,9 @@ static GLFWbool loadLibraries(void)
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
if (_glfw.win32.dwmapi.instance)
{
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
_glfw.win32.dwmapi.DwmIsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
_glfw.win32.dwmapi.DwmFlush = (PFN_DwmFlush)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
}
@@ -357,19 +357,19 @@ static HWND createHelperWindow(void)
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{
WCHAR* target;
int count;
int length;
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!length)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
return NULL;
}
target = calloc(count, sizeof(WCHAR));
target = calloc(length, sizeof(WCHAR));
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
@@ -385,19 +385,19 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{
char* target;
int size;
int length;
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!length)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
return NULL;
}
target = calloc(size, 1);
target = calloc(length, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
@@ -412,8 +412,8 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
//
void _glfwInputErrorWin32(int error, const char* description)
{
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
char message[_GLFW_MESSAGE_SIZE] = "";
WCHAR buffer[1024] = L"";
char message[2048] = "";
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
@@ -429,60 +429,6 @@ void _glfwInputErrorWin32(int error, const char* description)
_glfwInputError(error, "%s: %s", description, message);
}
// Updates key names according to the current keyboard layout
//
void _glfwUpdateKeyNamesWin32(void)
{
int key;
BYTE state[256] = {0};
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
{
UINT vk;
int scancode, length;
WCHAR chars[16];
scancode = _glfw.win32.scancodes[key];
if (scancode == -1)
continue;
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
{
const UINT vks[] = {
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
};
vk = vks[key - GLFW_KEY_KP_0];
}
else
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key],
sizeof(_glfw.win32.keynames[key]),
NULL, NULL);
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
@@ -502,7 +448,6 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfw_SetProcessDpiAwareness)
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+27 -6
View File
@@ -675,6 +675,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
int i, dpad = 0;
DWORD result;
XINPUT_STATE xis;
float axes[6] = { 0.f, 0.f, 0.f, 0.f, -1.f, -1.f };
const WORD buttons[10] =
{
XINPUT_GAMEPAD_A,
@@ -701,12 +702,32 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (mode == _GLFW_POLL_PRESENCE)
return GLFW_TRUE;
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 1, (xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 3, (xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
if ((float) xis.Gamepad.sThumbLX * xis.Gamepad.sThumbLX +
(float) xis.Gamepad.sThumbLY * xis.Gamepad.sThumbLY >
(float) XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE *
XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
{
axes[0] = (xis.Gamepad.sThumbLX + 0.5f) / 32767.f;
axes[1] = (xis.Gamepad.sThumbLY + 0.5f) / 32767.f;
}
if ((float) xis.Gamepad.sThumbRX * xis.Gamepad.sThumbRX +
(float) xis.Gamepad.sThumbRY * xis.Gamepad.sThumbRY >
(float) XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE *
XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
{
axes[2] = (xis.Gamepad.sThumbRX + 0.5f) / 32767.f;
axes[3] = (xis.Gamepad.sThumbRY + 0.5f) / 32767.f;
}
if (xis.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
axes[4] = xis.Gamepad.bLeftTrigger / 127.5f - 1.f;
if (xis.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
axes[5] = xis.Gamepad.bRightTrigger / 127.5f - 1.f;
for (i = 0; i < 6; i++)
_glfwInputJoystickAxis(js, i, axes[i]);
for (i = 0; i < 10; i++)
{
+16 -48
View File
@@ -33,27 +33,6 @@
#include <malloc.h>
// Callback for EnumDisplayMonitors in createMonitor
//
static BOOL CALLBACK monitorCallback(HMONITOR handle,
HDC dc,
RECT* rect,
LPARAM data)
{
MONITORINFOEXW mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
{
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
monitor->win32.handle = handle;
}
return TRUE;
}
// Create monitor from an adapter and (optionally) a display
//
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
@@ -62,8 +41,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
_GLFWmonitor* monitor;
char* name;
HDC dc;
DEVMODEW dm;
RECT rect;
if (display)
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
@@ -101,16 +78,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
NULL, NULL);
}
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
rect.left = dm.dmPosition.x;
rect.top = dm.dmPosition.y;
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
return monitor;
}
@@ -142,8 +109,8 @@ void _glfwPollMonitorsWin32(void)
{
int type = _GLFW_INSERT_LAST;
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
adapter.cb = sizeof(DISPLAY_DEVICEW);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
@@ -156,8 +123,8 @@ void _glfwPollMonitorsWin32(void)
for (displayIndex = 0; ; displayIndex++)
{
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
display.cb = sizeof(DISPLAY_DEVICEW);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
@@ -244,7 +211,7 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
return GLFW_TRUE;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmSize = sizeof(DEVMODEW);
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
DM_DISPLAYFREQUENCY;
dm.dmPelsWidth = best->width;
@@ -309,19 +276,19 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
DEVMODEW settings;
ZeroMemory(&settings, sizeof(DEVMODEW));
settings.dmSize = sizeof(DEVMODEW);
EnumDisplaySettingsExW(monitor->win32.adapterName,
ENUM_CURRENT_SETTINGS,
&dm,
&settings,
EDS_ROTATEDMODE);
if (xpos)
*xpos = dm.dmPosition.x;
*xpos = settings.dmPosition.x;
if (ypos)
*ypos = dm.dmPosition.y;
*ypos = settings.dmPosition.y;
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
@@ -337,8 +304,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
GLFWvidmode mode;
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
ZeroMemory(&dm, sizeof(DEVMODEW));
dm.dmSize = sizeof(DEVMODEW);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
break;
@@ -404,8 +371,9 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
ZeroMemory(&dm, sizeof(DEVMODEW));
dm.dmSize = sizeof(DEVMODEW);
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
+6 -12
View File
@@ -63,6 +63,7 @@
#include <wctype.h>
#include <windows.h>
#include <mmsystem.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
@@ -179,8 +180,8 @@ typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEF
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _glfw.win32.dwmapi.Flush
#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled
#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
@@ -232,7 +233,6 @@ typedef struct _GLFWwindowWin32
HICON smallIcon;
GLFWbool cursorTracked;
GLFWbool frameAction;
GLFWbool iconified;
GLFWbool maximized;
@@ -249,9 +249,9 @@ typedef struct _GLFWlibraryWin32
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
char keyName[64];
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
@@ -259,10 +259,6 @@ typedef struct _GLFWlibraryWin32
RAWINPUT* rawInput;
int rawInputSize;
// State for accumulating a non-wrapping event time
uint32_t lastTimestamp;
uint64_t eventTime;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
@@ -288,8 +284,8 @@ typedef struct _GLFWlibraryWin32
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmIsCompositionEnabled DwmIsCompositionEnabled;
PFN_DwmFlush DwmFlush;
} dwmapi;
struct {
@@ -303,7 +299,6 @@ typedef struct _GLFWlibraryWin32
//
typedef struct _GLFWmonitorWin32
{
HMONITOR handle;
// This size matches the static size of DISPLAY_DEVICE.DeviceName
WCHAR adapterName[32];
WCHAR displayName[32];
@@ -356,7 +351,6 @@ void _glfwUnregisterWindowClassWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);
+21 -69
View File
@@ -111,7 +111,7 @@ static HICON createIcon(const GLFWimage* image,
unsigned char* source = image->pixels;
ZeroMemory(&bi, sizeof(bi));
bi.bV5Size = sizeof(bi);
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = image->width;
bi.bV5Height = -image->height;
bi.bV5Planes = 1;
@@ -347,14 +347,6 @@ static int getKeyMods(void)
return mods;
}
// Updates the event time with the specified timestamp
//
static void updateEventTime(LONG timestamp)
{
_glfw.win32.eventTime += (uint32_t) timestamp - _glfw.win32.lastTimestamp;
_glfw.win32.lastTimestamp = timestamp;
}
// Retrieves and translates modifier keys
//
static int getAsyncKeyMods(void)
@@ -503,47 +495,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
switch (uMsg)
{
case WM_MOUSEACTIVATE:
{
// HACK: Postpone cursor disabling when the window was activated by
// clicking a caption button
if (HIWORD(lParam) == WM_LBUTTONDOWN)
{
if (LOWORD(lParam) == HTCLOSE ||
LOWORD(lParam) == HTMINBUTTON ||
LOWORD(lParam) == HTMAXBUTTON)
{
window->win32.frameAction = GLFW_TRUE;
}
}
break;
}
case WM_CAPTURECHANGED:
{
// HACK: Disable the cursor once the caption button action has been
// completed or cancelled
if (lParam == 0 && window->win32.frameAction)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
window->win32.frameAction = GLFW_FALSE;
}
break;
}
case WM_SETFOCUS:
{
_glfwInputWindowFocus(window, GLFW_TRUE);
// HACK: Do not disable cursor while the user is interacting with
// a caption button
if (window->win32.frameAction)
break;
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
@@ -592,18 +547,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0;
}
case WM_INPUTLANGCHANGE:
{
_glfwUpdateKeyNamesWin32();
break;
}
case WM_CHAR:
case WM_SYSCHAR:
case WM_UNICHAR:
{
const GLFWbool plain = (uMsg != WM_SYSCHAR);
updateEventTime(GetMessageTime());
if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
{
@@ -626,7 +574,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
const int scancode = (lParam >> 16) & 0x1ff;
const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
const int mods = getKeyMods();
updateEventTime(GetMessageTime());
if (key == _GLFW_KEY_INVALID)
break;
@@ -661,7 +608,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_XBUTTONUP:
{
int i, button, action;
updateEventTime(GetMessageTime());
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
button = GLFW_MOUSE_BUTTON_LEFT;
@@ -712,7 +658,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
updateEventTime(GetMessageTime());
// Disabled cursor motion input is provided by WM_INPUT
if (window->cursorMode == GLFW_CURSOR_DISABLED)
@@ -791,7 +736,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSELEAVE:
{
updateEventTime(GetMessageTime());
window->win32.cursorTracked = GLFW_FALSE;
_glfwInputCursorEnter(window, GLFW_FALSE);
return 0;
@@ -799,7 +743,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEWHEEL:
{
updateEventTime(GetMessageTime());
_glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
return 0;
}
@@ -807,7 +750,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEHWHEEL:
{
// This message is only sent on Windows Vista and later
updateEventTime(GetMessageTime());
// NOTE: The X-axis is inverted for consistency with macOS and X11
_glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
return 0;
@@ -816,8 +758,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
{
// HACK: Postpone cursor disabling while the user is moving or
// resizing the window or using the menu
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
@@ -827,8 +767,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
{
// HACK: Disable the cursor once the user is done moving or
// resizing the window or using the menu
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
@@ -1390,6 +1328,12 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
SetFocus(window->win32.handle);
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
ReleaseCapture();
SendMessage(window->win32.handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
@@ -1513,11 +1457,6 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.win32.eventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
MSG msg;
@@ -1678,7 +1617,20 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
const char* _glfwPlatformGetScancodeName(int scancode)
{
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
WCHAR name[16];
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 _glfwPlatformGetKeyScancode(int key)
+77 -68
View File
@@ -278,118 +278,119 @@ GLFWAPI void glfwWindowHint(int hint, int value)
{
case GLFW_RED_BITS:
_glfw.hints.framebuffer.redBits = value;
return;
break;
case GLFW_GREEN_BITS:
_glfw.hints.framebuffer.greenBits = value;
return;
break;
case GLFW_BLUE_BITS:
_glfw.hints.framebuffer.blueBits = value;
return;
break;
case GLFW_ALPHA_BITS:
_glfw.hints.framebuffer.alphaBits = value;
return;
break;
case GLFW_DEPTH_BITS:
_glfw.hints.framebuffer.depthBits = value;
return;
break;
case GLFW_STENCIL_BITS:
_glfw.hints.framebuffer.stencilBits = value;
return;
break;
case GLFW_ACCUM_RED_BITS:
_glfw.hints.framebuffer.accumRedBits = value;
return;
break;
case GLFW_ACCUM_GREEN_BITS:
_glfw.hints.framebuffer.accumGreenBits = value;
return;
break;
case GLFW_ACCUM_BLUE_BITS:
_glfw.hints.framebuffer.accumBlueBits = value;
return;
break;
case GLFW_ACCUM_ALPHA_BITS:
_glfw.hints.framebuffer.accumAlphaBits = value;
return;
break;
case GLFW_AUX_BUFFERS:
_glfw.hints.framebuffer.auxBuffers = value;
return;
break;
case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = value;
return;
break;
case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_FLOATING:
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_COCOA_FRAME_AUTOSAVE:
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_CLIENT_API:
_glfw.hints.context.client = value;
return;
break;
case GLFW_CONTEXT_CREATION_API:
_glfw.hints.context.source = value;
return;
break;
case GLFW_CONTEXT_VERSION_MAJOR:
_glfw.hints.context.major = value;
return;
break;
case GLFW_CONTEXT_VERSION_MINOR:
_glfw.hints.context.minor = value;
return;
break;
case GLFW_CONTEXT_ROBUSTNESS:
_glfw.hints.context.robustness = value;
return;
break;
case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_OPENGL_DEBUG_CONTEXT:
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value;
return;
break;
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
_glfw.hints.context.release = value;
return;
break;
case GLFW_REFRESH_RATE:
_glfw.hints.refreshRate = value;
return;
break;
default:
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
break;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
}
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
@@ -707,6 +708,16 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_glfwPlatformFocusWindow(window);
}
GLFWAPI void glfwDragWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformDragWindow(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -769,37 +780,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
value = value ? GLFW_TRUE : GLFW_FALSE;
if (attrib == GLFW_AUTO_ICONIFY)
window->autoIconify = value;
else if (attrib == GLFW_RESIZABLE)
switch (attrib)
{
if (window->resizable == value)
case GLFW_RESIZABLE:
if (window->resizable != value)
{
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
return;
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
else if (attrib == GLFW_DECORATED)
{
if (window->decorated == value)
case GLFW_DECORATED:
if (window->decorated != value)
{
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
return;
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
else if (attrib == GLFW_FLOATING)
{
if (window->floating == value)
case GLFW_FLOATING:
if (window->floating != value)
{
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
}
return;
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
case GLFW_AUTO_ICONIFY:
window->autoIconify = value;
return;
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
}
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
@@ -956,12 +971,6 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
return cbfun;
}
GLFWAPI double glfwGetEventTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
return _glfwPlatformGetEventTime();
}
GLFWAPI void glfwPollEvents(void)
{
_GLFW_REQUIRE_INIT();
+2 -6
View File
@@ -83,7 +83,6 @@ static void pointerHandleMotion(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
if (window->cursorMode == GLFW_CURSOR_DISABLED)
return;
else
@@ -110,7 +109,6 @@ static void pointerHandleButton(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
_glfw.wl.pointerSerial = serial;
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
@@ -138,7 +136,6 @@ static void pointerHandleAxis(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
/* Wayland scroll events are in pointer motion coordinate space (think
* two finger scroll). The factor 10 is commonly used to convert to
* "scroll step means 1.0. */
@@ -297,7 +294,7 @@ static int toGLFWKeyCode(uint32_t key)
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
{
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
if (sym == XKB_KEY_NoSymbol)
return sym;
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
!= XKB_COMPOSE_FEED_ACCEPTED)
@@ -352,7 +349,6 @@ static void keyboardHandleKey(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
keyCode = toGLFWKeyCode(key);
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
? GLFW_PRESS : GLFW_RELEASE;
@@ -741,7 +737,7 @@ const char* _glfwPlatformGetVersionString(void)
#else
" gettimeofday"
#endif
" evdev"
" /dev/js"
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
-4
View File
@@ -97,7 +97,6 @@ typedef struct _GLFWwindowWayland
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
} pointerLock;
} _GLFWwindowWayland;
// Wayland-specific global data
@@ -139,9 +138,6 @@ typedef struct _GLFWlibraryWayland
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
// The time of the last event
unsigned int lastEventTime;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
+5 -5
View File
@@ -612,6 +612,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
"Wayland: Focusing a window requires user interaction");
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, _glfw.wl.pointerSerial);
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
@@ -675,11 +680,6 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
"Wayland: Window attribute setting not implemented yet");
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.wl.lastEventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
handleEvents(0);
+28 -114
View File
@@ -505,63 +505,22 @@ static GLFWbool initExtensions(void)
}
}
_glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.randr.handle)
if (XRRQueryExtension(_glfw.x11.display,
&_glfw.x11.randr.eventBase,
&_glfw.x11.randr.errorBase))
{
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
if (XRRQueryExtension(_glfw.x11.display,
&_glfw.x11.randr.eventBase,
&_glfw.x11.randr.errorBase))
if (XRRQueryVersion(_glfw.x11.display,
&_glfw.x11.randr.major,
&_glfw.x11.randr.minor))
{
if (XRRQueryVersion(_glfw.x11.display,
&_glfw.x11.randr.major,
&_glfw.x11.randr.minor))
{
// The GLFW RandR path requires at least version 1.3
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
_glfw.x11.randr.available = GLFW_TRUE;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to query RandR version");
}
// The GLFW RandR path requires at least version 1.3
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
_glfw.x11.randr.available = GLFW_TRUE;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to query RandR version");
}
}
@@ -593,34 +552,12 @@ static GLFWbool initExtensions(void)
RROutputChangeNotifyMask);
}
_glfw.x11.xcursor.handle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.xcursor.handle)
if (XineramaQueryExtension(_glfw.x11.display,
&_glfw.x11.xinerama.major,
&_glfw.x11.xinerama.minor))
{
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
_glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
}
_glfw.x11.xinerama.handle = dlopen("libXinerama.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.xinerama.handle)
{
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
_glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
_glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
if (XineramaQueryExtension(_glfw.x11.display,
&_glfw.x11.xinerama.major,
&_glfw.x11.xinerama.minor))
{
if (XineramaIsActive(_glfw.x11.display))
_glfw.x11.xinerama.available = GLFW_TRUE;
}
if (XineramaIsActive(_glfw.x11.display))
_glfw.x11.xinerama.available = GLFW_TRUE;
}
_glfw.x11.xkb.major = 1;
@@ -647,7 +584,7 @@ static GLFWbool initExtensions(void)
_glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.x11xcb.handle)
{
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
_glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection)
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
}
@@ -674,7 +611,6 @@ static GLFWbool initExtensions(void)
// ICCCM standard clipboard atoms
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
_glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
// Clipboard manager atoms
@@ -779,7 +715,7 @@ void _glfwReleaseErrorHandlerX11(void)
//
void _glfwInputErrorX11(int error, const char* message)
{
char buffer[_GLFW_MESSAGE_SIZE];
char buffer[8192];
XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
buffer, sizeof(buffer));
@@ -793,9 +729,6 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
int i;
Cursor cursor;
if (!_glfw.x11.xcursor.handle)
return None;
XcursorImage* native = XcursorImageCreate(image->width, image->height);
if (native == NULL)
return None;
@@ -896,6 +829,12 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void)
{
if (_glfw.x11.x11xcb.handle)
{
dlclose(_glfw.x11.x11xcb.handle);
_glfw.x11.x11xcb.handle = NULL;
}
if (_glfw.x11.helperWindowHandle)
{
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
@@ -914,7 +853,6 @@ void _glfwPlatformTerminate(void)
_glfw.x11.hiddenCursorHandle = (Cursor) 0;
}
free(_glfw.x11.primarySelectionString);
free(_glfw.x11.clipboardString);
if (_glfw.x11.im)
@@ -931,30 +869,6 @@ void _glfwPlatformTerminate(void)
_glfw.x11.display = NULL;
}
if (_glfw.x11.x11xcb.handle)
{
dlclose(_glfw.x11.x11xcb.handle);
_glfw.x11.x11xcb.handle = NULL;
}
if (_glfw.x11.xcursor.handle)
{
dlclose(_glfw.x11.xcursor.handle);
_glfw.x11.xcursor.handle = NULL;
}
if (_glfw.x11.randr.handle)
{
dlclose(_glfw.x11.randr.handle);
_glfw.x11.randr.handle = NULL;
}
if (_glfw.x11.xinerama.handle)
{
dlclose(_glfw.x11.xinerama.handle);
_glfw.x11.xinerama.handle = NULL;
}
// NOTE: This needs to be done after XCloseDisplay, as libGL registers
// cleanup callbacks that get called by it
_glfwTerminateGLX();
@@ -973,7 +887,7 @@ const char* _glfwPlatformGetVersionString(void)
" gettimeofday"
#endif
#if defined(__linux__)
" evdev"
" /dev/js"
#endif
#if defined(_GLFW_BUILD_DLL)
" shared"
+1 -86
View File
@@ -47,60 +47,10 @@
// The XInput extension provides raw mouse motion input
#include <X11/extensions/XInput2.h>
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*);
typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*);
typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc);
typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc);
typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc);
typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput);
typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window);
typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window);
typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*);
typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*);
typedef void (* PFN_XRRSelectInput)(Display*,Window,int);
typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int);
typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*);
typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
#define XRRAllocGamma _glfw.x11.randr.AllocGamma
#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo
#define XRRFreeGamma _glfw.x11.randr.FreeGamma
#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo
#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources
#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma
#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize
#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary
#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
#define XRRQueryExtension _glfw.x11.randr.QueryExtension
#define XRRQueryVersion _glfw.x11.randr.QueryVersion
#define XRRSelectInput _glfw.x11.randr.SelectInput
#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig
#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma
#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
typedef Bool (* PFN_XineramaIsActive)(Display*);
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*);
#define XineramaIsActive _glfw.x11.xinerama.IsActive
#define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension
#define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens
typedef XID xcb_window_t;
typedef XID xcb_visualid_t;
typedef struct xcb_connection_t xcb_connection_t;
typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*);
#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection
typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*);
typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
@@ -211,8 +161,6 @@ typedef struct _GLFWlibraryX11
XIM im;
// Most recent error code received by X error handler
int errorCode;
// Primary selection string (while the primary selection is owned)
char* primarySelectionString;
// Clipboard string (while the selection is owned)
char* clipboardString;
// Key name string
@@ -225,9 +173,6 @@ typedef struct _GLFWlibraryX11
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// State for accumulating a non-wrapping event time
Time lastTimestamp;
uint64_t eventTime;
// Window manager atoms
Atom WM_PROTOCOLS;
@@ -269,7 +214,6 @@ typedef struct _GLFWlibraryX11
Atom TARGETS;
Atom MULTIPLE;
Atom CLIPBOARD;
Atom PRIMARY;
Atom CLIPBOARD_MANAGER;
Atom SAVE_TARGETS;
Atom NULL_;
@@ -280,30 +224,12 @@ typedef struct _GLFWlibraryX11
struct {
GLFWbool available;
void* handle;
int eventBase;
int errorBase;
int major;
int minor;
GLFWbool gammaBroken;
GLFWbool monitorBroken;
PFN_XRRAllocGamma AllocGamma;
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
PFN_XRRFreeGamma FreeGamma;
PFN_XRRFreeOutputInfo FreeOutputInfo;
PFN_XRRFreeScreenResources FreeScreenResources;
PFN_XRRGetCrtcGamma GetCrtcGamma;
PFN_XRRGetCrtcGammaSize GetCrtcGammaSize;
PFN_XRRGetCrtcInfo GetCrtcInfo;
PFN_XRRGetOutputInfo GetOutputInfo;
PFN_XRRGetOutputPrimary GetOutputPrimary;
PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent;
PFN_XRRQueryExtension QueryExtension;
PFN_XRRQueryVersion QueryVersion;
PFN_XRRSelectInput SelectInput;
PFN_XRRSetCrtcConfig SetCrtcConfig;
PFN_XRRSetCrtcGamma SetCrtcGamma;
PFN_XRRUpdateConfiguration UpdateConfiguration;
} randr;
struct {
@@ -330,26 +256,15 @@ typedef struct _GLFWlibraryX11
Atom format;
} xdnd;
struct {
void* handle;
PFN_XcursorImageCreate ImageCreate;
PFN_XcursorImageDestroy ImageDestroy;
PFN_XcursorImageLoadCursor ImageLoadCursor;
} xcursor;
struct {
GLFWbool available;
void* handle;
int major;
int minor;
PFN_XineramaIsActive IsActive;
PFN_XineramaQueryExtension QueryExtension;
PFN_XineramaQueryScreens QueryScreens;
} xinerama;
struct {
void* handle;
PFN_XGetXCBConnection GetXCBConnection;
PFN_XGetXCBConnection XGetXCBConnection;
} x11xcb;
struct {
+99 -147
View File
@@ -43,6 +43,7 @@
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
#define _NET_WM_MOVERESIZE_MOVE 8
// Additional mouse button names for XButtonEvent
#define Button6 6
@@ -671,17 +672,11 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{
int i;
char* selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const int formatCount = sizeof(formats) / sizeof(formats[0]);
if (request->selection == _glfw.x11.PRIMARY)
selectionString = _glfw.x11.primarySelectionString;
else
selectionString = _glfw.x11.clipboardString;
if (request->property == None)
{
// The requester is a legacy client (ICCCM section 2.2)
@@ -741,8 +736,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
targets[i],
8,
PropModeReplace,
(unsigned char *) selectionString,
strlen(selectionString));
(unsigned char*) _glfw.x11.clipboardString,
strlen(_glfw.x11.clipboardString));
}
else
targets[i + 1] = None;
@@ -793,8 +788,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
request->target,
8,
PropModeReplace,
(unsigned char *) selectionString,
strlen(selectionString));
(unsigned char*) _glfw.x11.clipboardString,
strlen(_glfw.x11.clipboardString));
return request->property;
}
@@ -807,16 +802,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
static void handleSelectionClear(XEvent* event)
{
if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
{
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = NULL;
}
else
{
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = NULL;
}
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = NULL;
}
static void handleSelectionRequest(XEvent* event)
@@ -837,82 +824,6 @@ static void handleSelectionRequest(XEvent* event)
XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);
}
static const char* getSelectionString(Atom selection)
{
size_t i;
char** selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
if (selection == _glfw.x11.PRIMARY)
selectionString = &_glfw.x11.primarySelectionString;
else
selectionString = &_glfw.x11.clipboardString;
if (XGetSelectionOwner(_glfw.x11.display, selection) ==
_glfw.x11.helperWindowHandle)
{
// Instead of doing a large number of X round-trips just to put this
// string into a window property and then read it back, just return it
return *selectionString;
}
free(*selectionString);
*selectionString = NULL;
for (i = 0; i < formatCount; i++)
{
char* data;
XEvent event;
XConvertSelection(_glfw.x11.display,
selection,
formats[i],
_glfw.x11.GLFW_SELECTION,
_glfw.x11.helperWindowHandle,
CurrentTime);
while (!XCheckTypedWindowEvent(_glfw.x11.display,
_glfw.x11.helperWindowHandle,
SelectionNotify,
&event))
{
waitForEvent(NULL);
}
if (event.xselection.property == None)
continue;
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property,
event.xselection.target,
(unsigned char**) &data))
{
*selectionString = strdup(data);
}
if (data)
XFree(data);
XDeleteProperty(_glfw.x11.display,
event.xselection.requestor,
event.xselection.property);
if (*selectionString)
break;
}
if (!*selectionString)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert clipboard to string");
}
return *selectionString;
}
// Make the specified window and its video mode active on its monitor
//
static GLFWbool acquireMonitor(_GLFWwindow* window)
@@ -1034,14 +945,6 @@ static unsigned int decodeUTF8(const char** s)
}
#endif /*X_HAVE_UTF8_STRING*/
// Updates the event time with the specified timestamp
//
static void updateEventTime(Time timestamp)
{
_glfw.x11.eventTime += timestamp - _glfw.x11.lastTimestamp;
_glfw.x11.lastTimestamp = timestamp;
}
// Process the specified X event
//
static void processEvent(XEvent *event)
@@ -1084,7 +987,6 @@ static void processEvent(XEvent *event)
const double* values = re->raw_values;
double xpos = window->virtualCursorPosX;
double ypos = window->virtualCursorPosY;
updateEventTime(re->time);
if (XIMaskIsSet(re->valuators.mask, 0))
{
@@ -1130,7 +1032,6 @@ static void processEvent(XEvent *event)
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
updateEventTime(event->xkey.time);
if (window->x11.ic)
{
@@ -1224,7 +1125,6 @@ static void processEvent(XEvent *event)
{
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
updateEventTime(event->xkey.time);
if (!_glfw.x11.xkb.detectable)
{
@@ -1265,7 +1165,6 @@ static void processEvent(XEvent *event)
case ButtonPress:
{
const int mods = translateState(event->xbutton.state);
updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
@@ -1300,7 +1199,6 @@ static void processEvent(XEvent *event)
case ButtonRelease:
{
const int mods = translateState(event->xbutton.state);
updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1)
{
@@ -1338,8 +1236,6 @@ static void processEvent(XEvent *event)
case EnterNotify:
{
updateEventTime(event->xcrossing.time);
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
// ignore the defined cursor for hidden cursor mode
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
@@ -1351,7 +1247,6 @@ static void processEvent(XEvent *event)
case LeaveNotify:
{
updateEventTime(event->xcrossing.time);
_glfwInputCursorEnter(window, GLFW_FALSE);
return;
}
@@ -1360,7 +1255,6 @@ static void processEvent(XEvent *event)
{
const int x = event->xmotion.x;
const int y = event->xmotion.y;
updateEventTime(event->xmotion.time);
if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY)
{
@@ -2250,6 +2144,28 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
XFlush(_glfw.x11.display);
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
int winXpos, winYpos;
double curXpos, curYpos;
XClientMessageEvent xclient;
memset(&xclient, 0, sizeof(XClientMessageEvent));
XUngrabPointer(_glfw.x11.display, 0);
XFlush(_glfw.x11.display);
_glfwPlatformGetCursorPos(window, &curXpos, &curYpos);
_glfwPlatformGetWindowPos(window, &winXpos, &winYpos);
xclient.type = ClientMessage;
xclient.window = window->x11.handle;
xclient.message_type = XInternAtom(_glfw.x11.display, "_NET_WM_MOVERESIZE", False);
xclient.format = 32;
xclient.data.l[0] = winXpos + curXpos;
xclient.data.l[1] = winYpos + curYpos;
xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent(_glfw.x11.display, _glfw.x11.root, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
@@ -2445,11 +2361,6 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
XFlush(_glfw.x11.display);
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.x11.eventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
_GLFWwindow* window;
@@ -2684,7 +2595,72 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
return getSelectionString(_glfw.x11.CLIPBOARD);
size_t i;
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
_glfw.x11.helperWindowHandle)
{
// Instead of doing a large number of X round-trips just to put this
// string into a window property and then read it back, just return it
return _glfw.x11.clipboardString;
}
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = NULL;
for (i = 0; i < formatCount; i++)
{
char* data;
XEvent event;
XConvertSelection(_glfw.x11.display,
_glfw.x11.CLIPBOARD,
formats[i],
_glfw.x11.GLFW_SELECTION,
_glfw.x11.helperWindowHandle,
CurrentTime);
while (!XCheckTypedWindowEvent(_glfw.x11.display,
_glfw.x11.helperWindowHandle,
SelectionNotify,
&event))
{
waitForEvent(NULL);
}
if (event.xselection.property == None)
continue;
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property,
event.xselection.target,
(unsigned char**) &data))
{
_glfw.x11.clipboardString = strdup(data);
}
if (data)
XFree(data);
XDeleteProperty(_glfw.x11.display,
event.xselection.requestor,
event.xselection.property);
if (_glfw.x11.clipboardString)
break;
}
if (_glfw.x11.clipboardString == NULL)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert clipboard to string");
}
return _glfw.x11.clipboardString;
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
@@ -2727,7 +2703,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
return GLFW_FALSE;
}
xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
xcb_connection_t* connection =
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
if (!connection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -2770,7 +2747,8 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
VkXcbSurfaceCreateInfoKHR sci;
PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
xcb_connection_t* connection =
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
if (!connection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -2852,29 +2830,3 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return window->x11.handle;
}
GLFWAPI void glfwSetX11SelectionString(const char* string)
{
_GLFW_REQUIRE_INIT();
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = strdup(string);
XSetSelectionOwner(_glfw.x11.display,
_glfw.x11.PRIMARY,
_glfw.x11.helperWindowHandle,
CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
_glfw.x11.helperWindowHandle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of primary selection");
}
}
GLFWAPI const char* glfwGetX11SelectionString(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return getSelectionString(_glfw.x11.PRIMARY);
}
+2 -4
View File
@@ -30,7 +30,6 @@ add_executable(cursor cursor.c ${GLAD})
add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD})
add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD})
add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD})
add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD})
add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD})
add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${GETOPT} ${GLAD})
add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GETOPT} ${GLAD})
@@ -46,8 +45,8 @@ if (RT_LIBRARY)
target_link_libraries(threads "${RT_LIBRARY}")
endif()
set(WINDOWS_BINARIES empty gamma icon inputlag joysticks sharing tearing threads
timeout title windows)
set(WINDOWS_BINARIES empty gamma icon joysticks sharing tearing threads timeout
title windows)
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
cursor)
@@ -74,7 +73,6 @@ endif()
if (APPLE)
set_target_properties(empty PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Empty Event")
set_target_properties(gamma PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gamma")
set_target_properties(inputlag PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Input Lag")
set_target_properties(joysticks PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Joysticks")
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing")
+12 -16
View File
@@ -336,35 +336,33 @@ static void window_maximize_callback(GLFWwindow* window, int maximized)
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s at %0.3f\n",
printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), button,
get_button_name(button),
get_mods_name(mods),
get_action_name(action),
glfwGetEventTime());
get_action_name(action));
}
static void cursor_position_callback(GLFWwindow* window, double x, double y)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Cursor position: %f %f at %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y, glfwGetEventTime());
printf("%08x to %i at %0.3f: Cursor position: %f %f\n",
counter++, slot->number, glfwGetTime(), x, y);
}
static void cursor_enter_callback(GLFWwindow* window, int entered)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Cursor %s window at %0.3f\n",
printf("%08x to %i at %0.3f: Cursor %s window\n",
counter++, slot->number, glfwGetTime(),
entered ? "entered" : "left",
glfwGetEventTime());
entered ? "entered" : "left");
}
static void scroll_callback(GLFWwindow* window, double x, double y)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f at %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y, glfwGetEventTime());
printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@@ -374,22 +372,20 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
if (name)
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s at %0.3f\n",
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
name,
get_mods_name(mods),
get_action_name(action),
glfwGetEventTime());
get_action_name(action));
}
else
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s at %0.3f\n",
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
get_mods_name(mods),
get_action_name(action),
glfwGetEventTime());
get_action_name(action));
}
if (action != GLFW_PRESS)
+1 -1
View File
@@ -806,7 +806,7 @@ int main(int argc, char** argv)
if (list_extensions)
list_context_extensions(client, major, minor);
printf("Vulkan loader: %s\n",
printf("Vulkan support: %s\n",
glfwVulkanSupported() ? "available" : "missing");
if (glfwVulkanSupported())
-305
View File
@@ -1,305 +0,0 @@
//========================================================================
// Input lag test
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test renders a marker at the cursor position reported by GLFW to
// check how much it lags behind the hardware mouse cursor
//
//========================================================================
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define NK_IMPLEMENTATION
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_STANDARD_VARARGS
#include <nuklear.h>
#define NK_GLFW_GL2_IMPLEMENTATION
#include <nuklear_glfw_gl2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
void usage(void)
{
printf("Usage: inputlag [-h] [-f]\n");
printf("Options:\n");
printf(" -f create full screen window\n");
printf(" -h show this help\n");
}
struct nk_vec2 cursor_new, cursor_pos, cursor_vel;
enum { cursor_sync_query, cursor_input_message } cursor_method = cursor_sync_query;
void sample_input(GLFWwindow* window)
{
float a = .25; // exponential smoothing factor
if (cursor_method == cursor_sync_query) {
double x, y;
glfwGetCursorPos(window, &x, &y);
cursor_new.x = (float) x;
cursor_new.y = (float) y;
}
cursor_vel.x = (cursor_new.x - cursor_pos.x) * a + cursor_vel.x * (1 - a);
cursor_vel.y = (cursor_new.y - cursor_pos.y) * a + cursor_vel.y * (1 - a);
cursor_pos = cursor_new;
}
void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos)
{
cursor_new.x = (float) xpos;
cursor_new.y = (float) ypos;
}
int enable_vsync = nk_true;
void update_vsync()
{
glfwSwapInterval(enable_vsync == nk_true ? 1 : 0);
}
int swap_clear = nk_false;
int swap_finish = nk_true;
int swap_occlusion_query = nk_false;
int swap_read_pixels = nk_false;
GLuint occlusion_query;
void swap_buffers(GLFWwindow* window)
{
glfwSwapBuffers(window);
if (swap_clear)
glClear(GL_COLOR_BUFFER_BIT);
if (swap_finish)
glFinish();
if (swap_occlusion_query) {
GLint occlusion_result;
if (!occlusion_query)
glGenQueries(1, &occlusion_query);
glBeginQuery(GL_SAMPLES_PASSED, occlusion_query);
glBegin(GL_POINTS);
glVertex2f(0, 0);
glEnd();
glEndQuery(GL_SAMPLES_PASSED);
glGetQueryObjectiv(occlusion_query, GL_QUERY_RESULT, &occlusion_result);
}
if (swap_read_pixels) {
unsigned char rgba[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
}
}
void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (action != GLFW_PRESS)
return;
switch (key)
{
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, 1);
break;
}
}
void draw_marker(struct nk_command_buffer* canvas, int lead, struct nk_vec2 pos)
{
struct nk_color colors[4] = { nk_rgb(255,0,0), nk_rgb(255,255,0), nk_rgb(0,255,0), nk_rgb(0,96,255) };
struct nk_rect rect = { -5 + pos.x, -5 + pos.y, 10, 10 };
nk_fill_circle(canvas, rect, colors[lead]);
}
int main(int argc, char** argv)
{
int ch, width, height;
unsigned long frame_count = 0;
double last_time, current_time;
double frame_rate = 0;
int fullscreen = GLFW_FALSE;
GLFWmonitor* monitor = NULL;
GLFWwindow* window;
struct nk_context* nk;
struct nk_font_atlas* atlas;
int show_forecasts = nk_true;
while ((ch = getopt(argc, argv, "fh")) != -1)
{
switch (ch)
{
case 'h':
usage();
exit(EXIT_SUCCESS);
case 'f':
fullscreen = GLFW_TRUE;
break;
}
}
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
if (fullscreen)
{
const GLFWvidmode* mode;
monitor = glfwGetPrimaryMonitor();
mode = glfwGetVideoMode(monitor);
width = mode->width;
height = mode->height;
}
else
{
width = 640;
height = 480;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
update_vsync();
last_time = glfwGetTime();
nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS);
nk_glfw3_font_stash_begin(&atlas);
nk_glfw3_font_stash_end();
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, cursor_pos_callback);
while (!glfwWindowShouldClose(window))
{
int width, height;
struct nk_rect area;
glfwPollEvents();
sample_input(window);
glfwGetWindowSize(window, &width, &height);
area = nk_rect(0.f, 0.f, (float) width, (float) height);
glClear(GL_COLOR_BUFFER_BIT);
nk_glfw3_new_frame();
if (nk_begin(nk, "", area, 0))
{
nk_flags align_left = NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE;
struct nk_command_buffer *canvas = nk_window_get_canvas(nk);
int lead;
for (lead = show_forecasts ? 3 : 0; lead >= 0; lead--)
draw_marker(canvas, lead, nk_vec2(cursor_pos.x + cursor_vel.x * lead,
cursor_pos.y + cursor_vel.y * lead));
// print instructions
nk_layout_row_dynamic(nk, 20, 1);
nk_label(nk, "Move mouse uniformly and check marker under cursor:", align_left);
for (lead = 0; lead <= 3; lead++) {
nk_layout_row_begin(nk, NK_STATIC, 12, 2);
nk_layout_row_push(nk, 25);
draw_marker(canvas, lead, nk_layout_space_to_screen(nk, nk_vec2(20, 5)));
nk_label(nk, "", 0);
nk_layout_row_push(nk, 500);
if (lead == 0)
nk_label(nk, "- current cursor position (no input lag)", align_left);
else
nk_labelf(nk, align_left, "- %d-frame forecast (input lag is %d frame)", lead, lead);
nk_layout_row_end(nk);
}
nk_layout_row_dynamic(nk, 20, 1);
nk_checkbox_label(nk, "Show forecasts", &show_forecasts);
nk_label(nk, "Input method:", align_left);
if (nk_option_label(nk, "glfwGetCursorPos (sync query)", cursor_method == cursor_sync_query))
cursor_method = cursor_sync_query;
if (nk_option_label(nk, "glfwSetCursorPosCallback (latest input message)", cursor_method == cursor_input_message))
cursor_method = cursor_input_message;
nk_label(nk, "", 0); // separator
nk_value_float(nk, "FPS", (float) frame_rate);
if (nk_checkbox_label(nk, "Enable vsync", &enable_vsync))
update_vsync();
nk_label(nk, "", 0); // separator
nk_label(nk, "After swap:", align_left);
nk_checkbox_label(nk, "glClear", &swap_clear);
nk_checkbox_label(nk, "glFinish", &swap_finish);
nk_checkbox_label(nk, "draw with occlusion query", &swap_occlusion_query);
nk_checkbox_label(nk, "glReadPixels", &swap_read_pixels);
}
nk_end(nk);
nk_glfw3_render(NK_ANTI_ALIASING_ON);
swap_buffers(window);
frame_count++;
current_time = glfwGetTime();
if (current_time - last_time > 1.0)
{
frame_rate = frame_count / (current_time - last_time);
frame_count = 0;
last_time = current_time;
}
}
glfwTerminate();
exit(EXIT_SUCCESS);
}
+7
View File
@@ -88,6 +88,12 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
}
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
glfwDragWindow(window);
}
int main(int argc, char** argv)
{
int i, ch;
@@ -131,6 +137,7 @@ int main(int argc, char** argv)
}
glfwSetKeyCallback(windows[i], key_callback);
glfwSetMouseButtonCallback(windows[i], mouse_button_callback);
glfwMakeContextCurrent(windows[i]);
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);