Skip to content

Commit

Permalink
Window|DisplayMode: Capture display when in fullscreen mode
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skyjake committed Mar 20, 2012
1 parent 977df28 commit 59105ad
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 24 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/displaymode.h
Expand Up @@ -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
}
Expand Down
17 changes: 13 additions & 4 deletions doomsday/engine/portable/src/displaymode.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -123,11 +128,13 @@ struct Mode : public DisplayMode
typedef std::set<Mode> 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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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));
}
81 changes: 62 additions & 19 deletions doomsday/engine/portable/src/window.cpp
Expand Up @@ -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();

Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand All @@ -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.
Expand All @@ -340,41 +341,83 @@ 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.
return false;
}
}

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())
Expand Down

0 comments on commit 59105ad

Please sign in to comment.