You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							896 lines
						
					
					
						
							29 KiB
						
					
					
				
			
		
		
	
	
							896 lines
						
					
					
						
							29 KiB
						
					
					
				| /*! | |
| 
 | |
| @page input_guide Input guide | |
|   | |
| @tableofcontents | |
| 
 | |
| This guide introduces the input related functions of GLFW.  For details on | |
| a specific function in this category, see the @ref input.  There are also guides | |
| for the other areas of GLFW. | |
| 
 | |
|  - @ref intro_guide | |
|  - @ref window_guide | |
|  - @ref context_guide | |
|  - @ref vulkan_guide | |
|  - @ref monitor_guide | |
| 
 | |
| GLFW provides many kinds of input.  While some can only be polled, like time, or | |
| only received via callbacks, like scrolling, many provide both callbacks and | |
| polling.  Callbacks are more work to use than polling but is less CPU intensive | |
| and guarantees that you do not miss state changes. | |
| 
 | |
| All input callbacks receive a window handle.  By using the | |
| [window user pointer](@ref window_userptr), you can access non-global structures | |
| or objects from your callbacks. | |
| 
 | |
| To get a better feel for how the various events callbacks behave, run the | |
| `events` test program.  It register every callback supported by GLFW and prints | |
| out all arguments provided for every event, along with time and sequence | |
| information. | |
| 
 | |
| 
 | |
| @section events Event processing | |
| 
 | |
| GLFW needs to poll the window system for events both to provide input to the | |
| application and to prove to the window system that the application hasn't locked | |
| up.  Event processing is normally done each frame after | |
| [buffer swapping](@ref buffer_swap).  Even when you have no windows, event | |
| polling needs to be done in order to receive monitor and joystick connection | |
| events. | |
| 
 | |
| There are three functions for processing pending events.  @ref glfwPollEvents, | |
| processes only those events that have already been received and then returns | |
| immediately. | |
| 
 | |
| @code | |
| glfwPollEvents(); | |
| @endcode | |
| 
 | |
| This is the best choice when rendering continuously, like most games do. | |
| 
 | |
| If you only need to update the contents of the window when you receive new | |
| input, @ref glfwWaitEvents is a better choice. | |
| 
 | |
| @code | |
| glfwWaitEvents(); | |
| @endcode | |
| 
 | |
| It puts the thread to sleep until at least one event has been received and then | |
| processes all received events.  This saves a great deal of CPU cycles and is | |
| useful for, for example, editing tools.  There must be at least one GLFW window | |
| for this function to sleep. | |
| 
 | |
| If you want to wait for events but have UI elements or other tasks that need | |
| periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout. | |
| 
 | |
| @code | |
| glfwWaitEventsTimeout(0.7); | |
| @endcode | |
| 
 | |
| It puts the thread to sleep until at least one event has been received, or until | |
| the specified number of seconds have elapsed.  It then processes any received | |
| events. | |
| 
 | |
| If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from | |
| another thread by posting an empty event to the event queue with @ref | |
| glfwPostEmptyEvent. | |
| 
 | |
| @code | |
| glfwPostEmptyEvent(); | |
| @endcode | |
| 
 | |
| Do not assume that callbacks will _only_ be called in response to the above | |
| functions.  While it is necessary to process events in one or more of the ways | |
| above, window systems that require GLFW to register callbacks of its own can | |
| pass events to GLFW in response to many window system function calls.  GLFW will | |
| pass those events on to the application callbacks before returning. | |
| 
 | |
| For example, on Windows the system function that @ref glfwSetWindowSize is | |
| implemented with will send window size events directly to the event callback | |
| that every window has and that GLFW implements for its windows.  If you have set | |
| a [window size callback](@ref window_size) GLFW will call it in turn with the | |
| new size before everything returns back out of the @ref glfwSetWindowSize call. | |
| 
 | |
| 
 | |
| @section input_keyboard Keyboard input | |
| 
 | |
| GLFW divides keyboard input into two categories; key events and character | |
| events.  Key events relate to actual physical keyboard keys, whereas character | |
| events relate to the Unicode code points generated by pressing some of them. | |
| 
 | |
| Keys and characters do not map 1:1.  A single key press may produce several | |
| characters, and a single character may require several keys to produce.  This | |
| may not be the case on your machine, but your users are likely not all using the | |
| same keyboard layout, input method or even operating system as you. | |
| 
 | |
| 
 | |
| @subsection input_key Key input | |
| 
 | |
| If you wish to be notified when a physical key is pressed or released or when it | |
| repeats, set a key callback. | |
| 
 | |
| @code | |
| glfwSetKeyCallback(window, key_callback); | |
| @endcode | |
| 
 | |
| The callback function receives the [keyboard key](@ref keys), platform-specific | |
| scancode, key action and [modifier bits](@ref mods). | |
| 
 | |
| @code | |
| void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) | |
| { | |
|     if (key == GLFW_KEY_E && action == GLFW_PRESS) | |
|         activate_airship(); | |
| } | |
| @endcode | |
| 
 | |
| The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`.  The key | |
| will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example | |
| _E-mail_ and _Play_ keys. | |
| 
 | |
| The scancode is unique for every key, regardless of whether it has a key token. | |
| Scancodes are platform-specific but consistent over time, so keys will have | |
| different scancodes depending on the platform but they are safe to save to disk. | |
| You can query the scancode for any [named key](@ref keys) on the current | |
| platform with @ref glfwGetKeyScancode. | |
| 
 | |
| @code | |
| const int scancode = glfwGetKeyScancode(GLFW_KEY_X); | |
| set_key_mapping(scancode, swap_weapons); | |
| @endcode | |
| 
 | |
| The last reported state for every [named key](@ref keys) is also saved in | |
| per-window state arrays that can be polled with @ref glfwGetKey. | |
| 
 | |
| @code | |
| int state = glfwGetKey(window, GLFW_KEY_E); | |
| if (state == GLFW_PRESS) | |
| { | |
|     activate_airship(); | |
| } | |
| @endcode | |
| 
 | |
| The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. | |
| 
 | |
| This function only returns cached key event state.  It does not poll the | |
| system for the current physical state of the key. | |
| 
 | |
| @anchor GLFW_STICKY_KEYS | |
| Whenever you poll state, you risk missing the state change you are looking for. | |
| If a pressed key is released again before you poll its state, you will have | |
| missed the key press.  The recommended solution for this is to use a | |
| key callback, but there is also the `GLFW_STICKY_KEYS` input mode. | |
| 
 | |
| @code | |
| glfwSetInputMode(window, GLFW_STICKY_KEYS, 1); | |
| @endcode | |
| 
 | |
| When sticky keys mode is enabled, the pollable state of a key will remain | |
| `GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey.  Once | |
| it has been polled, if a key release event had been processed in the meantime, | |
| the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. | |
| 
 | |
| The `GLFW_KEY_LAST` constant holds the highest value of any | |
| [named key](@ref keys). | |
| 
 | |
| 
 | |
| @subsection input_char Text input | |
| 
 | |
| GLFW supports text input in the form of a stream of | |
| [Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the | |
| operating system text input system.  Unlike key input, text input obeys keyboard | |
| layouts and modifier keys and supports composing characters using | |
| [dead keys](https://en.wikipedia.org/wiki/Dead_key).  Once received, you can | |
| encode the code points into UTF-8 or any other encoding you prefer. | |
| 
 | |
| Because an `unsigned int` is 32 bits long on all platforms supported by GLFW, | |
| you can treat the code point argument as native endian UTF-32. | |
| 
 | |
| There are two callbacks for receiving Unicode code points.  If you wish to | |
| offer regular text input, set a character callback. | |
| 
 | |
| @code | |
| glfwSetCharCallback(window, character_callback); | |
| @endcode | |
| 
 | |
| The callback function receives Unicode code points for key events that would | |
| have led to regular text input and generally behaves as a standard text field on | |
| that platform. | |
| 
 | |
| @code | |
| void character_callback(GLFWwindow* window, unsigned int codepoint) | |
| { | |
| } | |
| @endcode | |
| 
 | |
| If you wish to receive even those Unicode code points generated with modifier | |
| key combinations that a plain text field would ignore, or just want to know | |
| exactly what modifier keys were used, set a character with modifiers callback. | |
| 
 | |
| @code | |
| glfwSetCharModsCallback(window, charmods_callback); | |
| @endcode | |
| 
 | |
| The callback function receives Unicode code points and | |
| [modifier bits](@ref mods). | |
| 
 | |
| @code | |
| void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods) | |
| { | |
| } | |
| @endcode | |
| 
 | |
| 
 | |
| @subsection input_key_name Key names | |
| 
 | |
| If you wish to refer to keys by name, you can query the keyboard layout | |
| dependent name of printable keys with @ref glfwGetKeyName. | |
| 
 | |
| @code | |
| const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0); | |
| show_tutorial_hint("Press %s to move forward", key_name); | |
| @endcode | |
| 
 | |
| This function can handle both [keys and scancodes](@ref input_key).  If the | |
| specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is | |
| ignored.  This matches the behavior of the key callback, meaning the callback | |
| arguments can always be passed unmodified to this function. | |
| 
 | |
| 
 | |
| @section input_mouse Mouse input | |
| 
 | |
| Mouse input comes in many forms, including cursor motion, button presses and | |
| scrolling offsets.  The cursor appearance can also be changed, either to | |
| a custom image or a standard cursor shape from the system theme. | |
| 
 | |
| 
 | |
| @subsection cursor_pos Cursor position | |
| 
 | |
| If you wish to be notified when the cursor moves over the window, set a cursor | |
| position callback. | |
| 
 | |
| @code | |
| glfwSetCursorPosCallback(window, cursor_pos_callback); | |
| @endcode | |
| 
 | |
| The callback functions receives the cursor position, measured in screen | |
| coordinates but relative to the top-left corner of the window client area.  On | |
| platforms that provide it, the full sub-pixel cursor position is passed on. | |
| 
 | |
| @code | |
| static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) | |
| { | |
| } | |
| @endcode | |
| 
 | |
| The cursor position is also saved per-window and can be polled with @ref | |
| glfwGetCursorPos. | |
| 
 | |
| @code | |
| double xpos, ypos; | |
| glfwGetCursorPos(window, &xpos, &ypos); | |
| @endcode | |
| 
 | |
| 
 | |
| @subsection cursor_mode Cursor mode | |
| 
 | |
| @anchor GLFW_CURSOR | |
| The `GLFW_CURSOR` input mode provides several cursor modes for special forms of | |
| mouse motion input.  By default, the cursor mode is `GLFW_CURSOR_NORMAL`, | |
| meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor) | |
| is used and cursor motion is not limited. | |
| 
 | |
| If you wish to implement mouse motion based camera controls or other input | |
| schemes that require unlimited mouse movement, set the cursor mode to | |
| `GLFW_CURSOR_DISABLED`. | |
| 
 | |
| @code | |
| glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); | |
| @endcode | |
| 
 | |
| This will hide the cursor and lock it to the specified window.  GLFW will then | |
| take care of all the details of cursor re-centering and offset calculation and | |
| providing the application with a virtual cursor position.  This virtual position | |
| is provided normally via both the cursor position callback and through polling. | |
| 
 | |
| @note You should not implement your own version of this functionality using | |
| other features of GLFW.  It is not supported and will not work as robustly as | |
| `GLFW_CURSOR_DISABLED`. | |
| 
 | |
| If you just wish the cursor to become hidden when it is over a window, set | |
| the cursor mode to `GLFW_CURSOR_HIDDEN`. | |
| 
 | |
| @code | |
| glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); | |
| @endcode | |
| 
 | |
| This mode puts no limit on the motion of the cursor. | |
| 
 | |
| To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` | |
| cursor mode. | |
| 
 | |
| @code | |
| glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | |
| @endcode | |
| 
 | |
| 
 | |
| @subsection cursor_object Cursor objects | |
| 
 | |
| GLFW supports creating both custom and system theme cursor images, encapsulated | |
| as @ref GLFWcursor objects.  They are created with @ref glfwCreateCursor or @ref | |
| glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref | |
| glfwTerminate, if any remain. | |
| 
 | |
| 
 | |
| @subsubsection cursor_custom Custom cursor creation | |
| 
 | |
| A custom cursor is created with @ref glfwCreateCursor, which returns a handle to | |
| the created cursor object.  For example, this creates a 16x16 white square | |
| cursor with the hot-spot in the upper-left corner: | |
| 
 | |
| @code | |
| unsigned char pixels[16 * 16 * 4]; | |
| memset(pixels, 0xff, sizeof(pixels)); | |
| 
 | |
| GLFWimage image; | |
| image.width = 16; | |
| image.height = 16; | |
| image.pixels = pixels; | |
| 
 | |
| GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0); | |
| @endcode | |
| 
 | |
| If cursor creation fails, `NULL` will be returned, so it is necessary to check | |
| the return value. | |
| 
 | |
| The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits | |
| per channel with the red channel first.  The pixels are arranged canonically as | |
| sequential rows, starting from the top-left corner. | |
| 
 | |
| 
 | |
| @subsubsection cursor_standard Standard cursor creation | |
| 
 | |
| A cursor with a [standard shape](@ref shapes) from the current system cursor | |
| theme can be can be created with @ref glfwCreateStandardCursor. | |
| 
 | |
| @code | |
| GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); | |
| @endcode | |
| 
 | |
| These cursor objects behave in the exact same way as those created with @ref | |
| glfwCreateCursor except that the system cursor theme provides the actual image. | |
| 
 | |
| 
 | |
| @subsubsection cursor_destruction Cursor destruction | |
| 
 | |
| When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor. | |
| 
 | |
| @code | |
| glfwDestroyCursor(cursor); | |
| @endcode | |
| 
 | |
| Cursor destruction always succeeds.  If the cursor is current for any window, | |
| that window will revert to the default cursor.  This does not affect the cursor | |
| mode.  All remaining cursors remaining are destroyed when @ref glfwTerminate is | |
| called. | |
| 
 | |
| 
 | |
| @subsubsection cursor_set Cursor setting | |
| 
 | |
| A cursor can be set as current for a window with @ref glfwSetCursor. | |
| 
 | |
| @code | |
| glfwSetCursor(window, cursor); | |
| @endcode | |
| 
 | |
| Once set, the cursor image will be used as long as the system cursor is over the | |
| client area of the window and the [cursor mode](@ref cursor_mode) is set | |
| to `GLFW_CURSOR_NORMAL`. | |
| 
 | |
| A single cursor may be set for any number of windows. | |
| 
 | |
| To revert to the default cursor, set the cursor of that window to `NULL`. | |
| 
 | |
| @code | |
| glfwSetCursor(window, NULL); | |
| @endcode | |
| 
 | |
| When a cursor is destroyed, any window that has it set will revert to the | |
| default cursor.  This does not affect the cursor mode. | |
| 
 | |
| 
 | |
| @subsection cursor_enter Cursor enter/leave events | |
| 
 | |
| If you wish to be notified when the cursor enters or leaves the client area of | |
| a window, set a cursor enter/leave callback. | |
| 
 | |
| @code | |
| glfwSetCursorEnterCallback(window, cursor_enter_callback); | |
| @endcode | |
| 
 | |
| The callback function receives the new classification of the cursor. | |
| 
 | |
| @code | |
| void cursor_enter_callback(GLFWwindow* window, int entered) | |
| { | |
|     if (entered) | |
|     { | |
|         // The cursor entered the client area of the window | |
|     } | |
|     else | |
|     { | |
|         // The cursor left the client area of the window | |
|     } | |
| } | |
| @endcode | |
| 
 | |
| 
 | |
| @subsection input_mouse_button Mouse button input | |
| 
 | |
| If you wish to be notified when a mouse button is pressed or released, set | |
| a mouse button callback. | |
| 
 | |
| @code | |
| glfwSetMouseButtonCallback(window, mouse_button_callback); | |
| @endcode | |
| 
 | |
| The callback function receives the [mouse button](@ref buttons), button action | |
| and [modifier bits](@ref mods). | |
| 
 | |
| @code | |
| void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) | |
| { | |
|     if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) | |
|         popup_menu(); | |
| } | |
| @endcode | |
| 
 | |
| The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. | |
| 
 | |
| Mouse button states for [named buttons](@ref buttons) are also saved in | |
| per-window state arrays that can be polled with @ref glfwGetMouseButton. | |
| 
 | |
| @code | |
| int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); | |
| if (state == GLFW_PRESS) | |
| { | |
|     upgrade_cow(); | |
| } | |
| @endcode | |
| 
 | |
| The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. | |
| 
 | |
| This function only returns cached mouse button event state.  It does not poll | |
| the system for the current state of the mouse button. | |
| 
 | |
| @anchor GLFW_STICKY_MOUSE_BUTTONS | |
| Whenever you poll state, you risk missing the state change you are looking for. | |
| If a pressed mouse button is released again before you poll its state, you will have | |
| missed the button press.  The recommended solution for this is to use a | |
| mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` | |
| input mode. | |
| 
 | |
| @code | |
| glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); | |
| @endcode | |
| 
 | |
| When sticky mouse buttons mode is enabled, the pollable state of a mouse button | |
| will remain `GLFW_PRESS` until the state of that button is polled with @ref | |
| glfwGetMouseButton.  Once it has been polled, if a mouse button release event | |
| had been processed in the meantime, the state will reset to `GLFW_RELEASE`, | |
| otherwise it will remain `GLFW_PRESS`. | |
| 
 | |
| The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any | |
| [named button](@ref buttons). | |
| 
 | |
| 
 | |
| @subsection scrolling Scroll input | |
| 
 | |
| If you wish to be notified when the user scrolls, whether with a mouse wheel or | |
| touchpad gesture, set a scroll callback. | |
| 
 | |
| @code | |
| glfwSetScrollCallback(window, scroll_callback); | |
| @endcode | |
| 
 | |
| The callback function receives two-dimensional scroll offsets. | |
| 
 | |
| @code | |
| void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) | |
| { | |
| } | |
| @endcode | |
| 
 | |
| A simple mouse wheel, being vertical, provides offsets along the Y-axis. | |
| 
 | |
| 
 | |
| @section joystick Joystick input | |
| 
 | |
| The joystick functions expose connected joysticks and controllers, with both | |
| referred to as joysticks.  It supports up to sixteen joysticks, ranging from | |
| `GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to and including `GLFW_JOYSTICK_16` or | |
| `GLFW_JOYSTICK_LAST`.  You can test whether a [joystick](@ref joysticks) is | |
| present with @ref glfwJoystickPresent. | |
| 
 | |
| @code | |
| int present = glfwJoystickPresent(GLFW_JOYSTICK_1); | |
| @endcode | |
| 
 | |
| When GLFW is initialized, detected joysticks are added to to the beginning of | |
| the array.  Once a joystick is detected, it keeps its assigned ID until it is | |
| disconnected or the library is terminated, so as joysticks are connected and | |
| disconnected, there may appear gaps in the IDs. | |
| 
 | |
| Joystick axis, button and hat state is updated when polled and does not require | |
| a window to be created or events to be processed.  However, if you want joystick | |
| connection and disconnection events reliably delivered to the | |
| [joystick callback](@ref joystick_event) then you must | |
| [process events](@ref events). | |
| 
 | |
| To see all the properties of all connected joysticks in real-time, run the | |
| `joysticks` test program. | |
| 
 | |
| 
 | |
| @subsection joystick_axis Joystick axis states | |
| 
 | |
| The positions of all axes of a joystick are returned by @ref | |
| glfwGetJoystickAxes.  See the reference documentation for the lifetime of the | |
| returned array. | |
| 
 | |
| @code | |
| int count; | |
| const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count); | |
| @endcode | |
| 
 | |
| Each element in the returned array is a value between -1.0 and 1.0. | |
| 
 | |
| 
 | |
| @subsection joystick_button Joystick button states | |
| 
 | |
| The states of all buttons of a joystick are returned by @ref | |
| glfwGetJoystickButtons.  See the reference documentation for the lifetime of the | |
| returned array. | |
| 
 | |
| @code | |
| int count; | |
| const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count); | |
| @endcode | |
| 
 | |
| Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`. | |
| 
 | |
| For backward compatibility with earlier versions that did not have @ref | |
| glfwGetJoystickHats, the button array by default also includes all hats.  See | |
| the reference documentation for @ref glfwGetJoystickButtons for details. | |
| 
 | |
| 
 | |
| @subsection joystick_hat Joystick hat states | |
| 
 | |
| The states of all hats are returned by @ref glfwGetJoystickHats.  See the | |
| reference documentation for the lifetime of the returned array. | |
| 
 | |
| @code | |
| int count; | |
| const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count); | |
| @endcode | |
| 
 | |
| Each element in the returned array is one of the following: | |
| 
 | |
| Name                  | Value | |
| --------------------- | -------------------------------- | |
| `GLFW_HAT_CENTERED`   | 0 | |
| `GLFW_HAT_UP`         | 1 | |
| `GLFW_HAT_RIGHT`      | 2 | |
| `GLFW_HAT_DOWN`       | 4 | |
| `GLFW_HAT_LEFT`       | 8 | |
| `GLFW_HAT_RIGHT_UP`   | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP` | |
| `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN` | |
| `GLFW_HAT_LEFT_UP`    | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP` | |
| `GLFW_HAT_LEFT_DOWN`  | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN` | |
| 
 | |
| The diagonal directions are bitwise combinations of the primary (up, right, down | |
| and left) directions and you can test for these individually by ANDing it with | |
| the corresponding direction. | |
| 
 | |
| @code | |
| if (hats[2] & GLFW_HAT_RIGHT) | |
| { | |
|     // State of hat 2 could be right-up, right or right-down | |
| } | |
| @endcode | |
| 
 | |
| For backward compatibility with earlier versions that did not have @ref | |
| glfwGetJoystickHats, all hats are by default also included in the button array. | |
| See the reference documentation for @ref glfwGetJoystickButtons for details. | |
| 
 | |
| 
 | |
| @subsection joystick_name Joystick name | |
| 
 | |
| The human-readable, UTF-8 encoded name of a joystick is returned by @ref | |
| glfwGetJoystickName.  See the reference documentation for the lifetime of the | |
| returned string.            | |
| 
 | |
| @code | |
| const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4); | |
| @endcode | |
| 
 | |
| Joystick names are not guaranteed to be unique.  Two joysticks of the same model | |
| and make may have the same name.  Only the [joystick token](@ref joysticks) is | |
| guaranteed to be unique, and only until that joystick is disconnected. | |
| 
 | |
| 
 | |
| @subsection joystick_event Joystick configuration changes | |
| 
 | |
| If you wish to be notified when a joystick is connected or disconnected, set | |
| a joystick callback. | |
| 
 | |
| @code | |
| glfwSetJoystickCallback(joystick_callback); | |
| @endcode | |
| 
 | |
| The callback function receives the ID of the joystick that has been connected | |
| and disconnected and the event that occurred. | |
| 
 | |
| @code | |
| void joystick_callback(int jid, int event) | |
| { | |
|     if (event == GLFW_CONNECTED) | |
|     { | |
|         // The joystick was connected | |
|     } | |
|     else if (event == GLFW_DISCONNECTED) | |
|     { | |
|         // The joystick was disconnected | |
|     } | |
| } | |
| @endcode | |
| 
 | |
| For joystick connection and disconnection events to be delivered on all | |
| platforms, you need to call one of the [event processing](@ref events) | |
| functions.  Joystick disconnection may also be detected and the callback | |
| called by joystick functions.  The function will then return whatever it | |
| returns for a disconnected joystick. | |
| 
 | |
| 
 | |
| @subsection gamepad Gamepad input | |
| 
 | |
| The joystick functions provide unlabeled axes, buttons and hats, with no | |
| indication of where they are located on the device.  Their order may also vary | |
| between platforms even with the same device. | |
| 
 | |
| To solve this problem the SDL community crowdsourced the | |
| [SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project, | |
| a database of mappings from many different devices to an Xbox-like gamepad. | |
| 
 | |
| GLFW supports this mapping format and contains a copy of the mappings | |
| available at the time of release.  See @ref gamepad_mapping for how to update | |
| this at runtime.  Mappings will be assigned to joysticks automatically any time | |
| a joystick is connected or the mappings are updated. | |
| 
 | |
| You can check whether a joystick is both present and has a gamepad mapping with | |
| @ref glfwJoystickIsGamepad. | |
| 
 | |
| @code | |
| if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2)) | |
| { | |
|     // Use as gamepad | |
| } | |
| @endcode | |
| 
 | |
| If you are only interested in gamepad input you can use this function instead of | |
| @ref glfwJoystickPresent. | |
| 
 | |
| You can query the human-readable name provided by the gamepad mapping with @ref | |
| glfwGetGamepadName.  This may or may not be the same as the | |
| [joystick name](@ref joystick_name). | |
| 
 | |
| @code | |
| const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7); | |
| @endcode | |
| 
 | |
| To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState. | |
| 
 | |
| @code | |
| GLFWgamepadstate state; | |
| 
 | |
| if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state)) | |
| { | |
|     if (state.buttons[GLFW_GAMEPAD_BUTTON_A]) | |
|     { | |
|         input_jump(); | |
|     } | |
| 
 | |
|     input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]); | |
| } | |
| @endcode | |
| 
 | |
| The @ref GLFWgamepadstate struct has two arrays; one for button states and one | |
| for axis states.  The values for each button and axis are the same as for the | |
| @ref glfwGetJoystickButtons and @ref glfwGetJoystickAxes functions, i.e. | |
| `GLFW_PRESS` or `GLFW_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes. | |
| 
 | |
| The sizes of the arrays and the positions within each array are fixed. | |
| 
 | |
| The [button indices](@ref gamepad_buttons) are `GLFW_GAMEPAD_BUTTON_A`, | |
| `GLFW_GAMEPAD_BUTTON_B`, `GLFW_GAMEPAD_BUTTON_X`, `GLFW_GAMEPAD_BUTTON_Y`, | |
| `GLFW_GAMEPAD_BUTTON_LEFT_BUMPER`, `GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER`, | |
| `GLFW_GAMEPAD_BUTTON_BACK`, `GLFW_GAMEPAD_BUTTON_START`, | |
| `GLFW_GAMEPAD_BUTTON_GUIDE`, `GLFW_GAMEPAD_BUTTON_LEFT_THUMB`, | |
| `GLFW_GAMEPAD_BUTTON_RIGHT_THUMB`, `GLFW_GAMEPAD_BUTTON_DPAD_UP`, | |
| `GLFW_GAMEPAD_BUTTON_DPAD_RIGHT`, `GLFW_GAMEPAD_BUTTON_DPAD_DOWN` and | |
| `GLFW_GAMEPAD_BUTTON_DPAD_LEFT`. | |
| 
 | |
| For those who prefer, there are also the `GLFW_GAMEPAD_BUTTON_CROSS`, | |
| `GLFW_GAMEPAD_BUTTON_CIRCLE`, `GLFW_GAMEPAD_BUTTON_SQUARE` and | |
| `GLFW_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices. | |
| 
 | |
| The [axis indices](@ref gamepad_axes) are `GLFW_GAMEPAD_AXIS_LEFT_X`, | |
| `GLFW_GAMEPAD_AXIS_LEFT_Y`, `GLFW_GAMEPAD_AXIS_RIGHT_X`, | |
| `GLFW_GAMEPAD_AXIS_RIGHT_Y`, `GLFW_GAMEPAD_AXIS_LEFT_TRIGGER` and | |
| `GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER`. | |
| 
 | |
| The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal | |
| the largest available index for each array. | |
| 
 | |
| 
 | |
| @subsection gamepad_mapping Gamepad mappings | |
| 
 | |
| GLFW contains a copy of the mappings available in | |
| [SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the | |
| time of release.  Newer ones can be added at runtime with @ref | |
| glfwUpdateGamepadMappings. | |
| 
 | |
| @code | |
| const char* mappings = load_file_contents("gamecontrollerdb.txt"); | |
| 
 | |
| glfwUpdateGamepadMappings(mappings); | |
| @endcode | |
| 
 | |
| This function supports everything from single lines up to and including the | |
| unmodified contents of the whole `gamecontrollerdb.txt` file. | |
| 
 | |
| Below is a description of the mapping format.  Please keep in mind that __this | |
| description is not authoritative__.  The format is defined by the SDL and | |
| SDL_GameControllerDB projects and their documentation and code takes precedence. | |
| 
 | |
| Each mapping is a single line of comma-separated values describing the GUID, | |
| name and layout of the gamepad.  Lines that do not begin with a hexadecimal | |
| digit are ignored. | |
| 
 | |
| The first value is always the gamepad GUID, a 32 character long hexadecimal | |
| string that typically identifies its make, model, revision and the type of | |
| connection to the computer.  When this information is not available, the GUID is | |
| generated using the gamepad name.  GLFW uses the SDL 2.0.5+ GUID format but can | |
| convert from the older formats. | |
| 
 | |
| The second value is always the human-readable name of the gamepad. | |
| 
 | |
| All subsequent values are in the form `<field>:<value>` and describe the layout | |
| of the mapping.  These fields may not all be present and may occur in any order. | |
| 
 | |
| The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`, | |
| `dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and | |
| `rightstick`. | |
| 
 | |
| The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and | |
| `righttrigger`. | |
| 
 | |
| The value of an axis or button field can be a joystick button, a joystick axis, | |
| a hat bitmask or empty.  Joystick buttons are specified as `bN`, for example | |
| `b2` for the third button.  Joystick axes are specified as `aN`, for example | |
| `a7` for the eighth button.  Joystick hat bit masks are specified as `hN.N`, for | |
| example `h0.8` for left on the first hat.  More than one bit may be set in the | |
| mask. | |
| 
 | |
| The hat bit mask match the [hat states](@ref hat_state) in the joystick | |
| functions. | |
| 
 | |
| There is also the special `platform` field that specifies which platform the | |
| mapping is valid for.  Possible values are `Windows`, `Mac OS X` and `Linux`. | |
| Mappings without this field will always be considered valid. | |
| 
 | |
| Below is an example of what a gamepad mapping might look like.  It is the | |
| one built into GLFW for Xbox controllers accessed via the XInput API on Windows. | |
| This example has been broken into several lines to fit on the page, but real | |
| gamepad mappings must be a single line. | |
| 
 | |
| @code{.unparsed} | |
| 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, | |
| @endcode | |
| 
 | |
| @note GLFW does not yet support the range and inversion modifiers `+`, `-` and | |
| `~` that were recently added to SDL. | |
| 
 | |
| 
 | |
| @section time Time input | |
| 
 | |
| GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime. | |
| 
 | |
| @code | |
| double seconds = glfwGetTime(); | |
| @endcode | |
| 
 | |
| It returns the number of seconds since the timer was started when the library | |
| was initialized with @ref glfwInit.  The platform-specific time sources used | |
| usually have micro- or nanosecond resolution. | |
| 
 | |
| You can modify the reference time with @ref glfwSetTime. | |
| 
 | |
| @code | |
| glfwSetTime(4.0); | |
| @endcode | |
| 
 | |
| This sets the timer to the specified time, in seconds. | |
| 
 | |
| You can also access the raw timer value, measured in 1 / frequency | |
| seconds, with @ref glfwGetTimerValue. | |
| 
 | |
| @code | |
| uint64_t value = glfwGetTimerValue(); | |
| @endcode | |
| 
 | |
| The frequency of the raw timer varies depending on what time sources are | |
| available on the machine.  You can query its frequency, in Hz, with @ref | |
| glfwGetTimerFrequency. | |
| 
 | |
| @code | |
| uint64_t freqency = glfwGetTimerFrequency(); | |
| @endcode | |
| 
 | |
| 
 | |
| @section clipboard Clipboard input and output | |
| 
 | |
| If the system clipboard contains a UTF-8 encoded string or if it can be | |
| converted to one, you can retrieve it with @ref glfwGetClipboardString.  See the | |
| reference documentation for the lifetime of the returned string. | |
| 
 | |
| @code | |
| const char* text = glfwGetClipboardString(window); | |
| if (text) | |
| { | |
|     insert_text(text); | |
| } | |
| @endcode | |
| 
 | |
| If the clipboard is empty or if its contents could not be converted, `NULL` is | |
| returned. | |
| 
 | |
| The contents of the system clipboard can be set to a UTF-8 encoded string with | |
| @ref glfwSetClipboardString. | |
| 
 | |
| @code | |
| glfwSetClipboardString(window, "A string with words in it"); | |
| @endcode | |
| 
 | |
| The clipboard functions take a window handle argument because some window | |
| systems require a window to communicate with the system clipboard.  Any valid | |
| window may be used. | |
| 
 | |
| 
 | |
| @section path_drop Path drop input | |
| 
 | |
| If you wish to receive the paths of files and/or directories dropped on | |
| a window, set a file drop callback. | |
| 
 | |
| @code | |
| glfwSetDropCallback(window, drop_callback); | |
| @endcode | |
| 
 | |
| The callback function receives an array of paths encoded as UTF-8. | |
| 
 | |
| @code | |
| void drop_callback(GLFWwindow* window, int count, const char** paths) | |
| { | |
|     int i; | |
|     for (i = 0;  i < count;  i++) | |
|         handle_dropped_file(paths[i]); | |
| } | |
| @endcode | |
| 
 | |
| The path array and its strings are only valid until the file drop callback | |
| returns, as they may have been generated specifically for that event.  You need | |
| to make a deep copy of the array if you want to keep the paths. | |
| 
 | |
| */
 | |
| 
 |