2008-01-25 10:02:05 +00:00
|
|
|
|
#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;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
using OpenTK.Graphics;
|
2008-01-25 13:13:05 +00:00
|
|
|
|
using System.Diagnostics;
|
2008-01-25 10:02:05 +00:00
|
|
|
|
|
|
|
|
|
namespace OpenTK.Platform.X11
|
|
|
|
|
{
|
|
|
|
|
internal class X11XrandrDisplayDevice : IDisplayDeviceDriver
|
|
|
|
|
{
|
2008-01-25 13:13:05 +00:00
|
|
|
|
static object display_lock = new object();
|
|
|
|
|
|
2008-01-25 10:02:05 +00:00
|
|
|
|
#region --- Constructors ---
|
|
|
|
|
|
|
|
|
|
static X11XrandrDisplayDevice()
|
|
|
|
|
{
|
2008-01-25 14:32:51 +00:00
|
|
|
|
// Get available resolutions. Then, for each resolution get all
|
|
|
|
|
// available rates.
|
|
|
|
|
// TODO: Find a way to get all available depths, too.
|
2008-01-25 15:04:10 +00:00
|
|
|
|
// TODO: Global X11 lock.
|
|
|
|
|
for (int screen = 0; screen < API.ScreenCount; screen++)
|
|
|
|
|
{
|
|
|
|
|
List<DisplayResolution> available_res;
|
2008-01-25 15:31:38 +00:00
|
|
|
|
int[] depths;
|
2008-01-25 15:04:10 +00:00
|
|
|
|
float refreshRate;
|
2008-01-25 16:11:46 +00:00
|
|
|
|
int currentDepth;
|
|
|
|
|
|
2008-01-25 15:31:38 +00:00
|
|
|
|
FindAvailableDepths(screen, out depths);
|
|
|
|
|
FindAvailableResolutions(screen, depths, out available_res);
|
2008-01-25 16:11:46 +00:00
|
|
|
|
FindCurrentRefreshRate(screen, out refreshRate);
|
|
|
|
|
FindCurrentDepth(screen, out currentDepth);
|
|
|
|
|
|
2008-01-25 15:04:10 +00:00
|
|
|
|
// The default resolution (but not refresh rate) is the first one in available_res.
|
|
|
|
|
// Its refresh rate is discovered by the FindCurrentRefreshRate call.
|
2008-01-25 16:11:46 +00:00
|
|
|
|
// Its depth is discovered by the FindCurrentDepth call.
|
|
|
|
|
new DisplayDevice(new DisplayResolution(available_res[0].Width, available_res[0].Height, currentDepth, refreshRate),
|
2008-01-25 15:04:10 +00:00
|
|
|
|
screen == API.DefaultScreen, available_res);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal X11XrandrDisplayDevice() { }
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region --- Private Methods ---
|
2008-01-25 14:32:51 +00:00
|
|
|
|
|
2008-01-25 15:04:10 +00:00
|
|
|
|
#region static void FindAvailableResolutions(int screen, out List<DisplayResolution> resolutions)
|
|
|
|
|
|
2008-01-25 15:31:38 +00:00
|
|
|
|
static void FindAvailableResolutions(int screen, int[] depths, out List<DisplayResolution> resolutions)
|
2008-01-25 15:04:10 +00:00
|
|
|
|
{
|
|
|
|
|
resolutions = new List<DisplayResolution>();
|
|
|
|
|
unsafe
|
2008-01-25 13:13:05 +00:00
|
|
|
|
{
|
2008-01-25 15:04:10 +00:00
|
|
|
|
XRRScreenSize[] array = Functions.XRRSizes(API.DefaultDisplay, screen);
|
|
|
|
|
if (array == null)
|
|
|
|
|
throw new NotSupportedException("XRandR extensions not available.");
|
|
|
|
|
|
|
|
|
|
int resolution = 0;
|
|
|
|
|
foreach (XRRScreenSize size in array)
|
2008-01-25 13:13:05 +00:00
|
|
|
|
{
|
2008-01-25 15:04:10 +00:00
|
|
|
|
short[] rates = Functions.XRRRates(API.DefaultDisplay, screen, resolution);
|
|
|
|
|
|
|
|
|
|
// TODO: Is the rate != 0 conditional correct? It seems that XRRRates returns 0
|
|
|
|
|
// for modes that are larger than the screen can support (?)
|
|
|
|
|
foreach (short rate in rates)
|
|
|
|
|
if (rate != 0)
|
2008-01-25 15:31:38 +00:00
|
|
|
|
foreach (int depth in depths)
|
|
|
|
|
resolutions.Add(new DisplayResolution(size.Width, size.Height, depth, (float)rate));
|
2008-01-25 15:04:10 +00:00
|
|
|
|
++resolution;
|
2008-01-25 13:13:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2008-01-25 10:02:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-01-25 15:04:10 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-01-25 16:11:46 +00:00
|
|
|
|
#region static void FindCurrentRefreshRate(int screen, out float refreshRate)
|
|
|
|
|
|
2008-01-25 15:04:10 +00:00
|
|
|
|
static void FindCurrentRefreshRate(int screen, out float refreshRate)
|
2008-01-25 10:02:05 +00:00
|
|
|
|
{
|
2008-01-25 15:04:10 +00:00
|
|
|
|
IntPtr screen_config_ptr = Functions.XRRGetScreenInfo(API.DefaultDisplay, API.RootWindow);
|
|
|
|
|
ushort rotation = 0;
|
|
|
|
|
int size = Functions.XRRConfigCurrentConfiguration(screen_config_ptr, ref rotation);
|
|
|
|
|
short rate = Functions.XRRConfigCurrentRate(screen_config_ptr);
|
|
|
|
|
Functions.XRRFreeScreenConfigInfo(screen_config_ptr);
|
|
|
|
|
|
|
|
|
|
refreshRate = (float)rate;
|
2008-01-25 10:02:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-01-25 16:11:46 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region private static void FindAvailableDepths(int screen, out int[] depths)
|
|
|
|
|
|
2008-01-25 15:31:38 +00:00
|
|
|
|
private static void FindAvailableDepths(int screen, out int[] depths)
|
|
|
|
|
{
|
|
|
|
|
depths = Functions.XListDepths(API.DefaultDisplay, screen);
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-25 10:02:05 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-01-25 16:11:46 +00:00
|
|
|
|
#region private static void FindCurrentDepth(int screen, out int current_depth)
|
|
|
|
|
|
|
|
|
|
private static void FindCurrentDepth(int screen, out int current_depth)
|
|
|
|
|
{
|
|
|
|
|
current_depth = (int)Functions.XDefaultDepth(API.DefaultDisplay, screen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-01-25 10:02:05 +00:00
|
|
|
|
#region --- IDisplayDeviceDriver Members ---
|
|
|
|
|
|
|
|
|
|
public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
|
|
|
|
{
|
2008-01-25 10:03:13 +00:00
|
|
|
|
return false;
|
2008-01-25 10:02:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RestoreResolution(DisplayDevice device)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|