/*!

@page input Input guide
 
@tableofcontents

This guide introduces the input related functions of GLFW.  There are also
guides for the other areas of GLFW.

 - @ref intro
 - @ref window
 - @ref context
 - @ref monitor

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 visible windows and is normally
done each frame after [buffer swapping](@ref buffer_swap).

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 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.  These keys still
have unique, if platform-specific scancodes.

The scancode is unique for every key but is platform-specific, so a scancode
will map to different keys on different platforms.

The key will be `GLFW_KEY_UNKNOWN` for special keys like _E-mail_ or _Play_ that
don't have a key token.  Those keys will still have unique, if platform-specific
scancodes.

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


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


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


@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* clipboard = glfwGetClipboardString(window);
@endcode

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.

*/
