/*!

@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, there are those that provide both
callbacks and polling.  Where a callback is provided, that is the recommended
way to receive that kind of input.  The more you can use callbacks the less time
your users' machines will need to spend polling.

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 communicate regularly with the window system both in order to
receive events and to show that the application hasn't locked up.  Event
processing must be done regularly while you have any windows and 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
connection events.

There are two 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 continually, 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 that need periodic updates,
call @ref glfwWaitEventsTimeout.

@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 through either of the above
functions.  While it is necessary to process events in the event queue, some
window systems will send some events directly to the application, which in turn
causes callbacks to be called outside of regular event processing.


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

Key states for [named keys](@ref keys) are 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 state of the key.

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

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](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/UTF-32).

There are two callbacks for receiving Unicode code points.  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

If you wish to receive even those Unicode code points generated with modifier
key combinations that a plain text field would ignore, or just want to know
exactly what modifier keys were used, set a character with modifiers callback.

@code
glfwSetCharModsCallback(window, charmods_callback);
@endcode

The callback function receives Unicode code points and
[modifier bits](@ref mods).

@code
void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods)
{
}
@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.


@subsection input_key_scancode Key scancodes

If you need the platform dependent scancode for a [named key](@ref keys), you
can query it with @ref glfwGetKeyScancode.

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


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

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 just wish the cursor to become hidden when it is over a window, 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.  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.  All cursors remaining when @ref
glfwTerminate is called are destroyed as well.


@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 remove a cursor from a window, set the cursor of that window to `NULL`.

@code
glfwSetCursor(window, NULL);
@endcode

When a cursor is destroyed, it is removed from any window where it is set.  This
does not affect the cursor modes of those windows.


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

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 simple 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 `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, starting with `GLFW_JOYSTICK_1`.  Once a joystick is detected, it
keeps its assigned index until it is disconnected, so as joysticks are connected
and disconnected, they will become spread out.

Joystick state is updated as needed when a joystick function is called and does
not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents
to be called.


@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_1, &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* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count);
@endcode

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


@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_1);
@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 joy, int event)
{
    if (event == GLFW_CONNECTED)
    {
        // The joystick was connected
    }
    else if (event == GLFW_DISCONNECTED)
    {
        // The joystick was disconnected
    }
}
@endcode


@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(window);
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(window, "A string with words in it");
@endcode

The clipboard functions take a window handle argument because some window
systems require a window to communicate with the system clipboard.  Any valid
window may be used.


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

*/
