This commit is contained in:
Eden Salomon 2015-10-25 12:59:28 +00:00
commit b5d2b80140
10 changed files with 461 additions and 42 deletions

View File

@ -44,12 +44,29 @@ the event.
@subsubsection window_full_screen Full screen windows @subsubsection window_full_screen Full screen windows
To create a full screen window, you need to specify which monitor the window To create a full screen window, you can use the GLFW_FULLSCREEN window hint.
should use. In most cases, the user's primary monitor is a good choice. It is also possible to specify which monitor the window should use. In most
For more information about retrieving monitors, see @ref monitor_monitors. cases, the user's primary monitor is a good choice. For more information about
retrieving monitors, see @ref monitor_monitors.
@code @code
glfwWindowHint(GLFW_FULLSCREEN, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); 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 @endcode
Full screen windows cover the entire display area of a monitor, have no border 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 @code
const GLFWvidmode* mode = glfwGetVideoMode(monitor); const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwWindowHint(GLFW_FULLSCREEN, GLFW_TRUE);
glfwWindowHint(GLFW_RED_BITS, mode->redBits); glfwWindowHint(GLFW_RED_BITS, mode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); 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 intended primarily for debugging purposes and cannot be used to implement proper
full screen windows. This hint is ignored for full screen windows. 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 @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_FOCUSED` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
`GLFW_AUTO_ICONIFY` | `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_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_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
`GLFW_GREEN_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` `GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
@ -605,8 +627,9 @@ GLFWmonitor* monitor = glfwGetWindowMonitor(window);
This monitor handle is one of those returned by @ref glfwGetMonitors. This monitor handle is one of those returned by @ref glfwGetMonitors.
For windowed mode windows, this function returns `NULL`. This is the For windowed mode windows, this function returns the monitor that will be used
recommended way to tell full screen windows from windowed mode windows. 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 @subsection window_iconify Window iconification
@ -669,7 +692,8 @@ glfwHideWindow(window);
This makes the window completely invisible to the user, including removing it 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 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. Hidden windows can be shown with @ref glfwShowWindow.

View File

@ -622,6 +622,7 @@ extern "C" {
#define GLFW_DECORATED 0x00020005 #define GLFW_DECORATED 0x00020005
#define GLFW_AUTO_ICONIFY 0x00020006 #define GLFW_AUTO_ICONIFY 0x00020006
#define GLFW_FLOATING 0x00020007 #define GLFW_FLOATING 0x00020007
#define GLFW_FULLSCREEN 0x00020008
#define GLFW_RED_BITS 0x00021001 #define GLFW_RED_BITS 0x00021001
#define GLFW_GREEN_BITS 0x00021002 #define GLFW_GREEN_BITS 0x00021002
@ -1575,11 +1576,12 @@ GLFWAPI void glfwWindowHint(int target, int hint);
* of the created window, framebuffer and context, see @ref * of the created window, framebuffer and context, see @ref
* glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
* *
* To create a full screen window, you need to specify the monitor the window * To create a full screen window, you can use the GLFW_FULLSCREEN window hint.
* will cover. If no monitor is specified, windowed mode will be used. Unless * It is also possible to specify which monitor the window should use. If no
* you have a way for the user to choose a specific monitor, it is recommended * monitor is specified, the primary monitor is used. Unless you have a way for
* that you pick the primary monitor. For more information on how to query * the user to choose a specific monitor, it is recommended that you pick the
* connected monitors, see @ref monitor_monitors. * 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 * 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 * window's _desired video mode_. As long as a full screen window has input
@ -1610,7 +1612,7 @@ GLFWAPI void glfwWindowHint(int target, int hint);
* This must be greater than zero. * This must be greater than zero.
* @param[in] title The initial, UTF-8 encoded window title. * @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 * @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` * @param[in] share The window whose context to share resources with, or `NULL`
* to not share resources. * to not share resources.
* @return The handle of the created window, or `NULL` if an * @return The handle of the created window, or `NULL` if an
@ -2106,6 +2108,18 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
*/ */
GLFWAPI void glfwHideWindow(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. /*! @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 * This function returns the handle of the monitor that the specified window is

View File

@ -178,6 +178,7 @@ struct _GLFWwndconfig
GLFWbool focused; GLFWbool focused;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool fullscreen;
_GLFWmonitor* monitor; _GLFWmonitor* monitor;
}; };
@ -245,6 +246,7 @@ struct _GLFWwindow
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool closed; GLFWbool closed;
GLFWbool fullscreen;
void* userPointer; void* userPointer;
GLFWvidmode videoMode; GLFWvidmode videoMode;
_GLFWmonitor* monitor; _GLFWmonitor* monitor;
@ -583,6 +585,11 @@ void _glfwPlatformUnhideWindow(_GLFWwindow* window);
*/ */
void _glfwPlatformHideWindow(_GLFWwindow* window); void _glfwPlatformHideWindow(_GLFWwindow* window);
/*! @copydoc glfwToggleWindowFullscreen
* @ingroup platform
*/
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window);
/*! @brief Returns whether the window is focused. /*! @brief Returns whether the window is focused.
* @ingroup platform * @ingroup platform
*/ */

