static Rectangle SDL_GetDisplayBounds(int displayIndex) { if (Check_Display_Index(displayIndex, out Exception e)) { throw e; } SDL_VideoDisplay display = _video.displays[displayIndex]; if (_video.GetDisplayBounds != null) { return(_video.GetDisplayBounds(_video, display)); } // Assume that the displays are left to right Rectangle rect; if (displayIndex == 0) { rect = Rectangle.Empty; rect.X = 0; rect.Y = 0; } else { rect = SDL_GetDisplayBounds(displayIndex - 1); rect.X += rect.Width;// 默认多屏向右拓展? } rect.Width = display.current_mode.w; rect.Height = display.current_mode.h; return(rect); }
static bool SDL_AddDisplayMode(SDL_VideoDisplay display, SDL_DisplayMode mode) { SDL_DisplayMode[] modes; int i, nmodes; // Make sure we don't already have the mode in the list modes = display.display_modes; nmodes = display.num_display_modes; for (i = nmodes; CBool(i--);) { if (CompareMemory(mode, modes[i]) == 0) { return(false); } } // Go ahead and add the new mode if (nmodes == display.max_display_modes) { modes = Resize(display.display_modes, display.max_display_modes + 32); display.display_modes = modes; display.max_display_modes += 32; } modes[nmodes] = mode; display.num_display_modes++; // Re-sort video modes Array.Sort(display.display_modes, 0, display.num_display_modes , Comparer <SDL_DisplayMode> .Create(CompareModes)); return(true); }
static void SDL_SetDisplayModeForDisplay(SDL_VideoDisplay display, SDL_DisplayMode mode) { SDL_DisplayMode display_mode; SDL_DisplayMode current_mode; if (mode != null) { display_mode = mode.DeepCopy(); // Default to the current mode if (!CBool(display_mode.format)) { display_mode.format = display.current_mode.format; } if (!CBool(display_mode.w)) { display_mode.w = display.current_mode.w; } if (!CBool(display_mode.h)) { display_mode.h = display.current_mode.h; } if (!CBool(display_mode.refresh_rate)) { display_mode.refresh_rate = display.current_mode.refresh_rate; } // Get a good video mode, the closest one possible if (SDL_GetClosestDisplayModeForDisplay(display , display_mode , display_mode) == null) { throw new NativeException("No video mode large enough for {0}x{1}" , display_mode.w , display_mode.h); } } else { display_mode = display.desktop_mode; } // See if there's anything left to do current_mode = display.current_mode; if (CompareMemory(display_mode, current_mode) == 0) { return; } // Actually change the display mode if (_video.SetDisplayMode == null) { throw new NativeException("Video driver doesn't support changing display mode"); } _video.SetDisplayMode(_video, display, display_mode); display.current_mode = display_mode; }
static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay display) { if (!CBool(display.num_display_modes) && CBool(_video.GetDisplayModes)) { _video.GetDisplayModes(_video, display); Array.Sort(display.display_modes, 0, display.num_display_modes , Comparer <SDL_DisplayMode> .Create(CompareModes)); } return(display.num_display_modes); }
static int SDL_AddVideoDisplay(SDL_VideoDisplay display) { SDL_VideoDisplay[] displays; int index; displays = Resize(_video.displays, _video.num_displays + 1); index = _video.num_displays++; displays[index] = display; displays[index].device = _video; _video.displays = displays; if (display.name == null) { displays[index].name = index.ToString(); } return(index); }
static void SDL_UpdateFullscreenMode(SDL_Window window, bool fullscreen) { SDL_VideoDisplay display = SDL_GetDisplayForWindow(window); SDL_Window other; if (fullscreen) { // Hide any other fullscreen windows if (display.fullscreen_window != null && display.fullscreen_window != window) { SDL_MinimizeWindow(window); } } // See if anything needs to be done now if ((display.fullscreen_window == window) == fullscreen) { return; } // See if there are any fullscreen windows for (other = _video.windows; other != null; other = other.next) { bool setDisplayMode = false; if (other == window) { setDisplayMode = fullscreen; } else if (Fullscreen_Visible(other) && SDL_GetDisplayForWindow(other) == display) { setDisplayMode = true; } if (setDisplayMode) { SDL_DisplayMode fullscreen_mode; try { fullscreen_mode = SDL_GetWindowDisplayMode(other); bool resized = true; if (other.w == fullscreen_mode.w && other.h == fullscreen_mode.h) { resized = false; } // only do the mode change if we want exclusive fullscreen if ((window.flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { SDL_SetDisplayModeForDisplay(display, fullscreen_mode); } else { SDL_SetDisplayModeForDisplay(display, null); } if (_video.SetWindowFullscreen != null) { _video.SetWindowFullscreen(_video, other, display, true); } } catch (NativeException e) { IgnoreInDebugWriteLine(e); } } } }
static SDL_DisplayMode SDL_GetClosestDisplayModeForDisplay( SDL_VideoDisplay display, SDL_DisplayMode mode, SDL_DisplayMode closest) { uint target_format; int target_refresh_rate; int i; SDL_DisplayMode current, match; if (CBool(mode) || CBool(closest)) { throw new NativeException("Missing desired mode or closest mode parameter"); } // Default to the desktop format if (CBool(mode.format)) { target_format = mode.format; } else { target_format = display.desktop_mode.format; } // Default to the desktop refresh rate if (CBool(mode.refresh_rate)) { target_refresh_rate = mode.refresh_rate; } else { target_refresh_rate = display.desktop_mode.refresh_rate; } match = null; for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) { current = display.display_modes[i]; if (CBool(current.w) && (current.w < mode.w)) { // Out of sorted modes large enough here break; } if (CBool(current.h) && (current.h < mode.h)) { if (CBool(current.w) && (current.w == mode.w)) { // Out of sorted modes large enough here break; } /* * Wider, but not tall enough, due to a different * aspect ratio. This mode must be skipped, but closer * modes may still follow. */ continue; } if (match == null || current.w < match.w || current.h < match.h) { match = current; continue; } if (current.format != match.format) { // Sorted highest depth to lowest if (current.format == target_format || (SDL_BitsPerPixel(current.format) >= SDL_BitsPerPixel(target_format) && SDL_PixelType(current.format) == SDL_PixelType(target_format)) ) { match = current; } continue; } if (current.refresh_rate != match.refresh_rate) { // Sorted highest refresh to lowest if (current.refresh_rate >= target_refresh_rate) { match = current; } } } if (match != null) { if (CBool(match.format)) { closest.format = match.format; } else { closest.format = mode.format; } if (CBool(match.w) && CBool(match.h)) { closest.w = match.w; closest.h = match.h; } else { closest.w = mode.w; closest.h = mode.h; } if (CBool(match.refresh_rate)) { closest.refresh_rate = match.refresh_rate; } else { closest.refresh_rate = mode.refresh_rate; } closest.driverdata = match.driverdata; // Pick some reasonable defaults if the app and driver don't care if (!CBool(closest.format)) { closest.format = SDL_PIXELFORMAT_RGB888; } if (!CBool(closest.w)) { closest.w = 640; } if (!CBool(closest.h)) { closest.h = 480; } return(closest); } return(null); }
static unsafe int SDL_GetWindowDisplayIndex(SDL_Window window) { int displayIndex; int i, dist; int closest = -1; int closest_dist = 0x7FFFFFFF; Point center = Point.Empty; Point delta = Point.Empty; Rectangle rect; if (Check_Window_Magic(window, out Exception e)) { throw e; } if (SDL_WindowPos_IsUndefined(window.x) || SDL_WindowPos_IsCentered(window.x)) { displayIndex = window.x & 0xFFFF; if (displayIndex >= _video.num_displays) { displayIndex = 0; } return(displayIndex); } if (SDL_WindowPos_IsUndefined(window.y) || SDL_WindowPos_IsCentered(window.y)) { displayIndex = window.y & 0xFFFF; if (displayIndex >= _video.num_displays) { displayIndex = 0; } return(displayIndex); } // Find the display containing the window for (i = 0; i < _video.num_displays; ++i) { SDL_VideoDisplay display = _video.displays[i]; if (display.fullscreen_window == window) { return(i); } } center.X = window.x + window.w / 2; center.Y = window.y + window.h / 2; for (i = 0; i < _video.num_displays; ++i) { rect = SDL_GetDisplayBounds(i); if (SDL_EnclosePoints(¢er, 1, &rect, null)) { return(i); } // 取两个中心点距离最小的那个 delta.X = center.X - (rect.X + rect.Width / 2); delta.Y = center.Y - (rect.Y + rect.Width / 2); dist = delta.X * delta.X + delta.Y * delta.Y;// 确保无负数 if (dist < closest_dist) { closest = i; closest_dist = dist; } } if (closest < 0) { throw new NativeException("Couldn't find any displays"); } return(closest); }