Browse Source

Add love.window.getDisplayOrientation and a love.displayrotated callback. Resolves issue #1441.

Note that this tracks screen orientation, rather than device orientation.
Alex Szpakowski 6 years ago
parent
commit
d4762b4612

+ 35 - 0
src/modules/event/sdl/Event.cpp

@@ -369,6 +369,41 @@ Message *Event::convert(const SDL_Event &e)
 	case SDL_WINDOWEVENT:
 		msg = convertWindowEvent(e);
 		break;
+#if SDL_VERSION_ATLEAST(2, 0, 9)
+	case SDL_DISPLAYEVENT:
+		if (e.display.event == SDL_DISPLAYEVENT_ORIENTATION)
+		{
+			auto orientation = window::Window::ORIENTATION_UNKNOWN;
+			switch ((SDL_DisplayOrientation) e.display.data1)
+			{
+			case SDL_ORIENTATION_UNKNOWN:
+			default:
+				orientation = window::Window::ORIENTATION_UNKNOWN;
+				break;
+			case SDL_ORIENTATION_LANDSCAPE:
+				orientation = window::Window::ORIENTATION_LANDSCAPE;
+				break;
+			case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
+				orientation = window::Window::ORIENTATION_LANDSCAPE_FLIPPED;
+				break;
+			case SDL_ORIENTATION_PORTRAIT:
+				orientation = window::Window::ORIENTATION_PORTRAIT;
+				break;
+			case SDL_ORIENTATION_PORTRAIT_FLIPPED:
+				orientation = window::Window::ORIENTATION_PORTRAIT_FLIPPED;
+				break;
+			}
+
+			if (!window::Window::getConstant(orientation, txt))
+				txt = "unknown";
+
+			vargs.emplace_back((double)(e.display.display + 1));
+			vargs.emplace_back(txt);
+
+			msg = new Message("displayrotated", vargs);
+		}
+		break;
+#endif
 	case SDL_DROPFILE:
 		filesystem = Module::getInstance<filesystem::Filesystem>(Module::M_FILESYSTEM);
 		if (filesystem != nullptr)

+ 26 - 0
src/modules/window/Window.cpp

@@ -74,6 +74,21 @@ std::vector<std::string> Window::getConstants(MessageBoxType)
 	return messageBoxTypes.getNames();
 }
 
+bool Window::getConstant(const char *in, DisplayOrientation &out)
+{
+	return orientations.find(in, out);
+}
+
+bool Window::getConstant(DisplayOrientation in, const char *&out)
+{
+	return orientations.find(in, out);
+}
+
+std::vector<std::string> Window::getConstants(DisplayOrientation)
+{
+	return orientations.getNames();
+}
+
 StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntries[] =
 {
 	{"fullscreen", SETTING_FULLSCREEN},
@@ -113,5 +128,16 @@ StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM>::Entry Window::me
 
 StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM> Window::messageBoxTypes(Window::messageBoxTypeEntries, sizeof(Window::messageBoxTypeEntries));
 
+StringMap<Window::DisplayOrientation, Window::ORIENTATION_MAX_ENUM>::Entry Window::orientationEntries[] =
+{
+	{"unknown", ORIENTATION_UNKNOWN},
+	{"landscape", ORIENTATION_LANDSCAPE},
+	{"landscapeflipped", ORIENTATION_LANDSCAPE_FLIPPED},
+	{"portrait", ORIENTATION_PORTRAIT},
+	{"portraitflipped", ORIENTATION_PORTRAIT_FLIPPED},
+};
+
+StringMap<Window::DisplayOrientation, Window::ORIENTATION_MAX_ENUM> Window::orientations(Window::orientationEntries, sizeof(Window::orientationEntries));
+
 } // window
 } // love

+ 19 - 0
src/modules/window/Window.h

@@ -86,6 +86,16 @@ public:
 		MESSAGEBOX_MAX_ENUM
 	};
 
+	enum DisplayOrientation
+	{
+		ORIENTATION_UNKNOWN,
+		ORIENTATION_LANDSCAPE,
+		ORIENTATION_LANDSCAPE_FLIPPED,
+		ORIENTATION_PORTRAIT,
+		ORIENTATION_PORTRAIT_FLIPPED,
+		ORIENTATION_MAX_ENUM
+	};
+
 	struct WindowSize
 	{
 		int width;
@@ -132,6 +142,8 @@ public:
 
 	virtual const char *getDisplayName(int displayindex) const = 0;
 
+	virtual DisplayOrientation getDisplayOrientation(int displayindex) const = 0;
+
 	virtual std::vector<WindowSize> getFullscreenSizes(int displayindex) const = 0;
 
 	virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0;
@@ -206,6 +218,10 @@ public:
 	static bool getConstant(MessageBoxType in, const char *&out);
 	static std::vector<std::string> getConstants(MessageBoxType);
 
+	static bool getConstant(const char *in, DisplayOrientation &out);
+	static bool getConstant(DisplayOrientation in, const char *&out);
+	static std::vector<std::string> getConstants(DisplayOrientation);
+
 private:
 
 	static StringMap<Setting, SETTING_MAX_ENUM>::Entry settingEntries[];
@@ -217,6 +233,9 @@ private:
 	static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM>::Entry messageBoxTypeEntries[];
 	static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM> messageBoxTypes;
 
+	static StringMap<DisplayOrientation, ORIENTATION_MAX_ENUM>::Entry orientationEntries[];
+	static StringMap<DisplayOrientation, ORIENTATION_MAX_ENUM> orientations;
+
 }; // Window
 
 struct WindowSettings

