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

Commit

Permalink
Mostly fixed fullscreen mode on Mac OS X, and you can toggle it on an…
Browse files Browse the repository at this point in the history
…d off.

There are still some problems with the ConvertNSRect() calculations when switching video modes, which causes wierd window positioning issues, and the fullscreen window is still minimized on exit.
  • Loading branch information
slouken committed Feb 11, 2011
1 parent 316dd28 commit f266274
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 101 deletions.
30 changes: 23 additions & 7 deletions src/events/SDL_windowevents.c
Expand Up @@ -82,31 +82,47 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
SDL_OnWindowHidden(window);
break;
case SDL_WINDOWEVENT_MOVED:
if (window->flags & SDL_WINDOW_FULLSCREEN) {
if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
SDL_WINDOWPOS_ISUNDEFINED(data2)) {
return 0;
}
if (data1 == SDL_WINDOWPOS_UNDEFINED) {
data1 = window->x;
}
if (data2 == SDL_WINDOWPOS_UNDEFINED) {
data2 = window->y;
if (window->flags & SDL_WINDOW_FULLSCREEN) {
window->fullscreen.x = data1;
window->fullscreen.y = data1;
} else {
window->windowed.x = data1;
window->windowed.y = data1;
}
if (data1 == window->x && data2 == window->y) {
return 0;
}
window->x = data1;
window->y = data2;

if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* Do we really want to do this? */
return 0;
}
break;
case SDL_WINDOWEVENT_RESIZED:
if (window->flags & SDL_WINDOW_FULLSCREEN) {
return 0;
window->fullscreen.w = data1;
window->fullscreen.h = data1;
} else {
window->windowed.w = data1;
window->windowed.h = data1;
}
if (data1 == window->w && data2 == window->h) {
return 0;
}
window->w = data1;
window->h = data2;
SDL_OnWindowResized(window);

if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* Do we really want to do this? */
return 0;
}
break;
case SDL_WINDOWEVENT_MINIMIZED:
if (window->flags & SDL_WINDOW_MINIMIZED) {
Expand Down
11 changes: 0 additions & 11 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -40,9 +40,6 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)

/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */

/* Used to re-create the window with OpenGL capability */
extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);

static const float inv255f = 1.0f / 255.0f;

static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
Expand Down Expand Up @@ -146,14 +143,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_Renderer *renderer;
GLES_RenderData *data;
GLint value;
Uint32 window_flags;

window_flags = SDL_GetWindowFlags(window);
if (!(window_flags & SDL_WINDOW_OPENGL)) {
if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
return NULL;
}
}

renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
Expand Down
11 changes: 0 additions & 11 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -1085,27 +1085,16 @@ GLES2_RenderPresent(SDL_Renderer *renderer)

#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B

/* Used to re-create the window with OpenGL capability */
extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);

static SDL_Renderer *
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
{
SDL_Renderer *renderer;
GLES2_DriverContext *rdata;
Uint32 window_flags;
GLint nFormats;
#ifndef ZUNE_HD
GLboolean hasCompiler;
#endif

window_flags = SDL_GetWindowFlags(window);
if (!(window_flags & SDL_WINDOW_OPENGL)) {
if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
return NULL;
}
}

