-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathX11Helper.cs
More file actions
66 lines (57 loc) · 3.12 KB
/
Copy pathX11Helper.cs
File metadata and controls
66 lines (57 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Runtime.InteropServices;
using OpenTK.Graphics;
using OpenTK.Platform;
using OpenTK.Platform.X11;
namespace engenious.WinForms
{
internal static class X11Helper
{
[DllImport("libX11")]
static extern IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int alloc);
[DllImport("libX11", EntryPoint = "XGetVisualInfo")]
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr visualInfoMask, ref XVisualInfo template, out int numberOfItems);
[DllImport ("libX11", EntryPoint="XDefaultVisual")]
static extern IntPtr XDefaultVisual(IntPtr display, int screenNumber);
static IntPtr XGetVisualInfo(IntPtr display, int visualInfoMask, ref XVisualInfo template, out int numberOfItems)
{
return XGetVisualInfoInternal(display, (IntPtr)visualInfoMask, ref template, out numberOfItems);
}
public static IWindowInfo CreateWindowInfo(GraphicsMode mode, GameControl control)
{
// Use reflection to retrieve the necessary values from Mono's Windows.Forms implementation.
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
if (xplatui == null) throw new PlatformNotSupportedException(
"System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
// get the required handles from the X11 API.
var display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle");
IntPtr rootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow");
int screen = (int)GetStaticFieldValue(xplatui, "ScreenNo");
// get the XVisualInfo for this GraphicsMode
XVisualInfo info = new XVisualInfo();
info.VisualID = mode.Index ?? IntPtr.Zero;
IntPtr infoPtr = XGetVisualInfo(display, 1 /* VisualInfoMask.ID */, ref info, out _);
if (infoPtr == IntPtr.Zero)
infoPtr = (IntPtr) GetStaticFieldValue(xplatui, "CustomVisual");
if (infoPtr == IntPtr.Zero)
infoPtr = XDefaultVisual(display, screen);
info = (XVisualInfo)Marshal.PtrToStructure(infoPtr, typeof(XVisualInfo));
// set the X11 colormap.
SetStaticFieldValue(xplatui, "CustomVisual", info.Visual);
SetStaticFieldValue(xplatui, "CustomColormap", XCreateColormap(display, rootWindow, info.Visual, 0));
return Utilities.CreateX11WindowInfo(display, screen, control.Handle, rootWindow, infoPtr);
}
static object GetStaticFieldValue(Type type, string fieldName)
{
return type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
?.GetValue(null);
}
static void SetStaticFieldValue(Type type, string fieldName, object value)
{
type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
?.SetValue(null, value);
}
}
}