summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2023-02-11 19:14:23 +0100
committerGitHub <noreply@github.com>2023-02-11 19:14:23 +0100
commit5a25641317dd570757f33181e45393a74019dc30 (patch)
treef2fcd465287fb6a5e5a3cbc390b7362aabbb6942
parent740c56ce15935628ac6d613e582454c48adb978e (diff)
Very controlled GDIplus startup and shutdown #635 (#679)
Fall back to GDI if GDIplus is not available
-rw-r--r--.gitignore4
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.H11
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx16
-rw-r--r--src/drivers/WinAPI/fl_WinAPI_platform_init.cxx18
4 files changed, 44 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index 51e1e9951..764ca6526 100644
--- a/.gitignore
+++ b/.gitignore
@@ -90,3 +90,7 @@ src/xdg-shell-protocol.c
# libdecor/build/demo
# libdecor/build/egl
+/out/build/x64-Debug/.cmake/api/v1/query/client-MicrosoftVS/query.json
+/out/build/x64-Debug
+/CMakeSettings.json
+/CppProperties.json
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
index 6fa6840c8..941ac4db1 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
@@ -182,7 +182,16 @@ private:
Gdiplus::Color gdiplus_color_;
Gdiplus::Pen *pen_;
Gdiplus::SolidBrush *brush_;
- static ULONG_PTR gdiplusToken;
+ // The code below ensures the a connection to GDIplus is only made once, and that the
+ // matching connection shutdown is also done exactly once.
+ enum {
+ STATE_CLOSED = 0, // no connection, token is invalid
+ STATE_STARTUP, // attempt to start up, avoid recursions for whatever reason
+ STATE_OPEN, // connection was successful and the token is valid
+ STATE_SHUTDOWN // shutting down the gdi connection, avoid possible recursion
+ };
+ static int gdiplus_state_; // reflect the state of the GDIplus driver connection
+ static ULONG_PTR gdiplus_token_; // the token that GDIplus gives to us
public:
Fl_GDIplus_Graphics_Driver();
virtual ~Fl_GDIplus_Graphics_Driver();
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
index 188bd1d2d..7897dce53 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
@@ -53,10 +53,22 @@ int Fl_GDIplus_Graphics_Driver::antialias() {
#if USE_GDIPLUS
-ULONG_PTR Fl_GDIplus_Graphics_Driver::gdiplusToken = 0;
+int Fl_GDIplus_Graphics_Driver::gdiplus_state_ = Fl_GDIplus_Graphics_Driver::STATE_CLOSED;
+ULONG_PTR Fl_GDIplus_Graphics_Driver::gdiplus_token_ = 0;
void Fl_GDIplus_Graphics_Driver::shutdown() {
- Gdiplus::GdiplusShutdown(Fl_GDIplus_Graphics_Driver::gdiplusToken);
+ if (gdiplus_state_ == STATE_OPEN) {
+ gdiplus_state_ = STATE_SHUTDOWN;
+ Gdiplus::GdiplusShutdown(Fl_GDIplus_Graphics_Driver::gdiplus_token_);
+ gdiplus_token_ = 0;
+ gdiplus_state_ = STATE_CLOSED;
+ } else if (gdiplus_state_ == STATE_CLOSED) {
+// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called, but driver is closed.");
+ } else if (gdiplus_state_ == STATE_SHUTDOWN) {
+// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called recursively.");
+ } else if (gdiplus_state_ == STATE_STARTUP) {
+// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called while driver is starting up.");
+ }
}
#endif
diff --git a/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx b/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx
index bf5e34d36..5f3ba4ec4 100644
--- a/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx
+++ b/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx
@@ -34,8 +34,22 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
#if USE_GDIPLUS
// Initialize GDI+.
static Gdiplus::GdiplusStartupInput gdiplusStartupInput;
- if (Fl_GDIplus_Graphics_Driver::gdiplusToken == 0) {
- GdiplusStartup(&Fl_GDIplus_Graphics_Driver::gdiplusToken, &gdiplusStartupInput, NULL);
+ if (Fl_GDIplus_Graphics_Driver::gdiplus_state_ == Fl_GDIplus_Graphics_Driver::STATE_CLOSED) {
+ Fl_GDIplus_Graphics_Driver::gdiplus_state_ = Fl_GDIplus_Graphics_Driver::STATE_STARTUP;
+ Gdiplus::Status ret = GdiplusStartup(&Fl_GDIplus_Graphics_Driver::gdiplus_token_, &gdiplusStartupInput, NULL);
+ if (ret == Gdiplus::Status::Ok) {
+ Fl_GDIplus_Graphics_Driver::gdiplus_state_ = Fl_GDIplus_Graphics_Driver::STATE_OPEN;
+ } else {
+ Fl::warning("GdiplusStartup failed with error code %d.", ret);
+ Fl_GDIplus_Graphics_Driver::gdiplus_state_ = Fl_GDIplus_Graphics_Driver::STATE_CLOSED;
+ return new Fl_GDI_Graphics_Driver();
+ }
+ } else if (Fl_GDIplus_Graphics_Driver::gdiplus_state_ == Fl_GDIplus_Graphics_Driver::STATE_OPEN) {
+// Fl::warning("GdiplusStartup() called, but driver is already open.");
+ } else if (Fl_GDIplus_Graphics_Driver::gdiplus_state_ == Fl_GDIplus_Graphics_Driver::STATE_SHUTDOWN) {
+// Fl::warning("GdiplusStartup() called while driver is shutting down.");
+ } else if (Fl_GDIplus_Graphics_Driver::gdiplus_state_ == Fl_GDIplus_Graphics_Driver::STATE_STARTUP) {
+// Fl::warning("GdiplusStartup() called recursively.");
}
Fl_Graphics_Driver *driver = new Fl_GDIplus_Graphics_Driver();
return driver;