Merge branch 'feature-toggle-fullscreen'

This commit is contained in:
Eden Salomon 2015-10-22 21:09:42 +03:00
commit 75152357c4
10 changed files with 443 additions and 62 deletions

View File

@ -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.

View File

@ -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

View File

@ -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
*/

View File

@ -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)

View File

@ -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,16 +521,23 @@ 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);
}
else if (window->win32.iconified &&
(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,
@ -869,16 +889,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
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();

View File

@ -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:

View File

@ -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
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();
glfwWindowHint(GLFW_FULLSCREEN, monitor ? GLFW_TRUE : GLFW_FALSE);
window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL);
if (!window)
return NULL;