mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 05:36:35 +00:00
Merge branch 'feature-toggle-fullscreen'
This commit is contained in:
commit
75152357c4
@ -44,12 +44,29 @@ the event.
|
||||
|
||||
@subsubsection window_full_screen Full screen windows
|
||||
|
||||
To create a full screen window, you need to specify which monitor the window
|
||||
should use. In most cases, the user's primary monitor is a good choice.
|
||||
For more information about retrieving monitors, see @ref monitor_monitors.
|
||||
To create a full screen window, you can use the GLFW_FULLSCREEN window hint.
|
||||
It is also possible to specify which monitor the window should use. In most
|
||||
cases, the user's primary monitor is a good choice. For more information about
|
||||
retrieving monitors, see @ref monitor_monitors.
|
||||
|
||||
@code
|
||||
glfwWindowHint(GLFW_FULLSCREEN, GLFW_TRUE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL);
|
||||
// same as passing null for the monitor
|
||||
@endcode
|
||||
|
||||
The mode of a window, whether created as fullscreen or as a windowed mode window,
|
||||
can be toggled at any time using @ref glfwToggleWindowFullscreen.
|
||||
|
||||
@code
|
||||
glfwToggleWindowFullscreen(window);
|
||||
@endcode
|
||||
|
||||
You can also get the current window state with @ref glfwGetWindowAttrib.
|
||||
|
||||
@code
|
||||
int fullscreen = glfwGetWindowAttrib(window, GLFW_FULLSCREEN);
|
||||
@endcode
|
||||
|
||||
Full screen windows cover the entire display area of a monitor, have no border
|
||||
@ -92,6 +109,7 @@ such a window, simply request the current video mode.
|
||||
@code
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
|
||||
glfwWindowHint(GLFW_FULLSCREEN, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
|
||||
@ -174,6 +192,9 @@ above other regular windows, also called topmost or always-on-top. This is
|
||||
intended primarily for debugging purposes and cannot be used to implement proper
|
||||
full screen windows. This hint is ignored for full screen windows.
|
||||
|
||||
`GLFW_FULLSCREEN` specifies whether the window will be created in fullscreen mode.
|
||||
The window can always be switched back to windowed mode using @ref glfwToggleWindowFullscreen.
|
||||
|
||||
|
||||
@subsubsection window_hints_fb Framebuffer related hints
|
||||
|
||||
@ -304,6 +325,7 @@ Window hint | Default value | Supported values
|
||||
`GLFW_FOCUSED` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_AUTO_ICONIFY` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_FLOATING` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_FULLSCREEN` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||
`GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||
`GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||
@ -599,8 +621,9 @@ GLFWmonitor* monitor = glfwGetWindowMonitor(window);
|
||||
|
||||
This monitor handle is one of those returned by @ref glfwGetMonitors.
|
||||
|
||||
For windowed mode windows, this function returns `NULL`. This is the
|
||||
recommended way to tell full screen windows from windowed mode windows.
|
||||
For windowed mode windows, this function returns the monitor that will be used
|
||||
if the mode would be switched to fullscreen. Using this function to query the mode
|
||||
of the window will no longer work and @glfwGetWindowAttrib should be used instead.
|
||||
|
||||
|
||||
@subsection window_iconify Window iconification
|
||||
@ -663,7 +686,8 @@ glfwHideWindow(window);
|
||||
|
||||
This makes the window completely invisible to the user, including removing it
|
||||
from the task bar, dock or window list. Full screen windows cannot be hidden
|
||||
and calling @ref glfwHideWindow on a full screen window does nothing.
|
||||
and calling @ref glfwHideWindow on a full screen window does nothing. The window
|
||||
should be switched to windowed mode first and then hidden.
|
||||
|
||||
Hidden windows can be shown with @ref glfwShowWindow.
|
||||
|
||||
|
@ -614,6 +614,7 @@ extern "C" {
|
||||
#define GLFW_DECORATED 0x00020005
|
||||
#define GLFW_AUTO_ICONIFY 0x00020006
|
||||
#define GLFW_FLOATING 0x00020007
|
||||
#define GLFW_FULLSCREEN 0x00020008
|
||||
|
||||
#define GLFW_RED_BITS 0x00021001
|
||||
#define GLFW_GREEN_BITS 0x00021002
|
||||
@ -1570,11 +1571,12 @@ GLFWAPI void glfwWindowHint(int target, int hint);
|
||||
* of the created window, framebuffer and context, see @ref
|
||||
* glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
|
||||
*
|
||||
* To create a full screen window, you need to specify the monitor the window
|
||||
* will cover. If no monitor is specified, windowed mode will be used. Unless
|
||||
* you have a way for the user to choose a specific monitor, it is recommended
|
||||
* that you pick the primary monitor. For more information on how to query
|
||||
* connected monitors, see @ref monitor_monitors.
|
||||
* To create a full screen window, you can use the GLFW_FULLSCREEN window hint.
|
||||
* It is also possible to specify which monitor the window should use. If no
|
||||
* monitor is specified, the primary monitor is used. Unless you have a way for
|
||||
* the user to choose a specific monitor, it is recommended that you pick the
|
||||
* primary monitor. For more information on how to query connected monitors,
|
||||
* see @ref monitor_monitors.
|
||||
*
|
||||
* For full screen windows, the specified size becomes the resolution of the
|
||||
* window's _desired video mode_. As long as a full screen window has input
|
||||
@ -1605,7 +1607,7 @@ GLFWAPI void glfwWindowHint(int target, int hint);
|
||||
* This must be greater than zero.
|
||||
* @param[in] title The initial, UTF-8 encoded window title.
|
||||
* @param[in] monitor The monitor to use for full screen mode, or `NULL` to use
|
||||
* windowed mode.
|
||||
* the primary monitor.
|
||||
* @param[in] share The window whose context to share resources with, or `NULL`
|
||||
* to not share resources.
|
||||
* @return The handle of the created window, or `NULL` if an
|
||||
@ -2101,6 +2103,18 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
|
||||
*/
|
||||
GLFWAPI void glfwHideWindow(GLFWwindow* window);
|
||||
|
||||
/*! @brief Toggles between fullscreen and windowed mode on the specified window.
|
||||
*
|
||||
* The functions enters fullscreen mode if the specified window was previously
|
||||
* in windowed mode. If the window is already in fullscreen mode, the fuctions restores
|
||||
* the monitor video mode and the specified window switches back to windowed mode.
|
||||
*
|
||||
* @param[in] window The window to toggle the mode on.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
GLFWAPI void glfwToggleWindowFullscreen(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the monitor that the window uses for full screen mode.
|
||||
*
|
||||
* This function returns the handle of the monitor that the specified window is
|
||||
|
@ -178,6 +178,7 @@ struct _GLFWwndconfig
|
||||
GLFWbool focused;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool fullscreen;
|
||||
_GLFWmonitor* monitor;
|
||||
};
|
||||
|
||||
@ -245,6 +246,7 @@ struct _GLFWwindow
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool closed;
|
||||
GLFWbool fullscreen;
|
||||
void* userPointer;
|
||||
GLFWvidmode videoMode;
|
||||
_GLFWmonitor* monitor;
|
||||
@ -584,6 +586,11 @@ void _glfwPlatformUnhideWindow(_GLFWwindow* window);
|
||||
*/
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
||||
|
||||
/*! @copydoc glfwToggleWindowFullscreen
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns whether the window is focused.
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
@ -600,7 +600,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
// HACK: Use DwmFlush when desktop composition is enabled
|
||||
if (_glfwIsCompositionEnabled() && !window->monitor)
|
||||
if (_glfwIsCompositionEnabled() && !window->fullscreen)
|
||||
{
|
||||
int count = abs(window->wgl.interval);
|
||||
while (count--)
|
||||
@ -618,7 +618,7 @@ void _glfwPlatformSwapInterval(int interval)
|
||||
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||
// avoid interfering with DWM vsync
|
||||
if (_glfwIsCompositionEnabled() && !window->monitor)
|
||||
if (_glfwIsCompositionEnabled() && !window->fullscreen)
|
||||
interval = 0;
|
||||
|
||||
if (window->wgl.EXT_swap_control)
|
||||
|
@ -44,7 +44,7 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||
{
|
||||
DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
|
||||
if (window->decorated && !window->monitor)
|
||||
if (window->decorated && !window->fullscreen)
|
||||
{
|
||||
style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
|
||||
@ -63,7 +63,7 @@ static DWORD getWindowExStyle(const _GLFWwindow* window)
|
||||
{
|
||||
DWORD style = WS_EX_APPWINDOW;
|
||||
|
||||
if (window->decorated && !window->monitor)
|
||||
if (window->decorated && !window->fullscreen)
|
||||
style |= WS_EX_WINDOWEDGE;
|
||||
|
||||
return style;
|
||||
@ -224,15 +224,24 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
|
||||
return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF];
|
||||
}
|
||||
|
||||
static void updateWindowStyle(_GLFWwindow* window)
|
||||
{
|
||||
SetWindowLongPtr(window->win32.handle, GWL_EXSTYLE, getWindowExStyle(window));
|
||||
SetWindowLongPtr(window->win32.handle, GWL_STYLE, getWindowStyle(window));
|
||||
|
||||
_glfwPlatformShowWindow(window);
|
||||
}
|
||||
|
||||
// Enter full screen mode
|
||||
//
|
||||
static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
GLFWbool status;
|
||||
int xpos, ypos;
|
||||
|
||||
status = _glfwSetVideoMode(window->monitor, &window->videoMode);
|
||||
window->fullscreen = _glfwSetVideoMode(window->monitor, &window->videoMode);
|
||||
|
||||
updateWindowStyle(window);
|
||||
|
||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
|
||||
@ -240,7 +249,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||
xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS);
|
||||
|
||||
return status;
|
||||
return window->fullscreen;
|
||||
}
|
||||
|
||||
// Leave full screen mode
|
||||
@ -248,6 +257,10 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
{
|
||||
_glfwRestoreVideoMode(window->monitor);
|
||||
|
||||
window->fullscreen = GLFW_FALSE;
|
||||
|
||||
updateWindowStyle(window);
|
||||
}
|
||||
|
||||
// Window callback function (handles window events)
|
||||
@ -280,7 +293,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||
|
||||
if (window->monitor && window->autoIconify)
|
||||
if (window->fullscreen && window->autoIconify)
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
@ -294,7 +307,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case SC_SCREENSAVE:
|
||||
case SC_MONITORPOWER:
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
// We are running in full screen mode, so disallow
|
||||
// screen saver and screen blanking
|
||||
@ -508,8 +521,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
|
||||
{
|
||||
window->win32.iconified = GLFW_TRUE;
|
||||
if (window->monitor)
|
||||
|
||||
if (window->fullscreen)
|
||||
leaveFullscreenMode(window);
|
||||
|
||||
// We don't really toggle fullscreen,
|
||||
// just temporally restore monitor video mode
|
||||
window->fullscreen = GLFW_TRUE;
|
||||
|
||||
_glfwInputWindowIconify(window, GLFW_TRUE);
|
||||
}
|
||||
@ -517,7 +535,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
|
||||
{
|
||||
window->win32.iconified = GLFW_FALSE;
|
||||
if (window->monitor)
|
||||
|
||||
// check if we should go back to fullscreen mode
|
||||
if (window->fullscreen)
|
||||
enterFullscreenMode(window);
|
||||
|
||||
_glfwInputWindowIconify(window, GLFW_FALSE);
|
||||
@ -673,7 +693,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
||||
int xpos, ypos, fullWidth, fullHeight;
|
||||
WCHAR* wideTitle;
|
||||
|
||||
if (wndconfig->monitor)
|
||||
if (wndconfig->fullscreen)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
|
||||
@ -732,7 +752,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
}
|
||||
|
||||
if (wndconfig->floating && !wndconfig->monitor)
|
||||
if (wndconfig->floating && !wndconfig->fullscreen)
|
||||
{
|
||||
SetWindowPos(window->win32.handle,
|
||||
HWND_TOPMOST,
|
||||
@ -868,17 +888,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!createWindow(window, wndconfig, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
|
||||
if (wndconfig->fullscreen)
|
||||
{
|
||||
// the following function calls ShowWindow
|
||||
// which sends WM_SETFOCUS to windowProc()
|
||||
// Which then enters fullscreen mode if autoIconify is enabled (win32_window.c : line 283)
|
||||
_glfwPlatformShowWindow(window);
|
||||
if (!window->autoIconify) { // add this to prevent entering full screen mode twice when autoIconify == true
|
||||
if (!enterFullscreenMode(window))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if (!enterFullscreenMode(window))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -886,7 +901,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
leaveFullscreenMode(window);
|
||||
|
||||
destroyWindow(window);
|
||||
@ -939,7 +954,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
enterFullscreenMode(window);
|
||||
else
|
||||
{
|
||||
@ -1032,20 +1047,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
ShowWindow(window->win32.handle, SW_RESTORE);
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
|
||||
// Consider separating the following function calls to a different function?
|
||||
// e.g. RequestFocus(_GLFWwindow* window) (any of these might fail)
|
||||
BringWindowToTop(window->win32.handle);
|
||||
SetForegroundWindow(window->win32.handle);
|
||||
SetFocus(window->win32.handle);
|
||||
}
|
||||
|
||||
/* one example of separation */
|
||||
|
||||
int _glfwPlatformGrabFocus(_GLFWwindow* window)
|
||||
int WindowGrabFocus(_GLFWwindow* window)
|
||||
{
|
||||
if (!BringWindowToTop(window->win32.handle))
|
||||
return GLFW_FALSE;
|
||||
@ -1056,11 +1058,11 @@ int _glfwPlatformGrabFocus(_GLFWwindow* window)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestFocus(_GLFWwindow* window)
|
||||
void WindowRequestFocus(_GLFWwindow* window)
|
||||
{
|
||||
// The following can be used to flash the taskbar icon
|
||||
// if any of the focus related functions fail
|
||||
if (!_glfwPlatformGrabFocus(window)) {
|
||||
if (!WindowGrabFocus(window)) {
|
||||
// create a taskbar notification ("flash")
|
||||
FLASHWINFO info;
|
||||
info.cbSize = sizeof(FLASHWINFO);
|
||||
@ -1073,6 +1075,13 @@ void _glfwPlatformRequestFocus(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
WindowRequestFocus(window);
|
||||
}
|
||||
|
||||
|
||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
@ -1083,6 +1092,15 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
ShowWindow(window->win32.handle, SW_HIDE);
|
||||
}
|
||||
|
||||
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window)
|
||||
{
|
||||
if (window->fullscreen) {
|
||||
leaveFullscreenMode(window);
|
||||
} else {
|
||||
enterFullscreenMode(window);
|
||||
}
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
{
|
||||
return window->win32.handle == GetActiveWindow();
|
||||
|
32
src/window.c
32
src/window.c
@ -139,10 +139,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
wndconfig.width = width;
|
||||
wndconfig.height = height;
|
||||
wndconfig.title = title;
|
||||
wndconfig.monitor = (_GLFWmonitor*) monitor;
|
||||
wndconfig.monitor = (_GLFWmonitor*) (monitor ? monitor : glfwGetPrimaryMonitor());
|
||||
ctxconfig.share = (_GLFWwindow*) share;
|
||||
|
||||
if (wndconfig.monitor)
|
||||
if (wndconfig.fullscreen)
|
||||
{
|
||||
wndconfig.resizable = GLFW_TRUE;
|
||||
wndconfig.visible = GLFW_TRUE;
|
||||
@ -208,7 +208,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
// Restore the previously current context (or NULL)
|
||||
_glfwPlatformMakeContextCurrent(previous);
|
||||
|
||||
if (wndconfig.monitor)
|
||||
if (wndconfig.fullscreen)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
@ -324,6 +324,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
|
||||
case GLFW_FOCUSED:
|
||||
_glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_FULLSCREEN:
|
||||
_glfw.hints.window.fullscreen = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
@ -443,7 +446,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Full screen windows cannot be moved");
|
||||
@ -472,7 +475,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
window->videoMode.width = width;
|
||||
window->videoMode.height = height;
|
||||
@ -489,7 +492,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor || !window->resizable)
|
||||
if (window->fullscreen || !window->resizable)
|
||||
return;
|
||||
|
||||
_glfwPlatformSetWindowSizeLimits(window,
|
||||
@ -503,7 +506,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor || !window->resizable)
|
||||
if (window->fullscreen || !window->resizable)
|
||||
return;
|
||||
|
||||
if (!denom)
|
||||
@ -567,7 +570,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
return;
|
||||
|
||||
_glfwPlatformShowWindow(window);
|
||||
@ -579,12 +582,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
return;
|
||||
|
||||
_glfwPlatformHideWindow(window);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwToggleWindowFullscreen(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
_glfwPlatformToggleWindowFullscreen(window);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
@ -605,6 +617,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return window->decorated;
|
||||
case GLFW_FLOATING:
|
||||
return window->floating;
|
||||
case GLFW_FULLSCREEN:
|
||||
return window->fullscreen;
|
||||
case GLFW_CLIENT_API:
|
||||
return window->context.api;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
|
@ -47,10 +47,13 @@ set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
|
||||
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD})
|
||||
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
|
||||
|
||||
add_executable(options MACOSX_BUNDLE options.c ${GETOPT} ${GLAD})
|
||||
set_target_properties(options PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Options")
|
||||
|
||||
target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}")
|
||||
target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}")
|
||||
|
||||
set(WINDOWS_BINARIES empty sharing tearing threads title windows)
|
||||
set(WINDOWS_BINARIES empty sharing tearing threads title windows options)
|
||||
set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
|
||||
iconify joysticks monitors reopen cursor)
|
||||
|
||||
|
289
tests/options.c
Normal file
289
tests/options.c
Normal file
@ -0,0 +1,289 @@
|
||||
//========================================================================
|
||||
// Simple 'Graphics' options test
|
||||
// Copyright (C) 2015 Eden Salomon <Niko113355@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
//
|
||||
// This test creates a window with the ability to change during runtime
|
||||
// the window options typically seen in the 'Graphics' section of games.
|
||||
// This includes resolution, refresh rate, and fullscreen / windowed mode.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#define GLFW_EXPOSE_NATIVE_WGL
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
typedef struct _WindowState
|
||||
{
|
||||
SIZE* dimenstions;
|
||||
int size;
|
||||
int count;
|
||||
int current;
|
||||
} WindowState;
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void list_resolutions(GLFWwindow* window)
|
||||
{
|
||||
GLFWmonitor* monitor;
|
||||
int count;
|
||||
const GLFWvidmode* modes;
|
||||
|
||||
monitor = glfwGetWindowMonitor(window);
|
||||
modes = glfwGetVideoModes(monitor ? monitor : glfwGetPrimaryMonitor(), &count);
|
||||
|
||||
printf("List of supported resolutions:\n");
|
||||
printf(" +----+------------------------+----+\n");
|
||||
printf(" | | resolution | color | |\n");
|
||||
printf(" | id | width height | r g b | rf |\n");
|
||||
printf(" +----+------------------------+----+\n");
|
||||
for (int i = 0; i < count; ++i) {
|
||||
printf(" | %2d | %5d %6d | %d %d %d | %2d |\n",
|
||||
i + 1,
|
||||
modes[i].width, modes[i].height,
|
||||
modes[i].redBits,
|
||||
modes[i].greenBits,
|
||||
modes[i].blueBits,
|
||||
modes[i].refreshRate);
|
||||
}
|
||||
printf(" +----+------------------------+----+\n\n");
|
||||
}
|
||||
|
||||
static void setVideoMode(GLFWwindow* window, WindowState* state, int index)
|
||||
{
|
||||
GLFWmonitor* monitor;
|
||||
const GLFWvidmode* mode;
|
||||
int width, height;
|
||||
|
||||
state->current = (index + state->count) % state->count;
|
||||
width = state->dimenstions[state->current].cx;
|
||||
height = state->dimenstions[state->current].cy;
|
||||
|
||||
glfwSetWindowSize(window, width, height);
|
||||
|
||||
monitor = glfwGetWindowMonitor(window);
|
||||
mode = glfwGetVideoMode(monitor);
|
||||
|
||||
printf("Changed resolution to %dx%d [%d].\n", width, height, mode->refreshRate);
|
||||
}
|
||||
|
||||
static void controls()
|
||||
{
|
||||
printf("When the window is in focus, use the following keys to control the various options:\n");
|
||||
printf(" Esc Exit the application\n");
|
||||
printf(" h display this help\n");
|
||||
printf(" f toggle fullscreen / window mode\n");
|
||||
printf(" r toggle between different refresh rates\n");
|
||||
printf(" l list all supported resolutions\n");
|
||||
printf(" d, -> next resolution\n");
|
||||
printf(" a, <- previous resolution\n");
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
WindowState* state = (WindowState*) glfwGetWindowUserPointer(window);
|
||||
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_H:
|
||||
controls();
|
||||
break;
|
||||
case GLFW_KEY_L:
|
||||
list_resolutions(window);
|
||||
break;
|
||||
case GLFW_KEY_F:
|
||||
glfwToggleWindowFullscreen(window);
|
||||
break;
|
||||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
break;
|
||||
case GLFW_KEY_A:
|
||||
setVideoMode(window, state, state->current - 1);
|
||||
break;
|
||||
case GLFW_KEY_D:
|
||||
setVideoMode(window, state, state->current + 1);
|
||||
break;
|
||||
case GLFW_KEY_R:
|
||||
// TODO: toggle refresh rate on current resolution
|
||||
// as of now the highest value is used due to
|
||||
// GLFW_REFRESH_RATE being set to GLFW_DONT_CARE
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usage()
|
||||
{
|
||||
printf("Usage: oprions [OPTION]...\n");
|
||||
printf("Options:\n");
|
||||
printf(" -h, --help show this help\n");
|
||||
printf(" -l, --list-resolutions list all resolutions supported by the primary monitor\n");
|
||||
printf(" --width=640 specify the width of the window in pixels\n");
|
||||
printf(" --height=480 specify the height of the window in pixels\n");
|
||||
printf(" -r, --refresh-rate=RATE specify the refresh rate of the window in Hz\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ch;
|
||||
int width = 640;
|
||||
int height = 480;
|
||||
int list = GLFW_FALSE;
|
||||
int fullscreen = GLFW_FALSE;
|
||||
int running = GLFW_TRUE;
|
||||
GLFWwindow* window;
|
||||
GLFWmonitor* monitor;
|
||||
WindowState state = { NULL, 0, 0, 0 };
|
||||
int i, j, count;
|
||||
const GLFWvidmode* modes;
|
||||
|
||||
enum { HELP, RESOLUTIONS, WIDTH, HIEGHT, REFRESH, FULLSCREEN };
|
||||
|
||||
const struct option options[] =
|
||||
{
|
||||
{ "help", 0, NULL, HELP },
|
||||
{ "list-resolutions", 0, NULL, RESOLUTIONS },
|
||||
{ "width", 1, NULL, WIDTH },
|
||||
{ "height", 1, NULL, HIEGHT },
|
||||
{ "refresh-rate", 1, NULL, REFRESH },
|
||||
{ "fullscreen", 0, NULL, FULLSCREEN },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
while ((ch = getopt_long(argc, argv, "hlr:f", options, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
case HELP:
|
||||
usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
case RESOLUTIONS:
|
||||
list = GLFW_TRUE;
|
||||
break;
|
||||
case WIDTH:
|
||||
width = atoi(optarg);
|
||||
break;
|
||||
case HIEGHT:
|
||||
height = atoi(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
case REFRESH:
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, atoi(optarg));
|
||||
break;
|
||||
case 'f':
|
||||
case FULLSCREEN:
|
||||
glfwWindowHint(GLFW_FULLSCREEN, GLFW_TRUE);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
window = glfwCreateWindow(width, height, "Graphics Options", (fullscreen ? monitor : NULL), NULL);
|
||||
|
||||
modes = glfwGetVideoModes(monitor ? monitor : glfwGetPrimaryMonitor(), &count);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
SIZE size;
|
||||
|
||||
size.cx = modes[i].width;
|
||||
size.cy = modes[i].height;
|
||||
|
||||
for (j = 0; j < state.count; ++j) {
|
||||
if (state.dimenstions[j].cx == size.cx &&
|
||||
state.dimenstions[j].cy == size.cy)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < state.count)
|
||||
continue;
|
||||
|
||||
if (state.count == state.size)
|
||||
{
|
||||
if (state.count)
|
||||
state.size *= 2;
|
||||
else
|
||||
state.size = 128;
|
||||
|
||||
state.dimenstions = (SIZE*) realloc(state.dimenstions, state.size * sizeof(SIZE));
|
||||
}
|
||||
|
||||
state.count++;
|
||||
state.dimenstions[state.count - 1] = size;
|
||||
}
|
||||
|
||||
glfwSetWindowUserPointer(window, &state);
|
||||
|
||||
if (!window) {
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (list)
|
||||
list_resolutions(window);
|
||||
|
||||
controls();
|
||||
|
||||
while (running)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
if (glfwWindowShouldClose(window))
|
||||
running = GLFW_FALSE;
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
free(state.dimenstions);
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
10
tests/options.txt
Normal file
10
tests/options.txt
Normal file
@ -0,0 +1,10 @@
|
||||
TODO:
|
||||
- Change Resulution
|
||||
- Refresh Rate
|
||||
- Fullscreen / Window
|
||||
all in runtime
|
||||
|
||||
new state variables
|
||||
|
||||
|
||||
Enter fullscreen mode:
|
@ -76,6 +76,8 @@ static GLFWwindow* open_window(int width, int height, GLFWmonitor* monitor)
|
||||
|
||||
base = glfwGetTime();
|
||||
|
||||
glfwWindowHint(GLFW_FULLSCREEN, monitor ? GLFW_TRUE : GLFW_FALSE);
|
||||
|
||||
window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL);
|
||||
if (!window)
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user