/* Create the renderer struct */
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
if (!renderer) {
Expand Down
17 changes: 16 additions & 1 deletion src/video/SDL_sysvideo.h
Expand Up @@ -72,6 +72,20 @@ struct SDL_Window
const void *magic;
Uint32 id;
char *title;

/* The fullscreen values */
struct {
int x, y;
int w, h;
} fullscreen;

/* The windowed values */
struct {
int x, y;
int w, h;
} windowed;

/* The public values */
int x, y;
int w, h;
Uint32 flags;
Expand Down Expand Up @@ -106,7 +120,6 @@ struct SDL_VideoDisplay
SDL_DisplayMode *display_modes;
SDL_DisplayMode desktop_mode;
SDL_DisplayMode current_mode;
SDL_bool updating_fullscreen;

SDL_Window *fullscreen_window;

Expand Down Expand Up @@ -178,6 +191,8 @@ struct SDL_VideoDevice
void (*MaximizeWindow) (_THIS, SDL_Window * window);
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 (*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
113 changes: 76 additions & 37 deletions src/video/SDL_video.c
Expand Up @@ -600,21 +600,21 @@ SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
SDL_VideoDisplay *display = &_this->displays[displayIndex];

if (_this->GetDisplayBounds) {
if (_this->GetDisplayBounds(_this, display, rect) < 0) {
return -1;
if (_this->GetDisplayBounds(_this, display, rect) == 0) {
return 0;
}
}

/* Assume that the displays are left to right */
if (displayIndex == 0) {
rect->x = 0;
rect->y = 0;
} else {
/* Assume that the displays are left to right */
if (displayIndex == 0) {
rect->x = 0;
rect->y = 0;
} else {
SDL_GetDisplayBounds(displayIndex-1, rect);
rect->x += rect->w;
}
rect->w = display->desktop_mode.w;
rect->h = display->desktop_mode.h;
SDL_GetDisplayBounds(displayIndex-1, rect);
rect->x += rect->w;
}
rect->w = display->desktop_mode.w;
rect->h = display->desktop_mode.h;
}
return 0;
}
Expand Down Expand Up @@ -1016,14 +1016,13 @@ static void
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_Window *other;

/* See if we're already processing a window */
if (display->updating_fullscreen) {
/* See if anything changed */
if ((display->fullscreen_window == window) == attempt) {
return;
}

display->updating_fullscreen = SDL_TRUE;

/* See if we even want to do anything here */
if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
(window->flags & SDL_WINDOW_SHOWN)) {
Expand All @@ -1042,29 +1041,52 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)

if (FULLSCREEN_VISIBLE(window)) {
/* Hide any other fullscreen windows */
if (display->fullscreen_window != window) {
if (display->fullscreen_window &&
display->fullscreen_window != window) {
SDL_MinimizeWindow(display->fullscreen_window);
}
}

display->updating_fullscreen = SDL_FALSE;

/* See if there are any fullscreen windows */
for (window = _this->windows; window; window = window->next) {
if (FULLSCREEN_VISIBLE(window) &&
SDL_GetDisplayForWindow(window) == display) {
for (other = _this->windows; other; other = other->next) {
if (FULLSCREEN_VISIBLE(other) &&
SDL_GetDisplayForWindow(other) == display) {
SDL_DisplayMode fullscreen_mode;
if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) {
if (_this->PrepWindowFullscreen) {
_this->PrepWindowFullscreen(_this, other);
}

SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
display->fullscreen_window = window;

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

/* Generate a mode change events here */
SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED,
fullscreen_mode.w, fullscreen_mode.h);
return;
}
}
}

/* Nope, restore the desktop mode */
if (_this->PrepWindowFullscreen) {
_this->PrepWindowFullscreen(_this, window);
}

SDL_SetDisplayModeForDisplay(display, NULL);

if (_this->SetWindowFullscreen) {
_this->SetWindowFullscreen(_this, window);
}
display->fullscreen_window = NULL;

/* Generate a mode change events here */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
window->windowed.w, window->windowed.h);
}

SDL_Window *
Expand All @@ -1084,6 +1106,11 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
return NULL;
}
}

/* Some platforms have OpenGL enabled by default */
#if (SDL_VIDEO_OPENGL && __MACOSX__) || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
flags |= SDL_WINDOW_OPENGL;
#endif
if (flags & SDL_WINDOW_OPENGL) {
if (!_this->GL_CreateContext) {
SDL_SetError("No OpenGL support in video driver");
Expand Down Expand Up @@ -1169,13 +1196,6 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
SDL_SetError("No OpenGL support in video driver");
return -1;
}
if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
if (flags & SDL_WINDOW_OPENGL) {
SDL_GL_LoadLibrary(NULL);
} else {
SDL_GL_UnloadLibrary();
}
}

