Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Fixed a host of issues with Windows fullscreen modes. Toggling fullsc…
Browse files Browse the repository at this point in the history
…reen OpenGL works now in my test environment.
  • Loading branch information
slouken committed Feb 16, 2011
1 parent c5d64f3 commit 96f392a
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 132 deletions.
2 changes: 1 addition & 1 deletion src/video/SDL_sysvideo.h
Expand Up @@ -181,7 +181,7 @@ struct SDL_VideoDevice
void (*MinimizeWindow) (_THIS, SDL_Window * window);
void (*RestoreWindow) (_THIS, SDL_Window * window);
void (*PrepWindowFullscreen) (_THIS, SDL_Window * window);
void (*SetWindowFullscreen) (_THIS, SDL_Window * window);
void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
void (*SetWindowGrab) (_THIS, SDL_Window * window);
void (*DestroyWindow) (_THIS, SDL_Window * window);
int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
Expand Down
54 changes: 18 additions & 36 deletions src/video/SDL_video.c
Expand Up @@ -1001,32 +1001,11 @@ SDL_GetWindowPixelFormat(SDL_Window * window)
}

static void
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
SDL_UpdateFullscreenMode(SDL_Window * window)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_Window *other;

/* See if anything changed */
if ((display->fullscreen_window == window) == attempt) {
return;
}

/* See if we even want to do anything here */
if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
(window->flags & SDL_WINDOW_SHOWN)) {
if (attempt) {
/* We just gained some state, try to gain all states */
if (window->flags & SDL_WINDOW_MINIMIZED) {
SDL_RestoreWindow(window);
} else {
SDL_RaiseWindow(window);
}
} else {
/* We just lost some state, try to release all states */
SDL_MinimizeWindow(window);
}
}

if (FULLSCREEN_VISIBLE(window)) {
/* Hide any other fullscreen windows */
if (display->fullscreen_window &&
Expand All @@ -1035,6 +1014,11 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
}
}

/* See if anything needs to be done now */
if ((display->fullscreen_window == window) == FULLSCREEN_VISIBLE(window)) {
return;
}

/* See if there are any fullscreen windows */
for (other = _this->windows; other; other = other->next) {
if (FULLSCREEN_VISIBLE(other) &&
Expand All @@ -1048,7 +1032,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);

if (_this->SetWindowFullscreen) {
_this->SetWindowFullscreen(_this, other);
_this->SetWindowFullscreen(_this, other, display, SDL_TRUE);
}
display->fullscreen_window = other;

Expand All @@ -1068,7 +1052,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
SDL_SetDisplayModeForDisplay(display, NULL);

if (_this->SetWindowFullscreen) {
_this->SetWindowFullscreen(_this, window);
_this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
}
display->fullscreen_window = NULL;
}
Expand Down Expand Up @@ -1188,7 +1172,7 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
}

/* Restore video mode, etc. */
SDL_UpdateFullscreenMode(window, SDL_FALSE);
SDL_HideWindow(window);

/* Tear down the old native window */
if (window->surface) {
Expand Down Expand Up @@ -1373,10 +1357,10 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y)
{
CHECK_WINDOW_MAGIC(window, );

if (x != SDL_WINDOWPOS_UNDEFINED) {
if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
window->x = x;
}
if (y != SDL_WINDOWPOS_UNDEFINED) {
if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
window->y = y;
}
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
Expand Down Expand Up @@ -1569,13 +1553,11 @@ SDL_SetWindowFullscreen(SDL_Window * window, SDL_bool fullscreen)
}
if (fullscreen) {
window->flags |= SDL_WINDOW_FULLSCREEN;

SDL_UpdateFullscreenMode(window, SDL_TRUE);
} else {
window->flags &= ~SDL_WINDOW_FULLSCREEN;

SDL_UpdateFullscreenMode(window, SDL_FALSE);
}
SDL_UpdateFullscreenMode(window);

return 0;
}

Expand Down Expand Up @@ -1686,13 +1668,13 @@ void
SDL_OnWindowShown(SDL_Window * window)
{
SDL_RaiseWindow(window);
SDL_UpdateFullscreenMode(window, SDL_TRUE);
SDL_UpdateFullscreenMode(window);
}

void
SDL_OnWindowHidden(SDL_Window * window)
{
SDL_UpdateFullscreenMode(window, SDL_FALSE);
SDL_UpdateFullscreenMode(window);
}

void
Expand All @@ -1705,14 +1687,14 @@ SDL_OnWindowResized(SDL_Window * window)
void
SDL_OnWindowMinimized(SDL_Window * window)
{
SDL_UpdateFullscreenMode(window, SDL_FALSE);
SDL_UpdateFullscreenMode(window);
}

void
SDL_OnWindowRestored(SDL_Window * window)
{
SDL_RaiseWindow(window);
SDL_UpdateFullscreenMode(window, SDL_TRUE);
SDL_UpdateFullscreenMode(window);
}

void
Expand Down Expand Up @@ -1763,7 +1745,7 @@ SDL_DestroyWindow(SDL_Window * window)
CHECK_WINDOW_MAGIC(window, );

/* Restore video mode, etc. */
SDL_UpdateFullscreenMode(window, SDL_FALSE);
SDL_HideWindow(window);

if (window->surface) {
window->surface->flags &= ~SDL_DONTFREE;
Expand Down
2 changes: 1 addition & 1 deletion src/video/cocoa/SDL_cocoawindow.h
Expand Up @@ -102,7 +102,7 @@ extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window);
extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window);
extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window);
extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window);
extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window);
extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window);
extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window,
Expand Down
31 changes: 17 additions & 14 deletions src/video/cocoa/SDL_cocoawindow.m
Expand Up @@ -399,18 +399,22 @@ - (void)rightMouseDown:(NSEvent *)theEvent
@end

