From 59105ad7230c1f7c635bb84cc96f36b2caae797a Mon Sep 17 00:00:00 2001 From: skyjake Date: Tue, 20 Mar 2012 10:19:59 +0200 Subject: [PATCH] Window|DisplayMode: Capture display when in fullscreen mode One cannot capture the display simply based on which display mode is selected. Instead, capturing should be applied when a window goes in fullscreen mode. --- .../engine/portable/include/displaymode.h | 2 +- doomsday/engine/portable/src/displaymode.cpp | 17 +++- doomsday/engine/portable/src/window.cpp | 81 ++++++++++++++----- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/doomsday/engine/portable/include/displaymode.h b/doomsday/engine/portable/include/displaymode.h index aee77a99c3..4e8678fa55 100644 --- a/doomsday/engine/portable/include/displaymode.h +++ b/doomsday/engine/portable/include/displaymode.h @@ -63,7 +63,7 @@ const DisplayMode* DisplayMode_FindClosest(int width, int height, int depth, flo boolean DisplayMode_IsEqual(const DisplayMode* a, const DisplayMode* b); -int DisplayMode_Change(const DisplayMode* mode); +int DisplayMode_Change(const DisplayMode* mode, boolean shouldCapture); #ifdef __cplusplus } diff --git a/doomsday/engine/portable/src/displaymode.cpp b/doomsday/engine/portable/src/displaymode.cpp index 9d8bd41a45..04c15b4d14 100644 --- a/doomsday/engine/portable/src/displaymode.cpp +++ b/doomsday/engine/portable/src/displaymode.cpp @@ -65,6 +65,11 @@ struct Mode : public DisplayMode depth == other.depth && refreshRate == other.refreshRate; } + bool operator != (const Mode& other) const + { + return !(*this == other); + } + bool operator < (const Mode& b) const { if(height == b.height) @@ -123,11 +128,13 @@ struct Mode : public DisplayMode typedef std::set Modes; static Modes modes; static Mode originalMode; +static bool captured; int DisplayMode_Init(void) { if(inited) return true; + captured = false; DisplayMode_Native_Init(); for(int i = 0; i < DisplayMode_Native_Count(); ++i) @@ -159,11 +166,12 @@ void DisplayMode_Shutdown(void) qDebug() << "Restoring original display mode due to shutdown."; // Back to the original mode. - DisplayMode_Change(&originalMode); + DisplayMode_Change(&originalMode, false /*release captured*/); modes.clear(); DisplayMode_Native_Shutdown(); + captured = false; inited = false; } @@ -240,14 +248,15 @@ boolean DisplayMode_IsEqual(const DisplayMode* a, const DisplayMode* b) return Mode(*a) == Mode(*b); } -int DisplayMode_Change(const DisplayMode* mode) +int DisplayMode_Change(const DisplayMode* mode, boolean shouldCapture) { - if(Mode::fromCurrent() == *mode) + if(Mode::fromCurrent() == *mode && shouldCapture == captured) { qDebug() << "DisplayMode: Requested mode is the same as current, ignoring."; // Already in this mode. return true; } - return DisplayMode_Native_Change(mode); + captured = shouldCapture; + return DisplayMode_Native_Change(mode, shouldCapture || (originalMode != *mode)); } diff --git a/doomsday/engine/portable/src/window.cpp b/doomsday/engine/portable/src/window.cpp index 15dfd6eca4..3718bf8568 100644 --- a/doomsday/engine/portable/src/window.cpp +++ b/doomsday/engine/portable/src/window.cpp @@ -196,7 +196,7 @@ struct ddwindow_s const DisplayMode* mode = DisplayMode_FindClosest(width(), height(), colorDepthBits, 0); if(mode && !DisplayMode_IsEqual(DisplayMode_Current(), mode)) { - if(DisplayMode_Change(mode)) + if(DisplayMode_Change(mode, true /* fullscreen: capture */)) { widget->canvas().trapMouse(); @@ -213,12 +213,8 @@ struct ddwindow_s } else { - if(DisplayMode_IsEqual(DisplayMode_Current(), DisplayMode_OriginalMode())) - { - // No need to change. - return false; - } - return DisplayMode_Change(DisplayMode_OriginalMode()); + return DisplayMode_Change(DisplayMode_OriginalMode(), + false /* windowed: don't capture */); } return false; } @@ -309,6 +305,10 @@ struct ddwindow_s geometry.size.width, geometry.size.height, (flags & DDWF_MAXIMIZE) != 0); } + bool checkFlag(int flag) const { + return (flags & flag) != 0; + } + void setFlag(int flag, bool set = true) { if(set) @@ -331,6 +331,7 @@ struct ddwindow_s bool applyAttributes(int* attribs) { + bool changed = false; bool wasFullscreen = (flags & DDWF_FULLSCREEN) != 0; // Parse the attributes array and check the values. @@ -340,34 +341,70 @@ struct ddwindow_s switch(attribs[i++]) { case DDWA_X: - geometry.origin.x = attribs[i]; + if(x() != attribs[i]) + { + geometry.origin.x = attribs[i]; + changed = true; + } break; case DDWA_Y: - geometry.origin.y = attribs[i]; + if(y() != attribs[i]) + { + geometry.origin.y = attribs[i]; + changed = true; + } break; case DDWA_WIDTH: - geometry.size.width = attribs[i]; - if(geometry.size.width < WINDOW_MIN_WIDTH) return false; + if(width() != attribs[i]) + { + geometry.size.width = attribs[i]; + if(geometry.size.width < WINDOW_MIN_WIDTH) return false; + changed = true; + } break; case DDWA_HEIGHT: - geometry.size.height = attribs[i]; - if(geometry.size.height < WINDOW_MIN_HEIGHT) return false; + if(height() != attribs[i]) + { + geometry.size.height = attribs[i]; + if(geometry.size.height < WINDOW_MIN_HEIGHT) return false; + changed = true; + } break; case DDWA_CENTER: - setFlag(DDWF_CENTER, attribs[i]); + if(attribs[i] != checkFlag(DDWF_CENTER)) + { + setFlag(DDWF_CENTER, attribs[i]); + changed = true; + } break; case DDWA_MAXIMIZE: - setFlag(DDWF_MAXIMIZE, attribs[i]); + if(attribs[i] != checkFlag(DDWF_MAXIMIZE)) + { + setFlag(DDWF_MAXIMIZE, attribs[i]); + changed = true; + } break; case DDWA_FULLSCREEN: - setFlag(DDWF_FULLSCREEN, attribs[i]); + if(attribs[i] != checkFlag(DDWF_FULLSCREEN)) + { + setFlag(DDWF_FULLSCREEN, attribs[i]); + changed = true; + } break; case DDWA_VISIBLE: - setFlag(DDWF_VISIBLE, attribs[i]); + if(attribs[i] != checkFlag(DDWF_VISIBLE)) + { + setFlag(DDWF_VISIBLE, attribs[i]); + changed = true; + } break; case DDWA_COLOR_DEPTH_BITS: - colorDepthBits = attribs[i]; - if(colorDepthBits < 8 || colorDepthBits > 32) return false; // Illegal value. + if(attribs[i] != colorDepthBits) + { + colorDepthBits = attribs[i]; + if(colorDepthBits < 8 || colorDepthBits > 32) return false; // Illegal value. + changed = true; + } break; default: // Unknown attribute. @@ -375,6 +412,12 @@ struct ddwindow_s } } + if(!changed) + { + VERBOSE(Con_Message("New window attributes same as before.\n")); + return true; + } + // Check geometry for validity (window must be on the desktop // at least partially). if(!wasFullscreen && !(flags & DDWF_FULLSCREEN) && !isGeometryValid())