|
|
- /*!
-
- @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.
-
-
- @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 / 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.
-
- */
|