static unsigned int
GetStyleMask(SDL_Window * window)
GetWindowStyle(SDL_Window * window)
{
unsigned int style;

if (window->flags & SDL_WINDOW_BORDERLESS) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
style = NSBorderlessWindowMask;
} else {
style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
}
if (window->flags & SDL_WINDOW_RESIZABLE) {
style |= NSResizableWindowMask;
}
} else {
if (window->flags & SDL_WINDOW_BORDERLESS) {
style = NSBorderlessWindowMask;
} else {
style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
}
if (window->flags & SDL_WINDOW_RESIZABLE) {
style |= NSResizableWindowMask;
}
}
return style;
}

Expand Down Expand Up @@ -528,7 +532,7 @@ - (void)rightMouseDown:(NSEvent *)theEvent
rect.size.height = window->h;
ConvertNSRect(&rect);

style = GetStyleMask(window);
style = GetWindowStyle(window);

/* Figure out which screen to place this window */
NSArray *screens = [NSScreen screens];
Expand Down Expand Up @@ -704,15 +708,14 @@ - (void)rightMouseDown:(NSEvent *)theEvent
}

void
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window)
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
NSWindow *nswindow = data->nswindow;
NSRect rect;

if (FULLSCREEN_VISIBLE(window)) {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
if (fullscreen) {
SDL_Rect bounds;

Cocoa_GetDisplayBounds(_this, display, &bounds);
Expand All @@ -726,14 +729,14 @@ - (void)rightMouseDown:(NSEvent *)theEvent
[nswindow setContentSize:rect.size];
[nswindow setFrameOrigin:rect.origin];
} else {
[nswindow setStyleMask:GetStyleMask(window)];
[nswindow setStyleMask:GetWindowStyle(window)];

// This doesn't seem to do anything...
//[nswindow setFrameOrigin:origin];
}

#ifdef FULLSCREEN_TOGGLEABLE
if (FULLSCREEN_VISIBLE(window)) {
if (fullscreen) {
/* OpenGL is rendering to the window, so make it visible! */
[nswindow setLevel:CGShieldingWindowLevel()];
} else {
Expand Down
79 changes: 51 additions & 28 deletions src/video/windows/SDL_windowsmodes.c
Expand Up @@ -131,10 +131,6 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
}
}
}
if (SDL_ISPIXELFORMAT_INDEXED(mode->format)) {
/* We don't support palettized modes now */
return SDL_FALSE;
}
return SDL_TRUE;
}

Expand Down Expand Up @@ -170,35 +166,58 @@ WIN_AddDisplay(LPTSTR DeviceName)
int
WIN_InitModes(_THIS)
{
int pass;
DWORD i, j, count;
DISPLAY_DEVICE device;

device.cb = sizeof(device);
for (i = 0;; ++i) {
TCHAR DeviceName[32];

if (!EnumDisplayDevices(NULL, i, &device, 0)) {
break;
}
if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
continue;
}
SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
#ifdef DEBUG_MODES
printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
#endif
count = 0;
for (j = 0;; ++j) {
if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
/* Get the primary display in the first pass */
for (pass = 0; pass < 2; ++pass) {
for (i = 0; ; ++i) {
TCHAR DeviceName[32];

if (!EnumDisplayDevices(NULL, i, &device, 0)) {
break;
}
if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
continue;
}
count += WIN_AddDisplay(device.DeviceName);
}
if (count == 0) {
WIN_AddDisplay(DeviceName);
if (pass == 0) {
if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
continue;
}
} else {
if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
continue;
}
}
SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
#ifdef DEBUG_MODES
printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
#endif
count = 0;
for (j = 0; ; ++j) {
if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
break;
}
if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
continue;
}
if (pass == 0) {
if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
continue;
}
} else {
if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
continue;
}
}
count += WIN_AddDisplay(device.DeviceName);
}
if (count == 0) {
WIN_AddDisplay(DeviceName);
}
}
}
if (_this->num_displays == 0) {
Expand All @@ -211,7 +230,7 @@ WIN_InitModes(_THIS)
int
WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->current_mode.driverdata;

#ifdef _WIN32_WCE
// WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug
Expand Down Expand Up @@ -239,6 +258,10 @@ WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) {
break;
}
if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
/* We don't support palettized modes now */
continue;
}
if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
if (!SDL_AddDisplayMode(display, &mode)) {
SDL_free(mode.driverdata);
Expand All @@ -265,9 +288,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
status =
ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode,
NULL, CDS_FULLSCREEN, NULL);
if (status == DISP_CHANGE_SUCCESSFUL) {
return 0;
} else {
if (status != DISP_CHANGE_SUCCESSFUL) {
const char *reason = "Unknown reason";
switch (status) {
case DISP_CHANGE_BADFLAGS:
Expand All @@ -286,12 +307,14 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
return -1;
}
EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
return 0;
}

void
WIN_QuitModes(_THIS)
{
ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
/* All fullscreen windows should have restored modes by now */
}

/* vi: set ts=4 sw=4 expandtab: */
1 change: 1 addition & 0 deletions src/video/windows/SDL_windowsvideo.c
Expand Up @@ -124,6 +124,7 @@ WIN_CreateDevice(int devindex)
device->MaximizeWindow = WIN_MaximizeWindow;
device->MinimizeWindow = WIN_MinimizeWindow;
device->RestoreWindow = WIN_RestoreWindow;
device->SetWindowFullscreen = WIN_SetWindowFullscreen;
device->SetWindowGrab = WIN_SetWindowGrab;
device->DestroyWindow = WIN_DestroyWindow;
device->GetWindowWMInfo = WIN_GetWindowWMInfo;
Expand Down

0 comments on commit 96f392a

Please sign in to comment.