View File

@ -600,7 +600,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{ {
// HACK: Use DwmFlush when desktop composition is enabled // HACK: Use DwmFlush when desktop composition is enabled
if (_glfwIsCompositionEnabled() && !window->monitor) if (_glfwIsCompositionEnabled() && !window->fullscreen)
{ {
int count = abs(window->wgl.interval); int count = abs(window->wgl.interval);
while (count--) while (count--)
@ -618,7 +618,7 @@ void _glfwPlatformSwapInterval(int interval)
// HACK: Disable WGL swap interval when desktop composition is enabled to // HACK: Disable WGL swap interval when desktop composition is enabled to
// avoid interfering with DWM vsync // avoid interfering with DWM vsync
if (_glfwIsCompositionEnabled() && !window->monitor) if (_glfwIsCompositionEnabled() && !window->fullscreen)
interval = 0; interval = 0;
if (window->wgl.EXT_swap_control) if (window->wgl.EXT_swap_control)

View File

@ -44,7 +44,7 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
{ {
DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
if (window->decorated && !window->monitor) if (window->decorated && !window->fullscreen)
{ {
style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
@ -63,7 +63,7 @@ static DWORD getWindowExStyle(const _GLFWwindow* window)
{ {
DWORD style = WS_EX_APPWINDOW; DWORD style = WS_EX_APPWINDOW;
if (window->decorated && !window->monitor) if (window->decorated && !window->fullscreen)
style |= WS_EX_WINDOWEDGE; style |= WS_EX_WINDOWEDGE;
return style; return style;
@ -224,15 +224,24 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF]; 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 // Enter full screen mode
// //
static GLFWbool enterFullscreenMode(_GLFWwindow* window) static GLFWbool enterFullscreenMode(_GLFWwindow* window)
{ {
GLFWvidmode mode; GLFWvidmode mode;
GLFWbool status;
int xpos, ypos; int xpos, ypos;
status = _glfwSetVideoMode(window->monitor, &window->videoMode); window->fullscreen = _glfwSetVideoMode(window->monitor, &window->videoMode);
updateWindowStyle(window);
_glfwPlatformGetVideoMode(window->monitor, &mode); _glfwPlatformGetVideoMode(window->monitor, &mode);
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
@ -240,7 +249,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
SetWindowPos(window->win32.handle, HWND_TOPMOST, SetWindowPos(window->win32.handle, HWND_TOPMOST,
xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS); xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS);
return status; return window->fullscreen;
} }
// Leave full screen mode // Leave full screen mode
@ -248,6 +257,10 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
static void leaveFullscreenMode(_GLFWwindow* window) static void leaveFullscreenMode(_GLFWwindow* window)
{ {
_glfwRestoreVideoMode(window->monitor); _glfwRestoreVideoMode(window->monitor);
window->fullscreen = GLFW_FALSE;
updateWindowStyle(window);
} }
// Window callback function (handles window events) // Window callback function (handles window events)
@ -280,7 +293,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
if (window->monitor && window->autoIconify) if (window->fullscreen && window->autoIconify)
_glfwPlatformIconifyWindow(window); _glfwPlatformIconifyWindow(window);
_glfwInputWindowFocus(window, GLFW_FALSE); _glfwInputWindowFocus(window, GLFW_FALSE);
@ -294,7 +307,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case SC_SCREENSAVE: case SC_SCREENSAVE:
case SC_MONITORPOWER: case SC_MONITORPOWER:
{ {
if (window->monitor) if (window->fullscreen)
{ {
// We are running in full screen mode, so disallow // We are running in full screen mode, so disallow
// screen saver and screen blanking // screen saver and screen blanking
@ -508,8 +521,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (!window->win32.iconified && wParam == SIZE_MINIMIZED) if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
{ {
window->win32.iconified = GLFW_TRUE; window->win32.iconified = GLFW_TRUE;
if (window->monitor)
if (window->fullscreen)
leaveFullscreenMode(window); leaveFullscreenMode(window);
// We don't really toggle fullscreen,
// just temporally restore monitor video mode
window->fullscreen = GLFW_TRUE;
_glfwInputWindowIconify(window, GLFW_TRUE); _glfwInputWindowIconify(window, GLFW_TRUE);
} }
@ -517,7 +535,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
{ {
window->win32.iconified = GLFW_FALSE; window->win32.iconified = GLFW_FALSE;
if (window->monitor)
// check if we should go back to fullscreen mode
if (window->fullscreen)
enterFullscreenMode(window); enterFullscreenMode(window);
_glfwInputWindowIconify(window, GLFW_FALSE); _glfwInputWindowIconify(window, GLFW_FALSE);
@ -673,7 +693,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
int xpos, ypos, fullWidth, fullHeight; int xpos, ypos, fullWidth, fullHeight;
WCHAR* wideTitle; WCHAR* wideTitle;
if (wndconfig->monitor) if (wndconfig->fullscreen)
{ {
GLFWvidmode mode; GLFWvidmode mode;
@ -732,7 +752,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
} }
if (wndconfig->floating && !wndconfig->monitor) if (wndconfig->floating && !wndconfig->fullscreen)
{ {
SetWindowPos(window->win32.handle, SetWindowPos(window->win32.handle,
HWND_TOPMOST, HWND_TOPMOST,
@ -868,8 +888,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) if (!createWindow(window, wndconfig, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
if (window->monitor) if (wndconfig->fullscreen)
{ {
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
if (!enterFullscreenMode(window)) if (!enterFullscreenMode(window))
@ -881,7 +901,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{ {
if (window->monitor) if (window->fullscreen)
leaveFullscreenMode(window); leaveFullscreenMode(window);
destroyWindow(window); destroyWindow(window);
@ -934,7 +954,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{ {
if (window->monitor) if (window->fullscreen)
enterFullscreenMode(window); enterFullscreenMode(window);
else else
{ {
@ -1027,14 +1047,41 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
ShowWindow(window->win32.handle, SW_RESTORE); ShowWindow(window->win32.handle, SW_RESTORE);
} }
int WindowGrabFocus(_GLFWwindow* window)
{
if (!BringWindowToTop(window->win32.handle))
return GLFW_FALSE;
if (!SetForegroundWindow(window->win32.handle))
return GLFW_FALSE;
if (!SetFocus(window->win32.handle))
return GLFW_FALSE;
return GLFW_FALSE;
}
void WindowRequestFocus(_GLFWwindow* window)
{
// The following can be used to flash the taskbar icon
// if any of the focus related functions fail
if (!WindowGrabFocus(window)) {
// create a taskbar notification ("flash")
FLASHWINFO info;
info.cbSize = sizeof(FLASHWINFO);
info.hwnd = window->win32.handle;
info.dwFlags = FLASHW_TRAY;
info.uCount = 3;
info.dwTimeout = 0;
FlashWindowEx(&info);
}
}
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{ {
ShowWindow(window->win32.handle, SW_SHOW); ShowWindow(window->win32.handle, SW_SHOW);
BringWindowToTop(window->win32.handle); WindowRequestFocus(window);
SetForegroundWindow(window->win32.handle);
SetFocus(window->win32.handle);
} }
void _glfwPlatformUnhideWindow(_GLFWwindow* window) void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{ {
ShowWindow(window->win32.handle, SW_SHOW); ShowWindow(window->win32.handle, SW_SHOW);
@ -1045,6 +1092,15 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
ShowWindow(window->win32.handle, SW_HIDE); ShowWindow(window->win32.handle, SW_HIDE);
} }
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window)
{
if (window->fullscreen) {
leaveFullscreenMode(window);
} else {
enterFullscreenMode(window);
}
}
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
return window->win32.handle == GetActiveWindow(); return window->win32.handle == GetActiveWindow();

View File

@ -139,10 +139,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
wndconfig.width = width; wndconfig.width = width;
wndconfig.height = height; wndconfig.height = height;
wndconfig.title = title; wndconfig.title = title;
wndconfig.monitor = (_GLFWmonitor*) monitor; wndconfig.monitor = (_GLFWmonitor*) (monitor ? monitor : glfwGetPrimaryMonitor());
ctxconfig.share = (_GLFWwindow*) share; ctxconfig.share = (_GLFWwindow*) share;
if (wndconfig.monitor) if (wndconfig.fullscreen)
{ {
wndconfig.resizable = GLFW_TRUE; wndconfig.resizable = GLFW_TRUE;
wndconfig.visible = GLFW_TRUE; wndconfig.visible = GLFW_TRUE;
@ -202,7 +202,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
// Restore the previously current context (or NULL) // Restore the previously current context (or NULL)
_glfwPlatformMakeContextCurrent(previous); _glfwPlatformMakeContextCurrent(previous);
if (wndconfig.monitor) if (wndconfig.fullscreen)
{ {
int width, height; int width, height;
_glfwPlatformGetWindowSize(window, &width, &height); _glfwPlatformGetWindowSize(window, &width, &height);
@ -318,6 +318,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
case GLFW_FOCUSED: case GLFW_FOCUSED:
_glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_FULLSCREEN:
_glfw.hints.window.fullscreen = hint ? GLFW_TRUE : GLFW_FALSE;
break;
case GLFW_AUTO_ICONIFY: case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE;
break; break;
@ -437,7 +440,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor) if (window->fullscreen)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
"Full screen windows cannot be moved"); "Full screen windows cannot be moved");
@ -466,7 +469,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor) if (window->fullscreen)
{ {
window->videoMode.width = width; window->videoMode.width = width;
window->videoMode.height = height; window->videoMode.height = height;
@ -483,7 +486,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor || !window->resizable) if (window->fullscreen || !window->resizable)
return; return;
_glfwPlatformSetWindowSizeLimits(window, _glfwPlatformSetWindowSizeLimits(window,
@ -497,7 +500,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor || !window->resizable) if (window->fullscreen || !window->resizable)
return; return;
if (!denom) if (!denom)
@ -561,7 +564,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor) if (window->fullscreen)
return; return;
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
@ -573,12 +576,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor) if (window->fullscreen)
return; return;
_glfwPlatformHideWindow(window); _glfwPlatformHideWindow(window);
} }
GLFWAPI void glfwToggleWindowFullscreen(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT();
_glfwPlatformToggleWindowFullscreen(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
@ -599,6 +611,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return window->decorated; return window->decorated;
case GLFW_FLOATING: case GLFW_FLOATING:
return window->floating; return window->floating;
case GLFW_FULLSCREEN:
return window->fullscreen;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:
return window->context.api; return window->context.api;
case GLFW_CONTEXT_VERSION_MAJOR: case GLFW_CONTEXT_VERSION_MAJOR:

View File

@ -36,10 +36,13 @@ add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD})
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD}) add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD}) add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD})
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(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}")
target_link_libraries(threads "${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 set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
iconify joysticks monitors reopen cursor) iconify joysticks monitors reopen cursor)

289
tests/options.c Normal file
View 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
View File

@ -0,0 +1,10 @@
TODO:
- Change Resulution
- Refresh Rate
- Fullscreen / Window
all in runtime
new state variables
Enter fullscreen mode:

View File

@ -76,6 +76,8 @@ static GLFWwindow* open_window(int width, int height, GLFWmonitor* monitor)
base = glfwGetTime(); base = glfwGetTime();
glfwWindowHint(GLFW_FULLSCREEN, monitor ? GLFW_TRUE : GLFW_FALSE);
window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL); window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL);
if (!window) if (!window)
return NULL; return NULL;