# Input guide {#input_guide}

[TOC]

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 registers every callback supported by GLFW and prints
out all arguments provided for every event, along with time and sequence
information.


## Event processing {#events}

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.

```c
glfwPollEvents();
```

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.

```c
glfwWaitEvents();
```

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.

```c
glfwWaitEventsTimeout(0.7);
```

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.

```c
glfwPostEmptyEvent();
```

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.


## Keyboard input {#input_keyboard}

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 text that is 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.


### Key input {#input_key}

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

```c
glfwSetKeyCallback(window, key_callback);
```

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

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

The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`.  Events with
`GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press.  Most
keys will also emit events with `GLFW_REPEAT` actions while a key is held down.

Note that many keyboards have a limit on how many keys being simultaneous held
down that they can detect.  This limit is called
[key rollover](https://en.wikipedia.org/wiki/Key_rollover).

Key events with `GLFW_REPEAT` actions are intended for text input.  They are
emitted at the rate set in the user's keyboard settings.  At most one key is
repeated even if several keys are held down.  `GLFW_REPEAT` actions should not
be relied on to know which keys are being held down or to drive animation.
Instead you should either save the state of relevant keys based on `GLFW_PRESS`
and `GLFW_RELEASE` actions, or call @ref glfwGetKey, which provides basic cached
key state.

The key will be one of the existing [key tokens](@ref keys), or
`GLFW_KEY_UNKNOWN` if GLFW lacks a 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 [key token](@ref keys) supported on the
current platform with @ref glfwGetKeyScancode.

```c
const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
set_key_mapping(scancode, swap_weapons);
```

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

```c
int state = glfwGetKey(window, GLFW_KEY_E);
if (state == GLFW_PRESS)
{
    activate_airship();
}
```

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 state of the physical key.  It also does not provide any
key repeat information.

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

```c
glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE);
```

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.

```c
glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE);
```

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
[key token](@ref keys).


### Text input {#input_char}

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 is affected by
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.

```c
glfwSetCharCallback(window, character_callback);
```

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.

```c
void character_callback(GLFWwindow* window, unsigned int codepoint)
{
}
```


### Key names {#input_key_name}

If you wish to refer to keys by name, you can query the keyboard layout
dependent name of printable keys with @ref glfwGetKeyName.

```c
const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0);
show_tutorial_hint("Press %s to move forward", key_name);
```

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.


## Mouse input {#input_mouse}

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.


### Cursor position {#cursor_pos}

If you wish to be notified when the cursor moves over the window, set a cursor
position callback.

```c
glfwSetCursorPosCallback(window, cursor_position_callback);
```

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.

```c
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
{
}
```

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

```c
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
```


### 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`.

```c
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
```

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`.

```c
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
```

This mode puts no limit on the motion of the cursor.

If you wish the cursor to be visible but confined to the content area of the
window, set the cursor mode to `GLFW_CURSOR_CAPTURED`.

```c
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
```

The cursor will behave normally inside the content area but will not be able to
leave unless the window loses focus.

To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
cursor mode.

```c
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
```

If the cursor was disabled, this will move it back to its last visible position.


@anchor GLFW_RAW_MOUSE_MOTION
### 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.

```c
if (glfwRawMouseMotionSupported())
    glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
```

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.


### Cursor objects {#cursor_object}

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.


#### Custom cursor creation {#cursor_custom}

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:

```c
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);
```

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.


#### Standard cursor creation {#cursor_standard}

A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be created with @ref glfwCreateStandardCursor.

```c
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
```

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.

A few of these shapes are not available everywhere.  If a shape is unavailable,
`NULL` is returned.  See @ref glfwCreateStandardCursor for details.


#### Cursor destruction {#cursor_destruction}

When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.

```c
glfwDestroyCursor(cursor);
```

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.


#### Cursor setting {#cursor_set}

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

```c
glfwSetCursor(window, cursor);
```

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`.

