Use one display connection for all X11 communication. Seems to fix (not 100%) the crash problems encountered.

This commit is contained in:
the_fiddler 2008-03-24 13:12:02 +00:00
parent 6641076f3b
commit 034d524a87
8 changed files with 168 additions and 96 deletions

View file

@ -2,7 +2,7 @@
/* Licensed under the MIT/X11 license. /* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team. * Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution. * This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details. * See license.txt for licensing details.
*/ */
#endregion #endregion

View file

@ -339,8 +339,8 @@ namespace OpenTK.Graphics
Form form = new Form(); Form form = new Form();
form.ShowInTaskbar = false; form.ShowInTaskbar = false;
form.StartPosition = FormStartPosition.Manual; form.StartPosition = FormStartPosition.Manual;
form.FormBorderStyle = FormBorderStyle.None;
form.WindowState = FormWindowState.Maximized; form.WindowState = FormWindowState.Maximized;
form.FormBorderStyle = FormBorderStyle.None;
form.TopMost = true; form.TopMost = true;
form.BackColor = System.Drawing.Color.Black; form.BackColor = System.Drawing.Color.Black;
@ -353,9 +353,13 @@ namespace OpenTK.Graphics
void MoveToStartPositions() void MoveToStartPositions()
{ {
//int count = 0; int count = 0;
//foreach (Screen s in Screen.AllScreens) foreach (Screen s in Screen.AllScreens)
{
// forms[count++].Location = new System.Drawing.Point(s.Bounds.X, s.Bounds.Y); // forms[count++].Location = new System.Drawing.Point(s.Bounds.X, s.Bounds.Y);
//forms[count].Size = new System.Drawing.Size(4096, 4096);
count++;
}
} }
bool FadedOut bool FadedOut

View file

@ -9,6 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
@ -38,7 +39,6 @@ namespace OpenTK.Platform.X11
using Rotation = System.UInt16; using Rotation = System.UInt16;
using Status = System.Int32; using Status = System.Int32;
using SizeID = System.UInt16; using SizeID = System.UInt16;
using System.Diagnostics;
#endregion #endregion
@ -57,37 +57,56 @@ namespace OpenTK.Platform.X11
static int screenCount; static int screenCount;
internal static Display DefaultDisplay { get { return defaultDisplay; } } internal static Display DefaultDisplay { get { return defaultDisplay; } }
internal static int DefaultScreen { get { return defaultScreen; } } //internal static int DefaultScreen { get { return defaultScreen; } }
internal static Window RootWindow { get { return rootWindow; } } //internal static Window RootWindow { get { return rootWindow; } }
internal static int ScreenCount { get { return screenCount; } } internal static int ScreenCount { get { return screenCount; } }
internal static object Lock = new object();
#endregion #endregion
static API() static API()
{ {
//AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
//using (System.Windows.Forms.Control c = new System.Windows.Forms.Control()) { }
//Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
//defaultDisplay = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static |
// System.Reflection.BindingFlags.NonPublic).GetValue(null);
defaultDisplay = Functions.XOpenDisplay(IntPtr.Zero); defaultDisplay = Functions.XOpenDisplay(IntPtr.Zero);
defaultScreen = Functions.XDefaultScreen(DefaultDisplay);
rootWindow = Functions.XRootWindow(DefaultDisplay, DefaultScreen); if (defaultDisplay == IntPtr.Zero)
throw new PlatformException("Could not establish connection to the X-Server.");
//defaultScreen = Functions.XDefaultScreen(DefaultDisplay);
//rootWindow = Functions.XRootWindow(DefaultDisplay, DefaultScreen);
screenCount = Functions.XScreenCount(DefaultDisplay); screenCount = Functions.XScreenCount(DefaultDisplay);
Debug.Print("Default Display: {0}, Default Screen: {1}, Default Root Window: {2}, Screen Count: {3}", //Debug.Print("Default Display: {0}, Default Screen: {1}, Default Root Window: {2}, Screen Count: {3}",
DefaultDisplay, DefaultScreen, RootWindow, ScreenCount); // DefaultDisplay, DefaultScreen, RootWindow, ScreenCount);
Debug.Print("Display connection: {0}, Screen count: {1}", DefaultDisplay, ScreenCount);
} }
static void CurrentDomain_ProcessExit(object sender, EventArgs e) static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{ {
if (defaultDisplay != IntPtr.Zero) { Functions.XCloseDisplay(defaultDisplay); defaultDisplay = IntPtr.Zero; } if (defaultDisplay != IntPtr.Zero)
{
Functions.XCloseDisplay(defaultDisplay);
defaultDisplay = IntPtr.Zero;
defaultScreen = 0;
rootWindow = IntPtr.Zero;
}
} }
// Display management // Display management
[DllImport(_dll_name, EntryPoint = "XOpenDisplay")] //[DllImport(_dll_name, EntryPoint = "XOpenDisplay")]
extern public static IntPtr OpenDisplay([MarshalAs(UnmanagedType.LPTStr)] string display_name); //extern public static IntPtr OpenDisplay([MarshalAs(UnmanagedType.LPTStr)] string display_name);
[DllImport(_dll_name, EntryPoint = "XCloseDisplay")] //[DllImport(_dll_name, EntryPoint = "XCloseDisplay")]
extern public static void CloseDisplay(Display display); //extern public static void CloseDisplay(Display display);
[DllImport(_dll_name, EntryPoint = "XCreateColormap")] //[DllImport(_dll_name, EntryPoint = "XCreateColormap")]
extern public static IntPtr CreateColormap(Display display, Window window, IntPtr visual, int alloc); //extern public static IntPtr CreateColormap(Display display, Window window, IntPtr visual, int alloc);
#region Window handling #region Window handling

