/*!

@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 ID](@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("game/data/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.

If you are compiling GLFW from source with CMake you can update the built-in mappings by
building the _update_mappings_ target.  This runs the `GenerateMappings.cmake` CMake
script, which downloads `gamecontrollerdb.txt` and regenerates the `mappings.h` header
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`, `x`, `y`, `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 library was initialized with @ref
glfwInit.  The platform-specific time sources used typically have micro- or
nanosecond resolution.

You can modify the base time with @ref glfwSetTime.

@code
glfwSetTime(4.0);
@endcode

This sets the time to the specified time, in seconds, and it continues to count
from there.

You can also access the raw timer used to implement the functions above,
with @ref glfwGetTimerValue.

@code
uint64_t value = glfwGetTimerValue();
@endcode

This value is in 1&nbsp;/&nbsp;frequency seconds.  The frequency of the raw
timer varies depending on the operating system and hardware.  You can query the
frequency, in Hz, with @ref glfwGetTimerFrequency.

@code
uint64_t frequency = 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.

*/
