| /*! |
| |
| @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. |
| |
| 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, GLFW_TRUE); |
| @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`. |
| |
| @anchor GLFW_LOCK_KEY_MODS |
| If you wish to know what the state of the Caps Lock and Num Lock keys was when |
| input events were generated, set the `GLFW_LOCK_KEY_MODS` input mode. |
| |
| @code |
| glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE); |
| @endcode |
| |
| When this input mode is enabled, any callback that receives |
| [modifier bits](@ref mods) will have the @ref GLFW_MOD_CAPS_LOCK bit set if Caps |
| Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if |
| Num Lock was on. |
| |
| 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. |
| |
| 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 |
| |
| |
| @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 mouse 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_position_callback); |
| @endcode |
| |
| The callback functions receives the cursor position, measured in screen |
| coordinates but relative to the top-left corner of the window content 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 only wish the cursor to become hidden when it is over a window but still |
| want it to behave normally, 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 |
| |
| |
| @anchor GLFW_RAW_MOUSE_MOTION |
| @subsection raw_mouse_motion Raw mouse motion |
| |
| When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can |
| be enabled if available. |
| |
| Raw mouse motion is closer to the actual motion of the mouse across a surface. |
| It is not affected by the scaling and acceleration applied to the motion of the |
| desktop cursor. That processing is suitable for a cursor while raw motion is |
| better for controlling for example a 3D camera. Because of this, raw mouse |
| motion is only provided when the cursor is disabled. |
| |
| Call @ref glfwRawMouseMotionSupported to check if the current machine provides |
| raw motion and set the `GLFW_RAW_MOUSE_MOTION` input mode to enable it. It is |
| disabled by default. |
| |
| @code |
| if (glfwRawMouseMotionSupported()) |
| glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); |
| @endcode |
| |
| If supported, raw mouse motion can be enabled or disabled per-window and at any |
| time but it will only be provided when the cursor is disabled. |
| |
| |
| @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 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 |
| content 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 content 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 content area of the window |
| } |
| else |
| { |
| // The cursor left the content area of the window |
| } |
| } |
| @endcode |
| |
| You can query whether the cursor is currently inside the content area of the |
| window with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. |
| |
| @code |
| if (glfwGetWindowAttrib(window, GLFW_HOVERED)) |
| { |
| highlight_interface(); |
| } |
| @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, GLFW_TRUE); |
| @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 normal 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 |
| |
| Each joystick has zero or more axes, zero or more buttons, zero or more hats, |
| a human-readable name, a user pointer and an SDL compatible GUID. |
| |
| When GLFW is initialized, detected joysticks are added 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_userptr Joystick user pointer |
| |
| Each joystick has a user pointer that can be set with @ref |
| glfwSetJoystickUserPointer and queried with @ref glfwGetJoystickUserPointer. |
| This can be used for any purpose you need and will not be modified by GLFW. The |
| value will be kept until the joystick is disconnected or until the library is |
| terminated. |
| |
| The initial value of the pointer is `NULL`. |
| |
| |
| @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. |
| |
| Only @ref glfwGetJoystickName and @ref glfwGetJoystickUserPointer will return |
| useful values for a disconnected joystick and only before the monitor callback |
| returns. |
| |
| |
| @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. |
| |
| Before an axis there may be a `+` or `-` range modifier, for example `+a3` for |
| the positive half of the fourth axis. This restricts input to only the positive |
| or negative halves of the joystick axis. After an axis or half-axis there may |
| be the `~` inversion modifier, for example `a2~` or `-a7~`. This negates the |
| values of the gamepad axis. |
| |
| 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`. |
| |
| 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 output range and modifiers `+` and `-` that |
| were recently added to SDL. The input modifiers `+`, `-` and `~` are supported |
| and described above. |
| |
| |
| @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(NULL); |
| 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(NULL, "A string with words in it"); |
| @endcode |
| |
| |
| @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. |
| |
| */ |