mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-24 05:10:42 -04:00
Significantly simplify DisplayDevice
This commit is contained in:
parent
e24ef9e4e6
commit
a968a137a1
@ -20,40 +20,32 @@ 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 current_resolution = new DisplayResolution(), original_resolution;
|
||||
List<DisplayResolution> available_resolutions = new List<DisplayResolution>();
|
||||
IList<DisplayResolution> available_resolutions_readonly;
|
||||
DisplayResolution current_resolution = new DisplayResolution();
|
||||
bool primary;
|
||||
Rectangle bounds;
|
||||
|
||||
static readonly List<DisplayDevice> available_displays = new List<DisplayDevice>();
|
||||
static readonly IList<DisplayDevice> available_displays_readonly;
|
||||
static DisplayDevice primary_display;
|
||||
static Platform.IDisplayDeviceDriver implementation;
|
||||
|
||||
static DisplayDevice() {
|
||||
implementation = Platform.Factory.Default.CreateDisplayDeviceDriver();
|
||||
available_displays_readonly = available_displays.AsReadOnly();
|
||||
}
|
||||
|
||||
internal DisplayDevice() {
|
||||
available_displays.Add(this);
|
||||
available_resolutions_readonly = available_resolutions.AsReadOnly();
|
||||
}
|
||||
internal DisplayDevice() { AvailableDisplays.Add(this); }
|
||||
|
||||
internal DisplayDevice(DisplayResolution currentResolution, bool primary,
|
||||
IEnumerable<DisplayResolution> availableResolutions, Rectangle bounds) : this() {
|
||||
IEnumerable<DisplayResolution> resolutions, Rectangle bounds) : this() {
|
||||
#warning "Consolidate current resolution with bounds? Can they fall out of sync right now?"
|
||||
this.current_resolution = currentResolution;
|
||||
IsPrimary = primary;
|
||||
this.available_resolutions.AddRange(availableResolutions);
|
||||
AvailableResolutions.AddRange(resolutions);
|
||||
this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
|
||||
|
||||
Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
|
||||
available_displays.Count, primary ? "primary" : "secondary", available_resolutions.Count);
|
||||
AvailableDisplays.Count, primary ? "primary" : "secondary", AvailableResolutions.Count);
|
||||
}
|
||||
|
||||
/// <summary> Gets the bounds of this instance in pixel coordinates. </summary>
|
||||
/// <summary> Returns bounds of this instance in pixel coordinates. </summary>
|
||||
public Rectangle Bounds {
|
||||
get { return bounds; }
|
||||
internal set {
|
||||
@ -63,25 +55,25 @@ namespace OpenTK {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the width of this display in pixels.</summary>
|
||||
/// <summary> Returns width of this display in pixels. </summary>
|
||||
public int Width { get { return current_resolution.Width; } }
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the height of this display in pixels.</summary>
|
||||
/// <summary> Returns height of this display in pixels. </summary>
|
||||
public int Height { get { return current_resolution.Height; } }
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32.</summary>
|
||||
/// <summary> Returns number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. </summary>
|
||||
public int BitsPerPixel {
|
||||
get { return current_resolution.BitsPerPixel; }
|
||||
internal set { current_resolution.BitsPerPixel = value; }
|
||||
}
|
||||
|
||||
/// <summary> Gets a System.Single representing the vertical refresh rate of this display. </summary>
|
||||
/// <summary> Returns vertical refresh rate of this display. </summary>
|
||||
public float RefreshRate {
|
||||
get { return current_resolution.RefreshRate; }
|
||||
internal set { current_resolution.RefreshRate = value; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Boolean that indicates whether this Display is the primary Display in systems with multiple Displays.</summary>
|
||||
/// <summary> Returns whether this Display is the primary Display in systems with multiple Displays.</summary>
|
||||
public bool IsPrimary {
|
||||
get { return primary; }
|
||||
internal set {
|
||||
@ -93,108 +85,24 @@ namespace OpenTK {
|
||||
primary_display = this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Data unique to this Display. </summary>
|
||||
public object Metadata;
|
||||
|
||||
/// <summary> Selects an available resolution that matches the specified parameters. </summary>
|
||||
/// <param name="width">The width of the requested resolution in pixels.</param>
|
||||
/// <param name="height">The height of the requested resolution in pixels.</param>
|
||||
/// <param name="bitsPerPixel">The bits per pixel of the requested resolution.</param>
|
||||
/// <param name="refreshRate">The refresh rate of the requested resolution in hertz.</param>
|
||||
/// <returns>The requested DisplayResolution or null if the parameters cannot be met.</returns>
|
||||
/// <remarks> <para>If a matching resolution is not found, this function will retry ignoring the specified refresh rate,
|
||||
/// bits per pixel and resolution, in this order. If a matching resolution still doesn't exist, this function will
|
||||
/// return the current resolution.</para>
|
||||
/// <para>A parameter set to 0 or negative numbers will not be used in the search (e.g. if refreshRate is 0,
|
||||
/// any refresh rate will be considered valid).</para>
|
||||
/// <para>This function allocates memory.</para> </remarks>
|
||||
public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate) {
|
||||
DisplayResolution resolution = FindResolution(width, height, bitsPerPixel, refreshRate);
|
||||
if (resolution == null)
|
||||
resolution = FindResolution(width, height, bitsPerPixel, 0);
|
||||
if (resolution == null)
|
||||
resolution = FindResolution(width, height, 0, 0);
|
||||
if (resolution == null)
|
||||
return current_resolution;
|
||||
return resolution;
|
||||
}
|
||||
/// <summary> The list of <see cref="DisplayResolution"/> objects available on this device. </summary>
|
||||
public List<DisplayResolution> AvailableResolutions = new List<DisplayResolution>();
|
||||
|
||||
/// <summary> Gets the list of <see cref="DisplayResolution"/> objects available on this device. </summary>
|
||||
public IList<DisplayResolution> AvailableResolutions {
|
||||
get { return available_resolutions_readonly; }
|
||||
internal set
|
||||
{
|
||||
available_resolutions = (List<DisplayResolution>)value;
|
||||
available_resolutions_readonly = available_resolutions.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Changes the resolution of the DisplayDevice.</summary>
|
||||
/// <param name="resolution">The resolution to set. <see cref="DisplayDevice.SelectResolution"/></param>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
|
||||
/// <remarks>If the specified resolution is null, this function will restore the original DisplayResolution.</remarks>
|
||||
public void ChangeResolution(DisplayResolution resolution) {
|
||||
if (resolution == null)
|
||||
this.RestoreResolution();
|
||||
|
||||
if (resolution == current_resolution)
|
||||
return;
|
||||
|
||||
if (implementation.TryChangeResolution(this, resolution)) {
|
||||
if (original_resolution == null)
|
||||
original_resolution = current_resolution;
|
||||
current_resolution = resolution;
|
||||
} else
|
||||
throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}.",
|
||||
this, resolution));
|
||||
}
|
||||
|
||||
/// <summary>Changes the resolution of the DisplayDevice.</summary>
|
||||
/// <param name="width">The new width of the DisplayDevice.</param>
|
||||
/// <param name="height">The new height of the DisplayDevice.</param>
|
||||
/// <param name="bitsPerPixel">The new bits per pixel of the DisplayDevice.</param>
|
||||
/// <param name="refreshRate">The new refresh rate of the DisplayDevice.</param>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
|
||||
public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate) {
|
||||
this.ChangeResolution(this.SelectResolution(width, height, bitsPerPixel, refreshRate));
|
||||
}
|
||||
|
||||
/// <summary>Restores the original resolution of the DisplayDevice.</summary>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the original resolution could not be restored.</exception>
|
||||
public void RestoreResolution() {
|
||||
if (original_resolution != null) {
|
||||
if (implementation.TryRestoreResolution(this)) {
|
||||
current_resolution = original_resolution;
|
||||
original_resolution = null;
|
||||
} else
|
||||
throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to restore resolution.", this));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the list of available <see cref="DisplayDevice"/> objects. </summary>
|
||||
public static IList<DisplayDevice> AvailableDisplays {
|
||||
get { return available_displays_readonly; }
|
||||
}
|
||||
/// <summary> The list of available <see cref="DisplayDevice"/> objects. </summary>
|
||||
public static List<DisplayDevice> AvailableDisplays = new List<DisplayDevice>();
|
||||
|
||||
/// <summary>Gets the default (primary) display of this system.</summary>
|
||||
public static DisplayDevice Default { get { return primary_display; } }
|
||||
|
||||
DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate) {
|
||||
for (int i = 0; i < available_resolutions.Count; i++) {
|
||||
DisplayResolution res = available_resolutions[i];
|
||||
bool match = ((width > 0 && width == res.Width) || width == 0) &&
|
||||
((height > 0 && height == res.Height) || height == 0) &&
|
||||
((bitsPerPixel > 0 && bitsPerPixel == res.BitsPerPixel) || bitsPerPixel == 0) &&
|
||||
((refreshRate > 0 && System.Math.Abs(refreshRate - res.RefreshRate) < 1.0) || refreshRate == 0);
|
||||
|
||||
if (match) return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary> Returns a System.String representing this DisplayDevice. </summary>
|
||||
/// <returns>A System.String representing this DisplayDevice.</returns>
|
||||
public override string ToString() {
|
||||
return String.Format("{0}: {1} ({2} modes available)", IsPrimary ? "Primary" : "Secondary",
|
||||
Bounds.ToString(), available_resolutions.Count);
|
||||
Bounds.ToString(), AvailableResolutions.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ using OpenTK.Platform;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
public enum GameWindowFlags { Default = 0 };
|
||||
|
||||
/// <summary>
|
||||
/// The GameWindow class contains cross-platform methods to create and render on an OpenGL
|
||||
/// window, handle input and load resources.
|
||||
|
@ -1,41 +0,0 @@
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK {
|
||||
|
||||
/// <summary> Defines bitwise combianations of GameWindow construction options. </summary>
|
||||
[Flags]
|
||||
public enum GameWindowFlags {
|
||||
/// <summary> Indicates default construction options. </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary> Indicates that the GameWindow should cover the whole screen. </summary>
|
||||
Fullscreen = 1,
|
||||
}
|
||||
}
|
@ -86,11 +86,6 @@ namespace OpenTK {
|
||||
this.device = device;
|
||||
|
||||
implementation = Factory.Default.CreateNativeWindow(x, y, width, height, title, mode, options, this.device);
|
||||
|
||||
if ((options & GameWindowFlags.Fullscreen) != 0) {
|
||||
this.device.ChangeResolution(width, height, mode.ColorFormat.BitsPerPixel, 0);
|
||||
WindowState = WindowState.Fullscreen;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Closes the NativeWindow. </summary>
|
||||
@ -271,10 +266,6 @@ namespace OpenTK {
|
||||
/// <summary> Releases all non-managed resources belonging to this NativeWindow. </summary>
|
||||
public virtual void Dispose() {
|
||||
if (!IsDisposed) {
|
||||
if ((options & GameWindowFlags.Fullscreen) != 0) {
|
||||
//if (WindowState == WindowState.Fullscreen) WindowState = WindowState.Normal; // TODO: Revise.
|
||||
device.RestoreResolution();
|
||||
}
|
||||
implementation.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
IsDisposed = true;
|
||||
|
@ -1,160 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{35FEE071-2DE6-48A1-9343-B5C1F202A12B}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>OpenTK</RootNamespace>
|
||||
<AssemblyName>OpenTK</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<NoWin32Manifest>False</NoWin32Manifest>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<NoStdLib>False</NoStdLib>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<BaseAddress>4194304</BaseAddress>
|
||||
<RegisterForComInterop>False</RegisterForComInterop>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug'">
|
||||
<OutputPath>..\output\debug\</OutputPath>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<OutputPath>..\output\release\</OutputPath>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
<StartAction>Project</StartAction>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BindingsBase.cs" />
|
||||
<Compile Include="Debug.cs" />
|
||||
<Compile Include="DisplayDevice.cs" />
|
||||
<Compile Include="DisplayResolution.cs" />
|
||||
<Compile Include="FrameEventArgs.cs" />
|
||||
<Compile Include="GameWindow.cs" />
|
||||
<Compile Include="GameWindowFlags.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GL.cs" />
|
||||
<Compile Include="IGameWindow.cs" />
|
||||
<Compile Include="INativeWindow.cs" />
|
||||
<Compile Include="Interop.cs" />
|
||||
<Compile Include="KeyPressEventArgs.cs" />
|
||||
<Compile Include="MemUtils.cs" />
|
||||
<Compile Include="NativeWindow.cs" />
|
||||
<Compile Include="Graphics\ColorFormat.cs" />
|
||||
<Compile Include="Graphics\GraphicsContextBase.cs" />
|
||||
<Compile Include="Graphics\GraphicsContextException.cs" />
|
||||
<Compile Include="Graphics\GraphicsMode.cs" />
|
||||
<Compile Include="Graphics\GraphicsModeException.cs" />
|
||||
<Compile Include="Graphics\IGraphicsContext.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GLEnums.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GLHelper.cs" />
|
||||
<Compile Include="Input\Key.cs" />
|
||||
<Compile Include="Input\KeyboardDevice.cs" />
|
||||
<Compile Include="Input\MouseButton.cs" />
|
||||
<Compile Include="Input\MouseDevice.cs" />
|
||||
<Compile Include="Math\Matrix4.cs" />
|
||||
<Compile Include="Math\Vector2.cs" />
|
||||
<Compile Include="Math\Vector3.cs" />
|
||||
<Compile Include="Math\Vector4.cs" />
|
||||
<Compile Include="Platform\Configuration.cs" />
|
||||
<Compile Include="Platform\IDisplayDeviceDriver.cs" />
|
||||
<Compile Include="Platform\IPlatformFactory.cs" />
|
||||
<Compile Include="Platform\IWindowInfo.cs" />
|
||||
<Compile Include="Platform\MacOS\AglContext.cs" />
|
||||
<Compile Include="Platform\MacOS\Application.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\Agl.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\CarbonAPI.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\CoreFoundation.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\MacOSKeys.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\QuartzDisplayServicesAPI.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonGLNative.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonWindowInfo.cs" />
|
||||
<Compile Include="Platform\MacOS\MacOSException.cs" />
|
||||
<Compile Include="Platform\MacOS\MacOSKeyMap.cs" />
|
||||
<Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" />
|
||||
<Compile Include="Platform\PlatformException.cs" />
|
||||
<Compile Include="Platform\Windows\API.cs" />
|
||||
<Compile Include="Platform\Windows\Wgl.cs" />
|
||||
<Compile Include="Platform\Windows\WinDisplayDevice.cs" />
|
||||
<Compile Include="Platform\Windows\WinGLContext.cs" />
|
||||
<Compile Include="Platform\Windows\WinGLNative.cs" />
|
||||
<Compile Include="Platform\Windows\WinKeyMap.cs" />
|
||||
<Compile Include="Platform\Windows\WinWindowInfo.cs" />
|
||||
<Compile Include="Platform\NullContext.cs" />
|
||||
<Compile Include="Platform\X11\API.cs" />
|
||||
<Compile Include="Platform\X11\Functions.cs" />
|
||||
<Compile Include="Platform\X11\Glx.cs" />
|
||||
<Compile Include="Platform\X11\Structs.cs" />
|
||||
<Compile Include="Platform\X11\X11DisplayDevice.cs" />
|
||||
<Compile Include="Platform\X11\X11GLContext.cs" />
|
||||
<Compile Include="Platform\X11\X11GLNative.cs" />
|
||||
<Compile Include="Platform\X11\X11KeyMap.cs" />
|
||||
<Compile Include="Platform\X11\X11WindowInfo.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\AdapterDetails.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\AdapterInformation.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Device.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Direct3D.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\DisplayMode.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Enumerations.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\PresentParameters.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Resources.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Structures.cs" />
|
||||
<Compile Include="SharpDX\ComObject.cs" />
|
||||
<Compile Include="SharpDX\Raw.cs" />
|
||||
<Compile Include="SharpDX\Result.cs" />
|
||||
<Compile Include="WindowState.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Graphics" />
|
||||
<Folder Include="Graphics\OpenGL" />
|
||||
<Folder Include="Input" />
|
||||
<Folder Include="Math" />
|
||||
<Folder Include="Platform" />
|
||||
<Folder Include="Platform\MacOS" />
|
||||
<Folder Include="Platform\MacOS\CarbonBindings" />
|
||||
<Folder Include="Platform\Windows" />
|
||||
<Folder Include="Platform\X11" />
|
||||
<Folder Include="Properties" />
|
||||
<Folder Include="SharpDX" />
|
||||
<Folder Include="SharpDX.Direct3D" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\InteropPatcher\InteropPatcher.csproj">
|
||||
<Project>{4A4110EE-21CA-4715-AF67-0C8B7CE0642F}</Project>
|
||||
<Name>InteropPatcher</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||
<!-- This actually rewrites the calli and fixed code.-->
|
||||
<Target Name="AfterBuild">
|
||||
<Exec Command="$(OutputPath)InteropPatcher.exe $(OutDir)OpenTK.dll" />
|
||||
<!--Copy back *.dll from bin/Debug|Release to obj/Debug/Release directory-->
|
||||
<Copy SourceFiles="@(MainAssembly)" DestinationFolder="$(IntermediateOutputPath)" SkipUnchangedFiles="true" />
|
||||
<!-- Copy back *.pdb from bin/Debug|Release to obj/Debug/Release directory-->
|
||||
<Copy SourceFiles="@(_DebugSymbolsOutputPath)" DestinationFiles="@(_DebugSymbolsIntermediatePath)" SkipUnchangedFiles="true" Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true'" />
|
||||
</Target>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{35FEE071-2DE6-48A1-9343-B5C1F202A12B}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>OpenTK</RootNamespace>
|
||||
<AssemblyName>OpenTK</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<NoWin32Manifest>False</NoWin32Manifest>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<NoStdLib>False</NoStdLib>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<BaseAddress>4194304</BaseAddress>
|
||||
<RegisterForComInterop>False</RegisterForComInterop>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug'">
|
||||
<OutputPath>..\output\debug\</OutputPath>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<OutputPath>..\output\release\</OutputPath>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
<StartAction>Project</StartAction>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BindingsBase.cs" />
|
||||
<Compile Include="Debug.cs" />
|
||||
<Compile Include="DisplayDevice.cs" />
|
||||
<Compile Include="DisplayResolution.cs" />
|
||||
<Compile Include="FrameEventArgs.cs" />
|
||||
<Compile Include="GameWindow.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GL.cs" />
|
||||
<Compile Include="IGameWindow.cs" />
|
||||
<Compile Include="INativeWindow.cs" />
|
||||
<Compile Include="Interop.cs" />
|
||||
<Compile Include="KeyPressEventArgs.cs" />
|
||||
<Compile Include="MemUtils.cs" />
|
||||
<Compile Include="NativeWindow.cs" />
|
||||
<Compile Include="Graphics\ColorFormat.cs" />
|
||||
<Compile Include="Graphics\GraphicsContextBase.cs" />
|
||||
<Compile Include="Graphics\GraphicsContextException.cs" />
|
||||
<Compile Include="Graphics\GraphicsMode.cs" />
|
||||
<Compile Include="Graphics\GraphicsModeException.cs" />
|
||||
<Compile Include="Graphics\IGraphicsContext.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GLEnums.cs" />
|
||||
<Compile Include="Graphics\OpenGL\GLHelper.cs" />
|
||||
<Compile Include="Input\Key.cs" />
|
||||
<Compile Include="Input\KeyboardDevice.cs" />
|
||||
<Compile Include="Input\MouseButton.cs" />
|
||||
<Compile Include="Input\MouseDevice.cs" />
|
||||
<Compile Include="Math\Matrix4.cs" />
|
||||
<Compile Include="Math\Vector2.cs" />
|
||||
<Compile Include="Math\Vector3.cs" />
|
||||
<Compile Include="Math\Vector4.cs" />
|
||||
<Compile Include="Platform\Configuration.cs" />
|
||||
<Compile Include="Platform\IDisplayDeviceDriver.cs" />
|
||||
<Compile Include="Platform\IPlatformFactory.cs" />
|
||||
<Compile Include="Platform\IWindowInfo.cs" />
|
||||
<Compile Include="Platform\MacOS\AglContext.cs" />
|
||||
<Compile Include="Platform\MacOS\Application.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\Agl.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\CarbonAPI.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\CoreFoundation.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\MacOSKeys.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonBindings\QuartzDisplayServicesAPI.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonGLNative.cs" />
|
||||
<Compile Include="Platform\MacOS\CarbonWindowInfo.cs" />
|
||||
<Compile Include="Platform\MacOS\MacOSException.cs" />
|
||||
<Compile Include="Platform\MacOS\MacOSKeyMap.cs" />
|
||||
<Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" />
|
||||
<Compile Include="Platform\PlatformException.cs" />
|
||||
<Compile Include="Platform\Windows\API.cs" />
|
||||
<Compile Include="Platform\Windows\Wgl.cs" />
|
||||
<Compile Include="Platform\Windows\WinDisplayDevice.cs" />
|
||||
<Compile Include="Platform\Windows\WinGLContext.cs" />
|
||||
<Compile Include="Platform\Windows\WinGLNative.cs" />
|
||||
<Compile Include="Platform\Windows\WinKeyMap.cs" />
|
||||
<Compile Include="Platform\Windows\WinWindowInfo.cs" />
|
||||
<Compile Include="Platform\NullContext.cs" />
|
||||
<Compile Include="Platform\X11\API.cs" />
|
||||
<Compile Include="Platform\X11\Functions.cs" />
|
||||
<Compile Include="Platform\X11\Glx.cs" />
|
||||
<Compile Include="Platform\X11\Structs.cs" />
|
||||
<Compile Include="Platform\X11\X11DisplayDevice.cs" />
|
||||
<Compile Include="Platform\X11\X11GLContext.cs" />
|
||||
<Compile Include="Platform\X11\X11GLNative.cs" />
|
||||
<Compile Include="Platform\X11\X11KeyMap.cs" />
|
||||
<Compile Include="Platform\X11\X11WindowInfo.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\AdapterDetails.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\AdapterInformation.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Device.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Direct3D.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\DisplayMode.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Enumerations.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\PresentParameters.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Resources.cs" />
|
||||
<Compile Include="SharpDX.Direct3D\Structures.cs" />
|
||||
<Compile Include="SharpDX\ComObject.cs" />
|
||||
<Compile Include="SharpDX\Raw.cs" />
|
||||
<Compile Include="SharpDX\Result.cs" />
|
||||
<Compile Include="WindowState.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Graphics" />
|
||||
<Folder Include="Graphics\OpenGL" />
|
||||
<Folder Include="Input" />
|
||||
<Folder Include="Math" />
|
||||
<Folder Include="Platform" />
|
||||
<Folder Include="Platform\MacOS" />
|
||||
<Folder Include="Platform\MacOS\CarbonBindings" />
|
||||
<Folder Include="Platform\Windows" />
|
||||
<Folder Include="Platform\X11" />
|
||||
<Folder Include="Properties" />
|
||||
<Folder Include="SharpDX" />
|
||||
<Folder Include="SharpDX.Direct3D" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\InteropPatcher\InteropPatcher.csproj">
|
||||
<Project>{4A4110EE-21CA-4715-AF67-0C8B7CE0642F}</Project>
|
||||
<Name>InteropPatcher</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||
<!-- This actually rewrites the calli and fixed code.-->
|
||||
<Target Name="AfterBuild">
|
||||
<Exec Command="$(OutputPath)InteropPatcher.exe $(OutDir)OpenTK.dll" />
|
||||
<!--Copy back *.dll from bin/Debug|Release to obj/Debug/Release directory-->
|
||||
<Copy SourceFiles="@(MainAssembly)" DestinationFolder="$(IntermediateOutputPath)" SkipUnchangedFiles="true" />
|
||||
<!-- Copy back *.pdb from bin/Debug|Release to obj/Debug/Release directory-->
|
||||
<Copy SourceFiles="@(_DebugSymbolsOutputPath)" DestinationFiles="@(_DebugSymbolsIntermediatePath)" SkipUnchangedFiles="true" Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true'" />
|
||||
</Target>
|
||||
</Project>
|
@ -1,18 +1,15 @@
|
||||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
internal interface IDisplayDeviceDriver
|
||||
{
|
||||
bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
|
||||
bool TryRestoreResolution(DisplayDevice device);
|
||||
}
|
||||
}
|
||||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
internal interface IDisplayDeviceDriver {
|
||||
}
|
||||
}
|
||||
|
@ -1,155 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenTK.Platform.MacOS.Carbon;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
class QuartzDisplayDeviceDriver : IDisplayDeviceDriver
|
||||
{
|
||||
static Dictionary<DisplayDevice, IntPtr> displayMap =
|
||||
new Dictionary<DisplayDevice, IntPtr>();
|
||||
|
||||
static IntPtr mainDisplay;
|
||||
internal static IntPtr MainDisplay { get { return mainDisplay; } }
|
||||
|
||||
unsafe static QuartzDisplayDeviceDriver() {
|
||||
// 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;
|
||||
fixed(IntPtr* displayPtr = displays) {
|
||||
CG.CGGetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount);
|
||||
}
|
||||
|
||||
Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
|
||||
|
||||
for (int i = 0; i < displayCount; i++) {
|
||||
IntPtr curDisplay = displays[i];
|
||||
|
||||
// according to docs, first element in the array is always the main display.
|
||||
bool primary = (i == 0);
|
||||
if (primary)
|
||||
mainDisplay = curDisplay;
|
||||
|
||||
// gets current settings
|
||||
int currentWidth = CG.CGDisplayPixelsWide(curDisplay);
|
||||
int currentHeight = CG.CGDisplayPixelsHigh(curDisplay);
|
||||
Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight);
|
||||
|
||||
IntPtr displayModesPtr = CG.CGDisplayAvailableModes(curDisplay);
|
||||
CFArray displayModes = new CFArray(displayModesPtr);
|
||||
Debug.Print("Supports {0} display modes.", displayModes.Count);
|
||||
|
||||
DisplayResolution opentk_dev_current_res = null;
|
||||
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
|
||||
IntPtr currentModePtr = CG.CGDisplayCurrentMode(curDisplay);
|
||||
CFDictionary currentMode = new CFDictionary(currentModePtr);
|
||||
|
||||
for (int j = 0; j < displayModes.Count; j++)
|
||||
{
|
||||
CFDictionary dict = new CFDictionary(displayModes[j]);
|
||||
|
||||
int width = (int) dict.GetNumberValue("Width");
|
||||
int height = (int) dict.GetNumberValue("Height");
|
||||
int bpp = (int) dict.GetNumberValue("BitsPerPixel");
|
||||
double freq = dict.GetNumberValue("RefreshRate");
|
||||
bool current = currentMode.DictRef == dict.DictRef;
|
||||
|
||||
//if (current) Debug.Write(" * ");
|
||||
//else Debug.Write(" ");
|
||||
|
||||
//Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq);
|
||||
|
||||
DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq);
|
||||
opentk_dev_available_res.Add(thisRes);
|
||||
|
||||
if (current)
|
||||
opentk_dev_current_res = thisRes;
|
||||
}
|
||||
|
||||
HIRect bounds = CG.CGDisplayBounds(curDisplay);
|
||||
Rectangle newRect = 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_dev_current_res, primary, opentk_dev_available_res, newRect);
|
||||
|
||||
displayMap.Add(opentk_dev, curDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
internal static IntPtr HandleTo(DisplayDevice displayDevice) {
|
||||
if (displayMap.ContainsKey(displayDevice))
|
||||
return displayMap[displayDevice];
|
||||
else
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
#region IDisplayDeviceDriver Members
|
||||
|
||||
Dictionary<IntPtr, IntPtr> storedModes = new Dictionary<IntPtr, IntPtr>();
|
||||
List<IntPtr> displaysCaptured = new List<IntPtr>();
|
||||
|
||||
public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
||||
{
|
||||
IntPtr display = displayMap[device];
|
||||
IntPtr currentModePtr = CG.CGDisplayCurrentMode(display);
|
||||
|
||||
if (!storedModes.ContainsKey(display)) {
|
||||
storedModes.Add(display, currentModePtr);
|
||||
}
|
||||
|
||||
IntPtr displayModesPtr = CG.CGDisplayAvailableModes(display);
|
||||
CFArray displayModes = new CFArray(displayModesPtr);
|
||||
|
||||
for (int j = 0; j < displayModes.Count; j++) {
|
||||
CFDictionary dict = new CFDictionary(displayModes[j]);
|
||||
|
||||
int width = (int)dict.GetNumberValue("Width");
|
||||
int height = (int)dict.GetNumberValue("Height");
|
||||
int bpp = (int)dict.GetNumberValue("BitsPerPixel");
|
||||
double freq = dict.GetNumberValue("RefreshRate");
|
||||
|
||||
if (width == resolution.Width && height == resolution.Height &&
|
||||
bpp == resolution.BitsPerPixel && Math.Abs(freq - resolution.RefreshRate) < 1e-6) {
|
||||
if (!displaysCaptured.Contains(display)) {
|
||||
CG.CGDisplayCapture(display);
|
||||
}
|
||||
|
||||
Debug.Print("Changing resolution to {0}x{1}x{2}@{3}.", width, height, bpp, freq);
|
||||
CG.CGDisplaySwitchToMode(display, displayModes[j]);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryRestoreResolution(DisplayDevice device) {
|
||||
IntPtr display = displayMap[device];
|
||||
|
||||
if (storedModes.ContainsKey(display)) {
|
||||
Debug.Print("Restoring resolution.");
|
||||
|
||||
CG.CGDisplaySwitchToMode(display, storedModes[display]);
|
||||
CG.CGDisplayRelease(display);
|
||||
displaysCaptured.Remove(display);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenTK.Platform.MacOS.Carbon;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
class QuartzDisplayDeviceDriver : IDisplayDeviceDriver
|
||||
{
|
||||
static IntPtr mainDisplay;
|
||||
internal static IntPtr MainDisplay { get { return mainDisplay; } }
|
||||
|
||||
unsafe static QuartzDisplayDeviceDriver() {
|
||||
// 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;
|
||||
fixed(IntPtr* displayPtr = displays) {
|
||||
CG.CGGetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount);
|
||||
}
|
||||
|
||||
Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
|
||||
|
||||
for (int i = 0; i < displayCount; i++) {
|
||||
IntPtr curDisplay = displays[i];
|
||||
|
||||
// according to docs, first element in the array is always the main display.
|
||||
bool primary = (i == 0);
|
||||
if (primary)
|
||||
mainDisplay = curDisplay;
|
||||
|
||||
// gets current settings
|
||||
int currentWidth = CG.CGDisplayPixelsWide(curDisplay);
|
||||
int currentHeight = CG.CGDisplayPixelsHigh(curDisplay);
|
||||
Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight);
|
||||
|
||||
IntPtr displayModesPtr = CG.CGDisplayAvailableModes(curDisplay);
|
||||
CFArray displayModes = new CFArray(displayModesPtr);
|
||||
Debug.Print("Supports {0} display modes.", displayModes.Count);
|
||||
|
||||
DisplayResolution opentk_dev_current_res = null;
|
||||
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
|
||||
IntPtr currentModePtr = CG.CGDisplayCurrentMode(curDisplay);
|
||||
CFDictionary currentMode = new CFDictionary(currentModePtr);
|
||||
|
||||
for (int j = 0; j < displayModes.Count; j++)
|
||||
{
|
||||
CFDictionary dict = new CFDictionary(displayModes[j]);
|
||||
|
||||
int width = (int) dict.GetNumberValue("Width");
|
||||
int height = (int) dict.GetNumberValue("Height");
|
||||
int bpp = (int) dict.GetNumberValue("BitsPerPixel");
|
||||
double freq = dict.GetNumberValue("RefreshRate");
|
||||
bool current = currentMode.DictRef == dict.DictRef;
|
||||
|
||||
//if (current) Debug.Write(" * ");
|
||||
//else Debug.Write(" ");
|
||||
|
||||
//Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq);
|
||||
|
||||
DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq);
|
||||
opentk_dev_available_res.Add(thisRes);
|
||||
|
||||
if (current)
|
||||
opentk_dev_current_res = thisRes;
|
||||
}
|
||||
|
||||
HIRect bounds = CG.CGDisplayBounds(curDisplay);
|
||||
Rectangle newRect = 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_dev_current_res, primary, opentk_dev_available_res, newRect);
|
||||
opentk_dev.Metadata = curDisplay;
|
||||
}
|
||||
}
|
||||
|
||||
internal static IntPtr HandleTo(DisplayDevice device) {
|
||||
if (device == null || device.Metadata == null) return IntPtr.Zero;
|
||||
return (IntPtr)device.Metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,101 +1,75 @@
|
||||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenTK.Platform.Windows {
|
||||
|
||||
internal class WinDisplayDeviceDriver : IDisplayDeviceDriver {
|
||||
|
||||
static Dictionary<DisplayDevice, string> available_device_names =
|
||||
new Dictionary<DisplayDevice, string>(); // Needed for ChangeDisplaySettingsEx
|
||||
|
||||
/// <summary>Queries available display devices and display resolutions.</summary>
|
||||
static WinDisplayDeviceDriver() {
|
||||
// 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;
|
||||
List<DisplayResolution> availableRes = new List<DisplayResolution>();
|
||||
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;
|
||||
|
||||
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.Position.X, mode.Position.Y,
|
||||
mode.PelsWidth, mode.PelsHeight,
|
||||
mode.BitsPerPel, mode.DisplayFrequency);
|
||||
devPrimary = (winDev.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
availableRes.Clear();
|
||||
int i = 0;
|
||||
while (API.EnumDisplaySettings(winDev.DeviceName, i++, mode)) {
|
||||
// For example, the device \.\DISPLAYV1 returns a single resolution with bits per pixel of 0
|
||||
// We must skip these resolutions
|
||||
if (mode.BitsPerPel <= 0) continue;
|
||||
|
||||
availableRes.Add(new DisplayResolution(
|
||||
mode.Position.X, mode.Position.Y,
|
||||
mode.PelsWidth, mode.PelsHeight,
|
||||
mode.BitsPerPel, mode.DisplayFrequency));
|
||||
}
|
||||
|
||||
// This device has no valid resolutions, ignore it
|
||||
if (availableRes.Count == 0 || 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, availableRes, currentRes.Bounds);
|
||||
available_device_names.Add(device, winDev.DeviceName);
|
||||
currentRes = null;
|
||||
}
|
||||
}
|
||||
|
||||
public WinDisplayDeviceDriver() {
|
||||
}
|
||||
|
||||
public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution) {
|
||||
DeviceMode mode = null;
|
||||
|
||||
if (resolution != null) {
|
||||
mode = new DeviceMode();
|
||||
mode.PelsWidth = resolution.Width;
|
||||
mode.PelsHeight = resolution.Height;
|
||||
mode.BitsPerPel = resolution.BitsPerPixel;
|
||||
mode.DisplayFrequency = (int)resolution.RefreshRate;
|
||||
mode.Fields = Constants.DM_BITSPERPEL | Constants.DM_PELSWIDTH
|
||||
| Constants.DM_PELSHEIGHT | Constants.DM_DISPLAYFREQUENCY;
|
||||
}
|
||||
|
||||
return Constants.DISP_CHANGE_SUCCESSFUL ==
|
||||
API.ChangeDisplaySettingsEx(available_device_names[device], mode, IntPtr.Zero,
|
||||
ChangeDisplaySettingsEnum.Fullscreen, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public bool TryRestoreResolution(DisplayDevice device) {
|
||||
return TryChangeResolution(device, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenTK.Platform.Windows {
|
||||
|
||||
internal class WinDisplayDeviceDriver : IDisplayDeviceDriver {
|
||||
|
||||
/// <summary>Queries available display devices and display resolutions.</summary>
|
||||
static WinDisplayDeviceDriver() {
|
||||
// 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;
|
||||
List<DisplayResolution> availableRes = new List<DisplayResolution>();
|
||||
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;
|
||||
|
||||
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.Position.X, mode.Position.Y,
|
||||
mode.PelsWidth, mode.PelsHeight,
|
||||
mode.BitsPerPel, mode.DisplayFrequency);
|
||||
devPrimary = (winDev.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
availableRes.Clear();
|
||||
int i = 0;
|
||||
while (API.EnumDisplaySettings(winDev.DeviceName, i++, mode)) {
|
||||
// For example, the device \.\DISPLAYV1 returns a single resolution with bits per pixel of 0
|
||||
// We must skip these resolutions
|
||||
if (mode.BitsPerPel <= 0) continue;
|
||||
|
||||
availableRes.Add(new DisplayResolution(
|
||||
mode.Position.X, mode.Position.Y,
|
||||
mode.PelsWidth, mode.PelsHeight,
|
||||
mode.BitsPerPel, mode.DisplayFrequency));
|
||||
}
|
||||
|
||||
// This device has no valid resolutions, ignore it
|
||||
if (availableRes.Count == 0 || 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, availableRes, currentRes.Bounds);
|
||||
currentRes = null;
|
||||
}
|
||||
}
|
||||
|
||||
public WinDisplayDeviceDriver() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,240 +1,169 @@
|
||||
#region License
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.X11 {
|
||||
|
||||
internal class X11DisplayDevice : IDisplayDeviceDriver {
|
||||
// Store a mapping between resolutions and their respective
|
||||
// size_index (needed for XRRSetScreenConfig). The size_index
|
||||
// is simply the sequence number of the resolution as returned by
|
||||
// XRRSizes. This is done per available screen.
|
||||
static List<Dictionary<DisplayResolution, int>> screenResolutionToIndex =
|
||||
new List<Dictionary<DisplayResolution, int>>();
|
||||
// Store a mapping between DisplayDevices and their default resolutions.
|
||||
static Dictionary<DisplayDevice, int> deviceToDefaultResolution = new Dictionary<DisplayDevice, int>();
|
||||
// Store a mapping between DisplayDevices and X11 screens.
|
||||
static Dictionary<DisplayDevice, int> deviceToScreen = new Dictionary<DisplayDevice, int>();
|
||||
// Keep the time when the config of each screen was last updated.
|
||||
static List<IntPtr> lastConfigUpdate = new List<IntPtr>();
|
||||
|
||||
static bool xinerama_supported, xrandr_supported, xf86_supported;
|
||||
|
||||
static X11DisplayDevice() {
|
||||
List<DisplayDevice> devices = new List<DisplayDevice>();
|
||||
try {
|
||||
xinerama_supported = QueryXinerama(devices);
|
||||
} catch {
|
||||
Debug.Print("Xinerama query failed.");
|
||||
}
|
||||
|
||||
if (!xinerama_supported) {
|
||||
// We assume that devices are equivalent to the number of available screens.
|
||||
// Note: this won't work correctly in the case of distinct X servers.
|
||||
for (int i = 0; i < API.ScreenCount; i++) {
|
||||
DisplayDevice dev = new DisplayDevice();
|
||||
dev.IsPrimary = i == API.XDefaultScreen(API.DefaultDisplay);
|
||||
devices.Add(dev);
|
||||
deviceToScreen.Add(dev, i);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
xrandr_supported = QueryXRandR(devices);
|
||||
} catch { }
|
||||
|
||||
if (!xrandr_supported) {
|
||||
Debug.Print("XRandR query failed, falling back to XF86.");
|
||||
try {
|
||||
xf86_supported = QueryXF86(devices);
|
||||
} catch { }
|
||||
|
||||
if (!xf86_supported) {
|
||||
Debug.Print("XF86 query failed, no DisplayDevice support available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal X11DisplayDevice() { }
|
||||
|
||||
static bool QueryXinerama(List<DisplayDevice> devices) {
|
||||
// Try to use Xinerama to obtain the geometry of all output devices.
|
||||
int event_base, error_base;
|
||||
if (NativeMethods.XineramaQueryExtension(API.DefaultDisplay, out event_base, out error_base) &&
|
||||
NativeMethods.XineramaIsActive(API.DefaultDisplay)) {
|
||||
XineramaScreenInfo[] screens = NativeMethods.XineramaQueryScreens(API.DefaultDisplay);
|
||||
bool first = true;
|
||||
foreach (XineramaScreenInfo screen in screens) {
|
||||
DisplayDevice dev = new DisplayDevice();
|
||||
dev.Bounds = new Rectangle(screen.X, screen.Y, screen.Width, screen.Height);
|
||||
if (first) {
|
||||
// We consider the first device returned by Xinerama as the primary one.
|
||||
// Makes sense conceptually, but is there a way to verify this?
|
||||
dev.IsPrimary = true;
|
||||
first = false;
|
||||
}
|
||||
devices.Add(dev);
|
||||
// It seems that all X screens are equal to 0 is Xinerama is enabled, at least on Nvidia (verify?)
|
||||
deviceToScreen.Add(dev, 0 /*screen.ScreenNumber*/);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool QueryXRandR(List<DisplayDevice> devices) {
|
||||
// Get available resolutions. Then, for each resolution get all available rates.
|
||||
foreach (DisplayDevice dev in devices) {
|
||||
int screen = deviceToScreen[dev];
|
||||
|
||||
IntPtr lastUpdateTimestamp;
|
||||
API.XRRTimes(API.DefaultDisplay, screen, out lastUpdateTimestamp);
|
||||
lastConfigUpdate.Add(lastUpdateTimestamp);
|
||||
List<DisplayResolution> available_res = new List<DisplayResolution>();
|
||||
|
||||
// Add info for a new screen.
|
||||
screenResolutionToIndex.Add(new Dictionary<DisplayResolution, int>());
|
||||
int[] depths = API.XListDepths(API.DefaultDisplay, screen);
|
||||
|
||||
int resolution_count = 0;
|
||||
foreach (XRRScreenSize size in FindAvailableResolutions(screen)) {
|
||||
if (size.Width == 0 || size.Height == 0) {
|
||||
Debug.Print("[Warning] XRandR returned an invalid resolution ({0}) for display device {1}", size, screen);
|
||||
continue;
|
||||
}
|
||||
short[] rates = API.XRRRates(API.DefaultDisplay, screen, resolution_count);
|
||||
|
||||
// It seems that XRRRates returns 0 for modes that are larger than the screen
|
||||
// can support, as well as for all supported modes. On Ubuntu 7.10 the tool
|
||||
// "Screens and Graphics" does report these modes, though.
|
||||
foreach (short rate in rates) {
|
||||
// Note: some X servers (like Xming on Windows) do not report any rates other than 0.
|
||||
// If we only have 1 rate, add it even if it is 0.
|
||||
if (rate != 0 || rates.Length == 1)
|
||||
foreach (int depth in depths)
|
||||
available_res.Add(new DisplayResolution(0, 0, size.Width, size.Height, depth, rate));
|
||||
}
|
||||
// Keep the index of this resolution - we will need it for resolution changes later.
|
||||
foreach (int depth in depths) {
|
||||
// Note that Xinerama may return multiple devices for a single screen. XRandR will
|
||||
// not distinguish between the two as far as resolutions are supported (since XRandR
|
||||
// operates on X screens, not display devices) - we need to be careful not to add the
|
||||
// same resolution twice!
|
||||
DisplayResolution res = new DisplayResolution(0, 0, size.Width, size.Height, depth, 0);
|
||||
if (!screenResolutionToIndex[screen].ContainsKey(res))
|
||||
screenResolutionToIndex[screen].Add(res, resolution_count);
|
||||
}
|
||||
++resolution_count;
|
||||
}
|
||||
|
||||
IntPtr screenConfig = API.XRRGetScreenInfo(API.DefaultDisplay, API.XRootWindow(API.DefaultDisplay, screen));
|
||||
ushort curRotation;
|
||||
int curResolutionIndex = API.XRRConfigCurrentConfiguration(screenConfig, out curRotation);
|
||||
float curRefreshRate = API.XRRConfigCurrentRate(screenConfig);
|
||||
int curDepth = API.XDefaultDepth(API.DefaultDisplay, screen);
|
||||
API.XRRFreeScreenConfigInfo(screenConfig);
|
||||
|
||||
if (dev.Bounds == Rectangle.Empty)
|
||||
dev.Bounds = new Rectangle(0, 0, available_res[curResolutionIndex].Width, available_res[curResolutionIndex].Height);
|
||||
dev.BitsPerPixel = curDepth;
|
||||
dev.RefreshRate = curRefreshRate;
|
||||
dev.AvailableResolutions = available_res;
|
||||
|
||||
deviceToDefaultResolution.Add(dev, curResolutionIndex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool QueryXF86(List<DisplayDevice> devices) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static XRRScreenSize[] FindAvailableResolutions(int screen) {
|
||||
XRRScreenSize[] resolutions = API.XRRSizes(API.DefaultDisplay, screen);
|
||||
if (resolutions == null)
|
||||
throw new NotSupportedException("XRandR extensions not available.");
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
static bool ChangeResolutionXRandR(DisplayDevice device, DisplayResolution resolution) {
|
||||
int screen = deviceToScreen[device];
|
||||
IntPtr root = API.XRootWindow(API.DefaultDisplay, screen);
|
||||
IntPtr screen_config = API.XRRGetScreenInfo(API.DefaultDisplay, root);
|
||||
|
||||
ushort current_rotation;
|
||||
int current_resolution_index = API.XRRConfigCurrentConfiguration(screen_config, out current_rotation);
|
||||
int new_resolution_index;
|
||||
if (resolution != null)
|
||||
new_resolution_index = screenResolutionToIndex[screen]
|
||||
[new DisplayResolution(0, 0, resolution.Width, resolution.Height, resolution.BitsPerPixel, 0)];
|
||||
else
|
||||
new_resolution_index = deviceToDefaultResolution[device];
|
||||
|
||||
Debug.Print("Changing size of screen {0} from {1} to {2}",
|
||||
screen, current_resolution_index, new_resolution_index);
|
||||
|
||||
return 0 == API.XRRSetScreenConfigAndRate(API.DefaultDisplay, screen_config, root, new_resolution_index,
|
||||
current_rotation, (short)(resolution != null ? resolution.RefreshRate : 0), lastConfigUpdate[screen]);
|
||||
}
|
||||
|
||||
static bool ChangeResolutionXF86(DisplayDevice device, DisplayResolution resolution) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution) {
|
||||
// If resolution is null, restore the default resolution (new_resolution_index = 0).
|
||||
if (xrandr_supported) {
|
||||
return ChangeResolutionXRandR(device, resolution);
|
||||
} else if (xf86_supported) {
|
||||
return ChangeResolutionXF86(device, resolution);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryRestoreResolution(DisplayDevice device) {
|
||||
return TryChangeResolution(device, null);
|
||||
}
|
||||
|
||||
static class NativeMethods {
|
||||
const string Xinerama = "libXinerama";
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
public static extern bool XineramaQueryExtension(IntPtr dpy, out int event_basep, out int error_basep);
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
public static extern bool XineramaIsActive(IntPtr dpy);
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
static extern IntPtr XineramaQueryScreens(IntPtr dpy, out int count);
|
||||
|
||||
public unsafe static XineramaScreenInfo[] XineramaQueryScreens(IntPtr dpy) {
|
||||
int count;
|
||||
IntPtr screen_ptr = XineramaQueryScreens(dpy, out count);
|
||||
XineramaScreenInfo* ptr = (XineramaScreenInfo*)screen_ptr;
|
||||
|
||||
XineramaScreenInfo[] screens = new XineramaScreenInfo[count];
|
||||
for( int i = 0; i < screens.Length; i++ ) {
|
||||
screens[i] = *ptr++;
|
||||
}
|
||||
return screens;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct XineramaScreenInfo {
|
||||
public int ScreenNumber;
|
||||
public short X;
|
||||
public short Y;
|
||||
public short Width;
|
||||
public short Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
#region License
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.X11 {
|
||||
|
||||
internal class X11DisplayDevice : IDisplayDeviceDriver {
|
||||
static bool xinerama_supported, xrandr_supported, xf86_supported;
|
||||
|
||||
static X11DisplayDevice() {
|
||||
List<DisplayDevice> devices = new List<DisplayDevice>();
|
||||
try {
|
||||
xinerama_supported = QueryXinerama(devices);
|
||||
} catch {
|
||||
Debug.Print("Xinerama query failed.");
|
||||
}
|
||||
|
||||
if (!xinerama_supported) {
|
||||
// We assume that devices are equivalent to the number of available screens.
|
||||
// Note: this won't work correctly in the case of distinct X servers.
|
||||
for (int i = 0; i < API.ScreenCount; i++) {
|
||||
DisplayDevice dev = new DisplayDevice();
|
||||
dev.IsPrimary = i == API.XDefaultScreen(API.DefaultDisplay);
|
||||
dev.Metadata = i;
|
||||
devices.Add(dev);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
xrandr_supported = QueryXRandR(devices);
|
||||
} catch { }
|
||||
|
||||
if (!xrandr_supported) {
|
||||
Debug.Print("XRandR query failed, falling back to XF86.");
|
||||
try {
|
||||
xf86_supported = QueryXF86(devices);
|
||||
} catch { }
|
||||
|
||||
if (!xf86_supported) {
|
||||
Debug.Print("XF86 query failed, no DisplayDevice support available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal X11DisplayDevice() { }
|
||||
|
||||
static bool QueryXinerama(List<DisplayDevice> devices) {
|
||||
// Try to use Xinerama to obtain the geometry of all output devices.
|
||||
int event_base, error_base;
|
||||
if (NativeMethods.XineramaQueryExtension(API.DefaultDisplay, out event_base, out error_base) &&
|
||||
NativeMethods.XineramaIsActive(API.DefaultDisplay)) {
|
||||
XineramaScreenInfo[] screens = NativeMethods.XineramaQueryScreens(API.DefaultDisplay);
|
||||
bool first = true;
|
||||
foreach (XineramaScreenInfo screen in screens) {
|
||||
DisplayDevice dev = new DisplayDevice();
|
||||
dev.Bounds = new Rectangle(screen.X, screen.Y, screen.Width, screen.Height);
|
||||
if (first) {
|
||||
// We consider the first device returned by Xinerama as the primary one.
|
||||
// Makes sense conceptually, but is there a way to verify this?
|
||||
dev.IsPrimary = true;
|
||||
first = false;
|
||||
}
|
||||
devices.Add(dev);
|
||||
// It seems that all X screens are equal to 0 is Xinerama is enabled, at least on Nvidia (verify?)
|
||||
dev.Metadata = 0; /*screen.ScreenNumber*/
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool QueryXRandR(List<DisplayDevice> devices) {
|
||||
// Get available resolutions. Then, for each resolution get all available rates.
|
||||
foreach (DisplayDevice dev in devices) {
|
||||
int screen = (int)dev.Metadata;
|
||||
List<DisplayResolution> available_res = new List<DisplayResolution>();
|
||||
int[] depths = API.XListDepths(API.DefaultDisplay, screen);
|
||||
|
||||
int resolution_count = 0;
|
||||
foreach (XRRScreenSize size in FindAvailableResolutions(screen)) {
|
||||
if (size.Width == 0 || size.Height == 0) {
|
||||
Debug.Print("[Warning] XRandR returned an invalid resolution ({0}) for display device {1}", size, screen);
|
||||
continue;
|
||||
}
|
||||
short[] rates = API.XRRRates(API.DefaultDisplay, screen, resolution_count);
|
||||
|
||||
// It seems that XRRRates returns 0 for modes that are larger than the screen
|
||||
// can support, as well as for all supported modes. On Ubuntu 7.10 the tool
|
||||
// "Screens and Graphics" does report these modes, though.
|
||||
foreach (short rate in rates) {
|
||||
// Note: some X servers (like Xming on Windows) do not report any rates other than 0.
|
||||
// If we only have 1 rate, add it even if it is 0.
|
||||
if (rate != 0 || rates.Length == 1)
|
||||
foreach (int depth in depths)
|
||||
available_res.Add(new DisplayResolution(0, 0, size.Width, size.Height, depth, rate));
|
||||
}
|
||||
++resolution_count;
|
||||
}
|
||||
|
||||
IntPtr screenConfig = API.XRRGetScreenInfo(API.DefaultDisplay, API.XRootWindow(API.DefaultDisplay, screen));
|
||||
ushort curRotation;
|
||||
int curResolutionIndex = API.XRRConfigCurrentConfiguration(screenConfig, out curRotation);
|
||||
float curRefreshRate = API.XRRConfigCurrentRate(screenConfig);
|
||||
int curDepth = API.XDefaultDepth(API.DefaultDisplay, screen);
|
||||
API.XRRFreeScreenConfigInfo(screenConfig);
|
||||
|
||||
if (dev.Bounds == Rectangle.Empty)
|
||||
dev.Bounds = new Rectangle(0, 0, available_res[curResolutionIndex].Width, available_res[curResolutionIndex].Height);
|
||||
dev.BitsPerPixel = curDepth;
|
||||
dev.RefreshRate = curRefreshRate;
|
||||
dev.AvailableResolutions = available_res;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool QueryXF86(List<DisplayDevice> devices) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static XRRScreenSize[] FindAvailableResolutions(int screen) {
|
||||
XRRScreenSize[] resolutions = API.XRRSizes(API.DefaultDisplay, screen);
|
||||
if (resolutions == null)
|
||||
throw new NotSupportedException("XRandR extensions not available.");
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
static class NativeMethods {
|
||||
const string Xinerama = "libXinerama";
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
public static extern bool XineramaQueryExtension(IntPtr dpy, out int event_basep, out int error_basep);
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
public static extern bool XineramaIsActive(IntPtr dpy);
|
||||
|
||||
[DllImport(Xinerama)]
|
||||
static extern IntPtr XineramaQueryScreens(IntPtr dpy, out int count);
|
||||
|
||||
public unsafe static XineramaScreenInfo[] XineramaQueryScreens(IntPtr dpy) {
|
||||
int count;
|
||||
IntPtr screen_ptr = XineramaQueryScreens(dpy, out count);
|
||||
XineramaScreenInfo* ptr = (XineramaScreenInfo*)screen_ptr;
|
||||
|
||||
XineramaScreenInfo[] screens = new XineramaScreenInfo[count];
|
||||
for( int i = 0; i < screens.Length; i++ ) {
|
||||
screens[i] = *ptr++;
|
||||
}
|
||||
return screens;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct XineramaScreenInfo {
|
||||
public int ScreenNumber;
|
||||
public short X;
|
||||
public short Y;
|
||||
public short Width;
|
||||
public short Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
122
src/Client/Window.h
Normal file
122
src/Client/Window.h
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef CS_WINDOW_H
|
||||
#define CS_WINDOW_H
|
||||
#include "Typedefs.h"
|
||||
#include "String.h"
|
||||
#include "Compiler.h"
|
||||
#include "Bitmap.h"
|
||||
/* Abstracts creating and managing a native window.
|
||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
/* Gets the current contents of the clipboard. */
|
||||
void Window_GetClipboardText(STRING_TRANSIENT String* value);
|
||||
|
||||
/* Sets the current contents of the clipboard. */
|
||||
void Window_SetClipboardText(STRING_TRANSIENT String* value);
|
||||
|
||||
/* Sets the icon of this window. */
|
||||
void Window_SetIcon(Bitmap* bmp);
|
||||
|
||||
/* Sets the title of the window. */
|
||||
void Window_SetTitle(STRING_TRANSIENT String* title);
|
||||
|
||||
/* Gets whether this window has input focus. */
|
||||
bool Window_GetFocused(void);
|
||||
|
||||
/* Gets whether whether this window is visible. */
|
||||
bool Window_GetVisible(void);
|
||||
|
||||
/* Gets whether this window has been created and has not been destroyed. */
|
||||
bool Window_GetExists(void);
|
||||
|
||||
/// <summary> Gets the <see cref="OpenTK.Platform.IWindowInfo"/> for this window. </summary>
|
||||
IWindowInfo WindowInfo{ get; }
|
||||
|
||||
/// <summary> Gets or sets the <see cref="OpenTK.WindowState"/> for this window. </summary>
|
||||
WindowState WindowState{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets a <see cref="System.Drawing.Rectangle"/> structure the contains the external bounds of this window, in screen coordinates.
|
||||
/// External bounds include the title bar, borders and drawing area of the window. </summary>
|
||||
Rectangle Bounds{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets a <see cref="System.Drawing.Point"/> structure that contains the location of this window on the desktop. </summary>
|
||||
Point Location{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets a <see cref="System.Drawing.Size"/> structure that contains the external size of this window. </summary>
|
||||
Size Size{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets a <see cref="System.Drawing.Rectangle"/> structure that contains the internal bounds of this window, in client coordinates.
|
||||
/// The internal bounds include the drawing area of the window, but exclude the titlebar and window borders. </summary>
|
||||
Rectangle ClientRectangle{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets a <see cref="System.Drawing.Size"/> structure that contains the internal size this window. </summary>
|
||||
Size ClientSize{ get; set; }
|
||||
|
||||
/// <summary> Closes this window. </summary>
|
||||
void Close();
|
||||
|
||||
/// <summary> Processes pending window events. </summary>
|
||||
void ProcessEvents();
|
||||
|
||||
/// <summary> Transforms the specified point from screen to client coordinates. </summary>
|
||||
/// <param name="point"> A <see cref="System.Drawing.Point"/> to transform. </param>
|
||||
/// <returns> The point transformed to client coordinates. </returns>
|
||||
Point PointToClient(Point point);
|
||||
|
||||
/// <summary> Transforms the specified point from client to screen coordinates. </summary>
|
||||
/// <param name="point"> A <see cref="System.Drawing.Point"/> to transform. </param>
|
||||
/// <returns> The point transformed to screen coordinates. </returns>
|
||||
Point PointToScreen(Point point);
|
||||
|
||||
/// <summary> Gets the available KeyboardDevice. </summary>
|
||||
KeyboardDevice Keyboard{ get; }
|
||||
|
||||
/// <summary> Gets the available MouseDevice. </summary>
|
||||
MouseDevice Mouse{ get; }
|
||||
|
||||
/// <summary> Gets or sets the cursor position in screen coordinates. </summary>
|
||||
Point DesktopCursorPos{ get; set; }
|
||||
|
||||
/// <summary> Gets or sets whether the cursor is visible in the window. </summary>
|
||||
bool CursorVisible{ get; set; }
|
||||
|
||||
/// <summary> Occurs whenever the window is moved. </summary>
|
||||
event EventHandler<EventArgs> Move;
|
||||
|
||||
/// <summary> Occurs whenever the window is resized. </summary>
|
||||
event EventHandler<EventArgs> Resize;
|
||||
|
||||
/// <summary> Occurs when the window is about to close. </summary>
|
||||
event EventHandler<CancelEventArgs> Closing;
|
||||
|
||||
/// <summary> Occurs after the window has closed. </summary>
|
||||
event EventHandler<EventArgs> Closed;
|
||||
|
||||
/// <summary> Occurs when the window is disposed. </summary>
|
||||
event EventHandler<EventArgs> Disposed;
|
||||
|
||||
/// <summary> Occurs when the <see cref="Icon"/> property of the window changes. </summary>
|
||||
event EventHandler<EventArgs> IconChanged;
|
||||
|
||||
/// <summary> Occurs when the <see cref="Title"/> property of the window changes. </summary>
|
||||
event EventHandler<EventArgs> TitleChanged;
|
||||
|
||||
/// <summary> Occurs when the <see cref="Visible"/> property of the window changes. </summary>
|
||||
event EventHandler<EventArgs> VisibleChanged;
|
||||
|
||||
/// <summary> Occurs when the <see cref="Focused"/> property of the window changes. </summary>
|
||||
event EventHandler<EventArgs> FocusedChanged;
|
||||
|
||||
/// <summary> Occurs when the <see cref="WindowState"/> property of the window changes. </summary>
|
||||
event EventHandler<EventArgs> WindowStateChanged;
|
||||
|
||||
/// <summary> Occurs whenever a character is typed. </summary>
|
||||
event EventHandler<KeyPressEventArgs> KeyPress;
|
||||
|
||||
/// <summary> Occurs whenever the mouse cursor leaves the window <see cref="Bounds"/>. </summary>
|
||||
event EventHandler<EventArgs> MouseLeave;
|
||||
|
||||
/// <summary> Occurs whenever the mouse cursor enters the window <see cref="Bounds"/>. </summary>
|
||||
event EventHandler<EventArgs> MouseEnter;
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user