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 5b4bed3a09
commit ef16998dca
8 changed files with 168 additions and 96 deletions

View file

@ -2,7 +2,7 @@
/* 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.
* See license.txt for licensing details.
*/
#endregion

View file

@ -338,9 +338,9 @@ namespace OpenTK.Graphics
{
Form form = new Form();
form.ShowInTaskbar = false;
form.StartPosition = FormStartPosition.Manual;
form.FormBorderStyle = FormBorderStyle.None;
form.StartPosition = FormStartPosition.Manual;
form.WindowState = FormWindowState.Maximized;
form.FormBorderStyle = FormBorderStyle.None;
form.TopMost = true;
form.BackColor = System.Drawing.Color.Black;
@ -353,9 +353,13 @@ namespace OpenTK.Graphics
void MoveToStartPositions()
{
//int count = 0;
//foreach (Screen s in Screen.AllScreens)
// forms[count++].Location = new System.Drawing.Point(s.Bounds.X, s.Bounds.Y);
int count = 0;
foreach (Screen s in Screen.AllScreens)
{
// 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

View file

@ -8,7 +8,8 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace OpenTK.Platform.X11
{
@ -38,7 +39,6 @@ namespace OpenTK.Platform.X11
using Rotation = System.UInt16;
using Status = System.Int32;
using SizeID = System.UInt16;
using System.Diagnostics;
#endregion
@ -57,37 +57,56 @@ namespace OpenTK.Platform.X11
static int screenCount;
internal static Display DefaultDisplay { get { return defaultDisplay; } }
internal static int DefaultScreen { get { return defaultScreen; } }
internal static Window RootWindow { get { return rootWindow; } }
internal static int ScreenCount { get { return screenCount; } }
//internal static int DefaultScreen { get { return defaultScreen; } }
//internal static Window RootWindow { get { return rootWindow; } }
internal static int ScreenCount { get { return screenCount; } }
internal static object Lock = new object();
#endregion
static API()
{
//AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
defaultDisplay = Functions.XOpenDisplay(IntPtr.Zero);
defaultScreen = Functions.XDefaultScreen(DefaultDisplay);
rootWindow = Functions.XRootWindow(DefaultDisplay, DefaultScreen);
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);
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);
Debug.Print("Default Display: {0}, Default Screen: {1}, Default Root Window: {2}, Screen Count: {3}",
DefaultDisplay, DefaultScreen, RootWindow, ScreenCount);
//Debug.Print("Default Display: {0}, Default Screen: {1}, Default Root Window: {2}, Screen Count: {3}",
// DefaultDisplay, DefaultScreen, RootWindow, ScreenCount);
Debug.Print("Display connection: {0}, Screen count: {1}", DefaultDisplay, ScreenCount);
}
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
[DllImport(_dll_name, EntryPoint = "XOpenDisplay")]
extern public static IntPtr OpenDisplay([MarshalAs(UnmanagedType.LPTStr)] string display_name);
//[DllImport(_dll_name, EntryPoint = "XOpenDisplay")]
//extern public static IntPtr OpenDisplay([MarshalAs(UnmanagedType.LPTStr)] string display_name);
[DllImport(_dll_name, EntryPoint = "XCloseDisplay")]
extern public static void CloseDisplay(Display display);
//[DllImport(_dll_name, EntryPoint = "XCloseDisplay")]
//extern public static void CloseDisplay(Display display);
[DllImport(_dll_name, EntryPoint = "XCreateColormap")]
extern public static IntPtr CreateColormap(Display display, Window window, IntPtr visual, int alloc);
//[DllImport(_dll_name, EntryPoint = "XCreateColormap")]
//extern public static IntPtr CreateColormap(Display display, Window window, IntPtr visual, int alloc);
#region Window handling

View file

@ -12,7 +12,36 @@ using System.Text;
using System.Runtime.InteropServices;
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
{
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);
[DllImport("libX11", EntryPoint = "XGetVisualInfo")]
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template,
out int nitems);
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr 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);
}
}
[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)
.SetValue(null, window.VisualInfo.visual);
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 ---

View file

