From db6c2c6140640a886a122b29e0bed916d5fc001f Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 13 Jul 2018 18:42:49 +1000 Subject: [PATCH] Simplify DisplayDevice --- OpenTK/DisplayDevice.cs | 68 ++++---------------- OpenTK/Platform/MacOS/QuartzDisplayDevice.cs | 35 ++++------ OpenTK/Platform/Windows/WinDisplayDevice.cs | 47 +++++--------- src/Client/DisplayDevice.c | 27 +------- src/Client/DisplayDevice.h | 11 +--- src/Client/WinPlatform.c | 40 ++++++------ 6 files changed, 64 insertions(+), 164 deletions(-) diff --git a/OpenTK/DisplayDevice.cs b/OpenTK/DisplayDevice.cs index 06563b88c..d890ac27d 100644 --- a/OpenTK/DisplayDevice.cs +++ b/OpenTK/DisplayDevice.cs @@ -11,29 +11,6 @@ using System.Drawing; namespace OpenTK { - /// Contains information regarding a monitor's display resolution. - public class DisplayResolution { - internal DisplayResolution() { } - - // Creates a new DisplayResolution object for the primary DisplayDevice. - internal DisplayResolution(int width, int height, int bitsPerPixel, int refreshRate) { - Width = width; Height = height; - BitsPerPixel = bitsPerPixel; RefreshRate = refreshRate; - } - - /// The width of this display in pixels. - public int Width; - - /// The height of this display in pixels. - public int Height; - - /// The number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. - public int BitsPerPixel; - - /// The vertical refresh rate of this display. - public int RefreshRate; - } - /// Defines a display device on the underlying system. public class DisplayDevice { // TODO: Add support for refresh rate queries and switches. @@ -41,51 +18,28 @@ namespace OpenTK { // TODO: Add properties that describe the 'usable' size of the Display, i.e. the maximized size without the taskbar etc. // TODO: Does not detect changes to primary device. - DisplayResolution curResolution = new DisplayResolution(); - Rectangle bounds; - static DisplayDevice() { Platform.Factory.Default.InitDisplayDeviceDriver(); } internal DisplayDevice() { } - internal DisplayDevice(DisplayResolution curResolution, bool primary) { - #warning "Consolidate current resolution with bounds? Can they fall out of sync right now?" - this.curResolution = curResolution; - IsPrimary = primary; - this.bounds = new Rectangle(0, 0, curResolution.Width, curResolution.Height); - } + /// Bounds of this Display in pixel coordinates. + public Rectangle Bounds; - /// Returns bounds of this instance in pixel coordinates. - public Rectangle Bounds { - get { return bounds; } - internal set { - bounds = value; - curResolution.Height = bounds.Height; - curResolution.Width = bounds.Width; - } - } + /// Width of this display in pixels. + public int Width { get { return Bounds.Width; } } - /// Returns width of this display in pixels. - public int Width { get { return curResolution.Width; } } + /// Height of this display in pixels. + public int Height { get { return Bounds.Height; } } - /// Returns height of this display in pixels. - public int Height { get { return curResolution.Height; } } + /// Number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. + public int BitsPerPixel; - /// Returns number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. - public int BitsPerPixel { - get { return curResolution.BitsPerPixel; } - internal set { curResolution.BitsPerPixel = value; } - } + /// Vertical refresh rate of this display. + public int RefreshRate; - /// Returns vertical refresh rate of this display. - public int RefreshRate { - get { return curResolution.RefreshRate; } - internal set { curResolution.RefreshRate = value; } - } - - /// Returns whether this Display is the primary Display in systems with multiple Displays. + /// Whether this Display is the primary Display in systems with multiple Displays. public bool IsPrimary { set { if (value) Primary = this; } } /// Data unique to this Display. diff --git a/OpenTK/Platform/MacOS/QuartzDisplayDevice.cs b/OpenTK/Platform/MacOS/QuartzDisplayDevice.cs index f00e9c7dd..d3f8262de 100644 --- a/OpenTK/Platform/MacOS/QuartzDisplayDevice.cs +++ b/OpenTK/Platform/MacOS/QuartzDisplayDevice.cs @@ -7,12 +7,6 @@ namespace OpenTK.Platform.MacOS { internal static IntPtr MainDisplay; internal unsafe static void Init() { - // To minimize the need to add static methods to OpenTK.Graphics.DisplayDevice - // we only allow settings to be set through its constructor. - // Thus, we save all necessary parameters in temporary variables - // and construct the device when every needed detail is available. - // The main DisplayDevice constructor adds the newly constructed device - // to the list of available devices. const int maxDisplayCount = 20; IntPtr[] displays = new IntPtr[maxDisplayCount]; int displayCount; @@ -38,29 +32,26 @@ namespace OpenTK.Platform.MacOS { int modesCount = CF.CFArrayGetCount(modes); Debug.Print("Supports {0} display modes.", modesCount); - DisplayResolution opentk_curRes = null; + DisplayDevice device = new DisplayDevice(); IntPtr curMode = CG.CGDisplayCurrentMode(curDisplay); + for (int j = 0; j < modesCount; j++) { IntPtr mode = CF.CFArrayGetValueAtIndex(modes, j); - - int width = (int)CF.DictGetNumber(mode, "Width"); - int height = (int)CF.DictGetNumber(mode, "Height"); - int bpp = (int)CF.DictGetNumber(mode, "BitsPerPixel"); - int freq = (int)CF.DictGetNumber(mode, "RefreshRate"); - - if (mode == curMode) { - opentk_curRes = new DisplayResolution(width, height, bpp, freq); - } + if (mode != curMode) continue; + + device.Bounds.Width = (int)CF.DictGetNumber(mode, "Width"); + device.Bounds.Height = (int)CF.DictGetNumber(mode, "Height"); + device.BitsPerPixel = (int)CF.DictGetNumber(mode, "BitsPerPixel"); + device.RefreshRate = (int)CF.DictGetNumber(mode, "RefreshRate"); } HIRect bounds = CG.CGDisplayBounds(curDisplay); - Rectangle newRect = new Rectangle( + device.Bounds = new Rectangle( (int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.X, (int)bounds.Size.Y); - Debug.Print("Display {0} bounds: {1}", i, newRect); - - DisplayDevice opentk_dev = new DisplayDevice(opentk_curRes, primary); - opentk_dev.Bounds = newRect; - opentk_dev.Metadata = curDisplay; + Debug.Print("Display {0} bounds: {1}", i, device.Bounds); + + device.Metadata = curDisplay; + device.IsPrimary = primary; } } } diff --git a/OpenTK/Platform/Windows/WinDisplayDevice.cs b/OpenTK/Platform/Windows/WinDisplayDevice.cs index c1cddc0a0..b8f23eab4 100644 --- a/OpenTK/Platform/Windows/WinDisplayDevice.cs +++ b/OpenTK/Platform/Windows/WinDisplayDevice.cs @@ -15,42 +15,29 @@ namespace OpenTK.Platform.Windows { /// Queries available display devices and display resolutions. internal static void Init() { - // To minimize the need to add static methods to OpenTK.Graphics.DisplayDevice - // we only allow settings to be set through its constructor. - // Thus, we save all necessary parameters in temporary variables - // and construct the device when every needed detail is available. - // The main DisplayDevice constructor adds the newly constructed device - // to the list of available devices. - DisplayResolution currentRes = null; - bool devPrimary = false; - int deviceNum = 0; - // Get available video adapters and enumerate all monitors - WindowsDisplayDevice winDev = new WindowsDisplayDevice(); - while (API.EnumDisplayDevices(null, deviceNum++, winDev, 0)) { - if ((winDev.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == 0) - continue; - + int displayNum = 0; + WindowsDisplayDevice display = new WindowsDisplayDevice(); + + while (API.EnumDisplayDevices(null, displayNum++, display, 0)) { + if ((display.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == 0) continue; DeviceMode mode = new DeviceMode(); // The second function should only be executed when the first one fails (e.g. when the monitor is disabled) - if (API.EnumDisplaySettings(winDev.DeviceName, (int)DisplayModeSettings.Current, mode) || - API.EnumDisplaySettings(winDev.DeviceName, (int)DisplayModeSettings.Registry, mode)) { - if (mode.BitsPerPel > 0) { - currentRes = new DisplayResolution( - mode.PelsWidth, mode.PelsHeight, - mode.BitsPerPel, mode.DisplayFrequency); - devPrimary = (winDev.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0; - } + if (API.EnumDisplaySettings(display.DeviceName, (int)DisplayModeSettings.Current, mode) || + API.EnumDisplaySettings(display.DeviceName, (int)DisplayModeSettings.Registry, mode)) { + } else { + mode.BitsPerPel = 0; } - // This device has no valid resolution, ignore it - if (currentRes == null) continue; - - // Construct the OpenTK DisplayDevice through the accumulated parameters. - // The constructor automatically adds the DisplayDevice to the list of available devices. - DisplayDevice device = new DisplayDevice(currentRes, devPrimary); - currentRes = null; + if (mode.BitsPerPel == 0) continue; + DisplayDevice device = new DisplayDevice(); + + device.Bounds.Width = mode.PelsWidth; + device.Bounds.Height = mode.PelsHeight; + device.BitsPerPixel = mode.BitsPerPel; + device.RefreshRate = mode.DisplayFrequency; + device.IsPrimary = (display.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0; } } } diff --git a/src/Client/DisplayDevice.c b/src/Client/DisplayDevice.c index 50ee7cc96..969e30611 100644 --- a/src/Client/DisplayDevice.c +++ b/src/Client/DisplayDevice.c @@ -1,33 +1,10 @@ #include "DisplayDevice.h" -DisplayResolution DisplayResolution_Make(Int32 width, Int32 height, Int32 bitsPerPixel, Int32 refreshRate) { - DisplayResolution res; - res.Width = width; res.Height = height; - res.BitsPerPixel = bitsPerPixel; res.RefreshRate = refreshRate; - return res; -} - -DisplayDevice DisplayDevice_Make(DisplayResolution* curResolution) { - DisplayDevice device; - device.CurResolution = *curResolution; - device.Bounds = Rectangle2D_Make(0, 0, curResolution->Width, curResolution->Height); - device.Metadata = NULL; - return device; -} - -void DisplayDevice_SetBounds(DisplayDevice* device, Rectangle2D* bounds) { - device->Bounds = *bounds; - device->CurResolution.Width = bounds->Width; - device->CurResolution.Height = bounds->Height; -} - #if !CC_BUILD_D3D9 ColorFormat ColorFormat_FromBPP(Int32 bpp) { - ColorFormat format; - format.R = 0; format.G = 0; format.B = 0; format.A = 0; + ColorFormat format = { 0 }; format.BitsPerPixel = bpp; - format.IsIndexed = false; UInt8 rba; switch (bpp) { @@ -81,7 +58,7 @@ GraphicsMode GraphicsMode_Make(ColorFormat color, UInt8 depth, UInt8 stencil, UI } GraphicsMode GraphicsMode_MakeDefault(void) { - Int32 bpp = DisplayDevice_Default.CurResolution.BitsPerPixel; + Int32 bpp = DisplayDevice_Default.BitsPerPixel; ColorFormat format = ColorFormat_FromBPP(bpp); return GraphicsMode_Make(format, 24, 0, 2); } diff --git a/src/Client/DisplayDevice.h b/src/Client/DisplayDevice.h index 94bcda279..5fd06cc6b 100644 --- a/src/Client/DisplayDevice.h +++ b/src/Client/DisplayDevice.h @@ -12,22 +12,13 @@ * See license.txt for licensing detailed licensing details. */ -typedef struct DisplayResolution_ { +typedef struct DisplayDevice_ { Int32 Width, Height, BitsPerPixel; /* The vertical refresh rate of this display. */ Int32 RefreshRate; -} DisplayResolution; -DisplayResolution DisplayResolution_Make(Int32 width, Int32 height, Int32 bitsPerPixel, Int32 refreshRate); - - -typedef struct DisplayDevice_ { - DisplayResolution CurResolution; Rectangle2D Bounds; void* Metadata; } DisplayDevice; - -DisplayDevice DisplayDevice_Make(DisplayResolution* curResolution); -void DisplayDevice_SetBounds(DisplayDevice* device, Rectangle2D* bounds); /* The primary / default / main display device. */ DisplayDevice DisplayDevice_Default; diff --git a/src/Client/WinPlatform.c b/src/Client/WinPlatform.c index efb6da7f5..845bd513a 100644 --- a/src/Client/WinPlatform.c +++ b/src/Client/WinPlatform.c @@ -43,33 +43,33 @@ void Platform_Init(void) { ReturnCode wsaResult = WSAStartup(MAKEWORD(2, 2), &wsaData); ErrorHandler_CheckOrFail(wsaResult, "WSAStartup failed"); - UInt32 deviceNum = 0; /* Get available video adapters and enumerate all monitors */ - DISPLAY_DEVICEW device = { 0 }; - device.cb = sizeof(DISPLAY_DEVICEW); + UInt32 displayNum = 0; + DISPLAY_DEVICEW display = { 0 }; display.cb = sizeof(DISPLAY_DEVICEW); - while (EnumDisplayDevicesW(NULL, deviceNum, &device, 0)) { - deviceNum++; - if ((device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == 0) continue; - bool devPrimary = false; - DisplayResolution resolution = { 0 }; - DEVMODEW mode = { 0 }; - mode.dmSize = sizeof(DEVMODEW); + while (EnumDisplayDevicesW(NULL, displayNum, &display, 0)) { + displayNum++; + if ((display.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == 0) continue; + DEVMODEW mode = { 0 }; mode.dmSize = sizeof(DEVMODEW); /* The second function should only be executed when the first one fails (e.g. when the monitor is disabled) */ - if (EnumDisplaySettingsW(device.DeviceName, ENUM_CURRENT_SETTINGS, &mode) || - EnumDisplaySettingsW(device.DeviceName, ENUM_REGISTRY_SETTINGS, &mode)) { - if (mode.dmBitsPerPel > 0) { - resolution = DisplayResolution_Make(mode.dmPelsWidth, mode.dmPelsHeight, - mode.dmBitsPerPel, mode.dmDisplayFrequency); - devPrimary = (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0; - } + if (EnumDisplaySettingsW(display.DeviceName, ENUM_CURRENT_SETTINGS, &mode) || + EnumDisplaySettingsW(display.DeviceName, ENUM_REGISTRY_SETTINGS, &mode)) { + } else { + mode.dmBitsPerPel = 0; } /* This device has no valid resolution, ignore it */ - if (resolution.Width == 0 && resolution.Height == 0) continue; - if (!devPrimary) continue; - DisplayDevice_Default = DisplayDevice_Make(&resolution); + if (mode.dmBitsPerPel == 0) continue; + bool isPrimary = (display.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0; + if (!isPrimary) continue; + + DisplayDevice device = { 0 }; + device.Bounds.Width = mode.dmPelsWidth; + device.Bounds.Height = mode.dmPelsHeight; + device.BitsPerPixel = mode.dmBitsPerPel; + device.RefreshRate = mode.dmDisplayFrequency; + DisplayDevice_Default = device; } }