/*!

@page input_guide Input guide
 
@tableofcontents

This guide introduces the input related functions of GLFW.  For details on
a specific function in this category, see the @ref input.  There are also guides
for the other areas of GLFW.

 - @ref intro_guide
 - @ref window_guide
 - @ref context_guide
 - @ref vulkan_guide
 - @ref monitor_guide

GLFW provides many kinds of input.  While some can only be polled, like time, or
only received via callbacks, like scrolling, many provide both callbacks and
polling.  Callbacks are more work to use than polling but is less CPU intensive
and guarantees that you do not miss state changes.

All input callbacks receive a window handle.  By using the
[window user pointer](@ref window_userptr), you can access non-global structures
or objects from your callbacks.

To get a better feel for how the various events callbacks behave, run the
`events` test program.  It register every callback supported by GLFW and prints
out all arguments provided for every event, along with time and sequence
information.


@section events Event processing

GLFW needs to poll the window system for events both to provide input to the
application and to prove to the window system that the application hasn't locked
up.  Event processing is normally done each frame after
[buffer swapping](@ref buffer_swap).  Even when you have no windows, event
polling needs to be done in order to receive monitor and joystick connection
events.

There are three functions for processing pending events.  @ref glfwPollEvents,
processes only those events that have already been received and then returns
immediately.

@code
glfwPollEvents();
@endcode

This is the best choice when rendering continuously, like most games do.

If you only need to update the contents of the window when you receive new
input, @ref glfwWaitEvents is a better choice.

@code
glfwWaitEvents();
@endcode

It puts the thread to sleep until at least one event has been received and then
processes all received events.  This saves a great deal of CPU cycles and is
useful for, for example, editing tools.  There must be at least one GLFW window
for this function to sleep.

If you want to wait for events but have UI elements or other tasks that need
periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout.

@code
glfwWaitEventsTimeout(0.7);
@endcode

It puts the thread to sleep until at least one event has been received, or until
the specified number of seconds have elapsed.  It then processes any received
events.

If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
another thread by posting an empty event to the event queue with @ref
glfwPostEmptyEvent.

@code
glfwPostEmptyEvent();
@endcode

Do not assume that callbacks will _only_ be called in response to the above
functions.  While it is necessary to process events in one or more of the ways
above, window systems that require GLFW to register callbacks of its own can
pass events to GLFW in response to many window system function calls.  GLFW will
pass those events on to the application callbacks before returning.

For example, on Windows the system function that @ref glfwSetWindowSize is
implemented with will send window size events directly to the event callback
that every window has and that GLFW implements for its windows.  If you have set
a [window size callback](@ref window_size) GLFW will call it in turn with the
new size before everything returns back out of the @ref glfwSetWindowSize call.


@section input_keyboard Keyboard input

GLFW divides keyboard input into two categories; key events and character
events.  Key events relate to actual physical keyboard keys, whereas character
events relate to the Unicode code points generated by pressing some of them.

Keys and characters do not map 1:1.  A single key press may produce several
characters, and a single character may require several keys to produce.  This
may not be the case on your machine, but your users are likely not all using the
same keyboard layout, input method or even operating system as you.


@subsection input_key Key input

If you wish to be notified when a physical key is pressed or released or when it
repeats, set a key callback.

@code
glfwSetKeyCallback(window, key_callback);
@endcode

The callback function receives the [keyboard key](@ref keys), platform-specific
scancode, key action and [modifier bits](@ref mods).

@code
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_E && action == GLFW_PRESS)
        activate_airship();
}
@endcode

The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`.  The key
will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example
_E-mail_ and _Play_ keys.

The scancode is unique for every key, regardless of whether it has a key token.
Scancodes are platform-specific but consistent over time, so keys will have
different scancodes depending on the platform but they are safe to save to disk.
You can query the scancode for any [named key](@ref keys) on the current
platform with @ref glfwGetKeyScancode.

@code
const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
set_key_mapping(scancode, swap_weapons);
@endcode

The last reported state for every [named key](@ref keys) is also saved in
per-window state arrays that can be polled with @ref glfwGetKey.

@code
int state = glfwGetKey(window, GLFW_KEY_E);
if (state == GLFW_PRESS)
{
    activate_airship();
}
@endcode

The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.

This function only returns cached key event state.  It does not poll the
system for the current physical state of the key.

@anchor GLFW_STICKY_KEYS
Whenever you poll state, you risk missing the state change you are looking for.
If a pressed key is released again before you poll its state, you will have
missed the key press.  The recommended solution for this is to use a
key callback, but there is also the `GLFW_STICKY_KEYS` input mode.

@code
glfwSetInputMode(window, GLFW_STICKY_KEYS, 1);
@endcode

When sticky keys mode is enabled, the pollable state of a key will remain
`GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey.  Once
it has been polled, if a key release event had been processed in the meantime,
the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`.

@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, 1);
@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_pos_callback);
@endcode

The callback functions receives the cursor position, measured in screen
coordinates but relative to the top-left corner of the window client area.  On
platforms that provide it, the full sub-pixel cursor position is passed on.

@code
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
{
}
@endcode

The cursor position is also saved per-window and can be polled with @ref
glfwGetCursorPos.

@code
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
@endcode


@subsection cursor_mode Cursor mode

@anchor GLFW_CURSOR
The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
mouse motion input.  By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
is used and cursor motion is not limited.

If you wish to implement mouse motion based camera controls or other input
schemes that require unlimited mouse movement, set the cursor mode to
`GLFW_CURSOR_DISABLED`.

@code
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
@endcode

This will hide the cursor and lock it to the specified window.  GLFW will then
take care of all the details of cursor re-centering and offset calculation and
providing the application with a virtual cursor position.  This virtual position
is provided normally via both the cursor position callback and through polling.

@note You should not implement your own version of this functionality using
other features of GLFW.  It is not supported and will not work as robustly as
`GLFW_CURSOR_DISABLED`.

If you 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 remaining are destroyed when @ref glfwTerminate is
called.


@subsubsection cursor_set Cursor setting

A cursor can be set as current for a window with @ref glfwSetCursor.

@code
glfwSetCursor(window, cursor);
@endcode

Once set, the cursor image will be used as long as the system cursor is over the
client area of the window and the [cursor mode](@ref cursor_mode) is set
to `GLFW_CURSOR_NORMAL`.

A single cursor may be set for any number of windows.

To revert to the default cursor, set the cursor of that window to `NULL`.

@code
glfwSetCursor(window, NULL);
@endcode

When a cursor is destroyed, any window that has it set will revert to the
default cursor.  This does not affect the cursor mode.


@subsection cursor_enter Cursor enter/leave events

If you wish to be notified when the cursor enters or leaves the client area of
a window, set a cursor enter/leave callback.

@code
glfwSetCursorEnterCallback(window, cursor_enter_callback);
@endcode

The callback function receives the new classification of the cursor.

@code
void cursor_enter_callback(GLFWwindow* window, int entered)
{
    if (entered)
    {
        // The cursor entered the client area of the window
    }
    else
    {
        // The cursor left the client area of the window
    }
}
@endcode


@subsection input_mouse_button Mouse button input

If you wish to be notified when a mouse button is pressed or released, set
a mouse button callback.

@code
glfwSetMouseButtonCallback(window, mouse_button_callback);
@endcode

The callback function receives the [mouse button](@ref buttons), button action
and [modifier bits](@ref mods).

@code
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
        popup_menu();
}
@endcode

The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.

Mouse button states for [named buttons](@ref buttons) are also saved in
per-window state arrays that can be polled with @ref glfwGetMouseButton.

@code
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
if (state == GLFW_PRESS)
{
    upgrade_cow();
}
@endcode

The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.

This function only returns cached mouse button event state.  It does not poll
the system for the current state of the mouse button.

@anchor GLFW_STICKY_MOUSE_BUTTONS
Whenever you poll state, you risk missing the state change you are looking for.
If a pressed mouse button is released again before you poll its state, you will have
missed the button press.  The recommended solution for this is to use a
mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS`
input mode.

@code
glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1);
@endcode

When sticky mouse buttons mode is enabled, the pollable state of a mouse button
will remain `GLFW_PRESS` until the state of that button is polled with @ref
glfwGetMouseButton.  Once it has been polled, if a mouse button release event
had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
otherwise it will remain `GLFW_PRESS`.

The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
[named button](@ref buttons).


@subsection scrolling Scroll input

If you wish to be notified when the user scrolls, whether with a mouse wheel or
touchpad gesture, set a scroll callback.

@code
glfwSetScrollCallback(window, scroll_callback);
@endcode

The callback function receives two-dimensional scroll offsets.

@code
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
}
@endcode

A 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

When GLFW is initialized, detected joysticks are added to to the beginning of
the array.  Once a joystick is detected, it keeps its assigned ID until it is
disconnected or the library is terminated, so as joysticks are connected and
disconnected, there may appear gaps in the IDs.

Joystick axis, button and hat state is updated when polled and does not require
a window to be created or events to be processed.  However, if you want joystick
connection and disconnection events reliably delivered to the
[joystick callback](@ref joystick_event) then you must
[process events](@ref events).

To see all the properties of all connected joysticks in real-time, run the
`joysticks` test program.


@subsection joystick_axis Joystick axis states

The positions of all axes of a joystick are returned by @ref
glfwGetJoystickAxes.  See the reference documentation for the lifetime of the
returned array.

@code
int count;
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
@endcode

Each element in the returned array is a value between -1.0 and 1.0.


@subsection joystick_button Joystick button states

The states of all buttons of a joystick are returned by @ref
glfwGetJoystickButtons.  See the reference documentation for the lifetime of the
returned array.

@code
int count;
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
@endcode

Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.

For backward compatibility with earlier versions that did not have @ref
glfwGetJoystickHats, the button array by default also includes all hats.  See
the reference documentation for @ref glfwGetJoystickButtons for details.


@subsection joystick_hat Joystick hat states

The states of all hats are returned by @ref glfwGetJoystickHats.  See the
reference documentation for the lifetime of the returned array.

@code
int count;
const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
@endcode

Each element in the returned array is one of the following:

Name                  | Value
--------------------- | --------------------------------
`GLFW_HAT_CENTERED`   | 0
`GLFW_HAT_UP`         | 1
`GLFW_HAT_RIGHT`      | 2
`GLFW_HAT_DOWN`       | 4
`GLFW_HAT_LEFT`       | 8
`GLFW_HAT_RIGHT_UP`   | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
`GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
`GLFW_HAT_LEFT_UP`    | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
`GLFW_HAT_LEFT_DOWN`  | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`

The diagonal directions are bitwise combinations of the primary (up, right, down
and left) directions and you can test for these individually by ANDing it with
the corresponding direction.

@code
if (hats[2] & GLFW_HAT_RIGHT)
{
    // State of hat 2 could be right-up, right or right-down
}
@endcode

For backward compatibility with earlier versions that did not have @ref
glfwGetJoystickHats, all hats are by default also included in the button array.
See the reference documentation for @ref glfwGetJoystickButtons for details.


@subsection joystick_name Joystick name

The human-readable, UTF-8 encoded name of a joystick is returned by @ref
glfwGetJoystickName.  See the reference documentation for the lifetime of the
returned string.           

@code
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
@endcode

Joystick names are not guaranteed to be unique.  Two joysticks of the same model
and make may have the same name.  Only the [joystick token](@ref joysticks) is
guaranteed to be unique, and only until that joystick is disconnected.


@subsection joystick_event Joystick configuration changes

If you wish to be notified when a joystick is connected or disconnected, set
a joystick callback.

@code
glfwSetJoystickCallback(joystick_callback);
@endcode

The callback function receives the ID of the joystick that has been connected
and disconnected and the event that occurred.

@code
void joystick_callback(int jid, int event)
{
    if (event == GLFW_CONNECTED)
    {
        // The joystick was connected
    }
    else if (event == GLFW_DISCONNECTED)
    {
        // The joystick was disconnected
    }
}
@endcode

For joystick connection and disconnection events to be delivered on all
platforms, you need to call one of the [event processing](@ref events)
functions.  Joystick disconnection may also be detected and the callback
called by joystick functions.  The function will then return whatever it
returns for a disconnected joystick.


@subsection gamepad Gamepad input

The joystick functions provide unlabeled axes, buttons and hats, with no
indication of where they are located on the device.  Their order may also vary
between platforms even with the same device.

To solve this problem the SDL community crowdsourced the
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project,
a database of mappings from many different devices to an Xbox-like gamepad.

GLFW supports this mapping format and contains a copy of the mappings
available at the time of release.  See @ref gamepad_mapping for how to update
this at runtime.  Mappings will be assigned to joysticks automatically any time
a joystick is connected or the mappings are updated.

You can check whether a joystick is both present and has a gamepad mapping with
@ref glfwJoystickIsGamepad.

@code
if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2))
{
    // Use as gamepad
}
@endcode

If you are only interested in gamepad input you can use this function instead of
@ref glfwJoystickPresent.

You can query the human-readable name provided by the gamepad mapping with @ref
glfwGetGamepadName.  This may or may not be the same as the
[joystick name](@ref joystick_name).

@code
const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
@endcode

To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState.

@code
GLFWgamepadstate state;

if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state))
{
    if (state.buttons[GLFW_GAMEPAD_BUTTON_A])
    {
        input_jump();
    }

    input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]);
}
@endcode

The @ref GLFWgamepadstate struct has two arrays; one for button states and one
for axis states.  The values for each button and axis are the same as for the
@ref glfwGetJoystickButtons and @ref glfwGetJoystickAxes functions, i.e.
`GLFW_PRESS` or `GLFW_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes.

The sizes of the arrays and the positions within each array are fixed.

The [button indices](@ref gamepad_buttons) are `GLFW_GAMEPAD_BUTTON_A`,
`GLFW_GAMEPAD_BUTTON_B`, `GLFW_GAMEPAD_BUTTON_X`, `GLFW_GAMEPAD_BUTTON_Y`,
`GLFW_GAMEPAD_BUTTON_LEFT_BUMPER`, `GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER`,
`GLFW_GAMEPAD_BUTTON_BACK`, `GLFW_GAMEPAD_BUTTON_START`,
`GLFW_GAMEPAD_BUTTON_GUIDE`, `GLFW_GAMEPAD_BUTTON_LEFT_THUMB`,
`GLFW_GAMEPAD_BUTTON_RIGHT_THUMB`, `GLFW_GAMEPAD_BUTTON_DPAD_UP`,
`GLFW_GAMEPAD_BUTTON_DPAD_RIGHT`, `GLFW_GAMEPAD_BUTTON_DPAD_DOWN` and
`GLFW_GAMEPAD_BUTTON_DPAD_LEFT`.

For those who prefer, there are also the `GLFW_GAMEPAD_BUTTON_CROSS`,
`GLFW_GAMEPAD_BUTTON_CIRCLE`, `GLFW_GAMEPAD_BUTTON_SQUARE` and
`GLFW_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices.

The [axis indices](@ref gamepad_axes) are `GLFW_GAMEPAD_AXIS_LEFT_X`,
`GLFW_GAMEPAD_AXIS_LEFT_Y`, `GLFW_GAMEPAD_AXIS_RIGHT_X`,
`GLFW_GAMEPAD_AXIS_RIGHT_Y`, `GLFW_GAMEPAD_AXIS_LEFT_TRIGGER` and
`GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER`.

The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal
the largest available index for each array.


@subsection gamepad_mapping Gamepad mappings

GLFW contains a copy of the mappings available in
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the
time of release.  Newer ones can be added at runtime with @ref
glfwUpdateGamepadMappings.

@code
const char* mappings = load_file_contents("gamecontrollerdb.txt");

glfwUpdateGamepadMappings(mappings);
@endcode

This function supports everything from single lines up to and including the
unmodified contents of the whole `gamecontrollerdb.txt` file.

Below is a description of the mapping format.  Please keep in mind that __this
description is not authoritative__.  The format is defined by the SDL and
SDL_GameControllerDB projects and their documentation and code takes precedence.

Each mapping is a single line of comma-separated values describing the GUID,
name and layout of the gamepad.  Lines that do not begin with a hexadecimal
digit are ignored.

The first value is always the gamepad GUID, a 32 character long hexadecimal
string that typically identifies its make, model, revision and the type of
connection to the computer.  When this information is not available, the GUID is
generated using the gamepad name.  GLFW uses the SDL 2.0.5+ GUID format but can
convert from the older formats.

The second value is always the human-readable name of the gamepad.

All subsequent values are in the form `<field>:<value>` and describe the layout
of the mapping.  These fields may not all be present and may occur in any order.

The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
`rightstick`.

The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and
`righttrigger`.

The value of an axis or button field can be a joystick button, a joystick axis,
a hat bitmask or empty.  Joystick buttons are specified as `bN`, for example
`b2` for the third button.  Joystick axes are specified as `aN`, for example
`a7` for the eighth button.  Joystick hat bit masks are specified as `hN.N`, for
example `h0.8` for left on the first hat.  More than one bit may be set in the
mask.

The hat bit mask match the [hat states](@ref hat_state) in the joystick
functions.

There is also the special `platform` field that specifies which platform the
mapping is valid for.  Possible values are `Windows`, `Mac OS X` and `Linux`.

Below is an example of what a gamepad mapping might look like.  It is the
one built into GLFW for Xbox controllers accessed via the XInput API on Windows.
This example has been broken into several lines to fit on the page, but real
gamepad mappings must be a single line.

@code{.unparsed}
78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,
b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,
rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,
righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
@endcode

@note GLFW does not yet support the range and inversion modifiers `+`, `-` and
`~` that were recently added to SDL.


@section time Time input

GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime.

@code
double seconds = glfwGetTime();
@endcode

It returns the number of seconds since the timer was started when the library
was initialized with @ref glfwInit.  The platform-specific time sources used
usually have micro- or nanosecond resolution.

You can modify the reference time with @ref glfwSetTime.

@code
glfwSetTime(4.0);
@endcode

This sets the timer to the specified time, in seconds.

You can also access the raw timer value, measured in 1&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.

*/