@ -1,6 +1,8 @@
#region --- License ---
/* Copyright (c) 2007 Stefanos Apostolopoulos
* See license.txt for license info
/* 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
@ -93,7 +95,7 @@ namespace OpenTK.Platform.X11
// 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.
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)
throw new Exception("Could not open connection to X");
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
@ -157,13 +159,11 @@ namespace OpenTK.Platform.X11
XSetWindowAttributes attributes = new XSetWindowAttributes();
attributes.background_pixel = IntPtr.Zero;
attributes.border_pixel = IntPtr.Zero;
attributes.colormap =
API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
window.EventMask =
EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask |
EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask |
EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
attributes.event_mask = (IntPtr)window.EventMask;
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
@ -664,10 +664,10 @@ namespace OpenTK.Platform.X11
{
if (window != null)
{
if (window.WindowHandle != IntPtr.Zero)
if (window.WindowHandle != IntPtr.Zero)
Functions.XDestroyWindow(window.Display, window.WindowHandle);
if (window.Display != IntPtr.Zero)
Functions.XCloseDisplay(window.Display);
//if (window.Display != IntPtr.Zero)
// Functions.XCloseDisplay(window.Display);
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,
int buffers, bool stereo)
{
List<int> visualAttributes = new List<int>();
GraphicsMode gfx; // The actual GraphicsMode that will be selected.
List<int> visualAttributes = new List<int>();
IntPtr visual;
Debug.Print("Bits per pixel: {0}", color.BitsPerPixel);
if (color.BitsPerPixel > 0)
{
@ -40,6 +44,8 @@ namespace OpenTK.Platform.X11
visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
visualAttributes.Add(color.Alpha);
}
Debug.Print("Depth: {0}", depth);
if (depth > 0)
{
@ -71,56 +77,70 @@ namespace OpenTK.Platform.X11
if (stereo)
visualAttributes.Add((int)GLXAttribute.STEREO);
visualAttributes.Add((int)0);
visualAttributes.Add((int)0);
// Select a visual that matches the parameters set by the user.
lock (API.Lock)
{
IntPtr display = API.DefaultDisplay; //Functions.XOpenDisplay(IntPtr.Zero);
int screen = Functions.XDefaultScreen(display);
IntPtr root = Functions.XRootWindow(display, screen);
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
// Prepare Windows.Forms for creating OpenGL drawables.
// We reuse the display connection.
// TODO: Multiple screens.
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);
visual = Glx.ChooseVisual(display, screen, visualAttributes.ToArray());
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
if (visual == IntPtr.Zero)
throw new GraphicsContextException("Requested GraphicsMode not available.");
IntPtr visual = Glx.ChooseVisual(display, screen, visualAttributes.ToArray());
XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
if (visual == IntPtr.Zero)
throw new GraphicsContextException("Requested GraphicsMode not available.");
// See what we *really* got:
int r, g, b, a;
Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a);
Glx.GetConfig(display, ref info, GLXAttribute.RED_SIZE, out r);
Glx.GetConfig(display, ref info, GLXAttribute.GREEN_SIZE, out g);
Glx.GetConfig(display, ref info, GLXAttribute.BLUE_SIZE, out b);
int ar, ag, ab, aa;
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_ALPHA_SIZE, out aa);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab);
Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth);
Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
++buffers; // the above lines returns 0 - false and 1 - true.
int st;
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
stereo = st != 0;
XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
// See what we *really* got:
int r, g, b, a;
Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a);
Glx.GetConfig(display, ref info, GLXAttribute.RED_SIZE, out r);
Glx.GetConfig(display, ref info, GLXAttribute.GREEN_SIZE, out g);
Glx.GetConfig(display, ref info, GLXAttribute.BLUE_SIZE, out b);
int ar, ag, ab, aa;
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_ALPHA_SIZE, out aa);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab);
Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth);
Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
++buffers; // the above lines returns 0 - false and 1 - true.
int st;
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
stereo = st != 0;
GraphicsMode gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples,
new ColorFormat(ar, ag, ab, aa), buffers, stereo);
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, visual);
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(display, root, visual, 0));
gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples,
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)
.SetValue(null, visual);
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, Functions.XCreateColormap(display, root, visual, 0));
}
Functions.XFree(visual);
return gfx;
}
}

View file

@ -37,7 +37,6 @@ namespace OpenTK.Platform.X11
{
// Get available resolutions. Then, for each resolution get all
// available rates.
// TODO: Find a way to get all available depths, too.
// TODO: Global X11 lock.
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);
DisplayDevice current_device = new DisplayDevice(
new DisplayResolution(
available_res[current_resolution_index].Width,
available_res[current_resolution_index].Height,
current_depth, current_refresh_rate),
screen == API.DefaultScreen, available_res);
new DisplayResolution(available_res[current_resolution_index].Width, available_res[current_resolution_index].Height,
current_depth, current_refresh_rate),
screen == Functions.XDefaultScreen(API.DefaultDisplay),
available_res);
deviceToScreen.Add(current_device, screen);
deviceToDefaultResolution.Add(current_device, current_resolution_index);
@ -127,7 +125,7 @@ namespace OpenTK.Platform.X11
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;
int size = Functions.XRRConfigCurrentConfiguration(screen_config, out rotation);
short rate = Functions.XRRConfigCurrentRate(screen_config);