123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951 |
- /*!
- @page input_guide Input guide
- @tableofcontents
- This guide introduces the input related functions of GLFW. For details on
- a specific function in this category, see the @ref input. There are also guides
- for the other areas of GLFW.
- - @ref intro_guide
- - @ref window_guide
- - @ref context_guide
- - @ref vulkan_guide
- - @ref monitor_guide
- GLFW provides many kinds of input. While some can only be polled, like time, or
- only received via callbacks, like scrolling, many provide both callbacks and
- polling. Callbacks are more work to use than polling but is less CPU intensive
- and guarantees that you do not miss state changes.
- All input callbacks receive a window handle. By using the
- [window user pointer](@ref window_userptr), you can access non-global structures
- or objects from your callbacks.
- To get a better feel for how the various events callbacks behave, run the
- `events` test program. It register every callback supported by GLFW and prints
- out all arguments provided for every event, along with time and sequence
- information.
- @section events Event processing
- GLFW needs to poll the window system for events both to provide input to the
- application and to prove to the window system that the application hasn't locked
- up. Event processing is normally done each frame after
- [buffer swapping](@ref buffer_swap). Even when you have no windows, event
- polling needs to be done in order to receive monitor and joystick connection
- events.
- There are three functions for processing pending events. @ref glfwPollEvents,
- processes only those events that have already been received and then returns
- immediately.
- @code
- glfwPollEvents();
- @endcode
- This is the best choice when rendering continuously, like most games do.
- If you only need to update the contents of the window when you receive new
- input, @ref glfwWaitEvents is a better choice.
- @code
- glfwWaitEvents();
- @endcode
- It puts the thread to sleep until at least one event has been received and then
- processes all received events. This saves a great deal of CPU cycles and is
- useful for, for example, editing tools.
- If you want to wait for events but have UI elements or other tasks that need
- periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout.
- @code
- glfwWaitEventsTimeout(0.7);
- @endcode
- It puts the thread to sleep until at least one event has been received, or until
- the specified number of seconds have elapsed. It then processes any received
- events.
- If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
- another thread by posting an empty event to the event queue with @ref
- glfwPostEmptyEvent.
- @code
- glfwPostEmptyEvent();
- @endcode
- Do not assume that callbacks will _only_ be called in response to the above
- functions. While it is necessary to process events in one or more of the ways
- above, window systems that require GLFW to register callbacks of its own can
- pass events to GLFW in response to many window system function calls. GLFW will
- pass those events on to the application callbacks before returning.
- For example, on Windows the system function that @ref glfwSetWindowSize is
- implemented with will send window size events directly to the event callback
- that every window has and that GLFW implements for its windows. If you have set
- a [window size callback](@ref window_size) GLFW will call it in turn with the
- new size before everything returns back out of the @ref glfwSetWindowSize call.
- @section input_keyboard Keyboard input
- GLFW divides keyboard input into two categories; key events and character
- events. Key events relate to actual physical keyboard keys, whereas character
- events relate to the Unicode code points generated by pressing some of them.
- Keys and characters do not map 1:1. A single key press may produce several
- characters, and a single character may require several keys to produce. This
- may not be the case on your machine, but your users are likely not all using the
- same keyboard layout, input method or even operating system as you.
- @subsection input_key Key input
- If you wish to be notified when a physical key is pressed or released or when it
- repeats, set a key callback.
- @code
- glfwSetKeyCallback(window, key_callback);
- @endcode
- The callback function receives the [keyboard key](@ref keys), platform-specific
- scancode, key action and [modifier bits](@ref mods).
- @code
- void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
- {
- if (key == GLFW_KEY_E && action == GLFW_PRESS)
- activate_airship();
- }
- @endcode
- The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key
- will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example
- _E-mail_ and _Play_ keys.
- The scancode is unique for every key, regardless of whether it has a key token.
- Scancodes are platform-specific but consistent over time, so keys will have
- different scancodes depending on the platform but they are safe to save to disk.
- You can query the scancode for any [named key](@ref keys) on the current
- platform with @ref glfwGetKeyScancode.
- @code
- const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
- set_key_mapping(scancode, swap_weapons);
- @endcode
- The last reported state for every [named key](@ref keys) is also saved in
- per-window state arrays that can be polled with @ref glfwGetKey.
- @code
- int state = glfwGetKey(window, GLFW_KEY_E);
- if (state == GLFW_PRESS)
- {
- activate_airship();
- }
- @endcode
- The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
- This function only returns cached key event state. It does not poll the
- system for the current physical state of the key.
- @anchor GLFW_STICKY_KEYS
- Whenever you poll state, you risk missing the state change you are looking for.
- If a pressed key is released again before you poll its state, you will have
- missed the key press. The recommended solution for this is to use a
- key callback, but there is also the `GLFW_STICKY_KEYS` input mode.
- @code
- glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE);
- @endcode
- When sticky keys mode is enabled, the pollable state of a key will remain
- `GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once
- it has been polled, if a key release event had been processed in the meantime,
- the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`.
- @anchor GLFW_LOCK_KEY_MODS
- If you wish to know what the state of the Caps Lock and Num Lock keys was when
- input events were generated, set the `GLFW_LOCK_KEY_MODS` input mode.
- @code
- glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE);
- @endcode
- When this input mode is enabled, any callback that receives
- [modifier bits](@ref mods) will have the @ref GLFW_MOD_CAPS_LOCK bit set if Caps
- Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if
- Num Lock was on.
- The `GLFW_KEY_LAST` constant holds the highest value of any
- [named key](@ref keys).
- @subsection input_char Text input
- GLFW supports text input in the form of a stream of
- [Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
- operating system text input system. Unlike key input, text input obeys keyboard
- layouts and modifier keys and supports composing characters using
- [dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
- encode the code points into UTF-8 or any other encoding you prefer.
- Because an `unsigned int` is 32 bits long on all platforms supported by GLFW,
- you can treat the code point argument as native endian UTF-32.
- If you wish to offer regular text input, set a character callback.
- @code
- glfwSetCharCallback(window, character_callback);
- @endcode
- The callback function receives Unicode code points for key events that would
- have led to regular text input and generally behaves as a standard text field on
- that platform.
- @code
- void character_callback(GLFWwindow* window, unsigned int codepoint)
- {
- }
- @endcode
- @subsection input_key_name Key names
- If you wish to refer to keys by name, you can query the keyboard layout
- dependent name of printable keys with @ref glfwGetKeyName.
- @code
- const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0);
- show_tutorial_hint("Press %s to move forward", key_name);
- @endcode
- This function can handle both [keys and scancodes](@ref input_key). If the
- specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is
- ignored. This matches the behavior of the key callback, meaning the callback
- arguments can always be passed unmodified to this function.
- @section input_mouse Mouse input
- Mouse input comes in many forms, including 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.
- @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_position_callback);
- @endcode
- 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.
- @code
- static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
- {
- }
- @endcode
- The cursor position is also saved per-window and can be polled with @ref
- glfwGetCursorPos.
- @code
- double xpos, ypos;
- glfwGetCursorPos(window, &xpos, &ypos);
- @endcode
- @subsection cursor_mode Cursor mode
- @anchor GLFW_CURSOR
- The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
- mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
- meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
- is used and cursor motion is not limited.
- If you wish to implement mouse motion based camera controls or other input
- schemes that require unlimited mouse movement, set the cursor mode to
- `GLFW_CURSOR_DISABLED`.
- @code
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- @endcode
- This will hide the cursor and lock it to the specified window. GLFW will then
- take care of all the details of cursor re-centering and offset calculation and
- providing the application with a virtual cursor position. This virtual position
- is provided normally via both the cursor position callback and through polling.
- @note You should not implement your own version of this functionality using
- other features of GLFW. It is not supported and will not work as robustly as
- `GLFW_CURSOR_DISABLED`.
- If you only wish the cursor to become hidden when it is over a window but still
- want it to behave normally, set the cursor mode to `GLFW_CURSOR_HIDDEN`.
- @code
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
- @endcode
- This mode puts no limit on the motion of the cursor.
- To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
- cursor mode.
- @code
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- @endcode
- @anchor GLFW_RAW_MOUSE_MOTION
- @subsection 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.
- @code
- if (glfwRawMouseMotionSupported())
- glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
- @endcode
- 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.
- @subsection cursor_object Cursor objects
- GLFW supports creating both custom and system theme cursor images, encapsulated
- as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref
- glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref
- glfwTerminate, if any remain.
- @subsubsection cursor_custom Custom cursor creation
- A custom cursor is created with @ref glfwCreateCursor, which returns a handle to
- the created cursor object. For example, this creates a 16x16 white square
- cursor with the hot-spot in the upper-left corner:
- @code
- unsigned char pixels[16 * 16 * 4];
- memset(pixels, 0xff, sizeof(pixels));
- GLFWimage image;
- image.width = 16;
- image.height = 16;
- image.pixels = pixels;
- GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0);
- @endcode
- If cursor creation fails, `NULL` will be returned, so it is necessary to check
- the return value.
- The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
- per channel with the red channel first. The pixels are arranged canonically as
- sequential rows, starting from the top-left corner.
- @subsubsection cursor_standard Standard cursor creation
- A cursor with a [standard shape](@ref shapes) from the current system cursor
- theme can be can be created with @ref glfwCreateStandardCursor.
- @code
- GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
- @endcode
- These cursor objects behave in the exact same way as those created with @ref
- glfwCreateCursor except that the system cursor theme provides the actual image.
- @subsubsection cursor_destruction Cursor destruction
- When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.
- @code
- glfwDestroyCursor(cursor);
- @endcode
- Cursor destruction always succeeds. If the cursor is current for any window,
- that window will revert to the default cursor. This does not affect the cursor
- mode. All remaining cursors are destroyed when @ref glfwTerminate is called.
- @subsubsection cursor_set Cursor setting
- A cursor can be set as current for a window with @ref glfwSetCursor.
- @code
- glfwSetCursor(window, cursor);
- @endcode
- Once set, the cursor image will be used as long as the system cursor is over the
- 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`.
- @code
- glfwSetCursor(window, NULL);
- @endcode
- When a cursor is destroyed, any window that has it set will revert to the
- default cursor. This does not affect the cursor mode.
- @subsection cursor_enter Cursor enter/leave events
- If you wish to be notified when the cursor enters or leaves the content 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 content area of the window
- }
- else
- {
- // The cursor left the content area of the window
- }
- }
- @endcode
- 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.
- @code
- if (glfwGetWindowAttrib(window, GLFW_HOVERED))
- {
- highlight_interface();
- }
- @endcode
- @subsection input_mouse_button Mouse button input
- If you wish to be notified when a mouse button is pressed or released, set
- a mouse button callback.
- @code
- glfwSetMouseButtonCallback(window, mouse_button_callback);
- @endcode
- The callback function receives the [mouse button](@ref buttons), button action
- and [modifier bits](@ref mods).
- @code
- void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
- {
- if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
- popup_menu();
- }
- @endcode
- The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
- Mouse button states for [named buttons](@ref buttons) are also saved in
- per-window state arrays that can be polled with @ref glfwGetMouseButton.
- @code
- int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
- if (state == GLFW_PRESS)
- {
- upgrade_cow();
- }
- @endcode
- The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
- This function only returns cached mouse button event state. It does not poll
- the system for the current state of the mouse button.
- @anchor GLFW_STICKY_MOUSE_BUTTONS
- Whenever you poll state, you risk missing the state change you are looking for.
- If a pressed mouse button is released again before you poll its state, you will have
- missed the button press. The recommended solution for this is to use a
- mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS`
- input mode.
- @code
- glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE);
- @endcode
- When sticky mouse buttons mode is enabled, the pollable state of a mouse button
- will remain `GLFW_PRESS` until the state of that button is polled with @ref
- glfwGetMouseButton. Once it has been polled, if a mouse button release event
- had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
- otherwise it will remain `GLFW_PRESS`.
- The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
- [named button](@ref buttons).
- @subsection scrolling Scroll input
- If you wish to be notified when the user scrolls, whether with a mouse wheel or
- touchpad gesture, set a scroll callback.
- @code
- glfwSetScrollCallback(window, scroll_callback);
- @endcode
- The callback function receives two-dimensional scroll offsets.
- @code
- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
- {
- }
- @endcode
- A normal mouse wheel, being vertical, provides offsets along the Y-axis.
- @section joystick Joystick input
- The joystick functions expose connected joysticks and controllers, with both
- referred to as joysticks. It supports up to sixteen joysticks, ranging from
- `GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to and including `GLFW_JOYSTICK_16` or
- `GLFW_JOYSTICK_LAST`. You can test whether a [joystick](@ref joysticks) is
- present with @ref glfwJoystickPresent.
- @code
- int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
- @endcode
- 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.
- When GLFW is initialized, 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.
- @subsection joystick_axis Joystick axis states
- The positions of all axes of a joystick are returned by @ref
- glfwGetJoystickAxes. See the reference documentation for the lifetime of the
- returned array.
- @code
- int count;
- const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
- @endcode
- Each element in the returned array is a value between -1.0 and 1.0.
- @subsection joystick_button Joystick button states
- The states of all buttons of a joystick are returned by @ref
- glfwGetJoystickButtons. See the reference documentation for the lifetime of the
- returned array.
- @code
- int count;
- const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
- @endcode
- Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.
- For backward compatibility with earlier versions that did not have @ref
- glfwGetJoystickHats, the button array by default also includes all hats. See
- the reference documentation for @ref glfwGetJoystickButtons for details.
- @subsection joystick_hat Joystick hat states
- The states of all hats are returned by @ref glfwGetJoystickHats. See the
- reference documentation for the lifetime of the returned array.
- @code
- int count;
- const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
- @endcode
- Each element in the returned array is one of the following:
- Name | Value
- ---- | -----
- `GLFW_HAT_CENTERED` | 0
- `GLFW_HAT_UP` | 1
- `GLFW_HAT_RIGHT` | 2
- `GLFW_HAT_DOWN` | 4
- `GLFW_HAT_LEFT` | 8
- `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
- `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
- `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
- `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
- The diagonal directions are bitwise combinations of the primary (up, right, down
- and left) directions and you can test for these individually by ANDing it with
- the corresponding direction.
- @code
- if (hats[2] & GLFW_HAT_RIGHT)
- {
- // State of hat 2 could be right-up, right or right-down
- }
- @endcode
- For backward compatibility with earlier versions that did not have @ref
- glfwGetJoystickHats, all hats are by default also included in the button array.
- See the reference documentation for @ref glfwGetJoystickButtons for details.
- @subsection joystick_name Joystick name
- The human-readable, UTF-8 encoded name of a joystick is returned by @ref
- glfwGetJoystickName. See the reference documentation for the lifetime of the
- returned string.
- @code
- const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
- @endcode
- Joystick names are not guaranteed to be unique. Two joysticks of the same model
- and make may have the same name. Only the [joystick ID](@ref joysticks) is
- guaranteed to be unique, and only until that joystick is disconnected.
- @subsection joystick_userptr Joystick user pointer
- 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`.
- @subsection joystick_event Joystick configuration changes
- If you wish to be notified when a joystick is connected or disconnected, set
- a joystick callback.
- @code
- glfwSetJoystickCallback(joystick_callback);
- @endcode
- The callback function receives the ID of the joystick that has been connected
- and disconnected and the event that occurred.
- @code
- void joystick_callback(int jid, int event)
- {
- if (event == GLFW_CONNECTED)
- {
- // The joystick was connected
- }
- else if (event == GLFW_DISCONNECTED)
- {
- // The joystick was disconnected
- }
- }
- @endcode
- For joystick connection and disconnection events to be delivered on all
- platforms, you need to call one of the [event processing](@ref events)
- functions. Joystick disconnection may also be detected and the callback
- called by joystick functions. The function will then return whatever it
- returns for a disconnected joystick.
- Only @ref glfwGetJoystickName and @ref glfwGetJoystickUserPointer will return
- useful values for a disconnected joystick and only before the monitor callback
- returns.
- @subsection gamepad Gamepad input
- The joystick functions provide unlabeled axes, buttons and hats, with no
- indication of where they are located on the device. Their order may also vary
- between platforms even with the same device.
- To solve this problem the SDL community crowdsourced the
- [SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project,
- a database of mappings from many different devices to an Xbox-like gamepad.
- GLFW supports this mapping format and contains a copy of the mappings
- available at the time of release. See @ref gamepad_mapping for how to update
- this at runtime. Mappings will be assigned to joysticks automatically any time
- a joystick is connected or the mappings are updated.
- You can check whether a joystick is both present and has a gamepad mapping with
- @ref glfwJoystickIsGamepad.
- @code
- if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2))
- {
- // Use as gamepad
- }
- @endcode
- If you are only interested in gamepad input you can use this function instead of
- @ref glfwJoystickPresent.
- You can query the human-readable name provided by the gamepad mapping with @ref
- glfwGetGamepadName. This may or may not be the same as the
- [joystick name](@ref joystick_name).
- @code
- const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
- @endcode
- To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState.
- @code
- GLFWgamepadstate state;
- if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state))
- {
- if (state.buttons[GLFW_GAMEPAD_BUTTON_A])
- {
- input_jump();
- }
- input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]);
- }
- @endcode
- The @ref GLFWgamepadstate struct has two arrays; one for button states and one
- for axis states. The values for each button and axis are the same as for the
- @ref glfwGetJoystickButtons and @ref glfwGetJoystickAxes functions, i.e.
- `GLFW_PRESS` or `GLFW_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes.
- The sizes of the arrays and the positions within each array are fixed.
- The [button indices](@ref gamepad_buttons) are `GLFW_GAMEPAD_BUTTON_A`,
- `GLFW_GAMEPAD_BUTTON_B`, `GLFW_GAMEPAD_BUTTON_X`, `GLFW_GAMEPAD_BUTTON_Y`,
- `GLFW_GAMEPAD_BUTTON_LEFT_BUMPER`, `GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER`,
- `GLFW_GAMEPAD_BUTTON_BACK`, `GLFW_GAMEPAD_BUTTON_START`,
- `GLFW_GAMEPAD_BUTTON_GUIDE`, `GLFW_GAMEPAD_BUTTON_LEFT_THUMB`,
- `GLFW_GAMEPAD_BUTTON_RIGHT_THUMB`, `GLFW_GAMEPAD_BUTTON_DPAD_UP`,
- `GLFW_GAMEPAD_BUTTON_DPAD_RIGHT`, `GLFW_GAMEPAD_BUTTON_DPAD_DOWN` and
- `GLFW_GAMEPAD_BUTTON_DPAD_LEFT`.
- For those who prefer, there are also the `GLFW_GAMEPAD_BUTTON_CROSS`,
- `GLFW_GAMEPAD_BUTTON_CIRCLE`, `GLFW_GAMEPAD_BUTTON_SQUARE` and
- `GLFW_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices.
- The [axis indices](@ref gamepad_axes) are `GLFW_GAMEPAD_AXIS_LEFT_X`,
- `GLFW_GAMEPAD_AXIS_LEFT_Y`, `GLFW_GAMEPAD_AXIS_RIGHT_X`,
- `GLFW_GAMEPAD_AXIS_RIGHT_Y`, `GLFW_GAMEPAD_AXIS_LEFT_TRIGGER` and
- `GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER`.
- The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal
- the largest available index for each array.
- @subsection gamepad_mapping Gamepad mappings
- GLFW contains a copy of the mappings available in
- [SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the
- time of release. Newer ones can be added at runtime with @ref
- glfwUpdateGamepadMappings.
- @code
- const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt");
- glfwUpdateGamepadMappings(mappings);
- @endcode
- This function supports everything from single lines up to and including the
- unmodified contents of the whole `gamecontrollerdb.txt` file.
- 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`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
- `dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
- `rightstick`.
- The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and
- `righttrigger`.
- The value of an axis or button field can be a joystick button, a joystick axis,
- a hat bitmask or empty. Joystick buttons are specified as `bN`, for example
- `b2` for the third button. Joystick axes are specified as `aN`, for example
- `a7` for the eighth button. Joystick hat bit masks are specified as `hN.N`, for
- example `h0.8` for left on the first hat. More than one bit may be set in the
- mask.
- 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.
- @code{.unparsed}
- 78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,
- b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,
- rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,
- righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
- @endcode
- @note GLFW does not yet support the output range and modifiers `+` and `-` that
- were recently added to SDL. The input modifiers `+`, `-` and `~` are supported
- and described above.
- @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 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.
- @code
- glfwSetTime(4.0);
- @endcode
- 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.
- @code
- uint64_t value = glfwGetTimerValue();
- @endcode
- This value is in 1 / 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.
- @code
- uint64_t frequency = glfwGetTimerFrequency();
- @endcode
- @section clipboard Clipboard input and output
- If the system clipboard contains a UTF-8 encoded string or if it can be
- converted to one, you can retrieve it with @ref glfwGetClipboardString. See the
- reference documentation for the lifetime of the returned string.
- @code
- const char* text = glfwGetClipboardString(NULL);
- if (text)
- {
- insert_text(text);
- }
- @endcode
- If the clipboard is empty or if its contents could not be converted, `NULL` is
- returned.
- The contents of the system clipboard can be set to a UTF-8 encoded string with
- @ref glfwSetClipboardString.
- @code
- glfwSetClipboardString(NULL, "A string with words in it");
- @endcode
- @section path_drop Path drop input
- If you wish to receive the paths of files and/or directories dropped on
- a window, set a file drop callback.
- @code
- glfwSetDropCallback(window, drop_callback);
- @endcode
- The callback function receives an array of paths encoded as UTF-8.
- @code
- void drop_callback(GLFWwindow* window, int count, const char** paths)
- {
- int i;
- for (i = 0; i < count; i++)
- handle_dropped_file(paths[i]);
- }
- @endcode
- The path array and its strings are only valid until the file drop callback
- returns, as they may have been generated specifically for that event. You need
- to make a deep copy of the array if you want to keep the paths.
- */
|