/*!

@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 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_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


@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&nbsp;/&nbsp;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.

*/