View file

@ -13,6 +13,35 @@ using System.Runtime.InteropServices;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
#region Types
// using XID = System.Int32;
using Window = System.IntPtr;
using Drawable = System.IntPtr;
using Font = System.IntPtr;
using Pixmap = System.IntPtr;
using Cursor = System.IntPtr;
using Colormap = System.IntPtr;
using GContext = System.IntPtr;
using KeySym = System.IntPtr;
using Mask = System.IntPtr;
using Atom = System.IntPtr;
using VisualID = System.IntPtr;
using Time = System.UInt32;
using KeyCode = System.Byte; // Or maybe ushort?
using Display = System.IntPtr;
using XPointer = System.IntPtr;
// Randr and Xrandr
using Bool = System.Boolean;
using XRRScreenConfiguration = System.IntPtr; // opaque datatype
using Rotation = System.UInt16;
using Status = System.Int32;
using SizeID = System.UInt16;
#endregion
internal static partial class Functions internal static partial class Functions
{ {
public static readonly object Lock = new object(); public static readonly object Lock = new object();
@ -337,13 +366,15 @@ namespace OpenTK.Platform.X11
public extern static void XPeekEvent(IntPtr display, ref XEvent xevent); public extern static void XPeekEvent(IntPtr display, ref XEvent xevent);
[DllImport("libX11", EntryPoint = "XGetVisualInfo")] [DllImport("libX11", EntryPoint = "XGetVisualInfo")]
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems);
out int nitems);
public static IntPtr XGetVisualInfo(IntPtr display, XVisualInfoMask vinfo_mask, ref XVisualInfo template, out int nitems) public static IntPtr XGetVisualInfo(IntPtr display, XVisualInfoMask vinfo_mask, ref XVisualInfo template, out int nitems)
{ {
return XGetVisualInfoInternal(display, (IntPtr)(int)vinfo_mask, ref template, out nitems); return XGetVisualInfoInternal(display, (IntPtr)(int)vinfo_mask, ref template, out nitems);
} }
[DllImport("libX11")]
public static extern IntPtr XCreateColormap(Display display, Window window, IntPtr visual, int alloc);
} }
} }

View file

@ -39,7 +39,7 @@ namespace OpenTK.Platform.X11
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, window.VisualInfo.visual); .SetValue(null, window.VisualInfo.visual);
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0)); .SetValue(null, Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0));
} }
#region --- IGLControl Members --- #region --- IGLControl Members ---

View file