+ 20 - 0
src/modules/window/sdl/Window.cpp

@@ -743,6 +743,26 @@ const char *Window::getDisplayName(int displayindex) const
 	return name;
 }
 
+Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const
+{
+	// TODO: We can expose this everywhere, we just need to watch out for the
+	// SDL binary being older than the headers on Linux.
+#if SDL_VERSION_ATLEAST(2, 0, 9) && (defined(LOVE_ANDROID) || !defined(LOVE_LINUX))
+	switch (SDL_GetDisplayOrientation(displayindex))
+	{
+		case SDL_ORIENTATION_UNKNOWN: return ORIENTATION_UNKNOWN;
+		case SDL_ORIENTATION_LANDSCAPE: return ORIENTATION_LANDSCAPE;
+		case SDL_ORIENTATION_LANDSCAPE_FLIPPED: return ORIENTATION_LANDSCAPE_FLIPPED;
+		case SDL_ORIENTATION_PORTRAIT: return ORIENTATION_PORTRAIT;
+		case SDL_ORIENTATION_PORTRAIT_FLIPPED: return ORIENTATION_PORTRAIT_FLIPPED;
+	}
+#else
+	LOVE_UNUSED(displayindex);
+#endif
+
+	return ORIENTATION_UNKNOWN;
+}
+
 std::vector<Window::WindowSize> Window::getFullscreenSizes(int displayindex) const
 {
 	std::vector<WindowSize> sizes;

+ 2 - 0
src/modules/window/sdl/Window.h

@@ -57,6 +57,8 @@ public:
 
 	const char *getDisplayName(int displayindex) const override;
 
+	DisplayOrientation getDisplayOrientation(int displayindex) const override;
+
 	std::vector<WindowSize> getFullscreenSizes(int displayindex) const override;
 
 	void getDesktopDimensions(int displayindex, int &width, int &height) const override;

+ 20 - 0
src/modules/window/wrap_Window.cpp

@@ -215,6 +215,25 @@ int w_getMode(lua_State *L)
 	return 3;
 }
 
+int w_getDisplayOrientation(lua_State *L)
+{
+	int displayindex = 0;
+	if (!lua_isnoneornil(L, 1))
+		displayindex = (int) luaL_checkinteger(L, 1) - 1;
+	else
+	{
+		int x, y;
+		instance()->getPosition(x, y, displayindex);
+	}
+
+	const char *orientationstr = nullptr;
+	if (!Window::getConstant(instance()->getDisplayOrientation(displayindex), orientationstr))
+		return luaL_error(L, "Unknown display orientation type.");
+
+	lua_pushstring(L, orientationstr);
+	return 1;
+}
+
 int w_getFullscreenModes(lua_State *L)
 {
 	int displayindex = 0;
@@ -562,6 +581,7 @@ static const luaL_Reg functions[] =
 	{ "setMode", w_setMode },
 	{ "updateMode", w_updateMode },
 	{ "getMode", w_getMode },
+	{ "getDisplayOrientation", w_getDisplayOrientation },
 	{ "getFullscreenModes", w_getFullscreenModes },
 	{ "setFullscreen", w_setFullscreen },
 	{ "getFullscreen", w_getFullscreen },

+ 3 - 0
src/scripts/boot.lua

@@ -272,6 +272,9 @@ function love.createhandlers()
 			collectgarbage()
 			collectgarbage()
 		end,
+		displayrotated = function (display, orient)
+			if love.displayrotated then return love.displayrotated(display, orient) end
+		end,
 	}, {
 		__index = function(self, name)
 			error("Unknown event: " .. name)

+ 9 - 0
src/scripts/boot.lua.h

@@ -514,6 +514,15 @@ const unsigned char boot_lua[] =
 	0x09, 0x09, 0x09, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65, 0x28, 
 	0x29, 0x0a,
 	0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
+	0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x20, 0x3d, 
+	0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 
+	0x2c, 0x20, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 
+	0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 
+	0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x6f, 0x74, 0x61, 
+	0x74, 0x65, 0x64, 0x28, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x65, 0x6e, 
+	0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
 	0x09, 0x7d, 0x2c, 0x20, 0x7b, 0x0a,
 	0x09, 0x09, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 
 	0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a,