예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
 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);
 }
예제 #5
0
        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);
        }
예제 #6
0
        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);
                    }
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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(&center, 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);
        }