```c
glfwSetCursor(window, NULL);
```

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


### Cursor enter/leave events {#cursor_enter}

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

```c
glfwSetCursorEnterCallback(window, cursor_enter_callback);
```

The callback function receives the new classification of the cursor.

```c
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
    }
}
```

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.

```c
if (glfwGetWindowAttrib(window, GLFW_HOVERED))
{
    highlight_interface();
}
```


### Mouse button input {#input_mouse_button}

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

```c
glfwSetMouseButtonCallback(window, mouse_button_callback);
```

@anchor GLFW_UNLIMITED_MOUSE_BUTTONS
To handle all mouse buttons in the callback, instead of only ones with associated
[button tokens](@ref buttons), set the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
input mode.

```c
glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
```

When this input mode is enabled, GLFW doesn't limit the reported mouse buttons
to only those that have an associated button token, for compatibility with
earlier versions of GLFW, which never reported any buttons over
@ref GLFW_MOUSE_BUTTON_LAST, on which users could have relied on.

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

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

The mouse button is an integer that can be one of the
[mouse button tokens](@ref buttons) or, if the
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set, any other positive value.

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

The last reported state for every [mouse button token](@ref buttons) is also
saved in per-window state arrays that can be polled with @ref
glfwGetMouseButton. This is not effected by the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
input mode.

```c
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
if (state == GLFW_PRESS)
{
    upgrade_cow();
}
```

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.

```c
glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE);
```

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
[mouse button token](@ref buttons).


### Scroll input {#scrolling}

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

```c
glfwSetScrollCallback(window, scroll_callback);
```

The callback function receives two-dimensional scroll offsets.

```c
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
}
```

A normal mouse wheel, being vertical, provides offsets along the Y-axis.


## Joystick input {#joystick}

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.

```c
int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
```

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.

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.


### Joystick axis states {#joystick_axis}

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

```c
int count;
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
```

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


### Joystick button states {#joystick_button}

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

```c
int count;
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
```

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.


### Joystick hat states {#joystick_hat}

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

```c
int count;
const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
```

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.

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

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.


### 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.

```c
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
```

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.


### Joystick user pointer {#joystick_userptr}

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`.


### Joystick configuration changes {#joystick_event}

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

```c
glfwSetJoystickCallback(joystick_callback);
```

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

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

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.


### Gamepad input {#gamepad}

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][] project, a database of mappings from many different
devices to an Xbox-like gamepad.

[SDL_GameControllerDB]: https://github.com/gabomdq/SDL_GameControllerDB

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.

```c
if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2))
{
    // Use as gamepad
}
```

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).

```c
const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
```

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

```c
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]);
}
```

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.


### Gamepad mappings {#gamepad_mapping}

GLFW contains a copy of the mappings available in [SDL_GameControllerDB][] at
the time of release.  Newer ones can be added at runtime with @ref
glfwUpdateGamepadMappings.

```c
const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt");

glfwUpdateGamepadMappings(mappings);
```

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.

```
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,
```

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


## Time input {#time}

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

```c
double seconds = glfwGetTime();
```

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.

```c
glfwSetTime(4.0);
```

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.

```c
uint64_t value = glfwGetTimerValue();
```

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.

```c
uint64_t frequency = glfwGetTimerFrequency();
```


## Clipboard input and output {#clipboard}

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.

```c
const char* text = glfwGetClipboardString(NULL);
if (text)
{
    insert_text(text);
}
```

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.

```c
glfwSetClipboardString(NULL, "A string with words in it");
```


## Path drop input {#path_drop}

If you wish to receive the paths of files and/or directories dropped on
a window, set a file drop callback.

```c
glfwSetDropCallback(window, drop_callback);
```

The callback function receives an array of paths encoded as UTF-8.

```c
void drop_callback(GLFWwindow* window, int count, const char** paths)
{
    int i;
    for (i = 0;  i < count;  i++)
        handle_dropped_file(paths[i]);
}
```

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.