if (window->flags & SDL_WINDOW_FOREIGN) {
/* Can't destroy and re-create foreign windows, hrm */
Expand All @@ -1184,10 +1204,29 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
flags &= ~SDL_WINDOW_FOREIGN;
}

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

/* Tear down the old native window */
if (window->surface) {
window->surface->refcount = 0;
SDL_FreeSurface(window->surface);
}
if (_this->DestroyWindowFramebuffer) {
_this->DestroyWindowFramebuffer(_this, window);
}
if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
_this->DestroyWindow(_this, window);
}

if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
if (flags & SDL_WINDOW_OPENGL) {
SDL_GL_LoadLibrary(NULL);
} else {
SDL_GL_UnloadLibrary();
}
}

window->title = NULL;
window->flags = (flags & allowed_flags);

Expand Down Expand Up @@ -1396,13 +1435,13 @@ SDL_SetWindowSize(SDL_Window * window, int w, int h)
{
CHECK_WINDOW_MAGIC(window, );

window->w = w;
window->h = h;

if (_this->SetWindowSize) {
_this->SetWindowSize(_this, window);
/* FIXME: Should this change fullscreen modes? */
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
if (_this->SetWindowSize) {
_this->SetWindowSize(_this, window);
}
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
}
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
}

void
Expand Down
1 change: 0 additions & 1 deletion src/video/android/SDL_androidwindow.c
Expand Up @@ -42,7 +42,6 @@ Android_CreateWindow(_THIS, SDL_Window * window)
window->h = Android_ScreenHeight;

window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
window->flags |= SDL_WINDOW_OPENGL; /* window is always OpenGL */
window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */
window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
Expand Down
13 changes: 0 additions & 13 deletions src/video/cocoa/SDL_cocoamodes.m
Expand Up @@ -299,19 +299,6 @@ - (void) setFrame:(NSRect)frame;
CGReleaseDisplayFadeReservation(fade_token);
}

[[NSApp mainWindow] makeKeyAndOrderFront: nil];

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
/*
There is a bug in Cocoa where NSScreen doesn't synchronize
with CGDirectDisplay, so the main screen's frame is wrong.
As a result, coordinate translation produces incorrect results.
We can hack around this bug by setting the screen rect
ourselves. This hack should be removed if/when the bug is fixed.
*/
[[NSScreen mainScreen] setFrame:NSMakeRect(0,0,mode->w,mode->h)];
#endif

return 0;

/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
Expand Down
3 changes: 3 additions & 0 deletions src/video/cocoa/SDL_cocoaopengl.h
Expand Up @@ -26,6 +26,9 @@

#if SDL_VIDEO_OPENGL_CGL

/* Define this if you want to be able to toggle fullscreen mode seamlessly */
#define FULLSCREEN_TOGGLEABLE

struct SDL_GLDriverData
{
int initialized;
Expand Down
7 changes: 6 additions & 1 deletion src/video/cocoa/SDL_cocoaopengl.m
Expand Up @@ -81,9 +81,11 @@

pool = [[NSAutoreleasePool alloc] init];

#ifndef FULLSCREEN_TOGGLEABLE
if (window->flags & SDL_WINDOW_FULLSCREEN) {
attr[i++] = NSOpenGLPFAFullScreen;
}
#endif

attr[i++] = NSOpenGLPFAColorSize;
attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
Expand Down Expand Up @@ -199,9 +201,12 @@
SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
NSOpenGLContext *nscontext = (NSOpenGLContext *)context;

#ifndef FULLSCREEN_TOGGLEABLE
if (window->flags & SDL_WINDOW_FULLSCREEN) {
[nscontext setFullScreen];
} else {
} else
#endif
{
[nscontext setView:[windowdata->nswindow contentView]];
[nscontext update];
}
Expand Down

0 comments on commit f266274

Please sign in to comment.