|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
|
<meta name="generator" content="Doxygen 1.8.11"/>
|
|
<title>GLFW: Input guide</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<script type="text/javascript">
|
|
$(document).ready(function() { init_search(); });
|
|
</script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
<link href="extra.css" rel="stylesheet" type="text/css"/>
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<div class="glfwheader">
|
|
<a href="http://www.glfw.org/" id="glfwhome">GLFW</a>
|
|
<ul class="glfwnavbar">
|
|
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
|
|
<li><a href="http://www.glfw.org/download.html">Download</a></li>
|
|
<li><a href="http://www.glfw.org/media.html">Media</a></li>
|
|
<li><a href="http://www.glfw.org/community.html">Community</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.8.11 -->
|
|
<script type="text/javascript">
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
|
</script>
|
|
<div id="navrow1" class="tabs">
|
|
<ul class="tablist">
|
|
<li><a href="index.html"><span>Main Page</span></a></li>
|
|
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
|
|
<li><a href="modules.html"><span>Modules</span></a></li>
|
|
<li><a href="annotated.html"><span>Data Structures</span></a></li>
|
|
<li><a href="files.html"><span>Files</span></a></li>
|
|
<li>
|
|
<div id="MSearchBox" class="MSearchBoxInactive">
|
|
<span class="left">
|
|
<img id="MSearchSelect" src="search/mag_sel.png"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
alt=""/>
|
|
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
|
onfocus="searchBox.OnSearchFieldFocus(true)"
|
|
onblur="searchBox.OnSearchFieldFocus(false)"
|
|
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
|
</span><span class="right">
|
|
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
|
</span>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
</div><!-- top -->
|
|
<div class="header">
|
|
<div class="headertitle">
|
|
<div class="title">Input guide </div> </div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="toc"><h3>Table of Contents</h3>
|
|
<ul><li class="level1"><a href="#events">Event processing</a></li>
|
|
<li class="level1"><a href="#input_keyboard">Keyboard input</a><ul><li class="level2"><a href="#input_key">Key input</a></li>
|
|
<li class="level2"><a href="#input_char">Text input</a></li>
|
|
<li class="level2"><a href="#input_key_name">Key names</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="level1"><a href="#input_mouse">Mouse input</a><ul><li class="level2"><a href="#cursor_pos">Cursor position</a></li>
|
|
<li class="level2"><a href="#cursor_mode">Cursor modes</a></li>
|
|
<li class="level2"><a href="#cursor_object">Cursor objects</a><ul><li class="level3"><a href="#cursor_custom">Custom cursor creation</a></li>
|
|
<li class="level3"><a href="#cursor_standard">Standard cursor creation</a></li>
|
|
<li class="level3"><a href="#cursor_destruction">Cursor destruction</a></li>
|
|
<li class="level3"><a href="#cursor_set">Cursor setting</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="level2"><a href="#cursor_enter">Cursor enter/leave events</a></li>
|
|
<li class="level2"><a href="#input_mouse_button">Mouse button input</a></li>
|
|
<li class="level2"><a href="#scrolling">Scroll input</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="level1"><a href="#joystick">Joystick input</a><ul><li class="level2"><a href="#joystick_axis">Joystick axis states</a></li>
|
|
<li class="level2"><a href="#joystick_button">Joystick button states</a></li>
|
|
<li class="level2"><a href="#joystick_name">Joystick name</a></li>
|
|
<li class="level2"><a href="#joystick_event">Joystick configuration changes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="level1"><a href="#time">Time input</a></li>
|
|
<li class="level1"><a href="#clipboard">Clipboard input and output</a></li>
|
|
<li class="level1"><a href="#path_drop">Path drop input</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="textblock"><p>This guide introduces the input related functions of GLFW. For details on a specific function in this category, see the <a class="el" href="group__input.html">Input reference</a>. There are also guides for the other areas of GLFW.</p>
|
|
<ul>
|
|
<li><a class="el" href="intro_guide.html">Introduction to the API</a></li>
|
|
<li><a class="el" href="window_guide.html">Window guide</a></li>
|
|
<li><a class="el" href="context_guide.html">Context guide</a></li>
|
|
<li><a class="el" href="vulkan_guide.html">Vulkan guide</a></li>
|
|
<li><a class="el" href="monitor_guide.html">Monitor guide</a></li>
|
|
</ul>
|
|
<p>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.</p>
|
|
<p>All input callbacks receive a window handle. By using the <a class="el" href="window_guide.html#window_userptr">window user pointer</a>, you can access non-global structures or objects from your callbacks.</p>
|
|
<p>To get a better feel for how the various events callbacks behave, run the <code>events</code> test program. It register every callback supported by GLFW and prints out all arguments provided for every event, along with time and sequence information.</p>
|
|
<h1><a class="anchor" id="events"></a>
|
|
Event processing</h1>
|
|
<p>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 <a class="el" href="window_guide.html#buffer_swap">buffer swapping</a>. Even when you have no windows, event polling needs to be done in order to receive monitor connection events.</p>
|
|
<p>There are two functions for processing pending events. <a class="el" href="group__window.html#ga37bd57223967b4211d60ca1a0bf3c832">glfwPollEvents</a>, processes only those events that have already been received and then returns immediately.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__window.html#ga37bd57223967b4211d60ca1a0bf3c832">glfwPollEvents</a>();</div></div><!-- fragment --><p>This is the best choice when rendering continually, like most games do.</p>
|
|
<p>If you only need to update the contents of the window when you receive new input, <a class="el" href="group__window.html#ga554e37d781f0a997656c26b2c56c835e">glfwWaitEvents</a> is a better choice.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__window.html#ga554e37d781f0a997656c26b2c56c835e">glfwWaitEvents</a>();</div></div><!-- fragment --><p>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.</p>
|
|
<p>If you want to wait for events but have UI elements that need periodic updates, call <a class="el" href="group__window.html#ga605a178db92f1a7f1a925563ef3ea2cf">glfwWaitEventsTimeout</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__window.html#ga605a178db92f1a7f1a925563ef3ea2cf">glfwWaitEventsTimeout</a>(0.7);</div></div><!-- fragment --><p>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.</p>
|
|
<p>If the main thread is sleeping in <a class="el" href="group__window.html#ga554e37d781f0a997656c26b2c56c835e">glfwWaitEvents</a>, you can wake it from another thread by posting an empty event to the event queue with <a class="el" href="group__window.html#gab5997a25187e9fd5c6f2ecbbc8dfd7e9">glfwPostEmptyEvent</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__window.html#gab5997a25187e9fd5c6f2ecbbc8dfd7e9">glfwPostEmptyEvent</a>();</div></div><!-- fragment --><p>Do not assume that callbacks will <em>only</em> 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.</p>
|
|
<h1><a class="anchor" id="input_keyboard"></a>
|
|
Keyboard input</h1>
|
|
<p>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.</p>
|
|
<p>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.</p>
|
|
<h2><a class="anchor" id="input_key"></a>
|
|
Key input</h2>
|
|
<p>If you wish to be notified when a physical key is pressed or released or when it repeats, set a key callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga7e496507126f35ea72f01b2e6ef6d155">glfwSetKeyCallback</a>(window, key_callback);</div></div><!-- fragment --><p>The callback function receives the <a class="el" href="group__keys.html">keyboard key</a>, platform-specific scancode, key action and <a class="el" href="group__mods.html">modifier bits</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> key_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">int</span> key, <span class="keywordtype">int</span> scancode, <span class="keywordtype">int</span> action, <span class="keywordtype">int</span> mods)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (key == <a class="code" href="group__keys.html#gabf48fcc3afbe69349df432b470c96ef2">GLFW_KEY_E</a> && action == <a class="code" href="group__input.html#ga2485743d0b59df3791c45951c4195265">GLFW_PRESS</a>)</div><div class="line"> activate_airship();</div><div class="line">}</div></div><!-- fragment --><p>The action is one of <code>GLFW_PRESS</code>, <code>GLFW_REPEAT</code> or <code>GLFW_RELEASE</code>. The key will be <code>GLFW_KEY_UNKNOWN</code> if GLFW lacks a key token for it, for example <em>E-mail</em> and <em>Play</em> keys.</p>
|
|
<p>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.</p>
|
|
<p>Key states for <a class="el" href="group__keys.html">named keys</a> are also saved in per-window state arrays that can be polled with <a class="el" href="group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2">glfwGetKey</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">int</span> state = <a class="code" href="group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2">glfwGetKey</a>(window, <a class="code" href="group__keys.html#gabf48fcc3afbe69349df432b470c96ef2">GLFW_KEY_E</a>);</div><div class="line"><span class="keywordflow">if</span> (state == <a class="code" href="group__input.html#ga2485743d0b59df3791c45951c4195265">GLFW_PRESS</a>)</div><div class="line"> activate_airship();</div></div><!-- fragment --><p>The returned state is one of <code>GLFW_PRESS</code> or <code>GLFW_RELEASE</code>.</p>
|
|
<p>This function only returns cached key event state. It does not poll the system for the current state of the key.</p>
|
|
<p>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 <code>GLFW_STICKY_KEYS</code> input mode.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa92336e173da9c8834558b54ee80563b">glfwSetInputMode</a>(window, <a class="code" href="glfw3_8h.html#ae3bbe2315b7691ab088159eb6c9110fc">GLFW_STICKY_KEYS</a>, 1);</div></div><!-- fragment --><p>When sticky keys mode is enabled, the pollable state of a key will remain <code>GLFW_PRESS</code> until the state of that key is polled with <a class="el" href="group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2">glfwGetKey</a>. Once it has been polled, if a key release event had been processed in the meantime, the state will reset to <code>GLFW_RELEASE</code>, otherwise it will remain <code>GLFW_PRESS</code>.</p>
|
|
<p>The <code>GLFW_KEY_LAST</code> constant holds the highest value of any <a class="el" href="group__keys.html">named key</a>.</p>
|
|
<h2><a class="anchor" id="input_char"></a>
|
|
Text input</h2>
|
|
<p>GLFW supports text input in the form of a stream of <a href="https://en.wikipedia.org/wiki/Unicode">Unicode code points</a>, 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 <a href="https://en.wikipedia.org/wiki/Dead_key">dead keys</a>. Once received, you can encode the code points into <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> or any other encoding you prefer.</p>
|
|
<p>Because an <code>unsigned int</code> is 32 bits long on all platforms supported by GLFW, you can treat the code point argument as native endian <a href="https://en.wikipedia.org/wiki/UTF-32">UTF-32</a>.</p>
|
|
<p>There are two callbacks for receiving Unicode code points. If you wish to offer regular text input, set a character callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga556239421c6a5a243c66fca28da9f742">glfwSetCharCallback</a>(window, character_callback);</div></div><!-- fragment --><p>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.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> character_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> codepoint)</div><div class="line">{</div><div class="line">}</div></div><!-- fragment --><p>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.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga3f55ef5dc03a374e567f068b13c94afc">glfwSetCharModsCallback</a>(window, charmods_callback);</div></div><!-- fragment --><p>The callback function receives Unicode code points and <a class="el" href="group__mods.html">modifier bits</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> charmods_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> codepoint, <span class="keywordtype">int</span> mods)</div><div class="line">{</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="input_key_name"></a>
|
|
Key names</h2>
|
|
<p>If you wish to refer to keys by name, you can query the keyboard layout dependent name of printable keys with <a class="el" href="group__input.html#ga237a182e5ec0b21ce64543f3b5e7e2be">glfwGetKeyName</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* key_name = <a class="code" href="group__input.html#ga237a182e5ec0b21ce64543f3b5e7e2be">glfwGetKeyName</a>(<a class="code" href="group__keys.html#gaa06a712e6202661fc03da5bdb7b6e545">GLFW_KEY_W</a>, 0);</div><div class="line">show_tutorial_hint(<span class="stringliteral">"Press %s to move forward"</span>, key_name);</div></div><!-- fragment --><p>This function can handle both <a class="el" href="input_guide.html#input_key">keys and scancodes</a>. If the specified key is <code>GLFW_KEY_UNKNOWN</code> 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.</p>
|
|
<h1><a class="anchor" id="input_mouse"></a>
|
|
Mouse input</h1>
|
|
<p>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.</p>
|
|
<h2><a class="anchor" id="cursor_pos"></a>
|
|
Cursor position</h2>
|
|
<p>If you wish to be notified when the cursor moves over the window, set a cursor position callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga7dad39486f2c7591af7fb25134a2501d">glfwSetCursorPosCallback</a>(window, cursor_pos_callback);</div></div><!-- fragment --><p>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.</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> cursor_position_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">double</span> xpos, <span class="keywordtype">double</span> ypos)</div><div class="line">{</div><div class="line">}</div></div><!-- fragment --><p>The cursor position is also saved per-window and can be polled with <a class="el" href="group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc">glfwGetCursorPos</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">double</span> xpos, ypos;</div><div class="line"><a class="code" href="group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc">glfwGetCursorPos</a>(window, &xpos, &ypos);</div></div><!-- fragment --><h2><a class="anchor" id="cursor_mode"></a>
|
|
Cursor modes</h2>
|
|
<p>The <code>GLFW_CURSOR</code> input mode provides several cursor modes for special forms of mouse motion input. By default, the cursor mode is <code>GLFW_CURSOR_NORMAL</code>, meaning the regular arrow cursor (or another cursor set with <a class="el" href="group__input.html#gad3b4f38c8d5dae036bc8fa959e18343e">glfwSetCursor</a>) is used and cursor motion is not limited.</p>
|
|
<p>If you wish to implement mouse motion based camera controls or other input schemes that require unlimited mouse movement, set the cursor mode to <code>GLFW_CURSOR_DISABLED</code>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa92336e173da9c8834558b54ee80563b">glfwSetInputMode</a>(window, <a class="code" href="glfw3_8h.html#aade31da5b884a84a7625c6b059b9132c">GLFW_CURSOR</a>, <a class="code" href="glfw3_8h.html#a2315b99a329ce53e6a13a9d46fd5ca88">GLFW_CURSOR_DISABLED</a>);</div></div><!-- fragment --><p>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.</p>
|
|
<dl class="section note"><dt>Note</dt><dd>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 <code>GLFW_CURSOR_DISABLED</code>.</dd></dl>
|
|
<p>If you just wish the cursor to become hidden when it is over a window, set the cursor mode to <code>GLFW_CURSOR_HIDDEN</code>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa92336e173da9c8834558b54ee80563b">glfwSetInputMode</a>(window, <a class="code" href="glfw3_8h.html#aade31da5b884a84a7625c6b059b9132c">GLFW_CURSOR</a>, <a class="code" href="glfw3_8h.html#ac4d5cb9d78de8573349c58763d53bf11">GLFW_CURSOR_HIDDEN</a>);</div></div><!-- fragment --><p>This mode puts no limit on the motion of the cursor.</p>
|
|
<p>To exit out of either of these special modes, restore the <code>GLFW_CURSOR_NORMAL</code> cursor mode.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa92336e173da9c8834558b54ee80563b">glfwSetInputMode</a>(window, <a class="code" href="glfw3_8h.html#aade31da5b884a84a7625c6b059b9132c">GLFW_CURSOR</a>, <a class="code" href="glfw3_8h.html#ae04dd25c8577e19fa8c97368561f6c68">GLFW_CURSOR_NORMAL</a>);</div></div><!-- fragment --><h2><a class="anchor" id="cursor_object"></a>
|
|
Cursor objects</h2>
|
|
<p>GLFW supports creating both custom and system theme cursor images, encapsulated as <a class="el" href="glfw3_8h.html#a89261ae18c75e863aaf2656ecdd238f4">GLFWcursor</a> objects. They are created with <a class="el" href="group__input.html#gafca356935e10135016aa49ffa464c355">glfwCreateCursor</a> or <a class="el" href="group__input.html#gaa65f416d03ebbbb5b8db71a489fcb894">glfwCreateStandardCursor</a> and destroyed with <a class="el" href="group__input.html#ga81b952cd1764274d0db7fb3c5a79ba6a">glfwDestroyCursor</a>, or <a class="el" href="group__init.html#gaaae48c0a18607ea4a4ba951d939f0901">glfwTerminate</a>, if any remain.</p>
|
|
<h3><a class="anchor" id="cursor_custom"></a>
|
|
Custom cursor creation</h3>
|
|
<p>A custom cursor is created with <a class="el" href="group__input.html#gafca356935e10135016aa49ffa464c355">glfwCreateCursor</a>, 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:</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> pixels[16 * 16 * 4];</div><div class="line">memset(pixels, 0xff, <span class="keyword">sizeof</span>(pixels));</div><div class="line"></div><div class="line"><a class="code" href="structGLFWimage.html">GLFWimage</a> image;</div><div class="line">image.<a class="code" href="structGLFWimage.html#af6a71cc999fe6d3aea31dd7e9687d835">width</a> = 16;</div><div class="line">image.<a class="code" href="structGLFWimage.html#a0b7d95368f0c80d5e5c9875057c7dbec">height</a> = 16;</div><div class="line">image.<a class="code" href="structGLFWimage.html#a0c532a5c2bb715555279b7817daba0fb">pixels</a> = pixels;</div><div class="line"></div><div class="line"><a class="code" href="glfw3_8h.html#a89261ae18c75e863aaf2656ecdd238f4">GLFWcursor</a>* cursor = <a class="code" href="group__input.html#gafca356935e10135016aa49ffa464c355">glfwCreateCursor</a>(&image, 0, 0);</div></div><!-- fragment --><p>If cursor creation fails, <code>NULL</code> will be returned, so it is necessary to check the return value.</p>
|
|
<p>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.</p>
|
|
<h3><a class="anchor" id="cursor_standard"></a>
|
|
Standard cursor creation</h3>
|
|
<p>A cursor with a <a class="el" href="group__shapes.html">standard shape</a> from the current system cursor theme can be can be created with <a class="el" href="group__input.html#gaa65f416d03ebbbb5b8db71a489fcb894">glfwCreateStandardCursor</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="glfw3_8h.html#a89261ae18c75e863aaf2656ecdd238f4">GLFWcursor</a>* cursor = <a class="code" href="group__input.html#gaa65f416d03ebbbb5b8db71a489fcb894">glfwCreateStandardCursor</a>(<a class="code" href="group__shapes.html#gabb3eb0109f11bb808fc34659177ca962">GLFW_HRESIZE_CURSOR</a>);</div></div><!-- fragment --><p>These cursor objects behave in the exact same way as those created with <a class="el" href="group__input.html#gafca356935e10135016aa49ffa464c355">glfwCreateCursor</a> except that the system cursor theme provides the actual image.</p>
|
|
<h3><a class="anchor" id="cursor_destruction"></a>
|
|
Cursor destruction</h3>
|
|
<p>When a cursor is no longer needed, destroy it with <a class="el" href="group__input.html#ga81b952cd1764274d0db7fb3c5a79ba6a">glfwDestroyCursor</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga81b952cd1764274d0db7fb3c5a79ba6a">glfwDestroyCursor</a>(cursor);</div></div><!-- fragment --><p>Cursor destruction always succeeds. All cursors remaining when <a class="el" href="group__init.html#gaaae48c0a18607ea4a4ba951d939f0901">glfwTerminate</a> is called are destroyed as well.</p>
|
|
<h3><a class="anchor" id="cursor_set"></a>
|
|
Cursor setting</h3>
|
|
<p>A cursor can be set as current for a window with <a class="el" href="group__input.html#gad3b4f38c8d5dae036bc8fa959e18343e">glfwSetCursor</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gad3b4f38c8d5dae036bc8fa959e18343e">glfwSetCursor</a>(window, cursor);</div></div><!-- fragment --><p>Once set, the cursor image will be used as long as the system cursor is over the client area of the window and the <a class="el" href="input_guide.html#cursor_mode">cursor mode</a> is set to <code>GLFW_CURSOR_NORMAL</code>.</p>
|
|
<p>A single cursor may be set for any number of windows.</p>
|
|
<p>To remove a cursor from a window, set the cursor of that window to <code>NULL</code>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gad3b4f38c8d5dae036bc8fa959e18343e">glfwSetCursor</a>(window, NULL);</div></div><!-- fragment --><p>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.</p>
|
|
<h2><a class="anchor" id="cursor_enter"></a>
|
|
Cursor enter/leave events</h2>
|
|
<p>If you wish to be notified when the cursor enters or leaves the client area of a window, set a cursor enter/leave callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa299c41dd0a3d171d166354e01279e04">glfwSetCursorEnterCallback</a>(window, cursor_enter_callback);</div></div><!-- fragment --><p>The callback function receives the new classification of the cursor.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> cursor_enter_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">int</span> entered)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (entered)</div><div class="line"> {</div><div class="line"> <span class="comment">// The cursor entered the client area of the window</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> <span class="comment">// The cursor left the client area of the window</span></div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="input_mouse_button"></a>
|
|
Mouse button input</h2>
|
|
<p>If you wish to be notified when a mouse button is pressed or released, set a mouse button callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaef49b72d84d615bca0a6ed65485e035d">glfwSetMouseButtonCallback</a>(window, mouse_button_callback);</div></div><!-- fragment --><p>The callback function receives the <a class="el" href="group__buttons.html">mouse button</a>, button action and <a class="el" href="group__mods.html">modifier bits</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> mouse_button_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">int</span> button, <span class="keywordtype">int</span> action, <span class="keywordtype">int</span> mods)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (button == <a class="code" href="group__buttons.html#ga3e2f2cf3c4942df73cc094247d275e74">GLFW_MOUSE_BUTTON_RIGHT</a> && action == <a class="code" href="group__input.html#ga2485743d0b59df3791c45951c4195265">GLFW_PRESS</a>)</div><div class="line"> popup_menu();</div><div class="line">}</div></div><!-- fragment --><p>The action is one of <code>GLFW_PRESS</code> or <code>GLFW_RELEASE</code>.</p>
|
|
<p>Mouse button states for <a class="el" href="group__buttons.html">named buttons</a> are also saved in per-window state arrays that can be polled with <a class="el" href="group__input.html#gac1473feacb5996c01a7a5a33b5066704">glfwGetMouseButton</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">int</span> state = <a class="code" href="group__input.html#gac1473feacb5996c01a7a5a33b5066704">glfwGetMouseButton</a>(window, <a class="code" href="group__buttons.html#gaf37100431dcd5082d48f95ee8bc8cd56">GLFW_MOUSE_BUTTON_LEFT</a>);</div><div class="line"><span class="keywordflow">if</span> (state == <a class="code" href="group__input.html#ga2485743d0b59df3791c45951c4195265">GLFW_PRESS</a>)</div><div class="line"> upgrade_cow();</div></div><!-- fragment --><p>The returned state is one of <code>GLFW_PRESS</code> or <code>GLFW_RELEASE</code>.</p>
|
|
<p>This function only returns cached mouse button event state. It does not poll the system for the current state of the mouse button.</p>
|
|
<p>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 <code>GLFW_STICKY_MOUSE_BUTTONS</code> input mode.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaa92336e173da9c8834558b54ee80563b">glfwSetInputMode</a>(window, <a class="code" href="glfw3_8h.html#a4d7ce8ce71030c3b04e2b78145bc59d1">GLFW_STICKY_MOUSE_BUTTONS</a>, 1);</div></div><!-- fragment --><p>When sticky mouse buttons mode is enabled, the pollable state of a mouse button will remain <code>GLFW_PRESS</code> until the state of that button is polled with <a class="el" href="group__input.html#gac1473feacb5996c01a7a5a33b5066704">glfwGetMouseButton</a>. Once it has been polled, if a mouse button release event had been processed in the meantime, the state will reset to <code>GLFW_RELEASE</code>, otherwise it will remain <code>GLFW_PRESS</code>.</p>
|
|
<p>The <code>GLFW_MOUSE_BUTTON_LAST</code> constant holds the highest value of any <a class="el" href="group__buttons.html">named button</a>.</p>
|
|
<h2><a class="anchor" id="scrolling"></a>
|
|
Scroll input</h2>
|
|
<p>If you wish to be notified when the user scrolls, whether with a mouse wheel or touchpad gesture, set a scroll callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gacf02eb10504352f16efda4593c3ce60e">glfwSetScrollCallback</a>(window, scroll_callback);</div></div><!-- fragment --><p>The callback function receives two-dimensional scroll offsets.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> scroll_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">double</span> xoffset, <span class="keywordtype">double</span> yoffset)</div><div class="line">{</div><div class="line">}</div></div><!-- fragment --><p>A simple mouse wheel, being vertical, provides offsets along the Y-axis.</p>
|
|
<h1><a class="anchor" id="joystick"></a>
|
|
Joystick input</h1>
|
|
<p>The joystick functions expose connected joysticks and controllers, with both referred to as joysticks. It supports up to sixteen joysticks, ranging from <code>GLFW_JOYSTICK_1</code>, <code>GLFW_JOYSTICK_2</code> up to <code>GLFW_JOYSTICK_LAST</code>. You can test whether a <a class="el" href="group__joysticks.html">joystick</a> is present with <a class="el" href="group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790">glfwJoystickPresent</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">int</span> present = <a class="code" href="group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790">glfwJoystickPresent</a>(<a class="code" href="group__joysticks.html#ga34a0443d059e9f22272cd4669073f73d">GLFW_JOYSTICK_1</a>);</div></div><!-- fragment --><p>When GLFW is initialized, detected joysticks are added to to the beginning of the array, starting with <code>GLFW_JOYSTICK_1</code>. 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.</p>
|
|
<p>Joystick state is updated as needed when a joystick function is called and does not require a window to be created or <a class="el" href="group__window.html#ga37bd57223967b4211d60ca1a0bf3c832">glfwPollEvents</a> or <a class="el" href="group__window.html#ga554e37d781f0a997656c26b2c56c835e">glfwWaitEvents</a> to be called.</p>
|
|
<h2><a class="anchor" id="joystick_axis"></a>
|
|
Joystick axis states</h2>
|
|
<p>The positions of all axes of a joystick are returned by <a class="el" href="group__input.html#ga6271d46a5901ec2c99601ccf4dd14731">glfwGetJoystickAxes</a>. See the reference documentation for the lifetime of the returned array.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">int</span> count;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">float</span>* axes = <a class="code" href="group__input.html#ga6271d46a5901ec2c99601ccf4dd14731">glfwGetJoystickAxes</a>(<a class="code" href="group__joysticks.html#ga34a0443d059e9f22272cd4669073f73d">GLFW_JOYSTICK_1</a>, &count);</div></div><!-- fragment --><p>Each element in the returned array is a value between -1.0 and 1.0.</p>
|
|
<h2><a class="anchor" id="joystick_button"></a>
|
|
Joystick button states</h2>
|
|
<p>The states of all buttons of a joystick are returned by <a class="el" href="group__input.html#gace54cd930dcd502e118fe4021384ce1b">glfwGetJoystickButtons</a>. See the reference documentation for the lifetime of the returned array.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">int</span> count;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>* axes = <a class="code" href="group__input.html#gace54cd930dcd502e118fe4021384ce1b">glfwGetJoystickButtons</a>(<a class="code" href="group__joysticks.html#ga34a0443d059e9f22272cd4669073f73d">GLFW_JOYSTICK_1</a>, &count);</div></div><!-- fragment --><p>Each element in the returned array is either <code>GLFW_PRESS</code> or <code>GLFW_RELEASE</code>.</p>
|
|
<h2><a class="anchor" id="joystick_name"></a>
|
|
Joystick name</h2>
|
|
<p>The human-readable, UTF-8 encoded name of a joystick is returned by <a class="el" href="group__input.html#gac8d7f6107e05cfd106cfba973ab51e19">glfwGetJoystickName</a>. See the reference documentation for the lifetime of the returned string.</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* name = <a class="code" href="group__input.html#gac8d7f6107e05cfd106cfba973ab51e19">glfwGetJoystickName</a>(<a class="code" href="group__joysticks.html#ga34a0443d059e9f22272cd4669073f73d">GLFW_JOYSTICK_1</a>);</div></div><!-- fragment --><p>Joystick names are not guaranteed to be unique. Two joysticks of the same model and make may have the same name. Only the <a class="el" href="group__joysticks.html">joystick token</a> is guaranteed to be unique, and only until that joystick is disconnected.</p>
|
|
<h2><a class="anchor" id="joystick_event"></a>
|
|
Joystick configuration changes</h2>
|
|
<p>If you wish to be notified when a joystick is connected or disconnected, set a joystick callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gab1dc8379f1b82bb660a6b9c9fa06ca07">glfwSetJoystickCallback</a>(joystick_callback);</div></div><!-- fragment --><p>The callback function receives the ID of the joystick that has been connected and disconnected and the event that occurred.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> joystick_callback(<span class="keywordtype">int</span> joy, <span class="keywordtype">int</span> event)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (event == <a class="code" href="glfw3_8h.html#abe11513fd1ffbee5bb9b173f06028b9e">GLFW_CONNECTED</a>)</div><div class="line"> {</div><div class="line"> <span class="comment">// The joystick was connected</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (event == <a class="code" href="glfw3_8h.html#aab64b25921ef21d89252d6f0a71bfc32">GLFW_DISCONNECTED</a>)</div><div class="line"> {</div><div class="line"> <span class="comment">// The joystick was disconnected</span></div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="time"></a>
|
|
Time input</h1>
|
|
<p>GLFW provides high-resolution time input, in seconds, with <a class="el" href="group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a">glfwGetTime</a>.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">double</span> seconds = <a class="code" href="group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a">glfwGetTime</a>();</div></div><!-- fragment --><p>It returns the number of seconds since the timer was started when the library was initialized with <a class="el" href="group__init.html#ga317aac130a235ab08c6db0834907d85e">glfwInit</a>. The platform-specific time sources used usually have micro- or nanosecond resolution.</p>
|
|
<p>You can modify the reference time with <a class="el" href="group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0">glfwSetTime</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0">glfwSetTime</a>(4.0);</div></div><!-- fragment --><p>This sets the timer to the specified time, in seconds.</p>
|
|
<p>You can also access the raw timer value, measured in 1 / frequency seconds, with <a class="el" href="group__input.html#ga09b2bd37d328e0b9456c7ec575cc26aa">glfwGetTimerValue</a>.</p>
|
|
<div class="fragment"><div class="line">uint64_t value = <a class="code" href="group__input.html#ga09b2bd37d328e0b9456c7ec575cc26aa">glfwGetTimerValue</a>();</div></div><!-- fragment --><p>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 <a class="el" href="group__input.html#ga3289ee876572f6e91f06df3a24824443">glfwGetTimerFrequency</a>.</p>
|
|
<div class="fragment"><div class="line">uint64_t freqency = <a class="code" href="group__input.html#ga3289ee876572f6e91f06df3a24824443">glfwGetTimerFrequency</a>();</div></div><!-- fragment --><h1><a class="anchor" id="clipboard"></a>
|
|
Clipboard input and output</h1>
|
|
<p>If the system clipboard contains a UTF-8 encoded string or if it can be converted to one, you can retrieve it with <a class="el" href="group__input.html#ga5aba1d704d9ab539282b1fbe9f18bb94">glfwGetClipboardString</a>. See the reference documentation for the lifetime of the returned string.</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* text = <a class="code" href="group__input.html#ga5aba1d704d9ab539282b1fbe9f18bb94">glfwGetClipboardString</a>(window);</div><div class="line"><span class="keywordflow">if</span> (text)</div><div class="line"> insert_text(text);</div></div><!-- fragment --><p>If the clipboard is empty or if its contents could not be converted, <code>NULL</code> is returned.</p>
|
|
<p>The contents of the system clipboard can be set to a UTF-8 encoded string with <a class="el" href="group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd">glfwSetClipboardString</a>.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd">glfwSetClipboardString</a>(window, <span class="stringliteral">"A string with words in it"</span>);</div></div><!-- fragment --><p>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.</p>
|
|
<h1><a class="anchor" id="path_drop"></a>
|
|
Path drop input</h1>
|
|
<p>If you wish to receive the paths of files and/or directories dropped on a window, set a file drop callback.</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="group__input.html#ga41291bf15dd3ff564b3143aa6dc74a4b">glfwSetDropCallback</a>(window, drop_callback);</div></div><!-- fragment --><p>The callback function receives an array of paths encoded as UTF-8.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> drop_callback(<a class="code" href="group__window.html#ga3c96d80d363e67d13a41b5d1821f3242">GLFWwindow</a>* window, <span class="keywordtype">int</span> count, <span class="keyword">const</span> <span class="keywordtype">char</span>** paths)</div><div class="line">{</div><div class="line"> <span class="keywordtype">int</span> i;</div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < count; i++)</div><div class="line"> handle_dropped_file(paths[i]);</div><div class="line">}</div></div><!-- fragment --><p>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. </p>
|
|
</div></div><!-- contents -->
|
|
<address class="footer">
|
|
<p>
|
|
Last update on Thu Aug 18 2016 for GLFW 3.2.1
|
|
</p>
|
|
</address>
|
|
</body>
|
|
</html>
|