@ -1,6 +1,8 @@
#region --- License --- #region --- License ---
/* Copyright (c) 2007 Stefanos Apostolopoulos /* Licensed under the MIT/X11 license.
* See license.txt for license info * 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 #endregion
@ -93,7 +95,7 @@ namespace OpenTK.Platform.X11
// System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null); // System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
// Open a display connection to the X server, and obtain the screen and root window. // Open a display connection to the X server, and obtain the screen and root window.
window.Display = API.OpenDisplay(null); // null == default display //window.Display = API.DefaultDisplay; window.Display = API.DefaultDisplay;//Functions.XOpenDisplay(IntPtr.Zero); // IntPtr.Zero == default display
if (window.Display == IntPtr.Zero) if (window.Display == IntPtr.Zero)
throw new Exception("Could not open connection to X"); throw new Exception("Could not open connection to X");
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen; window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
@ -157,10 +159,8 @@ namespace OpenTK.Platform.X11
XSetWindowAttributes attributes = new XSetWindowAttributes(); XSetWindowAttributes attributes = new XSetWindowAttributes();
attributes.background_pixel = IntPtr.Zero; attributes.background_pixel = IntPtr.Zero;
attributes.border_pixel = IntPtr.Zero; attributes.border_pixel = IntPtr.Zero;
attributes.colormap = attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/); window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
window.EventMask =
EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.KeyPressMask |
EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask | EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask; EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
@ -666,8 +666,8 @@ namespace OpenTK.Platform.X11
{ {
if (window.WindowHandle != IntPtr.Zero) if (window.WindowHandle != IntPtr.Zero)
Functions.XDestroyWindow(window.Display, window.WindowHandle); Functions.XDestroyWindow(window.Display, window.WindowHandle);
if (window.Display != IntPtr.Zero) //if (window.Display != IntPtr.Zero)
Functions.XCloseDisplay(window.Display); // Functions.XCloseDisplay(window.Display);
window = null; window = null;
} }

View file

@ -25,7 +25,11 @@ namespace OpenTK.Platform.X11
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo) int buffers, bool stereo)
{ {
GraphicsMode gfx; // The actual GraphicsMode that will be selected.
List<int> visualAttributes = new List<int>(); List<int> visualAttributes = new List<int>();
IntPtr visual;
Debug.Print("Bits per pixel: {0}", color.BitsPerPixel);
if (color.BitsPerPixel > 0) if (color.BitsPerPixel > 0)
{ {
@ -41,6 +45,8 @@ namespace OpenTK.Platform.X11
visualAttributes.Add(color.Alpha); visualAttributes.Add(color.Alpha);
} }
Debug.Print("Depth: {0}", depth);
if (depth > 0) if (depth > 0)
{ {
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE); visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
@ -73,20 +79,15 @@ namespace OpenTK.Platform.X11
visualAttributes.Add((int)0); visualAttributes.Add((int)0);
// Prepare Windows.Forms for creating OpenGL drawables. // Select a visual that matches the parameters set by the user.
// We reuse the display connection. lock (API.Lock)
// TODO: Multiple screens. {
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); IntPtr display = API.DefaultDisplay; //Functions.XOpenDisplay(IntPtr.Zero);
IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle", int screen = Functions.XDefaultScreen(display);
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null); IntPtr root = Functions.XRootWindow(display, screen);
IntPtr root = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
int screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root); Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
IntPtr visual = Glx.ChooseVisual(display, screen, visualAttributes.ToArray()); visual = Glx.ChooseVisual(display, screen, visualAttributes.ToArray());
if (visual == IntPtr.Zero) if (visual == IntPtr.Zero)
throw new GraphicsContextException("Requested GraphicsMode not available."); throw new GraphicsContextException("Requested GraphicsMode not available.");
@ -113,13 +114,32 @@ namespace OpenTK.Platform.X11
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st); Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
stereo = st != 0; stereo = st != 0;
GraphicsMode gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples, gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples,
new ColorFormat(ar, ag, ab, aa), buffers, stereo); new ColorFormat(ar, ag, ab, aa), buffers, stereo);
//Functions.XCloseDisplay(display);
}
// Prepare Windows.Forms for creating OpenGL drawables.
lock (API.Lock)
{
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
IntPtr root = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
int screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, visual); .SetValue(null, visual);
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(display, root, visual, 0)); .SetValue(null, Functions.XCreateColormap(display, root, visual, 0));
}
Functions.XFree(visual);
return gfx; return gfx;
} }

View file

@ -37,7 +37,6 @@ namespace OpenTK.Platform.X11
{ {
// Get available resolutions. Then, for each resolution get all // Get available resolutions. Then, for each resolution get all
// available rates. // available rates.
// TODO: Find a way to get all available depths, too.
// TODO: Global X11 lock. // TODO: Global X11 lock.
for (int screen = 0; screen < API.ScreenCount; screen++) for (int screen = 0; screen < API.ScreenCount; screen++)
{ {
@ -85,11 +84,10 @@ namespace OpenTK.Platform.X11
int current_resolution_index = Functions.XRRConfigCurrentConfiguration(screen_config, out current_rotation); int current_resolution_index = Functions.XRRConfigCurrentConfiguration(screen_config, out current_rotation);
DisplayDevice current_device = new DisplayDevice( DisplayDevice current_device = new DisplayDevice(
new DisplayResolution( new DisplayResolution(available_res[current_resolution_index].Width, available_res[current_resolution_index].Height,
available_res[current_resolution_index].Width,
available_res[current_resolution_index].Height,
current_depth, current_refresh_rate), current_depth, current_refresh_rate),
screen == API.DefaultScreen, available_res); screen == Functions.XDefaultScreen(API.DefaultDisplay),
available_res);
deviceToScreen.Add(current_device, screen); deviceToScreen.Add(current_device, screen);
deviceToDefaultResolution.Add(current_device, current_resolution_index); deviceToDefaultResolution.Add(current_device, current_resolution_index);
@ -127,7 +125,7 @@ namespace OpenTK.Platform.X11
static float FindCurrentRefreshRate(int screen) static float FindCurrentRefreshRate(int screen)
{ {
IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, API.RootWindow); IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, Functions.XRootWindow(API.DefaultDisplay, screen));
ushort rotation = 0; ushort rotation = 0;
int size = Functions.XRRConfigCurrentConfiguration(screen_config, out rotation); int size = Functions.XRRConfigCurrentConfiguration(screen_config, out rotation);
short rate = Functions.XRRConfigCurrentRate(screen_config); short rate = Functions.XRRConfigCurrentRate(screen_config);