mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Added opt-in support for high-dpi mode in OS X when on a retina display (resolves issue #761).
Added a ‘highdpi’ boolean flag to t.window/love.window.setMode (defaults to false.) When the window is actually in high-dpi mode on a supported display, the graphics width and height and the mouse position are in pixels, rather than ‘window coordinates’. Added love.window.getPixelScale. Returns the scale factor of the window from user-space points to pixels (e.g. it will be 1 normally, and 2 on a retina display in OS X with high-dpi mode enabled.)
This commit is contained in:
@@ -26,19 +26,19 @@ namespace love
|
||||
namespace window
|
||||
{
|
||||
|
||||
Window *Window::singleton = NULL;
|
||||
Window *Window::singleton = nullptr;
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
if (singleton == this)
|
||||
singleton = NULL;
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
void Window::swapBuffers()
|
||||
{
|
||||
}
|
||||
|
||||
WindowAttributes::WindowAttributes()
|
||||
WindowSettings::WindowSettings()
|
||||
: fullscreen(false)
|
||||
, fstype(Window::FULLSCREEN_TYPE_NORMAL)
|
||||
, vsync(true)
|
||||
@@ -49,6 +49,7 @@ WindowAttributes::WindowAttributes()
|
||||
, borderless(false)
|
||||
, centered(true)
|
||||
, display(0)
|
||||
, highdpi(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,31 +63,32 @@ bool Window::getConstant(Window::FullscreenType in, const char *&out)
|
||||
return fullscreenTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Window::getConstant(const char *in, Window::Attribute &out)
|
||||
bool Window::getConstant(const char *in, Window::Setting &out)
|
||||
{
|
||||
return attributes.find(in, out);
|
||||
return settings.find(in, out);
|
||||
}
|
||||
|
||||
bool Window::getConstant(Window::Attribute in, const char *&out)
|
||||
bool Window::getConstant(Window::Setting in, const char *&out)
|
||||
{
|
||||
return attributes.find(in, out);
|
||||
return settings.find(in, out);
|
||||
}
|
||||
|
||||
StringMap<Window::Attribute, Window::ATTRIB_MAX_ENUM>::Entry Window::attributeEntries[] =
|
||||
StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntries[] =
|
||||
{
|
||||
{"fullscreen", ATTRIB_FULLSCREEN},
|
||||
{"fullscreentype", ATTRIB_FULLSCREEN_TYPE},
|
||||
{"vsync", ATTRIB_VSYNC},
|
||||
{"fsaa", ATTRIB_FSAA},
|
||||
{"resizable", ATTRIB_RESIZABLE},
|
||||
{"minwidth", ATTRIB_MIN_WIDTH},
|
||||
{"minheight", ATTRIB_MIN_HEIGHT},
|
||||
{"borderless", ATTRIB_BORDERLESS},
|
||||
{"centered", ATTRIB_CENTERED},
|
||||
{"display", ATTRIB_DISPLAY}
|
||||
{"fullscreen", SETTING_FULLSCREEN},
|
||||
{"fullscreentype", SETTING_FULLSCREEN_TYPE},
|
||||
{"vsync", SETTING_VSYNC},
|
||||
{"fsaa", SETTING_FSAA},
|
||||
{"resizable", SETTING_RESIZABLE},
|
||||
{"minwidth", SETTING_MIN_WIDTH},
|
||||
{"minheight", SETTING_MIN_HEIGHT},
|
||||
{"borderless", SETTING_BORDERLESS},
|
||||
{"centered", SETTING_CENTERED},
|
||||
{"display", SETTING_DISPLAY},
|
||||
{"highdpi", SETTING_HIGHDPI},
|
||||
};
|
||||
|
||||
StringMap<Window::Attribute, Window::ATTRIB_MAX_ENUM> Window::attributes(Window::attributeEntries, sizeof(Window::attributeEntries));
|
||||
StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));
|
||||
|
||||
StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM>::Entry Window::fullscreenTypeEntries[] =
|
||||
{
|
||||
|
||||
+29
-23
@@ -37,26 +37,27 @@ namespace window
|
||||
|
||||
// Forward-declared so it can be used in the class methods. We can't define the
|
||||
// whole thing here because it uses the Window::Type enum.
|
||||
struct WindowAttributes;
|
||||
struct WindowSettings;
|
||||
|
||||
class Window : public Module
|
||||
{
|
||||
public:
|
||||
|
||||
// Types of window attributes.
|
||||
enum Attribute
|
||||
// Different window settings.
|
||||
enum Setting
|
||||
{
|
||||
ATTRIB_FULLSCREEN,
|
||||
ATTRIB_FULLSCREEN_TYPE,
|
||||
ATTRIB_VSYNC,
|
||||
ATTRIB_FSAA,
|
||||
ATTRIB_RESIZABLE,
|
||||
ATTRIB_MIN_WIDTH,
|
||||
ATTRIB_MIN_HEIGHT,
|
||||
ATTRIB_BORDERLESS,
|
||||
ATTRIB_CENTERED,
|
||||
ATTRIB_DISPLAY,
|
||||
ATTRIB_MAX_ENUM
|
||||
SETTING_FULLSCREEN,
|
||||
SETTING_FULLSCREEN_TYPE,
|
||||
SETTING_VSYNC,
|
||||
SETTING_FSAA,
|
||||
SETTING_RESIZABLE,
|
||||
SETTING_MIN_WIDTH,
|
||||
SETTING_MIN_HEIGHT,
|
||||
SETTING_BORDERLESS,
|
||||
SETTING_CENTERED,
|
||||
SETTING_DISPLAY,
|
||||
SETTING_HIGHDPI,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
enum FullscreenType
|
||||
@@ -74,8 +75,8 @@ public:
|
||||
|
||||
virtual ~Window();
|
||||
|
||||
virtual bool setWindow(int width = 800, int height = 600, WindowAttributes *attribs = 0) = 0;
|
||||
virtual void getWindow(int &width, int &height, WindowAttributes &attribs) = 0;
|
||||
virtual bool setWindow(int width = 800, int height = 600, WindowSettings *settings = nullptr) = 0;
|
||||
virtual void getWindow(int &width, int &height, WindowSettings &settings) = 0;
|
||||
|
||||
virtual bool setFullscreen(bool fullscreen, FullscreenType fstype) = 0;
|
||||
virtual bool setFullscreen(bool fullscreen) = 0;
|
||||
@@ -113,14 +114,16 @@ public:
|
||||
virtual void setMouseGrab(bool grab) = 0;
|
||||
virtual bool isMouseGrabbed() const = 0;
|
||||
|
||||
virtual double getPixelScale() const = 0;
|
||||
|
||||
virtual const void *getHandle() const = 0;
|
||||
|
||||
//virtual static Window *createSingleton() = 0;
|
||||
//virtual static Window *getSingleton() = 0;
|
||||
// No virtual statics, of course, but you are supposed to implement these statics.
|
||||
|
||||
static bool getConstant(const char *in, Attribute &out);
|
||||
static bool getConstant(Attribute in, const char *&out);
|
||||
static bool getConstant(const char *in, Setting &out);
|
||||
static bool getConstant(Setting in, const char *&out);
|
||||
|
||||
static bool getConstant(const char *in, FullscreenType &out);
|
||||
static bool getConstant(FullscreenType in, const char *&out);
|
||||
@@ -131,17 +134,18 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<Attribute, ATTRIB_MAX_ENUM>::Entry attributeEntries[];
|
||||
static StringMap<Attribute, ATTRIB_MAX_ENUM> attributes;
|
||||
static StringMap<Setting, SETTING_MAX_ENUM>::Entry settingEntries[];
|
||||
static StringMap<Setting, SETTING_MAX_ENUM> settings;
|
||||
|
||||
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM>::Entry fullscreenTypeEntries[];
|
||||
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM> fullscreenTypes;
|
||||
|
||||
}; // Window
|
||||
|
||||
struct WindowAttributes
|
||||
struct WindowSettings
|
||||
{
|
||||
WindowAttributes();
|
||||
WindowSettings();
|
||||
|
||||
bool fullscreen; // = false
|
||||
Window::FullscreenType fstype; // = FULLSCREEN_TYPE_NORMAL
|
||||
bool vsync; // = true
|
||||
@@ -152,7 +156,9 @@ struct WindowAttributes
|
||||
bool borderless; // = false
|
||||
bool centered; // = true
|
||||
int display; // = 0
|
||||
}; // WindowFlags
|
||||
bool highdpi; // false
|
||||
|
||||
}; // WindowSettings
|
||||
|
||||
} // window
|
||||
} // love
|
||||
|
||||
@@ -63,21 +63,21 @@ Window::~Window()
|
||||
Window::_currentMode::_currentMode()
|
||||
: width(800)
|
||||
, height(600)
|
||||
, attribs()
|
||||
, settings()
|
||||
, icon(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
{
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
if (gfx)
|
||||
if (gfx != nullptr)
|
||||
gfx->unSetMode();
|
||||
|
||||
WindowAttributes f;
|
||||
WindowSettings f;
|
||||
|
||||
if (attribs)
|
||||
f = *attribs;
|
||||
if (settings)
|
||||
f = *settings;
|
||||
|
||||
f.minwidth = std::max(f.minwidth, 1);
|
||||
f.minheight = std::max(f.minheight, 1);
|
||||
@@ -116,15 +116,28 @@ bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
if (f.borderless)
|
||||
sdlflags |= SDL_WINDOW_BORDERLESS;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
if (f.highdpi)
|
||||
sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#endif
|
||||
|
||||
// Destroy and recreate the window if the dimensions or flags have changed.
|
||||
if (window)
|
||||
{
|
||||
int curdisplay = SDL_GetWindowDisplayIndex(window);
|
||||
Uint32 wflags = SDL_GetWindowFlags(window);
|
||||
wflags &= (SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS);
|
||||
|
||||
Uint32 testflags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP
|
||||
| SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
testflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#endif
|
||||
|
||||
wflags &= testflags;
|
||||
|
||||
if (sdlflags != wflags || width != curMode.width || height != curMode.height
|
||||
|| f.display != curdisplay || f.fsaa != curMode.attribs.fsaa)
|
||||
|| f.display != curdisplay || f.fsaa != curMode.settings.fsaa)
|
||||
{
|
||||
SDL_DestroyWindow(window);
|
||||
window = 0;
|
||||
@@ -182,10 +195,19 @@ bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
|
||||
created = true;
|
||||
|
||||
updateAttributes(f);
|
||||
updateSettings(f);
|
||||
|
||||
if (gfx)
|
||||
gfx->setMode(curMode.width, curMode.height);
|
||||
if (gfx != nullptr)
|
||||
{
|
||||
int width = curMode.width;
|
||||
int height = curMode.height;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
SDL_GL_GetDrawableSize(window, &width, &height);
|
||||
#endif
|
||||
|
||||
gfx->setMode(width, height);
|
||||
}
|
||||
|
||||
// Make sure the mouse keeps its previous grab setting.
|
||||
setMouseGrab(mouseGrabbed);
|
||||
@@ -250,8 +272,8 @@ bool Window::setContext(int fsaa, bool vsync)
|
||||
fsaa = (buffers > 0) ? samples : 0;
|
||||
}
|
||||
|
||||
curMode.attribs.fsaa = fsaa;
|
||||
curMode.attribs.vsync = SDL_GL_GetSwapInterval() != 0;
|
||||
curMode.settings.fsaa = fsaa;
|
||||
curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -271,7 +293,7 @@ void Window::setWindowGLAttributes(int fsaa) const
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
||||
}
|
||||
|
||||
void Window::updateAttributes(const WindowAttributes &newattribs)
|
||||
void Window::updateSettings(const WindowSettings &newsettings)
|
||||
{
|
||||
Uint32 wflags = SDL_GetWindowFlags(window);
|
||||
|
||||
@@ -280,54 +302,60 @@ void Window::updateAttributes(const WindowAttributes &newattribs)
|
||||
|
||||
if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
curMode.attribs.fullscreen = true;
|
||||
curMode.attribs.fstype = FULLSCREEN_TYPE_DESKTOP;
|
||||
curMode.settings.fullscreen = true;
|
||||
curMode.settings.fstype = FULLSCREEN_TYPE_DESKTOP;
|
||||
}
|
||||
else if ((wflags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)
|
||||
{
|
||||
curMode.attribs.fullscreen = true;
|
||||
curMode.attribs.fstype = FULLSCREEN_TYPE_NORMAL;
|
||||
curMode.settings.fullscreen = true;
|
||||
curMode.settings.fstype = FULLSCREEN_TYPE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
curMode.attribs.fullscreen = false;
|
||||
curMode.attribs.fstype = newattribs.fstype;
|
||||
curMode.settings.fullscreen = false;
|
||||
curMode.settings.fstype = newsettings.fstype;
|
||||
}
|
||||
|
||||
// The min width/height is set to 0 internally in SDL when in fullscreen.
|
||||
if (curMode.attribs.fullscreen)
|
||||
if (curMode.settings.fullscreen)
|
||||
{
|
||||
curMode.attribs.minwidth = newattribs.minwidth;
|
||||
curMode.attribs.minheight = newattribs.minheight;
|
||||
curMode.settings.minwidth = newsettings.minwidth;
|
||||
curMode.settings.minheight = newsettings.minheight;
|
||||
}
|
||||
else
|
||||
SDL_GetWindowMinimumSize(window, &curMode.attribs.minwidth, &curMode.attribs.minheight);
|
||||
SDL_GetWindowMinimumSize(window, &curMode.settings.minwidth, &curMode.settings.minheight);
|
||||
|
||||
curMode.attribs.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
|
||||
curMode.attribs.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
|
||||
curMode.attribs.centered = newattribs.centered;
|
||||
curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
|
||||
curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
|
||||
curMode.settings.centered = newsettings.centered;
|
||||
curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
|
||||
#else
|
||||
curMode.settings.highdpi = false;
|
||||
#endif
|
||||
|
||||
// Only minimize on focus loss if the window is in exclusive-fullscreen
|
||||
// mode (mimics behaviour of SDL 2.0.2+).
|
||||
// In OS X we always disable this to prevent dock minimization weirdness.
|
||||
#ifndef LOVE_MACOSX
|
||||
if (curMode.attribs.fullscreen && curMode.attribs.fstype == FULLSCREEN_TYPE_NORMAL)
|
||||
if (curMode.settings.fullscreen && curMode.settings.fstype == FULLSCREEN_TYPE_NORMAL)
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1");
|
||||
else
|
||||
#endif
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
}
|
||||
|
||||
void Window::getWindow(int &width, int &height, WindowAttributes &attribs)
|
||||
void Window::getWindow(int &width, int &height, WindowSettings &settings)
|
||||
{
|
||||
// Window position may be different from creation - update display index.
|
||||
if (window)
|
||||
curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
|
||||
width = curMode.width;
|
||||
height = curMode.height;
|
||||
attribs = curMode.attribs;
|
||||
settings = curMode.settings;
|
||||
}
|
||||
|
||||
bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
@@ -335,9 +363,9 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
WindowAttributes newattribs = curMode.attribs;
|
||||
newattribs.fullscreen = fullscreen;
|
||||
newattribs.fstype = fstype;
|
||||
WindowSettings newsettings = curMode.settings;
|
||||
newsettings.fullscreen = fullscreen;
|
||||
newsettings.fstype = fstype;
|
||||
|
||||
Uint32 sdlflags = 0;
|
||||
|
||||
@@ -361,12 +389,21 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
if (SDL_SetWindowFullscreen(window, sdlflags) == 0)
|
||||
{
|
||||
SDL_GL_MakeCurrent(window, context);
|
||||
updateAttributes(newattribs);
|
||||
updateSettings(newsettings);
|
||||
|
||||
// Update the viewport size now instead of waiting for event polling.
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
if (gfx)
|
||||
gfx->setViewportSize(curMode.width, curMode.height);
|
||||
if (gfx != nullptr)
|
||||
{
|
||||
int width = curMode.width;
|
||||
int height = curMode.height;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
SDL_GL_GetDrawableSize(window, &width, &height);
|
||||
#endif
|
||||
|
||||
gfx->setViewportSize(width, height);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -376,7 +413,7 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
|
||||
bool Window::setFullscreen(bool fullscreen)
|
||||
{
|
||||
return setFullscreen(fullscreen, curMode.attribs.fstype);
|
||||
return setFullscreen(fullscreen, curMode.settings.fstype);
|
||||
}
|
||||
|
||||
int Window::getDisplayCount() const
|
||||
@@ -559,6 +596,26 @@ bool Window::isMouseGrabbed() const
|
||||
return mouseGrabbed;
|
||||
}
|
||||
|
||||
double Window::getPixelScale() const
|
||||
{
|
||||
double scale = 1.0;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
if (window)
|
||||
{
|
||||
int wheight;
|
||||
SDL_GetWindowSize(window, nullptr, &wheight);
|
||||
|
||||
int dheight = wheight;
|
||||
SDL_GL_GetDrawableSize(window, nullptr, &dheight);
|
||||
|
||||
scale = (double) dheight / wheight;
|
||||
}
|
||||
#endif
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
const void *Window::getHandle() const
|
||||
{
|
||||
return window;
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
Window();
|
||||
~Window();
|
||||
|
||||
bool setWindow(int width = 800, int height = 600, WindowAttributes *attribs = 0);
|
||||
void getWindow(int &width, int &height, WindowAttributes &attribs);
|
||||
bool setWindow(int width = 800, int height = 600, WindowSettings *settings = nullptr);
|
||||
void getWindow(int &width, int &height, WindowSettings &settings);
|
||||
|
||||
bool setFullscreen(bool fullscreen, FullscreenType fstype);
|
||||
bool setFullscreen(bool fullscreen);
|
||||
@@ -79,6 +79,8 @@ public:
|
||||
void setMouseGrab(bool grab);
|
||||
bool isMouseGrabbed() const;
|
||||
|
||||
double getPixelScale() const;
|
||||
|
||||
const void *getHandle() const;
|
||||
|
||||
static love::window::Window *createSingleton();
|
||||
@@ -91,8 +93,8 @@ private:
|
||||
bool setContext(int fsaa, bool vsync);
|
||||
void setWindowGLAttributes(int fsaa) const;
|
||||
|
||||
// Update the saved window attribs based on the window's actual state.
|
||||
void updateAttributes(const WindowAttributes &newattribs);
|
||||
// Update the saved window settings based on the window's actual state.
|
||||
void updateSettings(const WindowSettings &newsettings);
|
||||
|
||||
std::string windowTitle;
|
||||
|
||||
@@ -102,7 +104,7 @@ private:
|
||||
|
||||
int width;
|
||||
int height;
|
||||
WindowAttributes attribs;
|
||||
WindowSettings settings;
|
||||
love::image::ImageData *icon;
|
||||
|
||||
} curMode;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace love
|
||||
namespace window
|
||||
{
|
||||
|
||||
static Window *instance = 0;
|
||||
static Window *instance = nullptr;
|
||||
|
||||
int w_getDisplayCount(lua_State *L)
|
||||
{
|
||||
@@ -34,10 +34,10 @@ int w_getDisplayCount(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *attribName(Window::Attribute attrib)
|
||||
static const char *settingName(Window::Setting setting)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
Window::getConstant(attrib, name);
|
||||
Window::getConstant(setting, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -62,91 +62,94 @@ int w_setMode(lua_State *L)
|
||||
return luax_typerror(L, -2, "string");
|
||||
|
||||
const char *key = luaL_checkstring(L, -2);
|
||||
Window::Attribute attrib;
|
||||
Window::Setting setting;
|
||||
|
||||
if (!Window::getConstant(key, attrib))
|
||||
return luaL_error(L, "Invalid window attribute: %s", key);
|
||||
if (!Window::getConstant(key, setting))
|
||||
return luaL_error(L, "Invalid window setting: %s", key);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
WindowAttributes attribs;
|
||||
WindowSettings settings;
|
||||
|
||||
lua_getfield(L, 3, attribName(Window::ATTRIB_FULLSCREEN_TYPE));
|
||||
lua_getfield(L, 3, settingName(Window::SETTING_FULLSCREEN_TYPE));
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
const char *typestr = luaL_checkstring(L, -1);
|
||||
|
||||
if (!Window::getConstant(typestr, attribs.fstype))
|
||||
if (!Window::getConstant(typestr, settings.fstype))
|
||||
return luaL_error(L, "Invalid fullscreen type: %s", typestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to "normal" fullscreen.
|
||||
attribs.fstype = Window::FULLSCREEN_TYPE_NORMAL;
|
||||
settings.fstype = Window::FULLSCREEN_TYPE_NORMAL;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
attribs.fullscreen = luax_boolflag(L, 3, attribName(Window::ATTRIB_FULLSCREEN), false);
|
||||
attribs.vsync = luax_boolflag(L, 3, attribName(Window::ATTRIB_VSYNC), true);
|
||||
attribs.fsaa = luax_intflag(L, 3, attribName(Window::ATTRIB_FSAA), 0);
|
||||
attribs.resizable = luax_boolflag(L, 3, attribName(Window::ATTRIB_RESIZABLE), false);
|
||||
attribs.minwidth = luax_intflag(L, 3, attribName(Window::ATTRIB_MIN_WIDTH), 1);
|
||||
attribs.minheight = luax_intflag(L, 3, attribName(Window::ATTRIB_MIN_HEIGHT), 1);
|
||||
attribs.borderless = luax_boolflag(L, 3, attribName(Window::ATTRIB_BORDERLESS), false);
|
||||
attribs.centered = luax_boolflag(L, 3, attribName(Window::ATTRIB_CENTERED), true);
|
||||
attribs.display = luax_intflag(L, 3, attribName(Window::ATTRIB_DISPLAY), 1);
|
||||
settings.fullscreen = luax_boolflag(L, 3, settingName(Window::SETTING_FULLSCREEN), false);
|
||||
settings.vsync = luax_boolflag(L, 3, settingName(Window::SETTING_VSYNC), true);
|
||||
settings.fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
|
||||
settings.resizable = luax_boolflag(L, 3, settingName(Window::SETTING_RESIZABLE), false);
|
||||
settings.minwidth = luax_intflag(L, 3, settingName(Window::SETTING_MIN_WIDTH), 1);
|
||||
settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
|
||||
settings.borderless = luax_boolflag(L, 3, settingName(Window::SETTING_BORDERLESS), false);
|
||||
settings.centered = luax_boolflag(L, 3, settingName(Window::SETTING_CENTERED), true);
|
||||
settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1);
|
||||
settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
|
||||
|
||||
// Display index is 1-based in Lua and 0-based internally.
|
||||
attribs.display--;
|
||||
settings.display--;
|
||||
|
||||
EXCEPT_GUARD(luax_pushboolean(L, instance->setWindow(w, h, &attribs));)
|
||||
EXCEPT_GUARD(luax_pushboolean(L, instance->setWindow(w, h, &settings));)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getMode(lua_State *L)
|
||||
{
|
||||
int w, h;
|
||||
WindowAttributes attribs;
|
||||
instance->getWindow(w, h, attribs);
|
||||
WindowSettings settings;
|
||||
instance->getWindow(w, h, settings);
|
||||
lua_pushnumber(L, w);
|
||||
lua_pushnumber(L, h);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
const char *fstypestr = "normal";
|
||||
Window::getConstant(attribs.fstype, fstypestr);
|
||||
Window::getConstant(settings.fstype, fstypestr);
|
||||
|
||||
lua_pushstring(L, fstypestr);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_FULLSCREEN_TYPE));
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_FULLSCREEN_TYPE));
|
||||
|
||||
luax_pushboolean(L, attribs.fullscreen);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_FULLSCREEN));
|
||||
luax_pushboolean(L, settings.fullscreen);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_FULLSCREEN));
|
||||
|
||||
luax_pushboolean(L, attribs.vsync);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_VSYNC));
|
||||
luax_pushboolean(L, settings.vsync);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_VSYNC));
|
||||
|
||||
lua_pushinteger(L, attribs.fsaa);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_FSAA));
|
||||
lua_pushinteger(L, settings.fsaa);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_FSAA));
|
||||
|
||||
luax_pushboolean(L, attribs.resizable);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_RESIZABLE));
|
||||
luax_pushboolean(L, settings.resizable);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_RESIZABLE));
|
||||
|
||||
lua_pushinteger(L, attribs.minwidth);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_MIN_WIDTH));
|
||||
lua_pushinteger(L, settings.minwidth);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_MIN_WIDTH));
|
||||
|
||||
lua_pushinteger(L, attribs.minheight);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_MIN_HEIGHT));
|
||||
lua_pushinteger(L, settings.minheight);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_MIN_HEIGHT));
|
||||
|
||||
luax_pushboolean(L, attribs.borderless);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_BORDERLESS));
|
||||
luax_pushboolean(L, settings.borderless);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_BORDERLESS));
|
||||
|
||||
luax_pushboolean(L, attribs.centered);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_CENTERED));
|
||||
luax_pushboolean(L, settings.centered);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_CENTERED));
|
||||
|
||||
// Display index is 0-based internally and 1-based in Lua.
|
||||
lua_pushinteger(L, attribs.display + 1);
|
||||
lua_setfield(L, -2, attribName(Window::ATTRIB_DISPLAY));
|
||||
lua_pushinteger(L, settings.display + 1);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_DISPLAY));
|
||||
|
||||
luax_pushboolean(L, settings.highdpi);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_HIGHDPI));
|
||||
|
||||
return 3;
|
||||
}
|
||||
@@ -202,14 +205,14 @@ int w_setFullscreen(lua_State *L)
|
||||
int w_getFullscreen(lua_State *L)
|
||||
{
|
||||
int w, h;
|
||||
WindowAttributes attribs;
|
||||
instance->getWindow(w, h, attribs);
|
||||
WindowSettings settings;
|
||||
instance->getWindow(w, h, settings);
|
||||
|
||||
const char *typestr;
|
||||
if (!Window::getConstant(attribs.fstype, typestr))
|
||||
if (!Window::getConstant(settings.fstype, typestr))
|
||||
luaL_error(L, "Unknown fullscreen type.");
|
||||
|
||||
luax_pushboolean(L, attribs.fullscreen);
|
||||
luax_pushboolean(L, settings.fullscreen);
|
||||
lua_pushstring(L, typestr);
|
||||
return 2;
|
||||
}
|
||||
@@ -300,6 +303,12 @@ int w_isVisible(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getPixelScale(lua_State *L)
|
||||
{
|
||||
lua_pushnumber(L, instance->getPixelScale());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] =
|
||||
{
|
||||
{ "getDisplayCount", w_getDisplayCount },
|
||||
@@ -320,6 +329,7 @@ static const luaL_Reg functions[] =
|
||||
{ "hasFocus", w_hasFocus },
|
||||
{ "hasMouseFocus", w_hasMouseFocus },
|
||||
{ "isVisible", w_isVisible },
|
||||
{ "getPixelScale", w_getPixelScale },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ int w_getTitle(lua_State *L);
|
||||
int w_hasFocus(lua_State *L);
|
||||
int w_hasMouseFocus(lua_State *L);
|
||||
int w_isVisible(lua_State *L);
|
||||
int w_getPixelScale(lua_State *L);
|
||||
extern "C" LOVE_EXPORT int luaopen_love_window(lua_State *L);
|
||||
|
||||
} // window
|
||||
|
||||
Reference in New Issue
Block a user