From 5175b0d1b599ea4c7b929f6b4282dd379fa116b8 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 17 Apr 2022 11:26:06 -0300 Subject: [PATCH 01/10] Windows: fix some cases of stuttering in windowed mode. Use DwmFlush instead of OpenGL vsync, when specific conditions are met. Fixes #1628. --- CMakeLists.txt | 1 + src/modules/window/sdl/Window.cpp | 52 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4ccb5409..3d6dbeab4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1755,6 +1755,7 @@ if(MSVC) set(LOVE_LINK_LIBRARIES ${LOVE_LINK_LIBRARIES} ws2_32.lib winmm.lib + dwmapi.lib ) set(LOVE_RC diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 798b606ed..bc2d0c2e2 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -44,6 +44,8 @@ #if defined(LOVE_WINDOWS) #include +#include +#include #elif defined(LOVE_MACOSX) #include "common/macosx.h" #endif @@ -1015,7 +1017,57 @@ bool Window::isMinimized() const void Window::swapBuffers() { +#ifdef LOVE_WINDOWS + bool useDwmFlush = false; + int swapInterval = getVSync(); + + // https://github.com/love2d/love/issues/1628 + // VSync can interact badly with Windows desktop composition (DWM) in windowed mode. DwmFlush can be used instead + // of vsync, but it's much less flexible so we're very conservative here with where it's used: + // - It won't work with exclusive or desktop fullscreen. + // - DWM refreshes don't always match the refresh rate of the monitor the window is in (or the requested swap + // interval), so we only use it when they do match. + // - The user may force GL vsync, and DwmFlush shouldn't be used together with GL vsync. + if (context != nullptr && !settings.fullscreen && swapInterval == 1) + { + // Desktop composition is always enabled in Windows 8+. But DwmIsCompositionEnabled won't always return true... + // (see DwmIsCompositionEnabled docs). + BOOL compositionEnabled = IsWindows8OrGreater(); + if (compositionEnabled || (SUCCEEDED(DwmIsCompositionEnabled(&compositionEnabled)) && compositionEnabled)) + { + DWM_TIMING_INFO info = {}; + info.cbSize = sizeof(DWM_TIMING_INFO); + double dwmRefreshRate = 0; + if (SUCCEEDED(DwmGetCompositionTimingInfo(nullptr, &info))) + dwmRefreshRate = (double)info.rateRefresh.uiNumerator / (double)info.rateRefresh.uiDenominator; + + SDL_DisplayMode dmode = {}; + int displayindex = SDL_GetWindowDisplayIndex(window); + + if (displayindex >= 0) + SDL_GetCurrentDisplayMode(displayindex, &dmode); + + if (dmode.refresh_rate > 0 && dwmRefreshRate > 0 && (fabs(dmode.refresh_rate - dwmRefreshRate) < 2)) + { + SDL_GL_SetSwapInterval(0); + if (SDL_GL_GetSwapInterval() == 0) + useDwmFlush = true; + else + SDL_GL_SetSwapInterval(swapInterval); + } + } + } +#endif + SDL_GL_SwapWindow(window); + +#ifdef LOVE_WINDOWS + if (useDwmFlush) + { + DwmFlush(); + SDL_GL_SetSwapInterval(swapInterval); + } +#endif } bool Window::hasFocus() const From 131b53d7957bc53e7a047b98a4f61b1f702b7e15 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 18 Jun 2022 17:15:20 -0300 Subject: [PATCH 02/10] Fix typo in Metal code for shader switching. --- src/modules/graphics/metal/Graphics.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index a12b2cc5f..0ceffda5e 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -527,7 +527,7 @@ void Graphics::setActive(bool enable) void Graphics::setShaderChanged() { - dirtyRenderState |= STATE_SHADER; + dirtyRenderState |= STATEBIT_SHADER; ++shaderSwitches; } From 69c4a496ddb45297209e0080984e95e7f33a5bf6 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 18 Jun 2022 17:59:55 -0300 Subject: [PATCH 03/10] Fix a few minor compiler warnings --- src/common/Stream.cpp | 2 +- src/modules/audio/openal/Pool.cpp | 2 +- src/modules/data/DataStream.cpp | 14 +++++++------- src/modules/system/sdl/System.h | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/common/Stream.cpp b/src/common/Stream.cpp index 01d4c593d..f8e13f540 100644 --- a/src/common/Stream.cpp +++ b/src/common/Stream.cpp @@ -69,7 +69,7 @@ bool Stream::write(Data *src) bool Stream::write(Data *src, int64 offset, int64 size) { - if (offset < 0 || size < 0 || offset + size > src->getSize()) + if (offset < 0 || size < 0 || offset + size > (int64) src->getSize()) throw love::Exception("Offset and size parameters do not fit within the given Data's size."); return write((const uint8 *) src->getData() + offset, size); diff --git a/src/modules/audio/openal/Pool.cpp b/src/modules/audio/openal/Pool.cpp index 667cf67b4..276bde1cf 100644 --- a/src/modules/audio/openal/Pool.cpp +++ b/src/modules/audio/openal/Pool.cpp @@ -34,7 +34,7 @@ static Variant::SharedTable *putSourcesAsSharedTable(std::vectorpairs.emplace_back((double) (i + 1), Variant(&Source::type, sources[i])); return table; diff --git a/src/modules/data/DataStream.cpp b/src/modules/data/DataStream.cpp index 54962845b..a9c6bfa1f 100644 --- a/src/modules/data/DataStream.cpp +++ b/src/modules/data/DataStream.cpp @@ -34,19 +34,19 @@ love::Type DataStream::type("DataStream", &Stream::type); DataStream::DataStream(Data *data) : data(data) - , offset(0) - , size(data->getSize()) , memory((const uint8 *) data->getData()) , writableMemory((uint8 *) data->getData()) // TODO: disallow writing sometimes? + , offset(0) + , size(data->getSize()) { } DataStream::DataStream(const DataStream &other) : data(other.data) - , offset(0) - , size(other.size) , memory(other.memory) , writableMemory(other.writableMemory) + , offset(0) + , size(other.size) { } @@ -79,7 +79,7 @@ int64 DataStream::read(void* data, int64 size) if (size <= 0) return 0; - if (offset >= getSize()) + if ((int64) offset >= getSize()) return 0; int64 readsize = std::min(size, getSize() - offset); @@ -95,7 +95,7 @@ bool DataStream::write(const void* data, int64 size) if (size <= 0 || writableMemory == nullptr) return false; - if (offset >= getSize()) + if ((int64) offset >= getSize()) return false; int64 writesize = std::min(size, getSize() - offset); @@ -123,7 +123,7 @@ bool DataStream::seek(int64 pos, SeekOrigin origin) else if (origin == SEEKORIGIN_END) pos += size; - if (pos < 0 || pos > size) + if (pos < 0 || pos > (int64) size) return false; offset = pos; diff --git a/src/modules/system/sdl/System.h b/src/modules/system/sdl/System.h index 0f0258dd4..167b115e0 100644 --- a/src/modules/system/sdl/System.h +++ b/src/modules/system/sdl/System.h @@ -43,14 +43,14 @@ public: virtual ~System() {} // Implements Module. - const char *getName() const; + const char *getName() const override; - int getProcessorCount() const; + int getProcessorCount() const override; - void setClipboardText(const std::string &text) const; - std::string getClipboardText() const; + void setClipboardText(const std::string &text) const override; + std::string getClipboardText() const override; - PowerState getPowerInfo(int &seconds, int &percent) const; + PowerState getPowerInfo(int &seconds, int &percent) const override; std::vector getPreferredLocales() const override; private: From 814aaa95cdaa05c0f70b66ec2af51565943e0bf3 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 18 Jun 2022 18:09:58 -0300 Subject: [PATCH 04/10] Fix compilation on Windows --- src/modules/window/sdl/Window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index b758de5ef..0666216a0 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -1190,7 +1190,7 @@ void Window::swapBuffers() // - DWM refreshes don't always match the refresh rate of the monitor the window is in (or the requested swap // interval), so we only use it when they do match. // - The user may force GL vsync, and DwmFlush shouldn't be used together with GL vsync. - if (context != nullptr && !settings.fullscreen && swapInterval == 1) + if (!settings.fullscreen && swapInterval == 1) { // Desktop composition is always enabled in Windows 8+. But DwmIsCompositionEnabled won't always return true... // (see DwmIsCompositionEnabled docs). From d586d1847446f5212d5f7e9efb94e50fcfba7d77 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 3 Jul 2022 17:03:58 -0300 Subject: [PATCH 05/10] Properly use SDL's new Windows dpi scaling hint. Fixes #1814. Fixes #1421. --- src/modules/window/Window.cpp | 5 +++++ src/modules/window/sdl/Window.cpp | 23 +++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index c2a69df2d..e310c3251 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -28,8 +28,13 @@ namespace window static bool highDPIAllowed = false; +// TODO: find a cleaner way to do this... +// The window backend (e.g. love.window.sdl) is expected to implement this. +void setHighDPIAllowedImplementation(bool enable); + void setHighDPIAllowed(bool enable) { + setHighDPIAllowedImplementation(enable); highDPIAllowed = enable; } diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 0666216a0..fd66a7d77 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -54,10 +54,27 @@ #define APIENTRY #endif +#ifndef SDL_HINT_WINDOWS_DPI_SCALING +#define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING" +#endif + namespace love { namespace window { + +// See src/modules/window/Window.cpp. +void setHighDPIAllowedImplementation(bool enable) +{ +#if defined(LOVE_WINDOWS) + // Windows uses a different API than SDL_WINDOW_ALLOW_HIGHDPI. + // This must be set before the video subsystem is initialized. + SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, enable ? "1" : "0"); +#else + LOVE_UNUSED(enable); +#endif +} + namespace sdl { @@ -73,12 +90,6 @@ Window::Window() , hasSDL203orEarlier(false) , contextAttribs() { - // Windows uses a different API than SDL_WINDOW_ALLOW_HIGHDPI. -#if defined(LOVE_WINDOWS) && defined(SDL_HINT_WINDOWS_DPI_SCALING) - // This must be set before the video subsystem is initialized. - SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, isHighDPIAllowed() ? "1" : "0"); -#endif - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) throw love::Exception("Could not initialize SDL video subsystem (%s)", SDL_GetError()); From 258d2334affed2773ae768e8f2ae24309b83ca91 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 9 Jul 2022 09:00:58 -0300 Subject: [PATCH 06/10] OpenGL: Fix missing 'keep' and 'zero' stencil action implementations. Fixes #1818 --- src/modules/graphics/opengl/Graphics.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 83732f8a1..18c2daf5a 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1414,12 +1414,17 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val if (enablestencil != gl.isStateEnabled(OpenGL::ENABLE_STENCIL_TEST)) gl.setEnableState(OpenGL::ENABLE_STENCIL_TEST, enablestencil); - GLenum glaction = GL_REPLACE; + GLenum glaction = GL_KEEP; switch (action) { + case STENCIL_KEEP: + glaction = GL_KEEP; + break; + case STENCIL_ZERO: + glaction = GL_ZERO; + break; case STENCIL_REPLACE: - default: glaction = GL_REPLACE; break; case STENCIL_INCREMENT: @@ -1437,6 +1442,9 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val case STENCIL_INVERT: glaction = GL_INVERT; break; + case STENCIL_MAX_ENUM: + glaction = GL_KEEP; + break; } /** From a77acef3583adfb9dba6ac6c581bffb4301a2ac6 Mon Sep 17 00:00:00 2001 From: Er2 Date: Sun, 10 Jul 2022 15:26:12 +0300 Subject: [PATCH 07/10] Fix compilation error on old SDL2 library. --- .gitignore | 10 ++++++++++ src/modules/system/sdl/System.cpp | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index af672d1b0..77655ee34 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,13 @@ +# automake products +/config.h +/config.h.in +/config.log +/config.status +/configure +/configure-modules-post.ac +/configure-modules-pre.ac +/configure.ac + /extra/reshax/Release/ /extra/reshax/Debug/ /extra/reshax/resources.h diff --git a/src/modules/system/sdl/System.cpp b/src/modules/system/sdl/System.cpp index df0c476cf..537830903 100644 --- a/src/modules/system/sdl/System.cpp +++ b/src/modules/system/sdl/System.cpp @@ -25,9 +25,12 @@ // SDL #include #include -#include #include +#if SDL_VERSION_ATLEAST(2, 0, 14) +#include +#endif + namespace love { namespace system From a2eaed33ebf42d05683863a0ae3f09dab6ad7585 Mon Sep 17 00:00:00 2001 From: slime Date: Fri, 22 Jul 2022 22:42:35 -0300 Subject: [PATCH 08/10] Update lua-https to latest source. Adds new methods. The newly supported methods are HEAD, PUT, DELETE, and PATCH. --- .../luahttps/src/android/AndroidClient.cpp | 8 ++++- .../java/org/love2d/luahttps/LuaHTTPS.java | 23 +++++++++++-- .../luahttps/src/apple/NSURLClient.mm | 12 +++---- .../luahttps/src/common/HTTPRequest.cpp | 14 +++++--- .../luahttps/src/common/HTTPSClient.cpp | 2 +- .../luahttps/src/common/HTTPSClient.h | 7 +--- .../luahttps/src/generic/CurlClient.cpp | 10 ++++-- src/libraries/luahttps/src/lua/main.cpp | 33 ++++++++++++------- .../src/windows/SChannelConnection.cpp | 8 +++-- 9 files changed, 80 insertions(+), 37 deletions(-) diff --git a/src/libraries/luahttps/src/android/AndroidClient.cpp b/src/libraries/luahttps/src/android/AndroidClient.cpp index 2b5b4d7d6..24cbb1d0e 100644 --- a/src/libraries/luahttps/src/android/AndroidClient.cpp +++ b/src/libraries/luahttps/src/android/AndroidClient.cpp @@ -97,6 +97,7 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req) jmethodID constructor = env->GetMethodID(httpsClass, "", "()V"); jmethodID setURL = env->GetMethodID(httpsClass, "setUrl", "(Ljava/lang/String;)V"); + jmethodID setMethod = env->GetMethodID(httpsClass, "setMethod", "(Ljava/lang/String;)V"); jmethodID request = env->GetMethodID(httpsClass, "request", "()Z"); jmethodID getInterleavedHeaders = env->GetMethodID(httpsClass, "getInterleavedHeaders", "()[Ljava/lang/String;"); jmethodID getResponse = env->GetMethodID(httpsClass, "getResponse", "()[B"); @@ -109,8 +110,13 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req) env->CallVoidMethod(httpsObject, setURL, url); env->DeleteLocalRef(url); + // Set method + jstring method = env->NewStringUTF(req.method.c_str()); + env->CallVoidMethod(httpsObject, setMethod, method); + env->DeleteLocalRef(method); + // Set post data - if (req.method == Request::POST) + if (req.postdata.size() > 0) { jmethodID setPostData = env->GetMethodID(httpsClass, "setPostData", "([B)V"); jbyteArray byteArray = env->NewByteArray((jsize) req.postdata.length()); diff --git a/src/libraries/luahttps/src/android/java/org/love2d/luahttps/LuaHTTPS.java b/src/libraries/luahttps/src/android/java/org/love2d/luahttps/LuaHTTPS.java index 0c9982580..986a51360 100644 --- a/src/libraries/luahttps/src/android/java/org/love2d/luahttps/LuaHTTPS.java +++ b/src/libraries/luahttps/src/android/java/org/love2d/luahttps/LuaHTTPS.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.ProtocolException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -22,6 +23,7 @@ class LuaHTTPS { static private String TAG = "LuaHTTPS"; private String urlString; + private String method; private byte[] postData; private byte[] response; private int responseCode; @@ -34,6 +36,7 @@ class LuaHTTPS { public void reset() { urlString = null; + method = "GET"; postData = null; response = null; responseCode = 0; @@ -50,6 +53,11 @@ class LuaHTTPS { this.postData = postData; } + @Keep + public void setMethod(String method) { + this.method = method.toUpperCase(); + } + @Keep public void addHeader(String key, String value) { headers.put(key, value); @@ -110,15 +118,22 @@ class LuaHTTPS { return false; } + // Set request method + try { + connection.setRequestMethod(method); + } catch (ProtocolException e) { + Log.e(TAG, "Error", e); + return false; + } + // Set header for (Map.Entry headerData: headers.entrySet()) { connection.setRequestProperty(headerData.getKey(), headerData.getValue()); } // Set post data - if (postData != null) { + if (postData != null && canSendData()) { connection.setDoOutput(true); - connection.setChunkedStreamingMode(0); try { OutputStream out = connection.getOutputStream(); @@ -168,4 +183,8 @@ class LuaHTTPS { connection.disconnect(); return true; } + + private boolean canSendData() { + return !method.equals("GET") && !method.equals("HEAD"); + } } diff --git a/src/libraries/luahttps/src/apple/NSURLClient.mm b/src/libraries/luahttps/src/apple/NSURLClient.mm index cc1e3a4ea..2708f8ea1 100644 --- a/src/libraries/luahttps/src/apple/NSURLClient.mm +++ b/src/libraries/luahttps/src/apple/NSURLClient.mm @@ -29,16 +29,12 @@ HTTPSClient::Reply NSURLClient::request(const HTTPSClient::Request &req) NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSData *bodydata = nil; - switch(req.method) + [request setHTTPMethod:@(req.method.c_str())]; + + if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD")) { - case Request::GET: - [request setHTTPMethod:@"GET"]; - break; - case Request::POST: bodydata = [NSData dataWithBytesNoCopy:(void*) req.postdata.data() length:req.postdata.size() freeWhenDone:NO]; - [request setHTTPMethod:@"POST"]; [request setHTTPBody:bodydata]; - break; } for (auto &header : req.headers) @@ -63,7 +59,7 @@ HTTPSClient::Reply NSURLClient::request(const HTTPSClient::Request &req) dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); HTTPSClient::Reply reply; - reply.responseCode = 400; + reply.responseCode = 0; if (body) { diff --git a/src/libraries/luahttps/src/common/HTTPRequest.cpp b/src/libraries/luahttps/src/common/HTTPRequest.cpp index bdb03c161..a8c3fbab1 100644 --- a/src/libraries/luahttps/src/common/HTTPRequest.cpp +++ b/src/libraries/luahttps/src/common/HTTPRequest.cpp @@ -35,7 +35,13 @@ HTTPSClient::Reply HTTPRequest::request(const HTTPSClient::Request &req) // Build the request { std::stringstream request; - request << (req.method == HTTPSClient::Request::GET ? "GET " : "POST ") << info.query << " HTTP/1.1\r\n"; + std::string method = req.method; + bool hasData = req.postdata.length() > 0; + + if (method.length() == 0) + method = hasData ? "POST" : "GET"; + + request << method << " " << info.query << " HTTP/1.1\r\n"; for (auto &header : req.headers) request << header.first << ": " << header.second << "\r\n"; @@ -44,15 +50,15 @@ HTTPSClient::Reply HTTPRequest::request(const HTTPSClient::Request &req) request << "Host: " << info.hostname << "\r\n"; - if (req.method == HTTPSClient::Request::POST && req.headers.count("Content-Type") == 0) + if (hasData && req.headers.count("Content-Type") == 0) request << "Content-Type: application/x-www-form-urlencoded\r\n"; - if (req.method == HTTPSClient::Request::POST) + if (hasData) request << "Content-Length: " << req.postdata.size() << "\r\n"; request << "\r\n"; - if (req.method == HTTPSClient::Request::POST) + if (hasData) request << req.postdata; // Send it diff --git a/src/libraries/luahttps/src/common/HTTPSClient.cpp b/src/libraries/luahttps/src/common/HTTPSClient.cpp index 09f2204d8..6e32ea533 100644 --- a/src/libraries/luahttps/src/common/HTTPSClient.cpp +++ b/src/libraries/luahttps/src/common/HTTPSClient.cpp @@ -31,7 +31,7 @@ bool HTTPSClient::ci_string_less::operator()(const std::string &lhs, const std:: HTTPSClient::Request::Request(const std::string &url) : url(url) - , method(GET) + , method("") { } diff --git a/src/libraries/luahttps/src/common/HTTPSClient.h b/src/libraries/luahttps/src/common/HTTPSClient.h index b20b33a86..8b2b23d88 100644 --- a/src/libraries/luahttps/src/common/HTTPSClient.h +++ b/src/libraries/luahttps/src/common/HTTPSClient.h @@ -20,12 +20,7 @@ public: header_map headers; std::string url; std::string postdata; - - enum Method - { - GET, - POST, - } method; + std::string method; }; struct Reply diff --git a/src/libraries/luahttps/src/generic/CurlClient.cpp b/src/libraries/luahttps/src/generic/CurlClient.cpp index 31c62c2d3..451db4b58 100644 --- a/src/libraries/luahttps/src/generic/CurlClient.cpp +++ b/src/libraries/luahttps/src/generic/CurlClient.cpp @@ -73,9 +73,15 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req) curl.easy_setopt(handle, CURLOPT_URL, req.url.c_str()); curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); - if (req.method == Request::POST) - { + if (req.method == "PUT") + curl.easy_setopt(handle, CURLOPT_PUT, 1L); + else if (req.method == "POST") curl.easy_setopt(handle, CURLOPT_POST, 1L); + else + curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, req.method.c_str()); + + if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD")) + { curl.easy_setopt(handle, CURLOPT_POSTFIELDS, req.postdata.c_str()); curl.easy_setopt(handle, CURLOPT_POSTFIELDSIZE, req.postdata.size()); } diff --git a/src/libraries/luahttps/src/lua/main.cpp b/src/libraries/luahttps/src/lua/main.cpp index d4304b86a..a2d843dbd 100644 --- a/src/libraries/luahttps/src/lua/main.cpp +++ b/src/libraries/luahttps/src/lua/main.cpp @@ -1,3 +1,6 @@ +#include +#include + extern "C" { #include @@ -7,6 +10,14 @@ extern "C" #include "../common/HTTPS.h" #include "../common/config.h" +static std::string validMethod[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}; + +static int str_toupper(char c) +{ + unsigned char uc = (unsigned char) c; + return toupper(uc); +} + static std::string w_checkstring(lua_State *L, int idx) { size_t len; @@ -34,20 +45,20 @@ static void w_readheaders(lua_State *L, int idx, HTTPSClient::header_map &header lua_pop(L, 1); } -static HTTPSClient::Request::Method w_optmethod(lua_State *L, int idx, HTTPSClient::Request::Method defaultMethod) +static std::string w_optmethod(lua_State *L, int idx, const std::string &defaultMethod) { + std::string *const validMethodEnd = validMethod + sizeof(validMethod) / sizeof(std::string); + if (lua_isnoneornil(L, idx)) return defaultMethod; - auto str = w_checkstring(L, idx); - if (str == "get") - return HTTPSClient::Request::GET; - else if (str == "post") - return HTTPSClient::Request::POST; - else - luaL_argerror(L, idx, "expected one of \"get\" or \"set\""); + std::string str = w_checkstring(L, idx); + std::transform(str.begin(), str.end(), str.begin(), str_toupper); - return defaultMethod; + if (std::find(validMethod, validMethodEnd, str) == validMethodEnd) + luaL_argerror(L, idx, "expected one of \"get\", \"head\", \"post\", \"put\", \"delete\", or \"patch\""); + + return str; } static int w_request(lua_State *L) @@ -61,13 +72,13 @@ static int w_request(lua_State *L) { advanced = true; - HTTPSClient::Request::Method defaultMethod = HTTPSClient::Request::GET; + std::string defaultMethod = "GET"; lua_getfield(L, 2, "data"); if (!lua_isnoneornil(L, -1)) { req.postdata = w_checkstring(L, -1); - defaultMethod = HTTPSClient::Request::POST; + defaultMethod = "POST"; } lua_pop(L, 1); diff --git a/src/libraries/luahttps/src/windows/SChannelConnection.cpp b/src/libraries/luahttps/src/windows/SChannelConnection.cpp index 36e289a18..2d334c0b2 100644 --- a/src/libraries/luahttps/src/windows/SChannelConnection.cpp +++ b/src/libraries/luahttps/src/windows/SChannelConnection.cpp @@ -55,8 +55,12 @@ static size_t dequeue(std::vector &buffer, char *data, size_t size) size_t remaining = buffer.size() - size; memcpy(data, &buffer[0], size); - memmove(&buffer[0], &buffer[size], remaining); - buffer.resize(remaining); + + if (remaining > 0) + { + memmove(&buffer[0], &buffer[size], remaining); + buffer.resize(remaining); + } return size; } From 870021b8bd15a7e0303f445aabb8884677e48369 Mon Sep 17 00:00:00 2001 From: slime Date: Sun, 24 Jul 2022 16:23:56 -0300 Subject: [PATCH 09/10] Potentially fix a crash when calling Text:add(""). #1824 --- src/modules/graphics/Text.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/Text.cpp index 9991aa681..7d53dacee 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/Text.cpp @@ -113,7 +113,6 @@ void Text::addTextData(const TextData &t) size_t voffset = vert_offset; - // Must be before the early exit below. if (!t.append_vertices) { voffset = 0; @@ -122,8 +121,8 @@ void Text::addTextData(const TextData &t) text_data.clear(); } - if (t.use_matrix) - t.matrix.transformXY(&vertices[0], &vertices[0], (int) vertices.size()); + if (t.use_matrix && !vertices.empty()) + t.matrix.transformXY(vertices.data(), vertices.data(), (int) vertices.size()); uploadVertices(vertices, voffset); From 8495cefd3bc2ef2d441e0c41d3dd03b6e2ecef12 Mon Sep 17 00:00:00 2001 From: slime Date: Tue, 9 Aug 2022 20:37:48 -0300 Subject: [PATCH 10/10] opengl: fix creating compressed array textures with > 1 layer. Fixes #1817. --- src/modules/graphics/opengl/Image.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 511d5d45a..f42ffa12d 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -116,16 +116,14 @@ void Image::loadData() { if (isCompressed() && (texType == TEXTURE_2D_ARRAY || texType == TEXTURE_VOLUME)) { + int mipslices = data.getSliceCount(mip); size_t mipsize = 0; - if (texType == TEXTURE_2D_ARRAY || texType == TEXTURE_VOLUME) - { - for (int slice = 0; slice < data.getSliceCount(mip); slice++) - mipsize += data.get(slice, mip)->getSize(); - } + for (int slice = 0; slice < mipslices; slice++) + mipsize += data.get(slice, mip)->getSize(); GLenum gltarget = OpenGL::getGLTextureType(texType); - glCompressedTexImage3D(gltarget, mip, fmt.internalformat, w, h, d, 0, mipsize, nullptr); + glCompressedTexImage3D(gltarget, mip, fmt.internalformat, w, h, mipslices, 0, mipsize, nullptr); } for (int slice = 0; slice < slicecount; slice++)