Mercurial > sdl-ios-xcode
diff src/video/SDL_video.c @ 3500:4b594623401b
Work in progress on multi-display support:
* Added display parameter to many internal functions so video modes can be set on displays that aren't the public current one.
* The fullscreen mode is associated with fullscreen windows - not displays, so different windows more naturally have a mode associated with them based on their width and height. It's no longer necessary to specify a fullscreen mode, a default one will be picked automatically for fullscreen windows.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 01 Dec 2009 05:57:15 +0000 |
parents | e1bd98b56e94 |
children | 467e67d301f3 |
line wrap: on
line diff
--- a/src/video/SDL_video.c Mon Nov 30 21:04:25 2009 +0000 +++ b/src/video/SDL_video.c Tue Dec 01 05:57:15 2009 +0000 @@ -256,16 +256,17 @@ } /* The software renderer is always available */ for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; if (_this->GL_CreateContext) { #if SDL_VIDEO_RENDER_OGL - SDL_AddRenderDriver(i, &GL_RenderDriver); + SDL_AddRenderDriver(display, &GL_RenderDriver); #endif #if SDL_VIDEO_RENDER_OGL_ES - SDL_AddRenderDriver(i, &GL_ES_RenderDriver); + SDL_AddRenderDriver(display, &GL_ES_RenderDriver); #endif } - if (_this->displays[i].num_render_drivers > 0) { - SDL_AddRenderDriver(i, &SW_RenderDriver); + if (display->num_render_drivers > 0) { + SDL_AddRenderDriver(display, &SW_RenderDriver); } } @@ -360,9 +361,8 @@ } SDL_bool -SDL_AddDisplayMode(int displayIndex, const SDL_DisplayMode * mode) +SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) { - SDL_VideoDisplay *display = &_this->displays[displayIndex]; SDL_DisplayMode *modes; int i, nmodes; @@ -397,16 +397,35 @@ } int +SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) +{ + if (!display->num_display_modes && _this->GetDisplayModes) { + _this->GetDisplayModes(_this, display); + SDL_qsort(display->display_modes, display->num_display_modes, + sizeof(SDL_DisplayMode), cmpmodes); + } + return display->num_display_modes; +} + +int SDL_GetNumDisplayModes() { if (_this) { - SDL_VideoDisplay *display = &SDL_CurrentDisplay; - if (!display->num_display_modes && _this->GetDisplayModes) { - _this->GetDisplayModes(_this); - SDL_qsort(display->display_modes, display->num_display_modes, - sizeof(SDL_DisplayMode), cmpmodes); - } - return display->num_display_modes; + return SDL_GetNumDisplayModesForDisplay(&SDL_CurrentDisplay); + } + return 0; +} + +int +SDL_GetDisplayModeForDisplay(SDL_VideoDisplay * display, int index, SDL_DisplayMode * mode) +{ + if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) { + SDL_SetError("index must be in the range of 0 - %d", + SDL_GetNumDisplayModesForDisplay(display) - 1); + return -1; + } + if (mode) { + *mode = display->display_modes[index]; } return 0; } @@ -414,13 +433,14 @@ int SDL_GetDisplayMode(int index, SDL_DisplayMode * mode) { - if (index < 0 || index >= SDL_GetNumDisplayModes()) { - SDL_SetError("index must be in the range of 0 - %d", - SDL_GetNumDisplayModes() - 1); - return -1; - } + return SDL_GetDisplayModeForDisplay(&SDL_CurrentDisplay, index, mode); +} + +int +SDL_GetDesktopDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ if (mode) { - *mode = SDL_CurrentDisplay.display_modes[index]; + *mode = display->desktop_mode; } return 0; } @@ -432,8 +452,14 @@ SDL_UninitializedVideo(); return -1; } + return SDL_GetDesktopDisplayModeForDisplay(&SDL_CurrentDisplay, mode); +} + +int +SDL_GetCurrentDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ if (mode) { - *mode = SDL_CurrentDisplay.desktop_mode; + *mode = display->current_mode; } return 0; } @@ -445,41 +471,41 @@ SDL_UninitializedVideo(); return -1; } - if (mode) { - *mode = SDL_CurrentDisplay.current_mode; - } - return 0; + return SDL_GetCurrentDisplayModeForDisplay(&SDL_CurrentDisplay, mode); } SDL_DisplayMode * -SDL_GetClosestDisplayMode(const SDL_DisplayMode * mode, - SDL_DisplayMode * closest) +SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, + const SDL_DisplayMode * mode, + SDL_DisplayMode * closest) { Uint32 target_format; int target_refresh_rate; int i; SDL_DisplayMode *current, *match; - if (!_this || !mode || !closest) { + if (!mode || !closest) { + SDL_SetError("Missing desired mode or closest mode parameter"); return NULL; } + /* Default to the desktop format */ if (mode->format) { target_format = mode->format; } else { - target_format = SDL_CurrentDisplay.desktop_mode.format; + target_format = display->desktop_mode.format; } /* Default to the desktop refresh rate */ if (mode->refresh_rate) { target_refresh_rate = mode->refresh_rate; } else { - target_refresh_rate = SDL_CurrentDisplay.desktop_mode.refresh_rate; + target_refresh_rate = display->desktop_mode.refresh_rate; } match = NULL; - for (i = 0; i < SDL_GetNumDisplayModes(); ++i) { - current = &SDL_CurrentDisplay.display_modes[i]; + for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) { + current = &display->display_modes[i]; if (current->w && (current->w < mode->w)) { /* Out of sorted modes large enough here */ @@ -555,19 +581,24 @@ return NULL; } +SDL_DisplayMode * +SDL_GetClosestDisplayMode(const SDL_DisplayMode * mode, + SDL_DisplayMode * closest) +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return SDL_GetClosestDisplayModeForDisplay(&SDL_CurrentDisplay, mode, closest); +} + int -SDL_SetDisplayMode(const SDL_DisplayMode * mode) +SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) { - SDL_VideoDisplay *display; SDL_DisplayMode display_mode; SDL_DisplayMode current_mode; int i, ncolors; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - display = &SDL_CurrentDisplay; if (!mode) { mode = &display->desktop_mode; } @@ -586,19 +617,22 @@ if (!display_mode.refresh_rate) { display_mode.refresh_rate = display->current_mode.refresh_rate; } + /* Get a good video mode, the closest one possible */ - if (!SDL_GetClosestDisplayMode(&display_mode, &display_mode)) { + if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) { SDL_SetError("No video mode large enough for %dx%d", display_mode.w, display_mode.h); return -1; } + /* See if there's anything left to do */ - SDL_GetCurrentDisplayMode(¤t_mode); + SDL_GetCurrentDisplayModeForDisplay(display, ¤t_mode); if (SDL_memcmp(&display_mode, ¤t_mode, sizeof(display_mode)) == 0) { return 0; } + /* Actually change the display mode */ - if (_this->SetDisplayMode(_this, &display_mode) < 0) { + if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { return -1; } display->current_mode = display_mode; @@ -624,84 +658,74 @@ SDL_BITSPERPIXEL(display_mode.format)); } } - /* Move any fullscreen windows into position */ - for (i = 0; i < display->num_windows; ++i) { - SDL_Window *window = &display->windows[i]; - if (FULLSCREEN_VISIBLE(window)) { - SDL_SetWindowPosition(window->id, window->x, window->y); - } - } return 0; } int -SDL_SetFullscreenDisplayMode(const SDL_DisplayMode * mode) +SDL_SetDisplayMode(const SDL_DisplayMode * mode) { - SDL_VideoDisplay *display; - SDL_DisplayMode fullscreen_mode; - int i; - if (!_this) { SDL_UninitializedVideo(); return -1; } - display = &SDL_CurrentDisplay; - if (!mode) { - mode = &display->desktop_mode; - } - if (!SDL_GetClosestDisplayMode(mode, &fullscreen_mode)) { + return SDL_SetDisplayModeForDisplay(&SDL_CurrentDisplay, mode); +} + +int +SDL_SetWindowDisplayMode(SDL_WindowID windowID, const SDL_DisplayMode * mode) +{ + SDL_Window *window = SDL_GetWindowFromID(windowID); + + if (!window) { + return -1; + } + + if (mode) { + window->fullscreen_mode = *mode; + } else { + SDL_zero(window->fullscreen_mode); + } +} + +int +SDL_GetWindowDisplayMode(SDL_WindowID windowID, SDL_DisplayMode * mode) +{ + SDL_Window *window = SDL_GetWindowFromID(windowID); + SDL_DisplayMode fullscreen_mode; + + if (!window) { + return -1; + } + + fullscreen_mode = window->fullscreen_mode; + if (!fullscreen_mode.w) { + fullscreen_mode.w = window->w; + } + if (!fullscreen_mode.h) { + fullscreen_mode.h = window->h; + } + + if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayFromWindow(window), + &fullscreen_mode, + &fullscreen_mode)) { SDL_SetError("Couldn't find display mode match"); return -1; } - if (SDL_memcmp - (&fullscreen_mode, &display->fullscreen_mode, - sizeof(fullscreen_mode)) == 0) { - /* Nothing to do... */ - return 0; - } - display->fullscreen_mode = fullscreen_mode; - - /* Actually set the mode if we have a fullscreen window visible */ - for (i = 0; i < display->num_windows; ++i) { - SDL_Window *window = &display->windows[i]; - if (FULLSCREEN_VISIBLE(window)) { - if (SDL_SetDisplayMode(&display->fullscreen_mode) < 0) { - return -1; - } - } - if (window->flags & SDL_WINDOW_FULLSCREEN) { - SDL_OnWindowResized(window); - } + if (mode) { + *mode = fullscreen_mode; } return 0; } int -SDL_GetFullscreenDisplayMode(SDL_DisplayMode * mode) -{ - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - if (mode) { - *mode = SDL_CurrentDisplay.fullscreen_mode; - } - return 0; -} - -int -SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors) +SDL_SetDisplayPaletteForDisplay(SDL_VideoDisplay * display, const SDL_Color * colors, int firstcolor, int ncolors) { SDL_Palette *palette; int status = 0; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - palette = SDL_CurrentDisplay.palette; + palette = display->palette; if (!palette) { SDL_SetError("Display mode does not have a palette"); return -1; @@ -709,7 +733,7 @@ status = SDL_SetPaletteColors(palette, colors, firstcolor, ncolors); if (_this->SetDisplayPalette) { - if (_this->SetDisplayPalette(_this, palette) < 0) { + if (_this->SetDisplayPalette(_this, display, palette) < 0) { status = -1; } } @@ -717,6 +741,35 @@ } int +SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors) +{ + if (!_this) { + SDL_UninitializedVideo(); + return -1; + } + return SDL_SetDisplayPaletteForDisplay(&SDL_CurrentDisplay, colors, firstcolor, ncolors); +} + +int +SDL_GetDisplayPaletteForDisplay(SDL_VideoDisplay * display, SDL_Color * colors, int firstcolor, int ncolors) +{ + SDL_Palette *palette; + + palette = display->palette; + if (!palette || !palette->ncolors) { + SDL_SetError("Display mode does not have a palette"); + return -1; + } + if (firstcolor < 0 || (firstcolor + ncolors) > palette->ncolors) { + SDL_SetError("Palette indices are out of range"); + return -1; + } + SDL_memcpy(colors, &palette->colors[firstcolor], + ncolors * sizeof(*colors)); + return 0; +} + +int SDL_GetDisplayPalette(SDL_Color * colors, int firstcolor, int ncolors) { SDL_Palette *palette; @@ -725,18 +778,7 @@ SDL_UninitializedVideo(); return -1; } - palette = SDL_CurrentDisplay.palette; - if (!palette->ncolors) { - SDL_SetError("Display mode does not have a palette"); - return -1; - } - if (firstcolor < 0 || (firstcolor + ncolors) > palette->ncolors) { - SDL_SetError("Palette indices are out of range"); - return -1; - } - SDL_memcpy(colors, &palette->colors[firstcolor], - ncolors * sizeof(*colors)); - return 0; + return SDL_GetDisplayPaletteForDisplay(&SDL_CurrentDisplay, colors, firstcolor, ncolors); } SDL_WindowID @@ -835,6 +877,7 @@ _this->CreateWindowFrom(_this, &window, data) < 0) { return 0; } + /* FIXME: Find out what display this window is actually on... */ display = &SDL_CurrentDisplay; num_windows = display->num_windows; windows = @@ -1248,6 +1291,7 @@ if (FULLSCREEN_VISIBLE(window)) { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + SDL_DisplayMode fullscreen_mode; /* Hide any other fullscreen windows */ int i; @@ -1258,7 +1302,9 @@ } } - SDL_SetDisplayMode(&display->fullscreen_mode); + if (SDL_GetWindowDisplayMode(windowID, &fullscreen_mode) == 0) { + SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); + } } } else { window->flags &= ~SDL_WINDOW_FULLSCREEN; @@ -1336,11 +1382,11 @@ { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - if (window->flags & SDL_WINDOW_FULLSCREEN) { - SDL_SetDisplayMode(&display->fullscreen_mode); + if (FULLSCREEN_VISIBLE(window)) { + SDL_SetDisplayMode(&window->fullscreen_mode); } if (display->gamma && _this->SetDisplayGammaRamp) { - _this->SetDisplayGammaRamp(_this, display->gamma); + _this->SetDisplayGammaRamp(_this, display, display->gamma); } if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) && _this->SetWindowGrab) { @@ -1353,12 +1399,12 @@ { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - if (window->flags & SDL_WINDOW_FULLSCREEN) { + if (FULLSCREEN_VISIBLE(window)) { SDL_MinimizeWindow(window->id); SDL_SetDisplayMode(NULL); } if (display->gamma && _this->SetDisplayGammaRamp) { - _this->SetDisplayGammaRamp(_this, display->saved_gamma); + _this->SetDisplayGammaRamp(_this, display, display->saved_gamma); } if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) && _this->SetWindowGrab) { @@ -1430,16 +1476,10 @@ } void -SDL_AddRenderDriver(int displayIndex, const SDL_RenderDriver * driver) +SDL_AddRenderDriver(SDL_VideoDisplay * display, const SDL_RenderDriver * driver) { - SDL_VideoDisplay *display; SDL_RenderDriver *render_drivers; - if (displayIndex >= _this->num_displays) { - return; - } - display = &_this->displays[displayIndex]; - render_drivers = SDL_realloc(display->render_drivers, (display->num_render_drivers +