From dd41ed9610ac7d4e7ca16c2ae857b8cbdc9f9dce Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Sat, 9 Oct 2010 19:10:39 +0000 Subject: [PATCH] Added XF86VM fallback when XRandR is missing (many thanks to jdomnitz!) --- Source/OpenTK/Platform/X11/API.cs | 50 +++++++++---------- .../OpenTK/Platform/X11/X11DisplayDevice.cs | 48 +++++++++++++++++- 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/Source/OpenTK/Platform/X11/API.cs b/Source/OpenTK/Platform/X11/API.cs index 1fcbadf6..442842e5 100644 --- a/Source/OpenTK/Platform/X11/API.cs +++ b/Source/OpenTK/Platform/X11/API.cs @@ -311,17 +311,17 @@ namespace OpenTK.Platform.X11 [StructLayout(LayoutKind.Sequential)] internal struct XF86VidModeModeLine { - short hdisplay; /* Number of display pixels horizontally */ - short hsyncstart; /* Horizontal sync start */ - short hsyncend; /* Horizontal sync end */ - short htotal; /* Total horizontal pixels */ - short vdisplay; /* Number of display pixels vertically */ - short vsyncstart; /* Vertical sync start */ - short vsyncend; /* Vertical sync start */ - short vtotal; /* Total vertical pixels */ - int flags; /* Mode flags */ - int privsize; /* Size of private */ - IntPtr _private; /* Server privates */ + public short hdisplay; /* Number of display pixels horizontally */ + public short hsyncstart; /* Horizontal sync start */ + public short hsyncend; /* Horizontal sync end */ + public short htotal; /* Total horizontal pixels */ + public short vdisplay; /* Number of display pixels vertically */ + public short vsyncstart; /* Vertical sync start */ + public short vsyncend; /* Vertical sync start */ + public short vtotal; /* Total vertical pixels */ + public int flags; /* Mode flags */ + public int privsize; /* Size of private */ + public IntPtr _private; /* Server privates */ } /// @@ -471,6 +471,13 @@ namespace OpenTK.Platform.X11 out int major_version_return, out int minor_version_return); + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeGetModeLine( + Display display, + int screen, + out int dotclock_return, + out XF86VidModeModeLine modeline); + [DllImport(_dll_name_vid)] extern public static bool XF86VidModeGetAllModeLines( Display display, @@ -479,6 +486,13 @@ namespace OpenTK.Platform.X11 /*XF86VidModeModeInfo*** <-- yes, that's three *'s. */ out IntPtr modesinfo); + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeGetViewPort( + Display display, + int screen, + out int x_return, + out int y_return); + [DllImport(_dll_name_vid)] extern public static bool XF86VidModeSetViewPort( Display display, @@ -490,12 +504,6 @@ namespace OpenTK.Platform.X11 Bool XF86VidModeSetClientVersion( Display *display); -Bool XF86VidModeGetModeLine( - Display *display, - int screen, - int *dotclock_return, - XF86VidModeModeLine *modeline); - Bool XF86VidModeDeleteModeLine( Display *display, int screen, @@ -511,7 +519,6 @@ Status XF86VidModeValidateModeLine( int screen, XF86VidModeModeLine *modeline); - Bool XF86VidModeLockModeSwitch( Display *display, int screen, @@ -522,13 +529,6 @@ Bool XF86VidModeGetMonitor( int screen, XF86VidModeMonitor *monitor); -Bool XF86VidModeGetViewPort( - Display *display, - int screen, - int *x_return, - int *y_return); - - XF86VidModeGetDotClocks( Display *display, int screen, diff --git a/Source/OpenTK/Platform/X11/X11DisplayDevice.cs b/Source/OpenTK/Platform/X11/X11DisplayDevice.cs index 95a96254..e3d80897 100644 --- a/Source/OpenTK/Platform/X11/X11DisplayDevice.cs +++ b/Source/OpenTK/Platform/X11/X11DisplayDevice.cs @@ -198,7 +198,53 @@ namespace OpenTK.Platform.X11 static bool QueryXF86(List devices) { - return false; + int major; + int minor; + + try + { + if (!API.XF86VidModeQueryVersion(API.DefaultDisplay, out major, out minor)) + return false; + } + catch (DllNotFoundException) + { + return false; + } + + int currentScreen = 0; + Debug.Print("Using XF86 v" + major.ToString() + "." + minor.ToString()); + + foreach (DisplayDevice dev in devices) + { + int count; + + IntPtr srcArray; + API.XF86VidModeGetAllModeLines(API.DefaultDisplay, currentScreen, out count, out srcArray); + Debug.Print(count.ToString() + " modes detected on screen " + currentScreen.ToString()); + IntPtr[] array = new IntPtr[count]; + Marshal.Copy(srcArray, array, 0, count); + API.XF86VidModeModeInfo Mode = new API.XF86VidModeModeInfo(); + + int x; + int y; + API.XF86VidModeGetViewPort(API.DefaultDisplay, currentScreen, out x, out y); + List resolutions = new List(); + for (int i = 0; i < count; i++) + { + Mode = (API.XF86VidModeModeInfo)Marshal.PtrToStructure(array[i], typeof(API.XF86VidModeModeInfo)); + resolutions.Add(new DisplayResolution(x, y, Mode.hdisplay, Mode.vdisplay, 24, (Mode.dotclock * 1000F) / (Mode.vtotal * Mode.htotal))); + } + + dev.AvailableResolutions = resolutions; + int pixelClock; + API.XF86VidModeModeLine currentMode; + API.XF86VidModeGetModeLine(API.DefaultDisplay, currentScreen, out pixelClock, out currentMode); + dev.Bounds = new Rectangle(x, y, currentMode.hdisplay, (currentMode.vdisplay == 0) ? currentMode.vsyncstart : currentMode.vdisplay); + dev.BitsPerPixel = FindCurrentDepth(currentScreen); + dev.RefreshRate = (pixelClock * 1000F) / (currentMode.vtotal * currentMode.htotal); + currentScreen++; + } + return true; } #region static int[] FindAvailableDepths(int screen)