Merge branch 'master' of github.com:nathan818fr/glfw into feature/toggle-rawinput

This commit is contained in:
Nathan Poirier 2019-02-04 16:55:47 +01:00
commit 6769475247
No known key found for this signature in database
GPG Key ID: 94C1CE923BD6A70C
32 changed files with 770 additions and 654 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ _ReSharper*
*.dir *.dir
*.vcxproj* *.vcxproj*
*.sln *.sln
.vs/
Win32 Win32
x64 x64
Debug Debug

View File

@ -75,7 +75,7 @@ more information.
## System requirements ## System requirements
GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other GLFW supports Windows XP and later and macOS 10.8 and later. Linux and other
Unix-like systems running the X Window System are supported even without Unix-like systems running the X Window System are supported even without
a desktop environment or modern extensions, although some features require a desktop environment or modern extensions, although some features require
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
@ -190,6 +190,8 @@ information on what to include when reporting a bug.
- Removed `GLFW_USE_RETINA` compile-time option - Removed `GLFW_USE_RETINA` compile-time option
- Removed `GLFW_USE_CHDIR` compile-time option - Removed `GLFW_USE_CHDIR` compile-time option
- Removed `GLFW_USE_MENUBAR` compile-time option - Removed `GLFW_USE_MENUBAR` compile-time option
- Removed requirement of at least one window for `glfwWaitEvents` and
`glfwPostEmptyEvent` (#1317)
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored - Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding - Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros OpenGL and OpenGL ES header macros
@ -198,6 +200,8 @@ information on what to include when reporting a bug.
- Bugfix: Invalid library paths were used in test and example CMake files (#930) - Bugfix: Invalid library paths were used in test and example CMake files (#930)
- Bugfix: The scancode for synthetic key release events was always zero - Bugfix: The scancode for synthetic key release events was always zero
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081) - Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor
ramp size (#1387,#1388)
- [Win32] Added system error strings to relevant GLFW error descriptions (#733) - [Win32] Added system error strings to relevant GLFW error descriptions (#733)
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125) - [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
@ -226,6 +230,8 @@ information on what to include when reporting a bug.
hint set to false (#1179,#1180) hint set to false (#1179,#1180)
- [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN` - [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN`
(#1315,#1316) (#1315,#1316)
- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some
circumstances (#1383)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125) - [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
@ -242,6 +248,11 @@ information on what to include when reporting a bug.
- [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display - [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display
- [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356) - [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356)
- [X11] Bugfix: Update cursor position on enter event (#1366) - [X11] Bugfix: Update cursor position on enter event (#1366)
- [X11] Bugfix: `glfwSetWindowMonitor` did not update hints when resizing
non-user-resizable windows
- [X11] Bugfix: `glfwSetWindowMonitor` did not flush output buffer in some cases
- [X11] Bugfix: `glfwSetWindowMonitor` did not update the EWMH state of hidden
windows (#1358)
- [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel - [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel
headers (#1196) headers (#1196)
- [Linux] Moved to evdev for joystick input (#906,#1005) - [Linux] Moved to evdev for joystick input (#906,#1005)
@ -252,6 +263,7 @@ information on what to include when reporting a bug.
- [Cocoa] Added support for Vulkan window surface creation via - [Cocoa] Added support for Vulkan window surface creation via
[MoltenVK](https://moltengl.com/moltenvk/) (#870) [MoltenVK](https://moltengl.com/moltenvk/) (#870)
- [Cocoa] Added support for loading a `MainMenu.nib` when available - [Cocoa] Added support for loading a `MainMenu.nib` when available
- [Cocoa] Disabled automatic window tabbing for created windows (#1250)
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852) - [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883) - [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function - [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
@ -276,6 +288,9 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218) - [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218)
- [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14 - [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14
(#1334,#1346) (#1334,#1346)
- [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373)
- [Cocoa] Bugfix: Some buttons for some joysticks were ignored (#1385)
- [Cocoa] Bugfix: Analog joystick buttons were not translated correctly (#1385)
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts - [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
- [WGL] Added support for `WGL_ARB_create_context_no_error` - [WGL] Added support for `WGL_ARB_create_context_no_error`
- [GLX] Added support for `GLX_ARB_create_context_no_error` - [GLX] Added support for `GLX_ARB_create_context_no_error`
@ -315,6 +330,7 @@ skills.
- John Bartholomew - John Bartholomew
- Coşku Baş - Coşku Baş
- Niklas Behrens - Niklas Behrens
- Andrew Belt
- Niklas Bergström - Niklas Bergström
- Denis Bernard - Denis Bernard
- Doug Binks - Doug Binks
@ -381,6 +397,7 @@ skills.
- Glenn Lewis - Glenn Lewis
- Shane Liesegang - Shane Liesegang
- Eyal Lotem - Eyal Lotem
- Aaron Loucks
- Tristam MacDonald - Tristam MacDonald
- Hans Mackowiak - Hans Mackowiak
- Дмитри Малышев - Дмитри Малышев
@ -397,6 +414,7 @@ skills.
- Bruce Mitchener - Bruce Mitchener
- Jack Moffitt - Jack Moffitt
- Jeff Molofee - Jeff Molofee
- Alexander Monakov
- Pierre Morel - Pierre Morel
- Jon Morton - Jon Morton
- Pierre Moulon - Pierre Moulon

View File

@ -57,8 +57,7 @@ glfwWaitEvents();
It puts the thread to sleep until at least one event has been received and then 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 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 useful for, for example, editing tools.
for this function to sleep.
If you want to wait for events but have UI elements or other tasks that need 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. periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout.
@ -249,7 +248,7 @@ glfwSetCursorPosCallback(window, cursor_position_callback);
@endcode @endcode
The callback functions receives the cursor position, measured in screen The callback functions receives the cursor position, measured in screen
coordinates but relative to the top-left corner of the window client area. On 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. platforms that provide it, the full sub-pixel cursor position is passed on.
@code @code
@ -378,7 +377,7 @@ glfwSetCursor(window, cursor);
@endcode @endcode
Once set, the cursor image will be used as long as the system cursor is over the 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 content area of the window and the [cursor mode](@ref cursor_mode) is set
to `GLFW_CURSOR_NORMAL`. to `GLFW_CURSOR_NORMAL`.
A single cursor may be set for any number of windows. A single cursor may be set for any number of windows.
@ -395,7 +394,7 @@ default cursor. This does not affect the cursor mode.
@subsection cursor_enter Cursor enter/leave events @subsection cursor_enter Cursor enter/leave events
If you wish to be notified when the cursor enters or leaves the client area of If you wish to be notified when the cursor enters or leaves the content area of
a window, set a cursor enter/leave callback. a window, set a cursor enter/leave callback.
@code @code
@ -409,16 +408,16 @@ void cursor_enter_callback(GLFWwindow* window, int entered)
{ {
if (entered) if (entered)
{ {
// The cursor entered the client area of the window // The cursor entered the content area of the window
} }
else else
{ {
// The cursor left the client area of the window // The cursor left the content area of the window
} }
} }
@endcode @endcode
You can query whether the cursor is currently inside the client area of the 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. window with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute.
@code @code

View File

@ -208,24 +208,24 @@ future that same call may generate a different error or become valid.
@section coordinate_systems Coordinate systems @section coordinate_systems Coordinate systems
GLFW has two primary coordinate systems: the _virtual screen_ and the window GLFW has two primary coordinate systems: the _virtual screen_ and the window
_client area_ or _content area_. Both use the same unit: _virtual screen _content area_ or _content area_. Both use the same unit: _virtual screen
coordinates_, or just _screen coordinates_, which don't necessarily correspond coordinates_, or just _screen coordinates_, which don't necessarily correspond
to pixels. to pixels.
<img src="spaces.svg" width="90%" /> <img src="spaces.svg" width="90%" />
Both the virtual screen and the client area coordinate systems have the X-axis Both the virtual screen and the content area coordinate systems have the X-axis
pointing to the right and the Y-axis pointing down. pointing to the right and the Y-axis pointing down.
Window and monitor positions are specified as the position of the upper-left Window and monitor positions are specified as the position of the upper-left
corners of their content areas relative to the virtual screen, while cursor corners of their content areas relative to the virtual screen, while cursor
positions are specified relative to a window's client area. positions are specified relative to a window's content area.
Because the origin of the window's client area coordinate system is also the Because the origin of the window's content area coordinate system is also the
point from which the window position is specified, you can translate client area point from which the window position is specified, you can translate content
coordinates to the virtual screen by adding the window position. The window area coordinates to the virtual screen by adding the window position. The
frame, when present, extends out from the client area but does not affect the window frame, when present, extends out from the content area but does not
window position. affect the window position.
Almost all positions and sizes in GLFW are measured in screen coordinates Almost all positions and sizes in GLFW are measured in screen coordinates
relative to one of the two origins above. This includes cursor positions, relative to one of the two origins above. This includes cursor positions,

View File

@ -128,7 +128,7 @@ window hint. It is enabled by default.
@subsection news_33_hover Mouse cursor hover window attribute @subsection news_33_hover Mouse cursor hover window attribute
GLFW now supports polling whether the cursor is hovering over the window client GLFW now supports polling whether the cursor is hovering over the window content
area with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. This area with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. This
attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event. attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event.
@ -308,7 +308,7 @@ glfwWaitEvents to return.
@subsection news_31_framesize Window frame size query @subsection news_31_framesize Window frame size query
GLFW now supports querying the size, on each side, of the frame around the GLFW now supports querying the size, on each side, of the frame around the
client area of a window, with @ref glfwGetWindowFrameSize. content area of a window, with @ref glfwGetWindowFrameSize.
@see [Window size](@ref window_size) @see [Window size](@ref window_size)
@ -506,7 +506,7 @@ glfwSetWindowFocusCallback.
@subsection news_30_enterleave Cursor enter/leave callback @subsection news_30_enterleave Cursor enter/leave callback
Each window now has a callback for when the mouse cursor enters or leaves its Each window now has a callback for when the mouse cursor enters or leaves its
client area, which is set with @ref glfwSetCursorEnterCallback. content area, which is set with @ref glfwSetCursorEnterCallback.
@subsection news_30_wndtitle Initial window title @subsection news_30_wndtitle Initial window title

View File

@ -13,7 +13,7 @@
height="327.98221" height="327.98221"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.4 r9939" inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="spaces.svg"> sodipodi:docname="spaces.svg">
<defs <defs
id="defs4"> id="defs4">
@ -38,11 +38,11 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="2.5611424" inkscape:zoom="1.8110012"
inkscape:cx="344.24359" inkscape:cx="320.68941"
inkscape:cy="163.9911" inkscape:cy="159.80509"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="svg2" inkscape:current-layer="layer1"
showgrid="false" showgrid="false"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1021" inkscape:window-height="1021"
@ -475,18 +475,18 @@
inkscape:export-ydpi="109.89113" /> inkscape:export-ydpi="109.89113" />
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="21.213203" x="21.213203"
y="340.20465" y="340.20465"
id="text3803" id="text3803"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/elmindreda/projects/glfw/glfw/docs/spaces.png" inkscape:export-filename="/home/elmindreda/projects/glfw/glfw/docs/spaces.png"
inkscape:export-xdpi="109.89113" inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113"><tspan inkscape:export-ydpi="109.89113"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan3805" id="tspan3805"
x="21.213203" x="21.213203"
y="340.20465" /></text> y="340.20465"
style="font-size:12px;line-height:1.25;font-family:sans-serif"> </tspan></text>
<g <g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3807"> id="text3807">
@ -647,74 +647,6 @@
style="font-size:10px" style="font-size:10px"
id="path3239" /> id="path3239" />
</g> </g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3826">
<path
d="m 172.22728,456.1171 0,1.04004 c -0.33204,-0.30924 -0.68686,-0.54036 -1.06445,-0.69336 -0.37436,-0.15299 -0.77312,-0.22949 -1.19629,-0.2295 -0.83334,10e-6 -1.47136,0.25554 -1.91407,0.76661 -0.44271,0.50781 -0.66406,1.24349 -0.66406,2.20703 0,0.96029 0.22135,1.69596 0.66406,2.20703 0.44271,0.50781 1.08073,0.76172 1.91407,0.76172 0.42317,0 0.82193,-0.0765 1.19629,-0.2295 0.37759,-0.15299 0.73241,-0.38411 1.06445,-0.69336 l 0,1.03028 c -0.34506,0.23437 -0.71127,0.41015 -1.09863,0.52734 -0.38412,0.11719 -0.79102,0.17578 -1.22071,0.17578 -1.10351,0 -1.97265,-0.33691 -2.60742,-1.01074 -0.63476,-0.67708 -0.95215,-1.59993 -0.95215,-2.76855 0,-1.17187 0.31739,-2.09472 0.95215,-2.76856 0.63477,-0.67707 1.50391,-1.01562 2.60742,-1.01562 0.4362,0 0.84635,0.0586 1.23047,0.17578 0.38737,0.11394 0.75032,0.28646 1.08887,0.51758"
style="font-size:10px"
id="path3108" />
<path
d="m 173.72142,455.24796 0.89844,0 0,7.59765 -0.89844,0 0,-7.59765"
style="font-size:10px"
id="path3110" />
<path
d="m 176.49486,457.37686 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3112" />
<path
d="m 183.94603,459.88663 0,0.43945 -4.13086,0 c 0.0391,0.61849 0.22461,1.0905 0.55664,1.41602 0.33528,0.32226 0.80078,0.4834 1.39649,0.48339 0.34504,1e-5 0.6787,-0.0423 1.00097,-0.12695 0.32552,-0.0846 0.64778,-0.21159 0.9668,-0.38086 l 0,0.84961 c -0.32227,0.13672 -0.65268,0.24089 -0.99121,0.3125 -0.33855,0.0716 -0.68197,0.10742 -1.03028,0.10742 -0.87239,0 -1.56413,-0.2539 -2.07519,-0.76172 -0.50781,-0.50781 -0.76172,-1.19466 -0.76172,-2.06054 0,-0.89518 0.24088,-1.60482 0.72266,-2.12891 0.48502,-0.52734 1.13769,-0.79101 1.958,-0.79101 0.73568,0 1.31673,0.23763 1.74317,0.71289 0.42968,0.47201 0.64452,1.11491 0.64453,1.92871 m -0.89844,-0.26367 c -0.007,-0.49154 -0.14486,-0.88379 -0.41504,-1.17676 -0.26693,-0.29297 -0.62175,-0.43945 -1.06445,-0.43946 -0.5013,1e-5 -0.90332,0.14161 -1.20605,0.42481 -0.29949,0.28321 -0.47201,0.68197 -0.51758,1.19629 l 3.20312,-0.005"
style="font-size:10px"
id="path3114" />
<path
d="m 189.96654,459.54483 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51758 -0.10092,-0.90495 -0.30273,-1.16211 -0.20183,-0.25716 -0.50457,-0.38574 -0.90821,-0.38574 -0.48503,0 -0.86751,0.15462 -1.14746,0.46386 -0.27995,0.30925 -0.41992,0.7308 -0.41992,1.26465 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29296,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19531 1.42578,0.58593 0.32226,0.38738 0.48339,0.95867 0.4834,1.71387"
style="font-size:10px"
id="path3116" />
<path
d="m 192.65697,455.82413 0,1.55273 1.85058,0 0,0.69824 -1.85058,0 0,2.96875 c 0,0.44597 0.0602,0.73243 0.18066,0.85938 0.1237,0.12695 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26042 -0.3955,-0.73242 -0.3955,-1.41602 l 0,-2.96875 -0.65918,0 0,-0.69824 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3118" />
<path
d="m 201.36302,460.09659 c -0.72591,0 -1.22884,0.083 -1.50879,0.24902 -0.27995,0.16602 -0.41992,0.44922 -0.41992,0.84961 0,0.31901 0.10417,0.57292 0.3125,0.76172 0.21159,0.18555 0.49805,0.27832 0.85938,0.27832 0.49804,0 0.8968,-0.17578 1.19628,-0.52734 0.30274,-0.35482 0.4541,-0.8252 0.45411,-1.41114 l 0,-0.20019 -0.89356,0 m 1.79199,-0.3711 0,3.12012 -0.89843,0 0,-0.83008 c -0.20509,0.33204 -0.46062,0.5778 -0.76661,0.73731 -0.30599,0.15625 -0.68034,0.23437 -1.12304,0.23437 -0.5599,0 -1.00586,-0.15625 -1.33789,-0.46875 -0.32878,-0.31575 -0.49317,-0.7373 -0.49317,-1.26465 0,-0.61523 0.20508,-1.07909 0.61524,-1.3916 0.41341,-0.31249 1.02864,-0.46874 1.8457,-0.46875 l 1.25977,0 0,-0.0879 c -1e-5,-0.4134 -0.13673,-0.73242 -0.41016,-0.95703 -0.27019,-0.22786 -0.65104,-0.34179 -1.14258,-0.3418 -0.3125,1e-5 -0.61686,0.0374 -0.91308,0.11231 -0.29623,0.0749 -0.58106,0.18718 -0.8545,0.33691 l 0,-0.83007 c 0.32878,-0.12695 0.64779,-0.22135 0.95704,-0.28321 0.30924,-0.0651 0.61034,-0.0976 0.90332,-0.0976 0.79101,0 1.38183,0.20508 1.77246,0.61523 0.39062,0.41016 0.58593,1.03191 0.58593,1.86523"
style="font-size:10px"
id="path3120" />
<path
d="m 208.17943,458.21671 c -0.10092,-0.0586 -0.21159,-0.10091 -0.33203,-0.12696 -0.11719,-0.0293 -0.2474,-0.0439 -0.39063,-0.0439 -0.50781,0 -0.89844,0.16602 -1.17187,0.49804 -0.27019,0.32878 -0.40528,0.80242 -0.40528,1.4209 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33203 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0146 0.0749,0.007 0.15788,0.0179 0.24903,0.0342 l 0.005,0.92286"
style="font-size:10px"
id="path3122" />
<path
d="m 213.59447,459.88663 0,0.43945 -4.13086,0 c 0.0391,0.61849 0.22461,1.0905 0.55664,1.41602 0.33528,0.32226 0.80078,0.4834 1.39648,0.48339 0.34505,1e-5 0.67871,-0.0423 1.00098,-0.12695 0.32552,-0.0846 0.64778,-0.21159 0.9668,-0.38086 l 0,0.84961 c -0.32227,0.13672 -0.65268,0.24089 -0.99121,0.3125 -0.33855,0.0716 -0.68197,0.10742 -1.03028,0.10742 -0.8724,0 -1.56413,-0.2539 -2.07519,-0.76172 -0.50782,-0.50781 -0.76172,-1.19466 -0.76172,-2.06054 0,-0.89518 0.24088,-1.60482 0.72265,-2.12891 0.48503,-0.52734 1.1377,-0.79101 1.95801,-0.79101 0.73567,0 1.31673,0.23763 1.74317,0.71289 0.42968,0.47201 0.64452,1.11491 0.64453,1.92871 m -0.89844,-0.26367 c -0.007,-0.49154 -0.14486,-0.88379 -0.41504,-1.17676 -0.26693,-0.29297 -0.62175,-0.43945 -1.06445,-0.43946 -0.50131,1e-5 -0.90333,0.14161 -1.20606,0.42481 -0.29948,0.28321 -0.472,0.68197 -0.51758,1.19629 l 3.20313,-0.005"
style="font-size:10px"
id="path3124" />
<path
d="m 217.55443,460.09659 c -0.72592,0 -1.22885,0.083 -1.50879,0.24902 -0.27995,0.16602 -0.41992,0.44922 -0.41992,0.84961 0,0.31901 0.10416,0.57292 0.3125,0.76172 0.21158,0.18555 0.49804,0.27832 0.85937,0.27832 0.49805,0 0.89681,-0.17578 1.19629,-0.52734 0.30273,-0.35482 0.4541,-0.8252 0.4541,-1.41114 l 0,-0.20019 -0.89355,0 m 1.79199,-0.3711 0,3.12012 -0.89844,0 0,-0.83008 c -0.20508,0.33204 -0.46061,0.5778 -0.7666,0.73731 -0.30599,0.15625 -0.68034,0.23437 -1.12305,0.23437 -0.55989,0 -1.00586,-0.15625 -1.33789,-0.46875 -0.32877,-0.31575 -0.49316,-0.7373 -0.49316,-1.26465 0,-0.61523 0.20508,-1.07909 0.61523,-1.3916 0.41341,-0.31249 1.02865,-0.46874 1.84571,-0.46875 l 1.25976,0 0,-0.0879 c 0,-0.4134 -0.13672,-0.73242 -0.41015,-0.95703 -0.27019,-0.22786 -0.65105,-0.34179 -1.14258,-0.3418 -0.3125,1e-5 -0.61687,0.0374 -0.91309,0.11231 -0.29622,0.0749 -0.58105,0.18718 -0.85449,0.33691 l 0,-0.83007 c 0.32877,-0.12695 0.64779,-0.22135 0.95703,-0.28321 0.30924,-0.0651 0.61035,-0.0976 0.90332,-0.0976 0.79101,0 1.38183,0.20508 1.77246,0.61523 0.39062,0.41016 0.58594,1.03191 0.58594,1.86523"
style="font-size:10px"
id="path3126" />
<path
d="m 226.50462,458.00674 c -0.48177,1e-5 -0.86263,0.18881 -1.14257,0.56641 -0.27995,0.37435 -0.41993,0.88868 -0.41993,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56152 0.47852,1e-5 0.85775,-0.1888 1.1377,-0.5664 0.27994,-0.3776 0.41992,-0.89193 0.41992,-1.54297 0,-0.64778 -0.13998,-1.16048 -0.41992,-1.53809 -0.27995,-0.38085 -0.65918,-0.57128 -1.1377,-0.57129 m 0,-0.76171 c 0.78125,0 1.39486,0.25391 1.84082,0.76171 0.44596,0.50782 0.66894,1.21095 0.66895,2.10938 -1e-5,0.89518 -0.22299,1.59831 -0.66895,2.10937 -0.44596,0.50782 -1.05957,0.76172 -1.84082,0.76172 -0.7845,0 -1.39974,-0.2539 -1.8457,-0.76172 -0.44271,-0.51106 -0.66406,-1.21419 -0.66406,-2.10937 0,-0.89843 0.22135,-1.60156 0.66406,-2.10938 0.44596,-0.5078 1.0612,-0.76171 1.8457,-0.76171"
style="font-size:10px"
id="path3128" />
<path
d="m 233.66771,458.21671 c -0.10092,-0.0586 -0.21159,-0.10091 -0.33203,-0.12696 -0.11719,-0.0293 -0.2474,-0.0439 -0.39063,-0.0439 -0.50781,0 -0.89844,0.16602 -1.17187,0.49804 -0.27019,0.32878 -0.40528,0.80242 -0.40528,1.4209 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33203 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0146 0.0749,0.007 0.15788,0.0179 0.24903,0.0342 l 0.005,0.92286"
style="font-size:10px"
id="path3130" />
<path
d="m 234.61986,457.37686 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3132" />
<path
d="m 240.99193,460.04776 c -1e-5,-0.65104 -0.1351,-1.15559 -0.40528,-1.51367 -0.26693,-0.35807 -0.6429,-0.53711 -1.12793,-0.53711 -0.48177,0 -0.85774,0.17904 -1.12792,0.53711 -0.26693,0.35808 -0.4004,0.86263 -0.4004,1.51367 0,0.64779 0.13347,1.15072 0.4004,1.50879 0.27018,0.35807 0.64615,0.53711 1.12792,0.53711 0.48503,0 0.861,-0.17904 1.12793,-0.53711 0.27018,-0.35807 0.40527,-0.861 0.40528,-1.50879 m 0.89844,2.11914 c -1e-5,0.93099 -0.20672,1.62272 -0.62012,2.0752 -0.41342,0.45572 -1.04655,0.68359 -1.89942,0.68359 -0.31575,0 -0.6136,-0.0244 -0.89355,-0.0732 -0.27995,-0.0456 -0.55176,-0.11719 -0.81543,-0.21485 l 0,-0.87402 c 0.26367,0.14323 0.52409,0.24902 0.78125,0.31738 0.25716,0.0684 0.5192,0.10254 0.78613,0.10254 0.58919,0 1.03027,-0.15462 1.32324,-0.46386 0.29297,-0.306 0.43945,-0.76986 0.43946,-1.39161 l 0,-0.44433 c -0.18555,0.32226 -0.42318,0.56315 -0.71289,0.72265 -0.28972,0.15951 -0.6364,0.23926 -1.04004,0.23926 -0.67058,0 -1.21094,-0.25553 -1.6211,-0.7666 -0.41015,-0.51107 -0.61523,-1.18815 -0.61523,-2.03125 0,-0.84635 0.20508,-1.52506 0.61523,-2.03613 0.41016,-0.51107 0.95052,-0.7666 1.6211,-0.7666 0.40364,0 0.75032,0.0797 1.04004,0.23925 0.28971,0.15951 0.52734,0.4004 0.71289,0.72266 l 0,-0.83008 0.89844,0 0,4.79004"
style="font-size:10px"
id="path3134" />
<path
d="m 243.74095,457.37686 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3136" />
<path
d="m 251.06029,459.54483 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51758 -0.10092,-0.90495 -0.30273,-1.16211 -0.20183,-0.25716 -0.50457,-0.38574 -0.90821,-0.38574 -0.48503,0 -0.86751,0.15462 -1.14746,0.46386 -0.27995,0.30925 -0.41992,0.7308 -0.41992,1.26465 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29296,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19531 1.42578,0.58593 0.32226,0.38738 0.48339,0.95867 0.4834,1.71387"
style="font-size:10px"
id="path3138" />
</g>
<g <g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3017"> id="text3017">
@ -868,5 +800,78 @@
style="font-size:5px" style="font-size:5px"
id="path3161" /> id="path3161" />
</g> </g>
<g
aria-label="Content area origin"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
id="text4089">
<path
d="m 172.21587,456.09125 v 1.04004 q -0.49805,-0.46387 -1.06446,-0.69336 -0.56152,-0.22949 -1.19629,-0.22949 -1.25,0 -1.91406,0.7666 -0.66406,0.76172 -0.66406,2.20703 0,1.44043 0.66406,2.20703 0.66406,0.76172 1.91406,0.76172 0.63477,0 1.19629,-0.22949 0.56641,-0.2295 1.06446,-0.69336 v 1.03027 q -0.51758,0.35156 -1.09864,0.52734 -0.57617,0.17578 -1.2207,0.17578 -1.65527,0 -2.60742,-1.01074 -0.95215,-1.01562 -0.95215,-2.76855 0,-1.75781 0.95215,-2.76856 0.95215,-1.01562 2.60742,-1.01562 0.6543,0 1.23047,0.17578 0.58105,0.1709 1.08887,0.51758 z"
style="font-size:10px"
id="path4091" />
<path
d="m 175.82915,457.9809 q -0.72266,0 -1.14258,0.5664 -0.41992,0.56153 -0.41992,1.54297 0,0.98145 0.41504,1.54785 0.41992,0.56153 1.14746,0.56153 0.71777,0 1.13769,-0.56641 0.41992,-0.56641 0.41992,-1.54297 0,-0.97168 -0.41992,-1.53808 -0.41992,-0.57129 -1.13769,-0.57129 z m 0,-0.76172 q 1.17187,0 1.84082,0.76172 0.66894,0.76171 0.66894,2.10937 0,1.34277 -0.66894,2.10938 -0.66895,0.76171 -1.84082,0.76171 -1.17676,0 -1.84571,-0.76171 -0.66406,-0.76661 -0.66406,-2.10938 0,-1.34766 0.66406,-2.10937 0.66895,-0.76172 1.84571,-0.76172 z"
style="font-size:10px"
id="path4093" />
<path
d="m 184.36919,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30274,-1.16211 -0.30273,-0.38574 -0.9082,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32226,-0.49316 0.75683,-0.7373 0.43946,-0.24414 1.01075,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4095" />
<path
d="m 187.05962,455.79828 v 1.55273 h 1.85058 v 0.69825 h -1.85058 v 2.96875 q 0,0.66894 0.18066,0.85937 0.18555,0.19043 0.74707,0.19043 h 0.92285 v 0.75195 h -0.92285 q -1.04004,0 -1.43555,-0.38574 -0.3955,-0.39062 -0.3955,-1.41601 v -2.96875 h -0.65918 v -0.69825 h 0.65918 v -1.55273 z"
style="font-size:10px"
id="path4097" />
<path
d="m 194.77446,459.86078 v 0.43945 h -4.13086 q 0.0586,0.92774 0.55664,1.41602 0.50293,0.4834 1.39649,0.4834 0.51757,0 1.00097,-0.12696 0.48828,-0.12695 0.9668,-0.38086 v 0.84961 q -0.4834,0.20508 -0.99121,0.3125 -0.50781,0.10742 -1.03028,0.10742 -1.30859,0 -2.07519,-0.76171 -0.76172,-0.76172 -0.76172,-2.06055 0,-1.34277 0.72266,-2.12891 0.72754,-0.79101 1.958,-0.79101 1.10352,0 1.74317,0.71289 0.64453,0.70801 0.64453,1.92871 z m -0.89844,-0.26367 q -0.01,-0.73731 -0.41504,-1.17676 -0.40039,-0.43945 -1.06445,-0.43945 -0.75195,0 -1.20605,0.4248 -0.44922,0.42481 -0.51758,1.19629 z"
style="font-size:10px"
id="path4099" />
<path
d="m 200.79497,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30273,-1.16211 -0.30274,-0.38574 -0.90821,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32227,-0.49316 0.75684,-0.7373 0.43945,-0.24414 1.01074,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4101" />
<path
d="m 203.4854,455.79828 v 1.55273 h 1.85058 v 0.69825 h -1.85058 v 2.96875 q 0,0.66894 0.18066,0.85937 0.18555,0.19043 0.74707,0.19043 h 0.92285 v 0.75195 h -0.92285 q -1.04004,0 -1.43555,-0.38574 -0.3955,-0.39062 -0.3955,-1.41601 v -2.96875 h -0.65918 v -0.69825 h 0.65918 v -1.55273 z"
style="font-size:10px"
id="path4103" />
<path
d="m 212.19145,460.07074 q -1.08887,0 -1.50879,0.24902 -0.41992,0.24903 -0.41992,0.84961 0,0.47852 0.3125,0.76172 0.31738,0.27832 0.85938,0.27832 0.74707,0 1.19629,-0.52734 0.4541,-0.53223 0.4541,-1.41113 v -0.2002 z m 1.79199,-0.37109 v 3.12011 h -0.89843 v -0.83007 q -0.30762,0.49804 -0.7666,0.7373 -0.45899,0.23437 -1.12305,0.23437 -0.83985,0 -1.33789,-0.46875 -0.49317,-0.47363 -0.49317,-1.26464 0,-0.92286 0.61524,-1.39161 0.62012,-0.46875 1.8457,-0.46875 h 1.25977 v -0.0879 q 0,-0.62011 -0.41016,-0.95703 -0.40527,-0.34179 -1.14258,-0.34179 -0.46875,0 -0.91308,0.1123 -0.44434,0.11231 -0.8545,0.33691 v -0.83007 q 0.49317,-0.19043 0.95704,-0.28321 0.46386,-0.0976 0.90332,-0.0976 1.18652,0 1.77246,0.61523 0.58593,0.61524 0.58593,1.86524 z"
style="font-size:10px"
id="path4105" />
<path
d="m 219.00786,458.19086 q -0.15137,-0.0879 -0.33203,-0.12696 -0.17578,-0.0439 -0.39063,-0.0439 -0.76172,0 -1.17187,0.49805 -0.40528,0.49316 -0.40528,1.42089 v 2.88086 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.28321,-0.49804 0.73731,-0.7373 0.4541,-0.24414 1.10351,-0.24414 0.0928,0 0.20508,0.0147 0.11231,0.01 0.24903,0.0342 z"
style="font-size:10px"
id="path4107" />
<path
d="m 224.4229,459.86078 v 0.43945 h -4.13086 q 0.0586,0.92774 0.55664,1.41602 0.50293,0.4834 1.39648,0.4834 0.51758,0 1.00098,-0.12696 0.48828,-0.12695 0.9668,-0.38086 v 0.84961 q -0.4834,0.20508 -0.99121,0.3125 -0.50782,0.10742 -1.03028,0.10742 -1.30859,0 -2.07519,-0.76171 -0.76172,-0.76172 -0.76172,-2.06055 0,-1.34277 0.72265,-2.12891 0.72754,-0.79101 1.95801,-0.79101 1.10352,0 1.74317,0.71289 0.64453,0.70801 0.64453,1.92871 z m -0.89844,-0.26367 q -0.01,-0.73731 -0.41504,-1.17676 -0.40039,-0.43945 -1.06445,-0.43945 -0.75196,0 -1.20606,0.4248 -0.44922,0.42481 -0.51758,1.19629 z"
style="font-size:10px"
id="path4109" />
<path
d="m 228.38286,460.07074 q -1.08887,0 -1.50879,0.24902 -0.41992,0.24903 -0.41992,0.84961 0,0.47852 0.3125,0.76172 0.31738,0.27832 0.85937,0.27832 0.74707,0 1.19629,-0.52734 0.4541,-0.53223 0.4541,-1.41113 v -0.2002 z m 1.79199,-0.37109 v 3.12011 h -0.89844 v -0.83007 q -0.30761,0.49804 -0.7666,0.7373 -0.45898,0.23437 -1.12305,0.23437 -0.83984,0 -1.33789,-0.46875 -0.49316,-0.47363 -0.49316,-1.26464 0,-0.92286 0.61523,-1.39161 0.62012,-0.46875 1.84571,-0.46875 h 1.25976 v -0.0879 q 0,-0.62011 -0.41015,-0.95703 -0.40528,-0.34179 -1.14258,-0.34179 -0.46875,0 -0.91309,0.1123 -0.44433,0.11231 -0.85449,0.33691 v -0.83007 q 0.49316,-0.19043 0.95703,-0.28321 0.46387,-0.0976 0.90332,-0.0976 1.18653,0 1.77246,0.61523 0.58594,0.61524 0.58594,1.86524 z"
style="font-size:10px"
id="path4111" />
<path
d="m 237.33305,457.9809 q -0.72265,0 -1.14257,0.5664 -0.41993,0.56153 -0.41993,1.54297 0,0.98145 0.41504,1.54785 0.41992,0.56153 1.14746,0.56153 0.71778,0 1.1377,-0.56641 0.41992,-0.56641 0.41992,-1.54297 0,-0.97168 -0.41992,-1.53808 -0.41992,-0.57129 -1.1377,-0.57129 z m 0,-0.76172 q 1.17188,0 1.84082,0.76172 0.66895,0.76171 0.66895,2.10937 0,1.34277 -0.66895,2.10938 -0.66894,0.76171 -1.84082,0.76171 -1.17675,0 -1.8457,-0.76171 -0.66406,-0.76661 -0.66406,-2.10938 0,-1.34766 0.66406,-2.10937 0.66895,-0.76172 1.8457,-0.76172 z"
style="font-size:10px"
id="path4113" />
<path
d="m 244.49614,458.19086 q -0.15137,-0.0879 -0.33203,-0.12696 -0.17578,-0.0439 -0.39063,-0.0439 -0.76172,0 -1.17187,0.49805 -0.40528,0.49316 -0.40528,1.42089 v 2.88086 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.28321,-0.49804 0.73731,-0.7373 0.4541,-0.24414 1.10352,-0.24414 0.0928,0 0.20507,0.0147 0.11231,0.01 0.24903,0.0342 z"
style="font-size:10px"
id="path4115" />
<path
d="m 245.44829,457.35101 h 0.89844 v 5.46875 h -0.89844 z m 0,-2.1289 h 0.89844 v 1.13769 h -0.89844 z"
style="font-size:10px"
id="path4117" />
<path
d="m 251.82036,460.02191 q 0,-0.97656 -0.40528,-1.51367 -0.40039,-0.53711 -1.12792,-0.53711 -0.72266,0 -1.12793,0.53711 -0.4004,0.53711 -0.4004,1.51367 0,0.97168 0.4004,1.50879 0.40527,0.53711 1.12793,0.53711 0.72753,0 1.12792,-0.53711 0.40528,-0.53711 0.40528,-1.50879 z m 0.89844,2.11914 q 0,1.39649 -0.62012,2.0752 -0.62012,0.68359 -1.89942,0.68359 -0.47363,0 -0.89355,-0.0732 -0.41992,-0.0684 -0.81543,-0.21484 v -0.87403 q 0.39551,0.21485 0.78125,0.31738 0.38574,0.10254 0.78613,0.10254 0.88379,0 1.32325,-0.46386 0.43945,-0.45899 0.43945,-1.3916 v -0.44434 q -0.27832,0.4834 -0.71289,0.72266 -0.43457,0.23925 -1.04004,0.23925 -1.00586,0 -1.6211,-0.7666 -0.61523,-0.7666 -0.61523,-2.03125 0,-1.26953 0.61523,-2.03613 0.61524,-0.7666 1.6211,-0.7666 0.60547,0 1.04004,0.23926 0.43457,0.23925 0.71289,0.72265 v -0.83008 h 0.89844 z"
style="font-size:10px"
id="path4119" />
<path
d="m 254.56938,457.35101 h 0.89844 v 5.46875 h -0.89844 z m 0,-2.1289 h 0.89844 v 1.13769 h -0.89844 z"
style="font-size:10px"
id="path4121" />
<path
d="m 261.88872,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30273,-1.16211 -0.30274,-0.38574 -0.90821,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32227,-0.49316 0.75684,-0.7373 0.43945,-0.24414 1.01074,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4123" />
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -599,7 +599,7 @@ void window_close_callback(GLFWwindow* window)
The size of a window can be changed with @ref glfwSetWindowSize. For windowed The size of a window can be changed with @ref glfwSetWindowSize. For windowed
mode windows, this sets the size, in mode windows, this sets the size, in
[screen coordinates](@ref coordinate_systems) of the _client area_ or _content [screen coordinates](@ref coordinate_systems) of the _content area_ or _content
area_ of the window. The window system may impose limits on window size. area_ of the window. The window system may impose limits on window size.
@code @code
@ -619,7 +619,7 @@ glfwSetWindowSizeCallback(window, window_size_callback);
@endcode @endcode
The callback function receives the new size, in screen coordinates, of the The callback function receives the new size, in screen coordinates, of the
client area of the window when the window is resized. content area of the window when the window is resized.
@code @code
void window_size_callback(GLFWwindow* window, int width, int height) void window_size_callback(GLFWwindow* window, int width, int height)
@ -640,9 +640,9 @@ calls. The window size is in screen coordinates, not pixels. Use the
[framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based [framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based
calls. calls.
The above functions work with the size of the client area, but decorated windows The above functions work with the size of the content area, but decorated
typically have title bars and window frames around this rectangle. You can windows typically have title bars and window frames around this rectangle. You
retrieve the extents of these with @ref glfwGetWindowFrameSize. can retrieve the extents of these with @ref glfwGetWindowFrameSize.
@code @code
int left, top, right, bottom; int left, top, right, bottom;
@ -650,7 +650,7 @@ glfwGetWindowFrameSize(window, &left, &top, &right, &bottom);
@endcode @endcode
The returned values are the distances, in screen coordinates, from the edges of The returned values are the distances, in screen coordinates, from the edges of
the client area to the corresponding edges of the full window. As they are the content area to the corresponding edges of the full window. As they are
distances and not coordinates, they are always zero or positive. distances and not coordinates, they are always zero or positive.
@ -737,10 +737,10 @@ GLFW_SCALE_TO_MONITOR window hint.
@subsection window_sizelimits Window size limits @subsection window_sizelimits Window size limits
The minimum and maximum size of the client area of a windowed mode window can be The minimum and maximum size of the content area of a windowed mode window can
enforced with @ref glfwSetWindowSizeLimits. The user may resize the window to be enforced with @ref glfwSetWindowSizeLimits. The user may resize the window
any size and aspect ratio within the specified limits, unless the aspect ratio to any size and aspect ratio within the specified limits, unless the aspect
is also set. ratio is also set.
@code @code
glfwSetWindowSizeLimits(window, 200, 200, 400, 400); glfwSetWindowSizeLimits(window, 200, 200, 400, 400);
@ -755,7 +755,7 @@ glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE);
To disable size limits for a window, set them all to `GLFW_DONT_CARE`. To disable size limits for a window, set them all to `GLFW_DONT_CARE`.
The aspect ratio of the client area of a windowed mode window can be enforced The aspect ratio of the content area of a windowed mode window can be enforced
with @ref glfwSetWindowAspectRatio. The user may resize the window freely with @ref glfwSetWindowAspectRatio. The user may resize the window freely
unless size limits are also set, but the size will be constrained to maintain unless size limits are also set, but the size will be constrained to maintain
the aspect ratio. the aspect ratio.
@ -785,7 +785,7 @@ are undefined if they conflict.
The position of a windowed-mode window can be changed with @ref The position of a windowed-mode window can be changed with @ref
glfwSetWindowPos. This moves the window so that the upper-left corner of its glfwSetWindowPos. This moves the window so that the upper-left corner of its
client area has the specified [screen coordinates](@ref coordinate_systems). content area has the specified [screen coordinates](@ref coordinate_systems).
The window system may put limitations on window placement. The window system may put limitations on window placement.
@code @code
@ -800,7 +800,7 @@ glfwSetWindowPosCallback(window, window_pos_callback);
@endcode @endcode
The callback function receives the new position, in screen coordinates, of the The callback function receives the new position, in screen coordinates, of the
upper-left corner of the client area when the window is moved. upper-left corner of the content area when the window is moved.
@code @code
void window_pos_callback(GLFWwindow* window, int xpos, int ypos) void window_pos_callback(GLFWwindow* window, int xpos, int ypos)
@ -809,7 +809,7 @@ void window_pos_callback(GLFWwindow* window, int xpos, int ypos)
@endcode @endcode
There is also @ref glfwGetWindowPos for directly retrieving the current position There is also @ref glfwGetWindowPos for directly retrieving the current position
of the client area of the window. of the content area of the window.
@code @code
int xpos, ypos; int xpos, ypos;
@ -1249,8 +1249,8 @@ __GLFW_MAXIMIZED__ indicates whether the specified window is maximized. See
@anchor GLFW_HOVERED_attrib @anchor GLFW_HOVERED_attrib
__GLFW_HOVERED__ indicates whether the cursor is currently directly over the __GLFW_HOVERED__ indicates whether the cursor is currently directly over the
client area of the window, with no other windows between. See @ref cursor_enter content area of the window, with no other windows between. See @ref
for details. cursor_enter for details.
@anchor GLFW_VISIBLE_attrib @anchor GLFW_VISIBLE_attrib
__GLFW_VISIBLE__ indicates whether the specified window is visible. See @ref __GLFW_VISIBLE__ indicates whether the specified window is visible. See @ref

View File

@ -165,7 +165,7 @@ void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n )
v2 = c.y - a.y; v2 = c.y - a.y;
v3 = c.z - a.z; v3 = c.z - a.z;
n->x = u2 * v3 - v2 * v3; n->x = u2 * v3 - v2 * u3;
n->y = u3 * v1 - v3 * u1; n->y = u3 * v1 - v3 * u1;
n->z = u1 * v2 - v1 * u2; n->z = u1 * v2 - v1 * u2;
} }
@ -302,7 +302,7 @@ void cursor_position_callback( GLFWwindow* window, double x, double y )
* The Boing ball is sphere in which each facet is a rectangle. * The Boing ball is sphere in which each facet is a rectangle.
* Facet colors alternate between red and white. * Facet colors alternate between red and white.
* The ball is built by stacking latitudinal circles. Each circle is composed * The ball is built by stacking latitudinal circles. Each circle is composed
* of a widely-separated set of points, so that each facet is noticably large. * of a widely-separated set of points, so that each facet is noticeably large.
*****************************************************************************/ *****************************************************************************/
void DrawBoingBall( void ) void DrawBoingBall( void )
{ {
@ -446,7 +446,7 @@ void DrawBoingBallBand( GLfloat long_lo,
static int colorToggle = 0; static int colorToggle = 0;
/* /*
* Iterate thru the points of a latitude circle. * Iterate through the points of a latitude circle.
* A latitude circle is a 2D set of X,Z points. * A latitude circle is a 2D set of X,Z points.
*/ */
for ( lat_deg = 0; for ( lat_deg = 0;

View File

@ -1171,9 +1171,9 @@ typedef void (* GLFWerrorfun)(int,const char*);
* *
* @param[in] window The window that was moved. * @param[in] window The window that was moved.
* @param[in] xpos The new x-coordinate, in screen coordinates, of the * @param[in] xpos The new x-coordinate, in screen coordinates, of the
* upper-left corner of the client area of the window. * upper-left corner of the content area of the window.
* @param[in] ypos The new y-coordinate, in screen coordinates, of the * @param[in] ypos The new y-coordinate, in screen coordinates, of the
* upper-left corner of the client area of the window. * upper-left corner of the content area of the window.
* *
* @sa @ref window_pos * @sa @ref window_pos
* @sa @ref glfwSetWindowPosCallback * @sa @ref glfwSetWindowPosCallback
@ -1350,9 +1350,9 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
* *
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
* @param[in] xpos The new cursor x-coordinate, relative to the left edge of * @param[in] xpos The new cursor x-coordinate, relative to the left edge of
* the client area. * the content area.
* @param[in] ypos The new cursor y-coordinate, relative to the top edge of the * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
* client area. * content area.
* *
* @sa @ref cursor_pos * @sa @ref cursor_pos
* @sa @ref glfwSetCursorPosCallback * @sa @ref glfwSetCursorPosCallback
@ -1368,7 +1368,7 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* This is the function signature for cursor enter/leave callback functions. * This is the function signature for cursor enter/leave callback functions.
* *
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
* @param[in] entered `GLFW_TRUE` if the cursor entered the window's client * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content
* area, or `GLFW_FALSE` if it left it. * area, or `GLFW_FALSE` if it left it.
* *
* @sa @ref cursor_enter * @sa @ref cursor_enter
@ -2157,9 +2157,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
/*! @brief Generates a gamma ramp and sets it for the specified monitor. /*! @brief Generates a gamma ramp and sets it for the specified monitor.
* *
* This function generates a 256-element gamma ramp from the specified exponent * This function generates an appropriately sized gamma ramp from the specified
* and then calls @ref glfwSetGammaRamp with it. The value must be a finite * exponent and then calls @ref glfwSetGammaRamp with it. The value must be
* number greater than zero. * a finite number greater than zero.
* *
* The software controlled gamma ramp is applied _in addition_ to the hardware * The software controlled gamma ramp is applied _in addition_ to the hardware
* gamma correction, which today is usually an approximation of sRGB gamma. * gamma correction, which today is usually an approximation of sRGB gamma.
@ -2238,8 +2238,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark Gamma ramp sizes other than 256 are not supported by all platforms * @remark The size of the specified gamma ramp should match the size of the
* or graphics hardware. * current ramp for that monitor.
* *
* @remark @win32 The gamma ramp size must be 256. * @remark @win32 The gamma ramp size must be 256.
* *
@ -2645,19 +2645,19 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
*/ */
GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
/*! @brief Retrieves the position of the client area of the specified window. /*! @brief Retrieves the position of the content area of the specified window.
* *
* This function retrieves the position, in screen coordinates, of the * This function retrieves the position, in screen coordinates, of the
* upper-left corner of the client area of the specified window. * upper-left corner of the content area of the specified window.
* *
* Any or all of the position arguments may be `NULL`. If an error occurs, all * Any or all of the position arguments may be `NULL`. If an error occurs, all
* non-`NULL` position arguments will be set to zero. * non-`NULL` position arguments will be set to zero.
* *
* @param[in] window The window to query. * @param[in] window The window to query.
* @param[out] xpos Where to store the x-coordinate of the upper-left corner of * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
* the client area, or `NULL`. * the content area, or `NULL`.
* @param[out] ypos Where to store the y-coordinate of the upper-left corner of * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
* the client area, or `NULL`. * the content area, or `NULL`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -2677,10 +2677,10 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
*/ */
GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
/*! @brief Sets the position of the client area of the specified window. /*! @brief Sets the position of the content area of the specified window.
* *
* This function sets the position, in screen coordinates, of the upper-left * This function sets the position, in screen coordinates, of the upper-left
* corner of the client area of the specified windowed mode window. If the * corner of the content area of the specified windowed mode window. If the
* window is a full screen window, this function does nothing. * window is a full screen window, this function does nothing.
* *
* __Do not use this function__ to move an already visible window unless you * __Do not use this function__ to move an already visible window unless you
@ -2690,8 +2690,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* cannot and should not override these limits. * cannot and should not override these limits.
* *
* @param[in] window The window to query. * @param[in] window The window to query.
* @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] xpos The x-coordinate of the upper-left corner of the content area.
* @param[in] ypos The y-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the content area.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -2712,9 +2712,9 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
*/ */
GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
/*! @brief Retrieves the size of the client area of the specified window. /*! @brief Retrieves the size of the content area of the specified window.
* *
* This function retrieves the size, in screen coordinates, of the client area * This function retrieves the size, in screen coordinates, of the content area
* of the specified window. If you wish to retrieve the size of the * of the specified window. If you wish to retrieve the size of the
* framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
* *
@ -2723,9 +2723,9 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* *
* @param[in] window The window whose size to retrieve. * @param[in] window The window whose size to retrieve.
* @param[out] width Where to store the width, in screen coordinates, of the * @param[out] width Where to store the width, in screen coordinates, of the
* client area, or `NULL`. * content area, or `NULL`.
* @param[out] height Where to store the height, in screen coordinates, of the * @param[out] height Where to store the height, in screen coordinates, of the
* client area, or `NULL`. * content area, or `NULL`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -2744,7 +2744,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
/*! @brief Sets the size limits of the specified window. /*! @brief Sets the size limits of the specified window.
* *
* This function sets the size limits of the client area of the specified * This function sets the size limits of the content area of the specified
* window. If the window is full screen, the size limits only take effect * window. If the window is full screen, the size limits only take effect
* once it is made windowed. If the window is not resizable, this function * once it is made windowed. If the window is not resizable, this function
* does nothing. * does nothing.
@ -2756,14 +2756,14 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* dimensions and all must be greater than or equal to zero. * dimensions and all must be greater than or equal to zero.
* *
* @param[in] window The window to set limits for. * @param[in] window The window to set limits for.
* @param[in] minwidth The minimum width, in screen coordinates, of the client * @param[in] minwidth The minimum width, in screen coordinates, of the content
* area, or `GLFW_DONT_CARE`. * area, or `GLFW_DONT_CARE`.
* @param[in] minheight The minimum height, in screen coordinates, of the * @param[in] minheight The minimum height, in screen coordinates, of the
* client area, or `GLFW_DONT_CARE`. * content area, or `GLFW_DONT_CARE`.
* @param[in] maxwidth The maximum width, in screen coordinates, of the client * @param[in] maxwidth The maximum width, in screen coordinates, of the content
* area, or `GLFW_DONT_CARE`. * area, or `GLFW_DONT_CARE`.
* @param[in] maxheight The maximum height, in screen coordinates, of the * @param[in] maxheight The maximum height, in screen coordinates, of the
* client area, or `GLFW_DONT_CARE`. * content area, or `GLFW_DONT_CARE`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
@ -2787,7 +2787,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
/*! @brief Sets the aspect ratio of the specified window. /*! @brief Sets the aspect ratio of the specified window.
* *
* This function sets the required aspect ratio of the client area of the * This function sets the required aspect ratio of the content area of the
* specified window. If the window is full screen, the aspect ratio only takes * specified window. If the window is full screen, the aspect ratio only takes
* effect once it is made windowed. If the window is not resizable, this * effect once it is made windowed. If the window is not resizable, this
* function does nothing. * function does nothing.
@ -2828,9 +2828,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
*/ */
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
/*! @brief Sets the size of the client area of the specified window. /*! @brief Sets the size of the content area of the specified window.
* *
* This function sets the size, in screen coordinates, of the client area of * This function sets the size, in screen coordinates, of the content area of
* the specified window. * the specified window.
* *
* For full screen windows, this function updates the resolution of its desired * For full screen windows, this function updates the resolution of its desired
@ -2846,9 +2846,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
* *
* @param[in] window The window to resize. * @param[in] window The window to resize.
* @param[in] width The desired width, in screen coordinates, of the window * @param[in] width The desired width, in screen coordinates, of the window
* client area. * content area.
* @param[in] height The desired height, in screen coordinates, of the window * @param[in] height The desired height, in screen coordinates, of the window
* client area. * content area.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -3252,7 +3252,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* The window position is ignored when setting a monitor. * The window position is ignored when setting a monitor.
* *
* When the monitor is `NULL`, the position, width and height are used to * When the monitor is `NULL`, the position, width and height are used to
* place the window client area. The refresh rate is ignored when no monitor * place the window content area. The refresh rate is ignored when no monitor
* is specified. * is specified.
* *
* If you only wish to update the resolution of a full screen window or the * If you only wish to update the resolution of a full screen window or the
@ -3265,12 +3265,12 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* @param[in] window The window whose monitor, size or video mode to set. * @param[in] window The window whose monitor, size or video mode to set.
* @param[in] monitor The desired monitor, or `NULL` to set windowed mode. * @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
* @param[in] xpos The desired x-coordinate of the upper-left corner of the * @param[in] xpos The desired x-coordinate of the upper-left corner of the
* client area. * content area.
* @param[in] ypos The desired y-coordinate of the upper-left corner of the * @param[in] ypos The desired y-coordinate of the upper-left corner of the
* client area. * content area.
* @param[in] width The desired with, in screen coordinates, of the client area * @param[in] width The desired with, in screen coordinates, of the content
* or video mode. * area or video mode.
* @param[in] height The desired height, in screen coordinates, of the client * @param[in] height The desired height, in screen coordinates, of the content
* area or video mode. * area or video mode.
* @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
* or `GLFW_DONT_CARE`. * or `GLFW_DONT_CARE`.
@ -3420,8 +3420,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
* *
* This function sets the position callback of the specified window, which is * This function sets the position callback of the specified window, which is
* called when the window is moved. The callback is provided with the * called when the window is moved. The callback is provided with the
* position, in screen coordinates, of the upper-left corner of the client area * position, in screen coordinates, of the upper-left corner of the content
* of the window. * area of the window.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set * @param[in] cbfun The new callback, or `NULL` to remove the currently set
@ -3448,7 +3448,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
* *
* This function sets the size callback of the specified window, which is * This function sets the size callback of the specified window, which is
* called when the window is resized. The callback is provided with the size, * called when the window is resized. The callback is provided with the size,
* in screen coordinates, of the client area of the window. * in screen coordinates, of the content area of the window.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set * @param[in] cbfun The new callback, or `NULL` to remove the currently set
@ -3505,7 +3505,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
/*! @brief Sets the refresh callback for the specified window. /*! @brief Sets the refresh callback for the specified window.
* *
* This function sets the refresh callback of the specified window, which is * This function sets the refresh callback of the specified window, which is
* called when the client area of the window needs to be redrawn, for example * called when the content area of the window needs to be redrawn, for example
* if the window has been exposed after having been covered by another window. * if the window has been exposed after having been covered by another window.
* *
* On compositing window systems such as Aero, Compiz, Aqua or Wayland, where * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where
@ -3719,10 +3719,6 @@ GLFWAPI void glfwPollEvents(void);
* GLFW will pass those events on to the application callbacks before * GLFW will pass those events on to the application callbacks before
* returning. * returning.
* *
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* Event processing is not required for joystick input to work. * Event processing is not required for joystick input to work.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@ -3770,14 +3766,13 @@ GLFWAPI void glfwWaitEvents(void);
* GLFW will pass those events on to the application callbacks before * GLFW will pass those events on to the application callbacks before
* returning. * returning.
* *
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* Event processing is not required for joystick input to work. * Event processing is not required for joystick input to work.
* *
* @param[in] timeout The maximum amount of time, in seconds, to wait. * @param[in] timeout The maximum amount of time, in seconds, to wait.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
*
* @reentrancy This function must not be called from a callback. * @reentrancy This function must not be called from a callback.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3797,10 +3792,6 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
* This function posts an empty event from the current thread to the event * This function posts an empty event from the current thread to the event
* queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return. * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
* *
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
@ -3850,8 +3841,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes: * modes:
* - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
* - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the
* area of the window but does not restrict the cursor from leaving. * content area of the window but does not restrict the cursor from leaving.
* - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
* and unlimited cursor movement. This is useful for implementing for * and unlimited cursor movement. This is useful for implementing for
* example 3D camera controls. * example 3D camera controls.
@ -4091,11 +4082,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
*/ */
GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
/*! @brief Retrieves the position of the cursor relative to the client area of /*! @brief Retrieves the position of the cursor relative to the content area of
* the window. * the window.
* *
* This function returns the position of the cursor, in screen coordinates, * This function returns the position of the cursor, in screen coordinates,
* relative to the upper-left corner of the client area of the specified * relative to the upper-left corner of the content area of the specified
* window. * window.
* *
* If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
@ -4111,9 +4102,9 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
* *
* @param[in] window The desired window. * @param[in] window The desired window.
* @param[out] xpos Where to store the cursor x-coordinate, relative to the * @param[out] xpos Where to store the cursor x-coordinate, relative to the
* left edge of the client area, or `NULL`. * left edge of the content area, or `NULL`.
* @param[out] ypos Where to store the cursor y-coordinate, relative to the to * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
* top edge of the client area, or `NULL`. * top edge of the content area, or `NULL`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -4129,11 +4120,11 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
*/ */
GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
/*! @brief Sets the position of the cursor, relative to the client area of the /*! @brief Sets the position of the cursor, relative to the content area of the
* window. * window.
* *
* This function sets the position, in screen coordinates, of the cursor * This function sets the position, in screen coordinates, of the cursor
* relative to the upper-left corner of the client area of the specified * relative to the upper-left corner of the content area of the specified
* window. The window must have input focus. If the window does not have * window. The window must have input focus. If the window does not have
* input focus when this function is called, it fails silently. * input focus when this function is called, it fails silently.
* *
@ -4148,9 +4139,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* *
* @param[in] window The desired window. * @param[in] window The desired window.
* @param[in] xpos The desired x-coordinate, relative to the left edge of the * @param[in] xpos The desired x-coordinate, relative to the left edge of the
* client area. * content area.
* @param[in] ypos The desired y-coordinate, relative to the top edge of the * @param[in] ypos The desired y-coordinate, relative to the top edge of the
* client area. * content area.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -4260,7 +4251,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
/*! @brief Sets the cursor for the window. /*! @brief Sets the cursor for the window.
* *
* This function sets the cursor image to be used when the cursor is over the * This function sets the cursor image to be used when the cursor is over the
* client area of the specified window. The set cursor will only be visible * content area of the specified window. The set cursor will only be visible
* when the [cursor mode](@ref cursor_mode) of the window is * when the [cursor mode](@ref cursor_mode) of the window is
* `GLFW_CURSOR_NORMAL`. * `GLFW_CURSOR_NORMAL`.
* *
@ -4342,9 +4333,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
* The character callback behaves as system text input normally does and will * The character callback behaves as system text input normally does and will
* not be called if modifier keys are held down that would prevent normal text * not be called if modifier keys are held down that would prevent normal text
* input on that platform, for example a Super (Command) key on macOS or Alt key * input on that platform, for example a Super (Command) key on macOS or Alt key
* on Windows. There is a * on Windows.
* [character with modifiers callback](@ref glfwSetCharModsCallback) that
* receives these events.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set * @param[in] cbfun The new callback, or `NULL` to remove the currently set
@ -4435,7 +4424,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo
* This function sets the cursor position callback of the specified window, * This function sets the cursor position callback of the specified window,
* which is called when the cursor is moved. The callback is provided with the * which is called when the cursor is moved. The callback is provided with the
* position, in screen coordinates, relative to the upper-left corner of the * position, in screen coordinates, relative to the upper-left corner of the
* client area of the window. * content area of the window.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set * @param[in] cbfun The new callback, or `NULL` to remove the currently set
@ -4458,7 +4447,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor
/*! @brief Sets the cursor enter/exit callback. /*! @brief Sets the cursor enter/exit callback.
* *
* This function sets the cursor boundary crossing callback of the specified * This function sets the cursor boundary crossing callback of the specified
* window, which is called when the cursor enters or leaves the client area of * window, which is called when the cursor enters or leaves the content area of
* the window. * the window.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.

View File

@ -27,6 +27,15 @@
#include "internal.h" #include "internal.h"
#include <sys/param.h> // For MAXPATHLEN #include <sys/param.h> // For MAXPATHLEN
// Needed for _NSGetProgname
#include <crt_externs.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSEventMaskKeyUp NSKeyUpMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagOption NSAlternateKeyMask
#endif
// Change to our application bundle's resources directory, if present // Change to our application bundle's resources directory, if present
// //
@ -64,6 +73,111 @@ static void changeToResourcesDirectory(void)
chdir(resourcesPath); chdir(resourcesPath);
} }
// Set up the menu bar (manually)
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
// could go away at any moment, lots of stuff that really should be
// localize(d|able), etc. Add a nib to save us this horror.
//
static void createMenuBar(void)
{
size_t i;
NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] =
{
@"CFBundleDisplayName",
@"CFBundleName",
@"CFBundleExecutable",
};
// Try to figure out what the calling application is called
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
{
id name = bundleInfo[nameKeys[i]];
if (name &&
[name isKindOfClass:[NSString class]] &&
![name isEqualToString:@""])
{
appName = name;
break;
}
}
if (!appName)
{
char** progname = _NSGetProgname();
if (progname && *progname)
appName = @(*progname);
else
appName = @"GLFW Application";
}
NSMenu* bar = [[NSMenu alloc] init];
[NSApp setMainMenu:bar];
NSMenuItem* appMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
NSMenu* appMenu = [[NSMenu alloc] init];
[appMenuItem setSubmenu:appMenu];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
action:@selector(orderFrontStandardAboutPanel:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
NSMenu* servicesMenu = [[NSMenu alloc] init];
[NSApp setServicesMenu:servicesMenu];
[[appMenu addItemWithTitle:@"Services"
action:NULL
keyEquivalent:@""] setSubmenu:servicesMenu];
[servicesMenu release];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
action:@selector(hide:)
keyEquivalent:@"h"];
[[appMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
[appMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
action:@selector(terminate:)
keyEquivalent:@"q"];
NSMenuItem* windowMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
[bar release];
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
[NSApp setWindowsMenu:windowMenu];
[windowMenuItem setSubmenu:windowMenu];
[windowMenu addItemWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
[windowMenu addItemWithTitle:@"Zoom"
action:@selector(performZoom:)
keyEquivalent:@""];
[windowMenu addItem:[NSMenuItem separatorItem]];
[windowMenu addItemWithTitle:@"Bring All to Front"
action:@selector(arrangeInFront:)
keyEquivalent:@""];
// TODO: Make this appear at the bottom of the menu (for consistency)
[windowMenu addItem:[NSMenuItem separatorItem]];
[[windowMenu addItemWithTitle:@"Enter Full Screen"
action:@selector(toggleFullScreen:)
keyEquivalent:@"f"]
setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
// Prior to Snow Leopard, we need to use this oddly-named semi-private API
// to get the application menu working properly.
SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
}
// Create key code translation tables // Create key code translation tables
// //
static void createKeyTables(void) static void createKeyTables(void)
@ -271,18 +385,93 @@ static GLFWbool initializeTIS(void)
return updateUnicodeDataNS(); return updateUnicodeDataNS();
} }
@interface GLFWLayoutListener : NSObject @interface GLFWHelper : NSObject
@end @end
@implementation GLFWLayoutListener @implementation GLFWHelper
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object - (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{ {
updateUnicodeDataNS(); updateUnicodeDataNS();
} }
- (void)doNothing:(id)object
{
}
@end // GLFWHelper
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
@end @end
@implementation GLFWApplicationDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowCloseRequest(window);
return NSTerminateCancel;
}
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
}
_glfwPollMonitorsNS();
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
if (_glfw.hints.init.ns.menubar)
{
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:&_glfw.ns.nibObjects];
#else
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
#endif
}
else
createMenuBar();
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp stop:nil];
_glfwPlatformPostEmptyEvent();
}
- (void)applicationDidHide:(NSNotification *)notification
{
int i;
for (i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeNS(_glfw.monitors[i]);
}
@end // GLFWApplicationDelegate
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
@ -291,13 +480,45 @@ static GLFWbool initializeTIS(void)
int _glfwPlatformInit(void) int _glfwPlatformInit(void)
{ {
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
_glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:_glfw.ns.helper
withObject:nil];
[NSApplication sharedApplication];
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
if (_glfw.ns.delegate == nil)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to create application delegate");
return GLFW_FALSE;
}
[NSApp setDelegate:_glfw.ns.delegate];
NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
if ([event modifierFlags] & NSEventModifierFlagCommand)
[[NSApp keyWindow] sendEvent:event];
return event;
};
_glfw.ns.keyUpMonitor =
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
handler:block];
if (_glfw.hints.init.ns.chdir) if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory(); changeToResourcesDirectory();
_glfw.ns.listener = [[GLFWLayoutListener alloc] init]; // Press and Hold prevents some keys from emitting repeated characters
NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.listener addObserver:_glfw.ns.helper
selector:@selector(selectedKeyboardInputSourceChanged:) selector:@selector(selectedKeyboardInputSourceChanged:)
name:NSTextInputContextKeyboardSelectionDidChangeNotification name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil]; object:nil];
@ -342,18 +563,21 @@ void _glfwPlatformTerminate(void)
_glfw.ns.delegate = nil; _glfw.ns.delegate = nil;
} }
if (_glfw.ns.listener) if (_glfw.ns.helper)
{ {
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener removeObserver:_glfw.ns.helper
name:NSTextInputContextKeyboardSelectionDidChangeNotification name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil]; object:nil];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener]; removeObserver:_glfw.ns.helper];
[_glfw.ns.listener release]; [_glfw.ns.helper release];
_glfw.ns.listener = nil; _glfw.ns.helper = nil;
} }
if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
free(_glfw.ns.clipboardString); free(_glfw.ns.clipboardString);
_glfwTerminateNSGL(); _glfwTerminateNSGL();

View File

@ -220,9 +220,18 @@ static void matchCallback(void* context,
case kHIDUsage_GD_Hatswitch: case kHIDUsage_GD_Hatswitch:
target = hats; target = hats;
break; break;
case kHIDUsage_GD_DPadUp:
case kHIDUsage_GD_DPadRight:
case kHIDUsage_GD_DPadDown:
case kHIDUsage_GD_DPadLeft:
case kHIDUsage_GD_SystemMainMenu:
case kHIDUsage_GD_Select:
case kHIDUsage_GD_Start:
target = buttons;
break;
} }
} }
else if (page == kHIDPage_Button) else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
target = buttons; target = buttons;
if (target) if (target)
@ -397,12 +406,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (raw > axis->maximum) if (raw > axis->maximum)
axis->maximum = raw; axis->maximum = raw;
const long delta = axis->maximum - axis->minimum; const long size = axis->maximum - axis->minimum;
if (delta == 0) if (size == 0)
_glfwInputJoystickAxis(js, (int) i, 0.f); _glfwInputJoystickAxis(js, (int) i, 0.f);
else else
{ {
const float value = (2.f * (raw - axis->minimum) / delta) - 1.f; const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
_glfwInputJoystickAxis(js, (int) i, value); _glfwInputJoystickAxis(js, (int) i, value);
} }
} }
@ -417,7 +426,8 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*) _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i); CFArrayGetValueAtIndex(js->ns.buttons, i);
const char value = getElementValue(js, button) - button->minimum; const char value = getElementValue(js, button) - button->minimum;
_glfwInputJoystickButton(js, (int) i, value); const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
_glfwInputJoystickButton(js, (int) i, state);
} }
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)

View File

@ -374,14 +374,10 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
{ {
if (!monitor->ns.screen) if (!monitor->ns.screen)
{ {
NSUInteger i; for (NSScreen* screen in [NSScreen screens])
NSArray* screens = [NSScreen screens];
for (i = 0; i < [screens count]; i++)
{ {
NSScreen* screen = [screens objectAtIndex:i];
NSNumber* displayID = NSNumber* displayID =
[[screen deviceDescription] objectForKey:@"NSScreenNumber"]; [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around // HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics // display replacement on machines with automatic graphics
@ -394,7 +390,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
} }
} }
if (i == [screens count]) if (!monitor->ns.screen)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find a screen for monitor"); "Cocoa: Failed to find a screen for monitor");
@ -467,7 +463,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
CVDisplayLinkRelease(link); CVDisplayLinkRelease(link);
} }
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
@ -489,6 +485,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
} }
free(values); free(values);
return GLFW_TRUE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)

View File

@ -105,11 +105,14 @@ typedef struct _GLFWlibraryNS
CGEventSourceRef eventSource; CGEventSourceRef eventSource;
id delegate; id delegate;
id autoreleasePool; id autoreleasePool;
GLFWbool finishedLaunching;
GLFWbool cursorHidden; GLFWbool cursorHidden;
TISInputSourceRef inputSource; TISInputSourceRef inputSource;
IOHIDManagerRef hidManager; IOHIDManagerRef hidManager;
id unicodeData; id unicodeData;
id listener; id helper;
id keyUpMonitor;
id nibObjects;
char keyName[64]; char keyName[64];
short int keycodes[256]; short int keycodes[256];

View File

@ -29,9 +29,6 @@
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
// Needed for _NSGetProgname
#include <crt_externs.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask #define NSWindowStyleMaskBorderless NSBorderlessWindowMask
#define NSWindowStyleMaskClosable NSClosableWindowMask #define NSWindowStyleMaskClosable NSClosableWindowMask
@ -46,7 +43,6 @@
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask #define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
#define NSEventMaskAny NSAnyEventMask #define NSEventMaskAny NSAnyEventMask
#define NSEventTypeApplicationDefined NSApplicationDefined #define NSEventTypeApplicationDefined NSApplicationDefined
#define NSEventTypeKeyUp NSKeyUp
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat #define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#endif #endif
@ -71,18 +67,9 @@ static NSUInteger getStyleMask(_GLFWwindow* window)
return styleMask; return styleMask;
} }
// Center the cursor in the view of the window // Returns whether the cursor is in the content area of the specified window
// //
static void centerCursor(_GLFWwindow *window) static GLFWbool cursorInContentArea(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Returns whether the cursor is in the client area of the specified window
//
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{ {
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
return [window->ns.view mouse:pos inRect:[window->ns.view frame]]; return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
@ -137,7 +124,7 @@ static void updateCursorMode(_GLFWwindow* window)
_glfwPlatformGetCursorPos(window, _glfwPlatformGetCursorPos(window,
&_glfw.ns.restoreCursorPosX, &_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY); &_glfw.ns.restoreCursorPosY);
centerCursor(window); _glfwCenterCursorInContentArea(window);
CGAssociateMouseAndMouseCursorPosition(false); CGAssociateMouseAndMouseCursorPosition(false);
} }
else if (_glfw.ns.disabledCursorWindow == window) else if (_glfw.ns.disabledCursorWindow == window)
@ -149,7 +136,7 @@ static void updateCursorMode(_GLFWwindow* window)
_glfw.ns.restoreCursorPosY); _glfw.ns.restoreCursorPosY);
} }
if (cursorInClientArea(window)) if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} }
@ -236,6 +223,8 @@ static NSUInteger translateKeyToModifierFlag(int key)
case GLFW_KEY_LEFT_SUPER: case GLFW_KEY_LEFT_SUPER:
case GLFW_KEY_RIGHT_SUPER: case GLFW_KEY_RIGHT_SUPER:
return NSEventModifierFlagCommand; return NSEventModifierFlagCommand;
case GLFW_KEY_CAPS_LOCK:
return NSEventModifierFlagCapsLock;
} }
return 0; return 0;
@ -282,7 +271,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window); _glfwCenterCursorInContentArea(window);
const int maximized = [window->ns.object isZoomed]; const int maximized = [window->ns.object isZoomed];
if (window->ns.maximized != maximized) if (window->ns.maximized != maximized)
@ -317,7 +306,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window); _glfwCenterCursorInContentArea(window);
int x, y; int x, y;
_glfwPlatformGetWindowPos(window, &x, &y); _glfwPlatformGetWindowPos(window, &x, &y);
@ -343,7 +332,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidBecomeKey:(NSNotification *)notification - (void)windowDidBecomeKey:(NSNotification *)notification
{ {
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window); _glfwCenterCursorInContentArea(window);
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
updateCursorMode(window); updateCursorMode(window);
@ -360,56 +349,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
@end @end
//------------------------------------------------------------------------
// Delegate for application related notifications
//------------------------------------------------------------------------
@interface GLFWApplicationDelegate : NSObject
@end
@implementation GLFWApplicationDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowCloseRequest(window);
return NSTerminateCancel;
}
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
}
_glfwPollMonitorsNS();
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp stop:nil];
_glfwPlatformPostEmptyEvent();
}
- (void)applicationDidHide:(NSNotification *)notification
{
int i;
for (i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeNS(_glfw.monitors[i]);
}
@end
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Content view class for the GLFW window // Content view class for the GLFW window
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -493,6 +432,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
updateCursorImage(window); updateCursorImage(window);
} }
- (BOOL)acceptsFirstMouse:(NSEvent *)event
{
return YES;
}
- (void)mouseDown:(NSEvent *)event - (void)mouseDown:(NSEvent *)event
{ {
_glfwInputMouseClick(window, _glfwInputMouseClick(window,
@ -658,7 +602,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
[self interpretKeyEvents:[NSArray arrayWithObject:event]]; [self interpretKeyEvents:@[event]];
} }
- (void)flagsChanged:(NSEvent *)event - (void)flagsChanged:(NSEvent *)event
@ -731,7 +675,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
char** paths = calloc(count, sizeof(char*)); char** paths = calloc(count, sizeof(char*));
for (NSUInteger i = 0; i < count; i++) for (NSUInteger i = 0; i < count; i++)
paths[i] = _glfw_strdup([[urls objectAtIndex:i] fileSystemRepresentation]); paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]);
_glfwInputDrop(window, (int) count, (const char**) paths); _glfwInputDrop(window, (int) count, (const char**) paths);
@ -856,210 +800,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
@end @end
//------------------------------------------------------------------------
// GLFW application class
//------------------------------------------------------------------------
@interface GLFWApplication : NSApplication
{
NSArray* nibObjects;
}
@end
@implementation GLFWApplication
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
// This works around an AppKit bug, where key up events while holding
// down the command key don't get sent to the key window.
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSEventTypeKeyUp &&
([event modifierFlags] & NSEventModifierFlagCommand))
{
[[self keyWindow] sendEvent:event];
}
else
[super sendEvent:event];
}
// No-op thread entry point
//
- (void)doNothing:(id)object
{
}
- (void)loadMainMenu
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:&nibObjects];
#else
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
#endif
}
@end
// Set up the menu bar (manually)
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
// could go away at any moment, lots of stuff that really should be
// localize(d|able), etc. Add a nib to save us this horror.
//
static void createMenuBar(void)
{
size_t i;
NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] =
{
@"CFBundleDisplayName",
@"CFBundleName",
@"CFBundleExecutable",
};
// Try to figure out what the calling application is called
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
{
id name = [bundleInfo objectForKey:nameKeys[i]];
if (name &&
[name isKindOfClass:[NSString class]] &&
![name isEqualToString:@""])
{
appName = name;
break;
}
}
if (!appName)
{
char** progname = _NSGetProgname();
if (progname && *progname)
appName = [NSString stringWithUTF8String:*progname];
else
appName = @"GLFW Application";
}
NSMenu* bar = [[NSMenu alloc] init];
[NSApp setMainMenu:bar];
NSMenuItem* appMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
NSMenu* appMenu = [[NSMenu alloc] init];
[appMenuItem setSubmenu:appMenu];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
action:@selector(orderFrontStandardAboutPanel:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
NSMenu* servicesMenu = [[NSMenu alloc] init];
[NSApp setServicesMenu:servicesMenu];
[[appMenu addItemWithTitle:@"Services"
action:NULL
keyEquivalent:@""] setSubmenu:servicesMenu];
[servicesMenu release];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
action:@selector(hide:)
keyEquivalent:@"h"];
[[appMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
[appMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
action:@selector(terminate:)
keyEquivalent:@"q"];
NSMenuItem* windowMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
[bar release];
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
[NSApp setWindowsMenu:windowMenu];
[windowMenuItem setSubmenu:windowMenu];
[windowMenu addItemWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
[windowMenu addItemWithTitle:@"Zoom"
action:@selector(performZoom:)
keyEquivalent:@""];
[windowMenu addItem:[NSMenuItem separatorItem]];
[windowMenu addItemWithTitle:@"Bring All to Front"
action:@selector(arrangeInFront:)
keyEquivalent:@""];
// TODO: Make this appear at the bottom of the menu (for consistency)
[windowMenu addItem:[NSMenuItem separatorItem]];
[[windowMenu addItemWithTitle:@"Enter Full Screen"
action:@selector(toggleFullScreen:)
keyEquivalent:@"f"]
setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
// Prior to Snow Leopard, we need to use this oddly-named semi-private API
// to get the application menu working properly.
SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
}
// Initialize the Cocoa Application Kit
//
static GLFWbool initializeAppKit(void)
{
if (NSApp)
return GLFW_TRUE;
// Implicitly create shared NSApplication instance
[GLFWApplication sharedApplication];
// Make Cocoa enter multi-threaded mode
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:NSApp
withObject:nil];
if (_glfw.hints.init.ns.menubar)
{
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
[NSApp loadMainMenu];
else
createMenuBar();
}
// There can only be one application delegate, but we allocate it the
// first time a window is created to keep all window code in this file
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
if (_glfw.ns.delegate == nil)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to create application delegate");
return GLFW_FALSE;
}
[NSApp setDelegate:_glfw.ns.delegate];
[NSApp run];
// Press and Hold prevents some keys from emitting repeated characters
NSDictionary* defaults =
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
@"ApplePressAndHoldEnabled",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
return GLFW_TRUE;
}
// Create the Cocoa window // Create the Cocoa window
// //
static GLFWbool createNativeWindow(_GLFWwindow* window, static GLFWbool createNativeWindow(_GLFWwindow* window,
@ -1126,7 +866,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
} }
if (strlen(wndconfig->ns.frameName)) if (strlen(wndconfig->ns.frameName))
[window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->ns.frameName]]; [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)];
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
@ -1141,10 +881,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setContentView:window->ns.view]; [window->ns.object setContentView:window->ns.view];
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; [window->ns.object setTitle:@(wndconfig->title)];
[window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setDelegate:window->ns.delegate];
[window->ns.object setAcceptsMouseMovedEvents:YES]; [window->ns.object setAcceptsMouseMovedEvents:YES];
[window->ns.object setRestorable:NO]; [window->ns.object setRestorable:NO];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
[window->ns.object setTabbingMode:NSWindowTabbingModeDisallowed];
#endif
_glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height); _glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height);
_glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight); _glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight);
@ -1162,8 +905,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
if (!initializeAppKit()) if (!_glfw.ns.finishedLaunching)
return GLFW_FALSE; {
[NSApp run];
_glfw.ns.finishedLaunching = GLFW_TRUE;
}
if (!createNativeWindow(window, wndconfig, fbconfig)) if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
@ -1232,11 +978,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
{ {
NSString* string = [NSString stringWithUTF8String:title]; [window->ns.object setTitle:@(title)];
[window->ns.object setTitle:string];
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
// if the window lacks NSWindowStyleMaskTitled // if the window lacks NSWindowStyleMaskTitled
[window->ns.object setMiniwindowTitle:string]; [window->ns.object setMiniwindowTitle:@(title)];
} }
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
@ -1387,9 +1132,9 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
void _glfwPlatformFocusWindow(_GLFWwindow* window) void _glfwPlatformFocusWindow(_GLFWwindow* window)
{ {
// Make us the active application // Make us the active application
// HACK: This has been moved here from initializeAppKit to prevent // HACK: This is here to prevent applications using only hidden windows from
// applications using only hidden windows from being activated, but // being activated, but should probably not be done every time any
// should probably not be done every time any window is shown // window is shown
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
[window->ns.object makeKeyAndOrderFront:nil]; [window->ns.object makeKeyAndOrderFront:nil];
@ -1564,9 +1309,6 @@ GLFWbool _glfwPlatformRawInputSupported(void)
void _glfwPlatformPollEvents(void) void _glfwPlatformPollEvents(void)
{ {
if (!initializeAppKit())
return;
for (;;) for (;;)
{ {
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
@ -1717,9 +1459,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
NSImage* native; NSImage* native;
NSBitmapImageRep* rep; NSBitmapImageRep* rep;
if (!initializeAppKit())
return GLFW_FALSE;
rep = [[NSBitmapImageRep alloc] rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL initWithBitmapDataPlanes:NULL
pixelsWide:image->width pixelsWide:image->width
@ -1755,9 +1494,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{ {
if (!initializeAppKit())
return GLFW_FALSE;
if (shape == GLFW_ARROW_CURSOR) if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor]; cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR) else if (shape == GLFW_IBEAM_CURSOR)
@ -1790,18 +1526,15 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
if (cursorInClientArea(window)) if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} }
void _glfwPlatformSetClipboardString(const char* string) void _glfwPlatformSetClipboardString(const char* string)
{ {
NSArray* types = [NSArray arrayWithObjects:NSPasteboardTypeString, nil];
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:types owner:nil]; [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
[pasteboard setString:[NSString stringWithUTF8String:string] [pasteboard setString:@(string) forType:NSPasteboardTypeString];
forType:NSPasteboardTypeString];
} }
const char* _glfwPlatformGetClipboardString(void) const char* _glfwPlatformGetClipboardString(void)

View File

@ -358,7 +358,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.source = ctxconfig->source; window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API; window->context.client = GLFW_OPENGL_API;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);; previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window); glfwMakeContextCurrent((GLFWwindow*) window);
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)

View File

@ -119,6 +119,30 @@ char* _glfw_strdup(const char* source)
return result; return result;
} }
float _glfw_fminf(float a, float b)
{
if (a != a)
return b;
else if (b != b)
return a;
else if (a < b)
return a;
else
return b;
}
float _glfw_fmaxf(float a, float b)
{
if (a != a)
return b;
else if (b != b)
return a;
else if (a > b)
return a;
else
return b;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////

View File

@ -333,7 +333,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
} }
// Notifies shared code of a cursor motion event // Notifies shared code of a cursor motion event
// The position is specified in client-area relative screen coordinates // The position is specified in content area relative screen coordinates
// //
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{ {
@ -453,6 +453,15 @@ void _glfwFreeJoystick(_GLFWjoystick* js)
memset(js, 0, sizeof(_GLFWjoystick)); memset(js, 0, sizeof(_GLFWjoystick));
} }
// Center the cursor in the content area of the specified window
//
void _glfwCenterCursorInContentArea(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////
@ -1252,7 +1261,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
if (e->type == _GLFW_JOYSTICK_AXIS) if (e->type == _GLFW_JOYSTICK_AXIS)
{ {
const float value = js->axes[e->index] * e->axisScale + e->axisOffset; const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f);
} }
else if (e->type == _GLFW_JOYSTICK_HATBIT) else if (e->type == _GLFW_JOYSTICK_HATBIT)
{ {

View File

@ -614,7 +614,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale); float* xscale, float* yscale);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string); void _glfwPlatformSetClipboardString(const char* string);
@ -763,10 +763,13 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
int buttonCount, int buttonCount,
int hatCount); int hatCount);
void _glfwFreeJoystick(_GLFWjoystick* js); void _glfwFreeJoystick(_GLFWjoystick* js);
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
GLFWbool _glfwInitVulkan(int mode); GLFWbool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void); void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result); const char* _glfwGetVulkanResultString(VkResult result);
char* _glfw_strdup(const char* source); char* _glfw_strdup(const char* source);
float _glfw_fminf(float a, float b);
float _glfw_fmaxf(float a, float b);

View File

@ -427,12 +427,12 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
{ {
int i; unsigned int i;
unsigned short values[256]; unsigned short* values;
GLFWgammaramp ramp; GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL); assert(handle != NULL);
assert(gamma == gamma); assert(gamma > 0.f);
assert(gamma >= 0.f);
assert(gamma <= FLT_MAX); assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -443,18 +443,22 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
return; return;
} }
for (i = 0; i < 256; i++) original = glfwGetGammaRamp(handle);
if (!original)
return;
values = calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++)
{ {
float value; float value;
// Calculate intensity // Calculate intensity
value = i / 255.f; value = i / (float) (original->size - 1);
// Apply gamma curve // Apply gamma curve
value = powf(value, 1.f / gamma) * 65535.f + 0.5f; value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp to value range // Clamp to value range
if (value > 65535.f) value = _glfw_fminf(value, 65535.f);
value = 65535.f;
values[i] = (unsigned short) value; values[i] = (unsigned short) value;
} }
@ -462,9 +466,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
ramp.red = values; ramp.red = values;
ramp.green = values; ramp.green = values;
ramp.blue = values; ramp.blue = values;
ramp.size = 256; ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp); glfwSetGammaRamp(handle, &ramp);
free(values);
} }
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
@ -475,7 +480,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
return NULL;
return &monitor->currentRamp; return &monitor->currentRamp;
} }
@ -501,7 +507,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size) if (!monitor->originalRamp.size)
_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); {
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
return;
}
_glfwPlatformSetGammaRamp(monitor, ramp); _glfwPlatformSetGammaRamp(monitor, ramp);
} }

View File

@ -58,8 +58,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
} }
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
return GLFW_FALSE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)

View File

@ -240,7 +240,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
if (ctxconfig->forward) if (ctxconfig->forward)
{ {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Foward-compatible contexts not supported"); "OSMesa: Forward-compatible contexts not supported");
return GLFW_FALSE; return GLFW_FALSE;
} }

View File

@ -31,26 +31,33 @@
#include <malloc.h> #include <malloc.h>
#include <assert.h> #include <assert.h>
// Return the value corresponding to the specified attribute
// Returns the specified attribute of the specified pixel format
// //
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) static int findPixelFormatAttribValue(const int* attribs,
int attribCount,
const int* values,
int attrib)
{ {
int value = 0; int i;
assert(_glfw.wgl.ARB_pixel_format); for (i = 0; i < attribCount; i++)
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
pixelFormat,
0, 1, &attrib, &value))
{ {
if (attribs[i] == attrib)
return values[i];
}
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute"); "WGL: Unknown pixel format attribute requested");
return 0; return 0;
} }
return value; #define addAttrib(a) \
{ \
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
attribs[attribCount++] = a; \
} }
#define findAttribValue(a) \
findPixelFormatAttribValue(attribs, attribCount, values, a)
// Return a list of available and usable framebuffer configs // Return a list of available and usable framebuffer configs
// //
@ -60,13 +67,58 @@ static int choosePixelFormat(_GLFWwindow* window,
{ {
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, pixelFormat, nativeCount, usableCount; int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0;
int attribs[40];
int values[sizeof(attribs) / sizeof(attribs[0])];
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
nativeCount = getPixelFormatAttrib(window, const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
1,
WGL_NUMBER_PIXEL_FORMATS_ARB); if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
1, 0, 1, &attrib, &nativeCount))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
addAttrib(WGL_SUPPORT_OPENGL_ARB);
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
addAttrib(WGL_PIXEL_TYPE_ARB);
addAttrib(WGL_ACCELERATION_ARB);
addAttrib(WGL_RED_BITS_ARB);
addAttrib(WGL_RED_SHIFT_ARB);
addAttrib(WGL_GREEN_BITS_ARB);
addAttrib(WGL_GREEN_SHIFT_ARB);
addAttrib(WGL_BLUE_BITS_ARB);
addAttrib(WGL_BLUE_SHIFT_ARB);
addAttrib(WGL_ALPHA_BITS_ARB);
addAttrib(WGL_ALPHA_SHIFT_ARB);
addAttrib(WGL_DEPTH_BITS_ARB);
addAttrib(WGL_STENCIL_BITS_ARB);
addAttrib(WGL_ACCUM_BITS_ARB);
addAttrib(WGL_ACCUM_RED_BITS_ARB);
addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
addAttrib(WGL_AUX_BUFFERS_ARB);
addAttrib(WGL_STEREO_ARB);
addAttrib(WGL_DOUBLE_BUFFER_ARB);
if (_glfw.wgl.ARB_multisample)
addAttrib(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
}
else
{
if (_glfw.wgl.EXT_colorspace)
addAttrib(WGL_COLORSPACE_EXT);
}
} }
else else
{ {
@ -77,64 +129,67 @@ static int choosePixelFormat(_GLFWwindow* window,
} }
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++) for (i = 0; i < nativeCount; i++)
{ {
const int n = i + 1;
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
pixelFormat = i + 1;
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
// Get pixel format attributes through "modern" extension // Get pixel format attributes through "modern" extension
if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
!getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB)) pixelFormat, 0,
attribCount,
attribs, values))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attributes");
return 0;
}
if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) ||
!findAttribValue(WGL_DRAW_TO_WINDOW_ARB))
{ {
continue; continue;
} }
if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
WGL_TYPE_RGBA_ARB)
{
continue; continue;
}
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
WGL_NO_ACCELERATION_ARB)
{
continue; continue;
}
u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); u->redBits = findAttribValue(WGL_RED_BITS_ARB);
u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB);
u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB);
u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB);
u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB);
u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB);
u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB);
u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB);
u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB);
u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB);
if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB)) if (findAttribValue(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE; u->stereo = GLFW_TRUE;
if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) if (findAttribValue(WGL_DOUBLE_BUFFER_ARB))
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample) if (_glfw.wgl.ARB_multisample)
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); u->samples = findAttribValue(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (_glfw.wgl.ARB_framebuffer_sRGB || if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB) _glfw.wgl.EXT_framebuffer_sRGB)
{ {
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
@ -142,14 +197,11 @@ static int choosePixelFormat(_GLFWwindow* window,
{ {
if (_glfw.wgl.EXT_colorspace) if (_glfw.wgl.EXT_colorspace)
{ {
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) == if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
WGL_COLORSPACE_SRGB_EXT)
{
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
} }
}
else else
{ {
// Get pixel format attributes through legacy PFDs // Get pixel format attributes through legacy PFDs
@ -157,7 +209,7 @@ static int choosePixelFormat(_GLFWwindow* window,
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
if (!DescribePixelFormat(window->context.wgl.dc, if (!DescribePixelFormat(window->context.wgl.dc,
n, pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
&pfd)) &pfd))
{ {
@ -200,7 +252,7 @@ static int choosePixelFormat(_GLFWwindow* window,
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
} }
u->handle = n; u->handle = pixelFormat;
usableCount++; usableCount++;
} }
@ -229,6 +281,9 @@ static int choosePixelFormat(_GLFWwindow* window,
return pixelFormat; return pixelFormat;
} }
#undef addAttrib
#undef findAttribValue
static void makeContextCurrentWGL(_GLFWwindow* window) static void makeContextCurrentWGL(_GLFWwindow* window)
{ {
if (window) if (window)
@ -377,7 +432,7 @@ GLFWbool _glfwInitWGL(void)
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context // NOTE: This code will accept the Microsoft GDI ICD; accelerated context
// creation failure occurs during manual pixel format enumeration // creation failure occurs during manual pixel format enumeration
dc = GetDC(_glfw.win32.helperWindowHandle);; dc = GetDC(_glfw.win32.helperWindowHandle);
ZeroMemory(&pfd, sizeof(pfd)); ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd); pfd.nSize = sizeof(pfd);

View File

@ -260,6 +260,8 @@ static void closeJoystick(_GLFWjoystick* js)
IDirectInputDevice8_Release(js->win32.device); IDirectInputDevice8_Release(js->win32.device);
} }
free(js->win32.objects);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED); _glfwInputJoystick(js, GLFW_DISCONNECTED);
} }

View File

@ -455,7 +455,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
&mode->blueBits); &mode->blueBits);
} }
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
HDC dc; HDC dc;
WORD values[768]; WORD values[768];
@ -469,6 +469,8 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
return GLFW_TRUE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)

View File

@ -186,14 +186,14 @@ static HICON createIcon(const GLFWimage* image,
return handle; return handle;
} }
// Translate client window size to full window size according to styles and DPI // Translate content area size to full window size according to styles and DPI
// //
static void getFullWindowSize(DWORD style, DWORD exStyle, static void getFullWindowSize(DWORD style, DWORD exStyle,
int clientWidth, int clientHeight, int contentWidth, int contentHeight,
int* fullWidth, int* fullHeight, int* fullWidth, int* fullHeight,
UINT dpi) UINT dpi)
{ {
RECT rect = { 0, 0, clientWidth, clientHeight }; RECT rect = { 0, 0, contentWidth, contentHeight };
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
@ -204,7 +204,7 @@ static void getFullWindowSize(DWORD style, DWORD exStyle,
*fullHeight = rect.bottom - rect.top; *fullHeight = rect.bottom - rect.top;
} }
// Enforce the client rect aspect ratio based on which edge is being dragged // Enforce the content area aspect ratio based on which edge is being dragged
// //
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
{ {
@ -236,15 +236,6 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
} }
} }
// Centers the cursor over the window client area
//
static void centerCursor(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to its cursor mode // Updates the cursor image according to its cursor mode
// //
static void updateCursorImage(_GLFWwindow* window) static void updateCursorImage(_GLFWwindow* window)
@ -287,7 +278,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.win32.restoreCursorPosX, &_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY); &_glfw.win32.restoreCursorPosY);
updateCursorImage(window); updateCursorImage(window);
centerCursor(window); _glfwCenterCursorInContentArea(window);
updateClipRect(window); updateClipRect(window);
if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid))) if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid)))
@ -317,9 +308,9 @@ static void enableCursor(_GLFWwindow* window)
} }
} }
// Returns whether the cursor is in the client area of the specified window // Returns whether the cursor is in the content area of the specified window
// //
static GLFWbool cursorInClientArea(_GLFWwindow* window) static GLFWbool cursorInContentArea(_GLFWwindow* window)
{ {
RECT area; RECT area;
POINT pos; POINT pos;
@ -1069,6 +1060,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return TRUE; return TRUE;
} }
case WM_NCACTIVATE:
case WM_NCPAINT:
{
// Prevent title bar from being drawn after restoring a minimized
// undecorated window
if (!window->decorated)
return TRUE;
break;
}
case WM_DWMCOMPOSITIONCHANGED: case WM_DWMCOMPOSITIONCHANGED:
{ {
if (window->win32.transparent) if (window->win32.transparent)
@ -1081,7 +1083,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (window->win32.scaleToMonitor) if (window->win32.scaleToMonitor)
break; break;
// Adjust the window size to keep the client area size constant // Adjust the window size to keep the content area size constant
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
{ {
RECT source = {0}, target = {0}; RECT source = {0}, target = {0};
@ -1251,7 +1253,7 @@ static int createNativeWindow(_GLFWwindow* window,
window->win32.scaleToMonitor = wndconfig->scaleToMonitor; window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
// Adjust window size to account for DPI scaling of the window frame and // Adjust window size to account for DPI scaling of the window frame and
// optionally DPI scaling of the client area // optionally DPI scaling of the content area
// This cannot be done until we know what monitor it was placed on // This cannot be done until we know what monitor it was placed on
if (!window->monitor) if (!window->monitor)
{ {
@ -1786,7 +1788,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
int _glfwPlatformWindowHovered(_GLFWwindow* window) int _glfwPlatformWindowHovered(_GLFWwindow* window)
{ {
return cursorInClientArea(window); return cursorInContentArea(window);
} }
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
@ -1997,7 +1999,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
} }
else if (_glfw.win32.disabledCursorWindow == window) else if (_glfw.win32.disabledCursorWindow == window)
enableCursor(window); enableCursor(window);
else if (cursorInClientArea(window)) else if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} }
@ -2060,7 +2062,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
if (cursorInClientArea(window)) if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} }

View File

@ -67,7 +67,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
} }
// Notifies shared code that a window has moved // Notifies shared code that a window has moved
// The position is specified in client-area relative screen coordinates // The position is specified in content area relative screen coordinates
// //
void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
{ {
@ -143,7 +143,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
window->monitor = monitor; window->monitor = monitor;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -231,11 +230,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (window->monitor) if (window->monitor)
{ {
if (wndconfig.centerCursor) if (wndconfig.centerCursor)
{ _glfwCenterCursorInContentArea(window);
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
} }
else else
{ {
@ -1079,10 +1074,6 @@ GLFWAPI void glfwPollEvents(void)
GLFWAPI void glfwWaitEvents(void) GLFWAPI void glfwWaitEvents(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (!_glfw.windowListHead)
return;
_glfwPlatformWaitEvents(); _glfwPlatformWaitEvents();
} }
@ -1105,9 +1096,5 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout)
GLFWAPI void glfwPostEmptyEvent(void) GLFWAPI void glfwPostEmptyEvent(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (!_glfw.windowListHead)
return;
_glfwPlatformPostEmptyEvent(); _glfwPlatformPostEmptyEvent();
} }

View File

@ -180,19 +180,18 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
*mode = monitor->modes[monitor->wl.currentMode]; *mode = monitor->modes[monitor->wl.currentMode];
} }
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp getting not supported yet"); "Wayland: Gamma ramp access it not available");
return GLFW_FALSE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
const GLFWgammaramp* ramp) const GLFWgammaramp* ramp)
{ {
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp setting not supported yet"); "Wayland: Gamma ramp access is not available");
} }

View File

@ -422,7 +422,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
} }
} }
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{ {
@ -438,6 +438,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma); XRRFreeGamma(gamma);
return GLFW_TRUE;
} }
else if (_glfw.x11.vidmode.available) else if (_glfw.x11.vidmode.available)
{ {
@ -449,6 +450,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
XF86VidModeGetGammaRamp(_glfw.x11.display, XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen, _glfw.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue); ramp->size, ramp->red, ramp->green, ramp->blue);
return GLFW_TRUE;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
return GLFW_FALSE;
} }
} }
@ -481,6 +489,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
(unsigned short*) ramp->green, (unsigned short*) ramp->green,
(unsigned short*) ramp->blue); (unsigned short*) ramp->blue);
} }
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
}
} }

View File

@ -501,15 +501,6 @@ static char* convertLatin1toUTF8(const char* source)
return target; return target;
} }
// Centers the cursor over the window client area
//
static void centerCursor(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to its cursor mode // Updates the cursor image according to its cursor mode
// //
static void updateCursorImage(_GLFWwindow* window) static void updateCursorImage(_GLFWwindow* window)
@ -553,7 +544,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.x11.restoreCursorPosX, &_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY); &_glfw.x11.restoreCursorPosY);
updateCursorImage(window); updateCursorImage(window);
centerCursor(window); _glfwCenterCursorInContentArea(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True, XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
@ -2404,10 +2395,14 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
} }
else else
{ {
if (!window->resizable)
updateNormalHints(window, width, height);
XMoveResizeWindow(_glfw.x11.display, window->x11.handle, XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
xpos, ypos, width, height); xpos, ypos, width, height);
} }
XFlush(_glfw.x11.display);
return; return;
} }
@ -2416,16 +2411,21 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_glfwInputWindowMonitor(window, monitor); _glfwInputWindowMonitor(window, monitor);
updateNormalHints(window, width, height); updateNormalHints(window, width, height);
updateWindowMode(window);
if (window->monitor) if (window->monitor)
{
if (!_glfwPlatformWindowVisible(window))
{ {
XMapRaised(_glfw.x11.display, window->x11.handle); XMapRaised(_glfw.x11.display, window->x11.handle);
if (waitForVisibilityNotify(window)) waitForVisibilityNotify(window);
}
updateWindowMode(window);
acquireMonitor(window); acquireMonitor(window);
} }
else else
{ {
updateWindowMode(window);
XMoveResizeWindow(_glfw.x11.display, window->x11.handle, XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
xpos, ypos, width, height); xpos, ypos, width, height);
} }

View File

@ -33,7 +33,7 @@ add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD})
add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD}) add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD})
add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD}) add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD})
add_executable(opacity WIN32 MACOSX_BUNDLE opacity.c ${GLAD}) add_executable(opacity WIN32 MACOSX_BUNDLE opacity.c ${GLAD})
add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD}) add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GETOPT} ${GLAD})
add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD}) add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD})
add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD}) add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD})
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD}) add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD})

View File

@ -429,15 +429,6 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint)
get_character_string(codepoint)); get_character_string(codepoint));
} }
static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n",
counter++, slot->number, glfwGetTime(), codepoint,
get_character_string(codepoint),
get_mods_name(mods));
}
static void drop_callback(GLFWwindow* window, int count, const char** paths) static void drop_callback(GLFWwindow* window, int count, const char** paths)
{ {
int i; int i;
@ -533,7 +524,7 @@ int main(int argc, char** argv)
break; break;
case 'n': case 'n':
count = (int) strtol(optarg, NULL, 10); count = (int) strtoul(optarg, NULL, 10);
break; break;
default: default:
@ -560,12 +551,6 @@ int main(int argc, char** argv)
height = 480; height = 480;
} }
if (!count)
{
fprintf(stderr, "Invalid user\n");
exit(EXIT_FAILURE);
}
slots = calloc(count, sizeof(Slot)); slots = calloc(count, sizeof(Slot));
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -616,7 +601,6 @@ int main(int argc, char** argv)
glfwSetScrollCallback(slots[i].window, scroll_callback); glfwSetScrollCallback(slots[i].window, scroll_callback);
glfwSetKeyCallback(slots[i].window, key_callback); glfwSetKeyCallback(slots[i].window, key_callback);
glfwSetCharCallback(slots[i].window, char_callback); glfwSetCharCallback(slots[i].window, char_callback);
glfwSetCharModsCallback(slots[i].window, char_mods_callback);
glfwSetDropCallback(slots[i].window, drop_callback); glfwSetDropCallback(slots[i].window, drop_callback);
glfwMakeContextCurrent(slots[i].window); glfwMakeContextCurrent(slots[i].window);

View File

@ -35,6 +35,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "getopt.h"
#include "linmath.h" #include "linmath.h"
static const struct static const struct
@ -68,6 +69,14 @@ static int swap_tear;
static int swap_interval; static int swap_interval;
static double frame_rate; static double frame_rate;
static void usage(void)
{
printf("Usage: tearing [-f] [-h]\n");
printf("Options:\n");
printf(" -f use full screen\n");
printf(" -h show this help\n");
}
static void update_window_title(GLFWwindow* window) static void update_window_title(GLFWwindow* window)
{ {
char title[256]; char title[256];
@ -154,6 +163,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
unsigned long frame_count = 0; unsigned long frame_count = 0;
GLFWmonitor* monitor = NULL;
int ch, width, height;
double last_time, current_time; double last_time, current_time;
GLFWwindow* window; GLFWwindow* window;
GLuint vertex_buffer, vertex_shader, fragment_shader, program; GLuint vertex_buffer, vertex_shader, fragment_shader, program;
@ -164,10 +175,46 @@ int main(int argc, char** argv)
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
while ((ch = getopt(argc, argv, "hf")) != -1)
{
switch (ch)
{
case 'h':
usage();
exit(EXIT_SUCCESS);
case 'f':
monitor = glfwGetPrimaryMonitor();
break;
default:
usage();
exit(EXIT_FAILURE);
}
}
if (monitor)
{
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
width = mode->width;
height = mode->height;
}
else
{
width = 640;
height = 480;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(640, 480, "Tearing detector", NULL, NULL); window = glfwCreateWindow(width, height, "Tearing detector", monitor, NULL);
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();