From abebaeb48e846e4189c042ccbaa833e766981ae3 Mon Sep 17 00:00:00 2001 From: Emmanuel Date: Tue, 22 Sep 2020 09:54:00 +0000 Subject: [PATCH] fix glx issues, 1.0.4-pre5 --- GLWidget/GLWidget.cs | 2 - GLWidget/GLWidget.csproj | 2 +- GLWidget/GTKBindingHelper.cs | 3 + GLWidget/OpenTK/Platform/X11/API.cs | 1149 ++++++++++++++++- GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs | 82 +- GLWidget/OpenTK/Platform/X11/Bindings/Xkb.cs | 304 +++++ GLWidget/OpenTK/Platform/X11/Functions.cs | 32 +- .../OpenTK/Platform/X11/X11DisplayDevice.cs | 19 +- GLWidget/OpenTK/Platform/X11/X11Factory.cs | 11 +- GLWidget/OpenTK/Platform/X11/X11GLContext.cs | 93 +- GLWidgetTestGTK3/MainWindow.cs | 2 + 11 files changed, 1614 insertions(+), 85 deletions(-) create mode 100644 GLWidget/OpenTK/Platform/X11/Bindings/Xkb.cs diff --git a/GLWidget/GLWidget.cs b/GLWidget/GLWidget.cs index 2344623..28577f2 100644 --- a/GLWidget/GLWidget.cs +++ b/GLWidget/GLWidget.cs @@ -118,8 +118,6 @@ namespace OpenTK /// Constructs a new GLWidget public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags graphicsContextFlags) { - OpenTK.Toolkit.Init(); - SingleBuffer = graphicsMode.Buffers == 1; ColorBPP = graphicsMode.ColorFormat.BitsPerPixel; AccumulatorBPP = graphicsMode.AccumulatorFormat.BitsPerPixel; diff --git a/GLWidget/GLWidget.csproj b/GLWidget/GLWidget.csproj index e6c9bb1..a63b41a 100644 --- a/GLWidget/GLWidget.csproj +++ b/GLWidget/GLWidget.csproj @@ -3,7 +3,7 @@ netstandard2.1 true GLWigdet for GTKSharp, using Opentk. - 1.0.4-pre4 + 1.0.4-pre5 https://github.com/Ryujinx/GLWidget True diff --git a/GLWidget/GTKBindingHelper.cs b/GLWidget/GTKBindingHelper.cs index 98b4cb0..5d66473 100644 --- a/GLWidget/GTKBindingHelper.cs +++ b/GLWidget/GTKBindingHelper.cs @@ -82,6 +82,9 @@ namespace OpenTK // Try to load OpenTK.Graphics assembly. Assembly assembly; + + OpenTK.Toolkit.Init(); + try { assembly = Assembly.Load("OpenTK.Graphics"); diff --git a/GLWidget/OpenTK/Platform/X11/API.cs b/GLWidget/OpenTK/Platform/X11/API.cs index 125f337..5a9f0ee 100644 --- a/GLWidget/OpenTK/Platform/X11/API.cs +++ b/GLWidget/OpenTK/Platform/X11/API.cs @@ -47,13 +47,33 @@ namespace OpenTK.Platform.X11 using Status = System.Int32; using SizeID = System.UInt16; + /// + /// X11 has some defined values they are defined with c's #define in X.h + /// + internal static class Consts + { + /// + /// Universal null resource or null atom. From header: #define None 0L + /// + public static readonly IntPtr None = IntPtr.Zero; + // + /// + /// Special time value. From header: #define CurrentTime 0L + /// + public static readonly IntPtr CurrentTime = IntPtr.Zero; // + } + internal static class API { private const string _dll_name = "libX11"; private const string _dll_name_vid = "libXxf86vm"; + private static Window rootWindow; + internal static Display DefaultDisplay { get; private set; } + private static int DefaultScreen { get; set; } + //internal static Window RootWindow { get { return rootWindow; } } internal static int ScreenCount { get; } @@ -80,6 +100,189 @@ namespace OpenTK.Platform.X11 //AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); } + private static void CurrentDomain_ProcessExit(object sender, EventArgs e) + { + 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 = "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 = "XCreateSimpleWindow")] + public extern static Window CreateSimpleWindow( + Display display, + Window parent, + int x, int y, + int width, int height, + int border_width, + long border, + long background + ); + + [DllImport(_dll_name, EntryPoint = "XResizeWindow")] + public extern static int XResizeWindow(Display display, Window window, int width, int height); + + [DllImport(_dll_name, EntryPoint = "XDestroyWindow")] + public extern static void DestroyWindow(Display display, Window window); + + [DllImport(_dll_name, EntryPoint = "XMapWindow")] + extern public static void MapWindow(Display display, Window window); + + [DllImport(_dll_name, EntryPoint = "XMapRaised")] + extern public static void MapRaised(Display display, Window window); + + [DllImport(_dll_name, EntryPoint = "XDefaultVisual")] + extern public static IntPtr DefaultVisual(Display display, int screen_number); + + /// + /// Frees the memory used by an X structure. Only use on unmanaged structures! + /// + /// A pointer to the structure that will be freed. + [DllImport(_dll_name, EntryPoint = "XFree")] + extern public static void Free(IntPtr buffer); + + [System.Security.SuppressUnmanagedCodeSecurity] + [DllImport(_dll_name, EntryPoint = "XEventsQueued")] + extern public static int EventsQueued(Display display, int mode); + + [System.Security.SuppressUnmanagedCodeSecurity] + [DllImport(_dll_name, EntryPoint = "XPending")] + extern public static int Pending(Display display); + + //[System.Security.SuppressUnmanagedCodeSecurity] + [DllImport(_dll_name, EntryPoint = "XNextEvent")] + extern public static void NextEvent( + Display display, + [MarshalAs(UnmanagedType.AsAny)][In, Out]object e); + + [DllImport(_dll_name, EntryPoint = "XNextEvent")] + extern public static void NextEvent(Display display, [In, Out] IntPtr e); + + [DllImport(_dll_name, EntryPoint = "XPeekEvent")] + extern public static void PeekEvent( + Display display, + [MarshalAs(UnmanagedType.AsAny)][In, Out]object event_return + ); + + [DllImport(_dll_name, EntryPoint = "XPeekEvent")] + extern public static void PeekEvent(Display display, [In, Out]XEvent event_return); + + [DllImport(_dll_name, EntryPoint = "XSendEvent")] + [return: MarshalAs(UnmanagedType.Bool)] + extern public static bool SendEvent(Display display, Window window, bool propagate, + [MarshalAs(UnmanagedType.SysInt)]EventMask event_mask, ref XEvent event_send); + + /// + /// The XSelectInput() function requests that the X server report the events associated + /// with the specified event mask. + /// + /// Specifies the connection to the X server. + /// Specifies the window whose events you are interested in. + /// Specifies the event mask. + /// + /// Initially, X will not report any of these events. + /// Events are reported relative to a window. + /// If a window is not interested in a device event, + /// it usually propagates to the closest ancestor that is interested, + /// unless the do_not_propagate mask prohibits it. + /// Setting the event-mask attribute of a window overrides any previous call for the same window but not for other clients. Multiple clients can select for the same events on the same window with the following restrictions: + /// Multiple clients can select events on the same window because their event masks are disjoint. When the X server generates an event, it reports it to all interested clients. + /// Only one client at a time can select CirculateRequest, ConfigureRequest, or MapRequest events, which are associated with the event mask SubstructureRedirectMask. + /// Only one client at a time can select a ResizeRequest event, which is associated with the event mask ResizeRedirectMask. + /// Only one client at a time can select a ButtonPress event, which is associated with the event mask ButtonPressMask. + /// The server reports the event to all interested clients. + /// XSelectInput() can generate a BadWindow error. + /// + [DllImport(_dll_name, EntryPoint = "XSelectInput")] + public static extern void SelectInput(Display display, Window w, EventMask event_mask); + + /// + /// When the predicate procedure finds a match, XCheckIfEvent() copies the matched event into the client-supplied XEvent structure and returns True. (This event is removed from the queue.) If the predicate procedure finds no match, XCheckIfEvent() returns False, and the output buffer will have been flushed. All earlier events stored in the queue are not discarded. + /// + /// Specifies the connection to the X server. + /// Returns a copy of the matched event's associated structure. + /// Specifies the procedure that is to be called to determine if the next event in the queue matches what you want + /// Specifies the user-supplied argument that will be passed to the predicate procedure. + /// true if the predicate returns true for some event, false otherwise + [DllImport(_dll_name, EntryPoint = "XCheckIfEvent")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CheckIfEvent(Display display, ref XEvent event_return, + /*[MarshalAs(UnmanagedType.FunctionPtr)] */ CheckEventPredicate predicate, /*XPointer*/ IntPtr arg); + + [DllImport(_dll_name, EntryPoint = "XIfEvent")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool IfEvent(Display display, ref XEvent event_return, + /*[MarshalAs(UnmanagedType.FunctionPtr)] */ CheckEventPredicate predicate, /*XPointer*/ IntPtr arg); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate bool CheckEventPredicate(Display display, ref XEvent @event, IntPtr arg); + + [DllImport(_dll_name, EntryPoint = "XCheckMaskEvent")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CheckMaskEvent(Display display, EventMask event_mask, ref XEvent event_return); + + [DllImport(_dll_name, EntryPoint = "XGrabPointer")] + extern public static ErrorCodes GrabPointer(Display display, IntPtr grab_window, + bool owner_events, int event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, + IntPtr confine_to, IntPtr cursor, int time); + + [DllImport(_dll_name, EntryPoint = "XUngrabPointer")] + extern public static ErrorCodes UngrabPointer(Display display, int time); + + [DllImport(_dll_name, EntryPoint = "XGrabKeyboard")] + extern public static ErrorCodes GrabKeyboard(Display display, IntPtr grab_window, + bool owner_events, GrabMode pointer_mode, GrabMode keyboard_mode, int time); + + [DllImport(_dll_name, EntryPoint = "XUngrabKeyboard")] + extern public static void UngrabKeyboard(Display display, int time); + + /// + /// The XGetKeyboardMapping() function returns the symbols for the specified number of KeyCodes starting with first_keycode. + /// + /// Specifies the connection to the X server. + /// Specifies the first KeyCode that is to be returned. + /// Specifies the number of KeyCodes that are to be returned + /// Returns the number of KeySyms per KeyCode. + /// + /// + /// The value specified in first_keycode must be greater than or equal to min_keycode as returned by XDisplayKeycodes(), or a BadValue error results. In addition, the following expression must be less than or equal to max_keycode as returned by XDisplayKeycodes(): + /// first_keycode + keycode_count - 1 + /// If this is not the case, a BadValue error results. The number of elements in the KeySyms list is: + /// keycode_count * keysyms_per_keycode_return + /// KeySym number N, counting from zero, for KeyCode K has the following index in the list, counting from zero: + /// (K - first_code) * keysyms_per_code_return + N + /// The X server arbitrarily chooses the keysyms_per_keycode_return value to be large enough to report all requested symbols. A special KeySym value of NoSymbol is used to fill in unused elements for individual KeyCodes. To free the storage returned by XGetKeyboardMapping(), use XFree(). + /// XGetKeyboardMapping() can generate a BadValue error. + /// Diagnostics: + /// BadValue: Some numeric value falls outside the range of values accepted by the request. Unless a specific range is specified for an argument, the full range defined by the argument's type is accepted. Any argument defined as a set of alternatives can generate this error. + /// + [DllImport(_dll_name, EntryPoint = "XGetKeyboardMapping")] + public static extern KeySym GetKeyboardMapping(Display display, KeyCode first_keycode, int keycode_count, + ref int keysyms_per_keycode_return); + + /// + /// The XDisplayKeycodes() function returns the min-keycodes and max-keycodes supported by the specified display. + /// + /// Specifies the connection to the X server. + /// Returns the minimum number of KeyCodes + /// Returns the maximum number of KeyCodes. + /// The minimum number of KeyCodes returned is never less than 8, and the maximum number of KeyCodes returned is never greater than 255. Not all KeyCodes in this range are required to have corresponding keys. + [DllImport(_dll_name, EntryPoint = "XDisplayKeycodes")] + public static extern void DisplayKeycodes(Display display, ref int min_keycodes_return, ref int max_keycodes_return); + [StructLayout(LayoutKind.Sequential)] internal struct XF86VidModeModeLine { @@ -166,6 +369,74 @@ namespace OpenTK.Platform.X11 private IntPtr _private; /* Server privates */ } + //Monitor information: + [StructLayout(LayoutKind.Sequential)] + internal struct XF86VidModeMonitor + { + [MarshalAs(UnmanagedType.LPStr)] private string vendor; /* Name of manufacturer */ + [MarshalAs(UnmanagedType.LPStr)] private string model; /* Model name */ + private float EMPTY; /* unused, for backward compatibility */ + + private byte nhsync; /* Number of horiz sync ranges */ + /*XF86VidModeSyncRange* */ + private IntPtr hsync; /* Horizontal sync ranges */ + + private byte nvsync; /* Number of vert sync ranges */ + /*XF86VidModeSyncRange* */ + private IntPtr vsync; /* Vertical sync ranges */ + } + + [StructLayout(LayoutKind.Sequential)] + internal struct XF86VidModeSyncRange + { + private float hi; /* Top of range */ + private float lo; /* Bottom of range */ + } + + [StructLayout(LayoutKind.Sequential)] + internal struct XF86VidModeNotifyEvent + { + private int type; /* of event */ + private ulong serial; /* # of last request processed by server */ + private bool send_event; /* true if this came from a SendEvent req */ + private Display display; /* Display the event was read from */ + private IntPtr root; /* root window of event screen */ + private int state; /* What happened */ + private int kind; /* What happened */ + + private bool forced; /* extents of new region */ + /* Time */ + private IntPtr time; /* event timestamp */ + } + + [StructLayout(LayoutKind.Sequential)] + internal struct XF86VidModeGamma + { + private float red; /* Red Gamma value */ + private float green; /* Green Gamma value */ + private float blue; /* Blue Gamma value */ + } + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeQueryExtension( + Display display, + out int event_base_return, + out int error_base_return); + /* + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeSwitchMode( + Display display, + int screen, + int zoom); + */ + + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeSwitchToMode( + Display display, + int screen, + IntPtr + /*XF86VidModeModeInfo* */ modeline); + + [DllImport(_dll_name_vid)] extern public static bool XF86VidModeQueryVersion( Display display, @@ -194,6 +465,121 @@ namespace OpenTK.Platform.X11 out int x_return, out int y_return); + [DllImport(_dll_name_vid)] + extern public static bool XF86VidModeSetViewPort( + Display display, + int screen, + int x, + int y); + + /* +Bool XF86VidModeSetClientVersion( + Display *display); + +Bool XF86VidModeDeleteModeLine( + Display *display, + int screen, + XF86VidModeModeInfo *modeline); + +Bool XF86VidModeModModeLine( + Display *display, + int screen, + XF86VidModeModeLine *modeline); + +Status XF86VidModeValidateModeLine( + Display *display, + int screen, + XF86VidModeModeLine *modeline); + +Bool XF86VidModeLockModeSwitch( + Display *display, + int screen, + int lock); + +Bool XF86VidModeGetMonitor( + Display *display, + int screen, + XF86VidModeMonitor *monitor); + +XF86VidModeGetDotClocks( + Display *display, + int screen, + int *flags return, + int *number of clocks return, + int *max dot clock return, + int **clocks return); + +XF86VidModeGetGamma( + Display *display, + int screen, + XF86VidModeGamma *Gamma); + +XF86VidModeSetGamma( + Display *display, + int screen, + XF86VidModeGamma *Gamma); + +XF86VidModeGetGammaRamp( + Display *display, + int screen, + int size, + unsigned short *red array, + unsigned short *green array, + unsigned short *blue array); + +XF86VidModeSetGammaRamp( + Display *display, + int screen, + int size, + unsigned short *red array, + unsigned short *green array, + unsigned short *blue array); + +XF86VidModeGetGammaRampSize( + Display *display, + int screen, + int *size); + * */ + + [DllImport(_dll_name, EntryPoint = "XLookupKeysym")] + public static extern KeySym LookupKeysym(ref XKeyEvent key_event, int index); + + } + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XcursorImage + { + public XcursorUInt version; + public XcursorDim size; + public XcursorDim width; + public XcursorDim height; + public XcursorDim xhot; + public XcursorDim yhot; + public XcursorUInt delay; + public XcursorPixel* pixels; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XcursorImages + { + public int nimage; + public XcursorImage **images; + public char *name; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XcursorCursors + { + public Display dpy; + public int refcount; + public int ncursor; + public Cursor *cursors; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XcursorAnimate + { + public XcursorCursors *cursors; + public int sequence; } [StructLayout(LayoutKind.Sequential)] @@ -217,12 +603,68 @@ namespace OpenTK.Platform.X11 } } + [StructLayout(LayoutKind.Sequential)] + internal struct SizeHints + { + public long flags; /* marks which fields in this structure are defined */ + public int x, y; /* Obsolete */ + public int width, height; /* Obsolete */ + public int min_width, min_height; + public int max_width, max_height; + public int width_inc, height_inc; + public Rectangle min_aspect, max_aspect; + public int base_width, base_height; + public int win_gravity; + internal struct Rectangle + { + public int x; /* numerator */ + public int y; /* denominator */ + private void stop_the_compiler_warnings() { x = y = 0; } + } + /* this structure may be extended in the future */ + } + internal struct XRRScreenSize { internal int Width, Height; internal int MWidth, MHeight; }; + unsafe internal struct Screen + { + private XExtData ext_data; /* hook for extension to hang buffer */ + private IntPtr display; /* back pointer to display structure */ /* _XDisplay */ + private Window root; /* Root window id. */ + + private int width, height; /* width and height of screen */ + private int mwidth, mheight; /* width and height of in millimeters */ + + private int ndepths; /* number of depths possible */ + //Depth *depths; /* list of allowable depths on the screen */ + private int root_depth; /* bits per pixel */ + //Visual* root_visual; /* root visual */ + private IntPtr default_gc; /* GC for the root root visual */ // GC + + private Colormap cmap; /* default color map */ + private UIntPtr white_pixel; // unsigned long + private UIntPtr black_pixel; /* White and Black pixel values */ // unsigned long + private int max_maps, min_maps; /* max and min color maps */ + + private int backing_store; /* Never, WhenMapped, Always */ + private Bool save_unders; + private long root_input_mask; /* initial root input mask */ + } + + unsafe internal class XExtData + { + private int number; /* number returned by XRegisterExtension */ + private XExtData next; /* next item on list of buffer for structure */ + + private delegate int FreePrivateDelegate(XExtData extension); + + private FreePrivateDelegate FreePrivate; /* called to free private storage */ + private XPointer private_data; /* buffer private to this extension. */ + }; [StructLayout(LayoutKind.Sequential)] internal struct MotifWmHints @@ -281,6 +723,69 @@ namespace OpenTK.Platform.X11 FullApplicationModal = 3 } + internal struct Constants + { + public const int QueuedAlready = 0; + public const int QueuedAfterReading = 1; + public const int QueuedAfterFlush = 2; + + public const int CopyFromParent = 0; + public const int CWX = 1; + public const int InputOutput = 1; + public const int InputOnly = 2; + + /* The hints we recognize */ + public const string XA_WIN_PROTOCOLS = "_WIN_PROTOCOLS"; + public const string XA_WIN_ICONS = "_WIN_ICONS"; + public const string XA_WIN_WORKSPACE = "_WIN_WORKSPACE"; + public const string XA_WIN_WORKSPACE_COUNT = "_WIN_WORKSPACE_COUNT"; + public const string XA_WIN_WORKSPACE_NAMES = "_WIN_WORKSPACE_NAMES"; + public const string XA_WIN_LAYER = "_WIN_LAYER"; + public const string XA_WIN_STATE = "_WIN_STATE"; + public const string XA_WIN_HINTS = "_WIN_HINTS"; + public const string XA_WIN_WORKAREA = "_WIN_WORKAREA"; + public const string XA_WIN_CLIENT_LIST = "_WIN_CLIENT_LIST"; + public const string XA_WIN_APP_STATE = "_WIN_APP_STATE"; + public const string XA_WIN_EXPANDED_SIZE = "_WIN_EXPANDED_SIZE"; + public const string XA_WIN_CLIENT_MOVING = "_WIN_CLIENT_MOVING"; + public const string XA_WIN_SUPPORTING_WM_CHECK = "_WIN_SUPPORTING_WM_CHECK"; + } + + internal enum WindowLayer + { + Desktop = 0, + Below = 2, + Normal = 4, + OnTop = 6, + Dock = 8, + AboveDock = 10, + Menu = 12, + } + + internal enum WindowState + { + Sticky = (1 << 0), /* everyone knows sticky */ + Minimized = (1 << 1), /* ??? */ + MaximizedVertically = (1 << 2), /* window in maximized V state */ + MaximizedHorizontally = (1 << 3), /* window in maximized H state */ + Hidden = (1 << 4), /* not on taskbar but window visible */ + Shaded = (1 << 5), /* shaded (NeXT style), */ + HID_WORKSPACE = (1 << 6), /* not on current desktop */ + HID_TRANSIENT = (1 << 7), /* owner of transient is hidden */ + FixedPosition = (1 << 8), /* window is fixed in position even */ + ArrangeIgnore = (1 << 9), /* ignore for auto arranging */ + } + + internal enum WindowHints + { + SkipFocus = (1 << 0), /* "alt-tab" skips this win */ + SkipWinlist = (1 << 1), /* not in win list */ + SkipTaskbar = (1 << 2), /* not on taskbar */ + GroupTransient = (1 << 3), /* ??????? */ + FocusOnClick = (1 << 4), /* app only accepts focus when clicked */ + DoNotCover = (1 << 5), /* attempt to not cover this window */ + } + internal enum ErrorCodes : int { Success = 0, @@ -303,6 +808,430 @@ namespace OpenTK.Platform.X11 BadImplementation = 17, } + [Flags] + internal enum CreateWindowMask : long//: ulong + { + CWBackPixmap = (1L << 0), + CWBackPixel = (1L << 1), + CWSaveUnder = (1L << 10), + CWEventMask = (1L << 11), + CWDontPropagate = (1L << 12), + CWColormap = (1L << 13), + CWCursor = (1L << 14), + CWBorderPixmap = (1L << 2), + CWBorderPixel = (1L << 3), + CWBitGravity = (1L << 4), + CWWinGravity = (1L << 5), + CWBackingStore = (1L << 6), + CWBackingPlanes = (1L << 7), + CWBackingPixel = (1L << 8), + CWOverrideRedirect = (1L << 9), + + //CWY = (1 << 1), + //CWWidth = (1 << 2), + //CWHeight = (1 << 3), + //CWBorderWidth = (1 << 4), + //CWSibling = (1 << 5), + //CWStackMode = (1 << 6), + } + + /// + /// Defines LATIN-1 and miscellaneous keys. + /// + [CLSCompliant(false)] + internal enum XKey + { + /* + * TTY function keys, cleverly chosen to map to ASCII, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code). + */ + + BackSpace = 0xff08, /* Back space, back char */ + Tab = 0xff09, + Linefeed = 0xff0a, /* Linefeed, LF */ + Clear = 0xff0b, + Return = 0xff0d, /* Return, enter */ + Pause = 0xff13, /* Pause, hold */ + Scroll_Lock = 0xff14, + Sys_Req = 0xff15, + Escape = 0xff1b, + Delete = 0xffff, /* Delete, rubout */ + + + + /* International & multi-key character composition */ + + Multi_key = 0xff20, /* Multi-key character compose */ + Codeinput = 0xff37, + SingleCandidate = 0xff3c, + MultipleCandidate = 0xff3d, + PreviousCandidate = 0xff3e, + + /* Japanese keyboard support */ + + Kanji = 0xff21, /* Kanji, Kanji convert */ + Muhenkan = 0xff22, /* Cancel Conversion */ + Henkan_Mode = 0xff23, /* Start/Stop Conversion */ + Henkan = 0xff23, /* Alias for Henkan_Mode */ + Romaji = 0xff24, /* to Romaji */ + Hiragana = 0xff25, /* to Hiragana */ + Katakana = 0xff26, /* to Katakana */ + Hiragana_Katakana = 0xff27, /* Hiragana/Katakana toggle */ + Zenkaku = 0xff28, /* to Zenkaku */ + Hankaku = 0xff29, /* to Hankaku */ + Zenkaku_Hankaku = 0xff2a, /* Zenkaku/Hankaku toggle */ + Touroku = 0xff2b, /* Add to Dictionary */ + Massyo = 0xff2c, /* Delete from Dictionary */ + Kana_Lock = 0xff2d, /* Kana Lock */ + Kana_Shift = 0xff2e, /* Kana Shift */ + Eisu_Shift = 0xff2f, /* Alphanumeric Shift */ + Eisu_toggle = 0xff30, /* Alphanumeric toggle */ + Kanji_Bangou = 0xff37, /* Codeinput */ + Zen_Koho = 0xff3d, /* Multiple/All Candidate(s) */ + Mae_Koho = 0xff3e, /* Previous Candidate */ + + /* 0xff31 thru 0xff3f are under XK_KOREAN */ + + /* Cursor control & motion */ + + Home = 0xff50, + Left = 0xff51, /* Move left, left arrow */ + Up = 0xff52, /* Move up, up arrow */ + Right = 0xff53, /* Move right, right arrow */ + Down = 0xff54, /* Move down, down arrow */ + Prior = 0xff55, /* Prior, previous */ + Page_Up = 0xff55, + Next = 0xff56, /* Next */ + Page_Down = 0xff56, + End = 0xff57, /* EOL */ + Begin = 0xff58, /* BOL */ + + + /* Misc functions */ + + Select = 0xff60, /* Select, mark */ + Print = 0xff61, + Execute = 0xff62, /* Execute, run, do */ + Insert = 0xff63, /* Insert, insert here */ + Undo = 0xff65, + Redo = 0xff66, /* Redo, again */ + Menu = 0xff67, + Find = 0xff68, /* Find, search */ + Cancel = 0xff69, /* Cancel, stop, abort, exit */ + Help = 0xff6a, /* Help */ + Break = 0xff6b, + Mode_switch = 0xff7e, /* Character set switch */ + script_switch = 0xff7e, /* Alias for mode_switch */ + Num_Lock = 0xff7f, + + /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + + KP_Space = 0xff80, /* Space */ + KP_Tab = 0xff89, + KP_Enter = 0xff8d, /* Enter */ + KP_F1 = 0xff91, /* PF1, KP_A, ... */ + KP_F2 = 0xff92, + KP_F3 = 0xff93, + KP_F4 = 0xff94, + KP_Home = 0xff95, + KP_Left = 0xff96, + KP_Up = 0xff97, + KP_Right = 0xff98, + KP_Down = 0xff99, + KP_Prior = 0xff9a, + KP_Page_Up = 0xff9a, + KP_Next = 0xff9b, + KP_Page_Down = 0xff9b, + KP_End = 0xff9c, + KP_Begin = 0xff9d, + KP_Insert = 0xff9e, + KP_Delete = 0xff9f, + KP_Equal = 0xffbd, /* Equals */ + KP_Multiply = 0xffaa, + KP_Add = 0xffab, + KP_Separator = 0xffac, /* Separator, often comma */ + KP_Subtract = 0xffad, + KP_Decimal = 0xffae, + KP_Divide = 0xffaf, + + KP_0 = 0xffb0, + KP_1 = 0xffb1, + KP_2 = 0xffb2, + KP_3 = 0xffb3, + KP_4 = 0xffb4, + KP_5 = 0xffb5, + KP_6 = 0xffb6, + KP_7 = 0xffb7, + KP_8 = 0xffb8, + KP_9 = 0xffb9, + + /* + * Auxiliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufacturers have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + + F1 = 0xffbe, + F2 = 0xffbf, + F3 = 0xffc0, + F4 = 0xffc1, + F5 = 0xffc2, + F6 = 0xffc3, + F7 = 0xffc4, + F8 = 0xffc5, + F9 = 0xffc6, + F10 = 0xffc7, + F11 = 0xffc8, + L1 = 0xffc8, + F12 = 0xffc9, + L2 = 0xffc9, + F13 = 0xffca, + L3 = 0xffca, + F14 = 0xffcb, + L4 = 0xffcb, + F15 = 0xffcc, + L5 = 0xffcc, + F16 = 0xffcd, + L6 = 0xffcd, + F17 = 0xffce, + L7 = 0xffce, + F18 = 0xffcf, + L8 = 0xffcf, + F19 = 0xffd0, + L9 = 0xffd0, + F20 = 0xffd1, + L10 = 0xffd1, + F21 = 0xffd2, + R1 = 0xffd2, + F22 = 0xffd3, + R2 = 0xffd3, + F23 = 0xffd4, + R3 = 0xffd4, + F24 = 0xffd5, + R4 = 0xffd5, + F25 = 0xffd6, + R5 = 0xffd6, + F26 = 0xffd7, + R6 = 0xffd7, + F27 = 0xffd8, + R7 = 0xffd8, + F28 = 0xffd9, + R8 = 0xffd9, + F29 = 0xffda, + R9 = 0xffda, + F30 = 0xffdb, + R10 = 0xffdb, + F31 = 0xffdc, + R11 = 0xffdc, + F32 = 0xffdd, + R12 = 0xffdd, + F33 = 0xffde, + R13 = 0xffde, + F34 = 0xffdf, + R14 = 0xffdf, + F35 = 0xffe0, + R15 = 0xffe0, + + /* Modifiers */ + + Shift_L = 0xffe1, /* Left shift */ + Shift_R = 0xffe2, /* Right shift */ + Control_L = 0xffe3, /* Left control */ + Control_R = 0xffe4, /* Right control */ + Caps_Lock = 0xffe5, /* Caps lock */ + Shift_Lock = 0xffe6, /* Shift lock */ + + Meta_L = 0xffe7, /* Left meta */ + Meta_R = 0xffe8, /* Right meta */ + Alt_L = 0xffe9, /* Left alt */ + Alt_R = 0xffea, /* Right alt */ + Super_L = 0xffeb, /* Left super */ + Super_R = 0xffec, /* Right super */ + Hyper_L = 0xffed, /* Left hyper */ + Hyper_R = 0xffee, /* Right hyper */ + + ISO_Level3_Shift = 0xfe03, + + /* + * Latin 1 + * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) + * Byte 3 = 0 + */ + + space = 0x0020, /* U+0020 SPACE */ + exclam = 0x0021, /* U+0021 EXCLAMATION MARK */ + quotedbl = 0x0022, /* U+0022 QUOTATION MARK */ + numbersign = 0x0023, /* U+0023 NUMBER SIGN */ + dollar = 0x0024, /* U+0024 DOLLAR SIGN */ + percent = 0x0025, /* U+0025 PERCENT SIGN */ + ampersand = 0x0026, /* U+0026 AMPERSAND */ + apostrophe = 0x0027, /* U+0027 APOSTROPHE */ + quoteright = 0x0027, /* deprecated */ + parenleft = 0x0028, /* U+0028 LEFT PARENTHESIS */ + parenright = 0x0029, /* U+0029 RIGHT PARENTHESIS */ + asterisk = 0x002a, /* U+002A ASTERISK */ + plus = 0x002b, /* U+002B PLUS SIGN */ + comma = 0x002c, /* U+002C COMMA */ + minus = 0x002d, /* U+002D HYPHEN-MINUS */ + period = 0x002e, /* U+002E FULL STOP */ + slash = 0x002f, /* U+002F SOLIDUS */ + Number0 = 0x0030, /* U+0030 DIGIT ZERO */ + Number1 = 0x0031, /* U+0031 DIGIT ONE */ + Number2 = 0x0032, /* U+0032 DIGIT TWO */ + Number3 = 0x0033, /* U+0033 DIGIT THREE */ + Number4 = 0x0034, /* U+0034 DIGIT FOUR */ + Number5 = 0x0035, /* U+0035 DIGIT FIVE */ + Number6 = 0x0036, /* U+0036 DIGIT SIX */ + Number7 = 0x0037, /* U+0037 DIGIT SEVEN */ + Number8 = 0x0038, /* U+0038 DIGIT EIGHT */ + Number9 = 0x0039, /* U+0039 DIGIT NINE */ + colon = 0x003a, /* U+003A COLON */ + semicolon = 0x003b, /* U+003B SEMICOLON */ + less = 0x003c, /* U+003C LESS-THAN SIGN */ + equal = 0x003d, /* U+003D EQUALS SIGN */ + greater = 0x003e, /* U+003E GREATER-THAN SIGN */ + question = 0x003f, /* U+003F QUESTION MARK */ + at = 0x0040, /* U+0040 COMMERCIAL AT */ + A = 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ + B = 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ + C = 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ + D = 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ + E = 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ + F = 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ + G = 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ + H = 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ + I = 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ + J = 0x004a, /* U+004A LATIN CAPITAL LETTER J */ + K = 0x004b, /* U+004B LATIN CAPITAL LETTER K */ + L = 0x004c, /* U+004C LATIN CAPITAL LETTER L */ + M = 0x004d, /* U+004D LATIN CAPITAL LETTER M */ + N = 0x004e, /* U+004E LATIN CAPITAL LETTER N */ + O = 0x004f, /* U+004F LATIN CAPITAL LETTER O */ + P = 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ + Q = 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ + R = 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ + S = 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ + T = 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ + U = 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ + V = 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ + W = 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ + X = 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ + Y = 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ + Z = 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ + bracketleft = 0x005b, /* U+005B LEFT SQUARE BRACKET */ + backslash = 0x005c, /* U+005C REVERSE SOLIDUS */ + bracketright = 0x005d, /* U+005D RIGHT SQUARE BRACKET */ + asciicircum = 0x005e, /* U+005E CIRCUMFLEX ACCENT */ + underscore = 0x005f, /* U+005F LOW LINE */ + grave = 0x0060, /* U+0060 GRAVE ACCENT */ + quoteleft = 0x0060, /* deprecated */ + a = 0x0061, /* U+0061 LATIN SMALL LETTER A */ + b = 0x0062, /* U+0062 LATIN SMALL LETTER B */ + c = 0x0063, /* U+0063 LATIN SMALL LETTER C */ + d = 0x0064, /* U+0064 LATIN SMALL LETTER D */ + e = 0x0065, /* U+0065 LATIN SMALL LETTER E */ + f = 0x0066, /* U+0066 LATIN SMALL LETTER F */ + g = 0x0067, /* U+0067 LATIN SMALL LETTER G */ + h = 0x0068, /* U+0068 LATIN SMALL LETTER H */ + i = 0x0069, /* U+0069 LATIN SMALL LETTER I */ + j = 0x006a, /* U+006A LATIN SMALL LETTER J */ + k = 0x006b, /* U+006B LATIN SMALL LETTER K */ + l = 0x006c, /* U+006C LATIN SMALL LETTER L */ + m = 0x006d, /* U+006D LATIN SMALL LETTER M */ + n = 0x006e, /* U+006E LATIN SMALL LETTER N */ + o = 0x006f, /* U+006F LATIN SMALL LETTER O */ + p = 0x0070, /* U+0070 LATIN SMALL LETTER P */ + q = 0x0071, /* U+0071 LATIN SMALL LETTER Q */ + r = 0x0072, /* U+0072 LATIN SMALL LETTER R */ + s = 0x0073, /* U+0073 LATIN SMALL LETTER S */ + t = 0x0074, /* U+0074 LATIN SMALL LETTER T */ + u = 0x0075, /* U+0075 LATIN SMALL LETTER U */ + v = 0x0076, /* U+0076 LATIN SMALL LETTER V */ + w = 0x0077, /* U+0077 LATIN SMALL LETTER W */ + x = 0x0078, /* U+0078 LATIN SMALL LETTER X */ + y = 0x0079, /* U+0079 LATIN SMALL LETTER Y */ + z = 0x007a, /* U+007A LATIN SMALL LETTER Z */ + braceleft = 0x007b, /* U+007B LEFT CURLY BRACKET */ + bar = 0x007c, /* U+007C VERTICAL LINE */ + braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */ + asciitilde = 0x007e, /* U+007E TILDE */ + + // Extra keys + + XF86AudioMute = 0x1008ff12, + XF86AudioLowerVolume = 0x1008ff11, + XF86AudioRaiseVolume = 0x1008ff13, + XF86PowerOff = 0x1008ff2a, + XF86Suspend = 0x1008ffa7, + XF86Copy = 0x1008ff57, + XF86Paste = 0x1008ff6d, + XF86Cut = 0x1008ff58, + XF86MenuKB = 0x1008ff65, + XF86Calculator = 0x1008ff1d, + XF86Sleep = 0x1008ff2f, + XF86WakeUp = 0x1008ff2b, + XF86Explorer = 0x1008ff5d, + XF86Send = 0x1008ff7b, + XF86Xfer = 0x1008ff8a, + XF86Launch1 = 0x1008ff41, + XF86Launch2 = 0x1008ff42, + XF86Launch3 = 0x1008ff43, + XF86Launch4 = 0x1008ff44, + XF86Launch5 = 0x1008ff45, + XF86LaunchA = 0x1008ff4a, + XF86LaunchB = 0x1008ff4b, + XF86WWW = 0x1008ff2e, + XF86DOS = 0x1008ff5a, + XF86ScreenSaver = 0x1008ff2d, + XF86RotateWindows = 0x1008ff74, + XF86Mail = 0x1008ff19, + XF86Favorites = 0x1008ff30, + XF86MyComputer = 0x1008ff33, + XF86Back = 0x1008ff26, + XF86Forward = 0x1008ff27, + XF86Eject = 0x1008ff2c, + XF86AudioPlay = 0x1008ff14, + XF86AudioStop = 0x1008ff15, + XF86AudioPrev = 0x1008ff16, + XF86AudioNext = 0x1008ff17, + XF86AudioRecord = 0x1008ff1c, + XF86AudioPause = 0x1008ff31, + XF86AudioRewind = 0x1008ff3e, + XF86AudioForward = 0x1008ff97, + XF86Phone = 0x1008ff6e, + XF86Tools = 0x1008ff81, + XF86HomePage = 0x1008ff18, + XF86Close = 0x1008ff56, + XF86Reload = 0x1008ff73, + XF86ScrollUp = 0x1008ff78, + XF86ScrollDown = 0x1008ff79, + XF86New = 0x1008ff68, + XF86TouchpadToggle = 0x1008ffa9, + XF86WebCam = 0x1008ff8f, + XF86Search = 0x1008ff1b, + XF86Finance = 0x1008ff3c, + XF86Shop = 0x1008ff36, + XF86MonBrightnessDown = 0x1008ff03, + XF86MonBrightnessUp = 0x1008ff02, + XF86AudioMedia = 0x1008ff32, + XF86Display = 0x1008ff59, + XF86KbdLightOnOff = 0x1008ff04, + XF86KbdBrightnessDown = 0x1008ff06, + XF86KbdBrightnessUp = 0x1008ff05, + XF86Reply = 0x1008ff72, + XF86MailForward = 0x1008ff90, + XF86Save = 0x1008ff77, + XF86Documents = 0x1008ff5b, + XF86Battery = 0x1008ff93, + XF86Bluetooth = 0x1008ff94, + XF86WLAN = 0x1008ff95, + + SunProps = 0x1005ff70, + SunOpen = 0x1005ff73, + } + public enum XVisualClass : int { StaticGray = 0, @@ -328,13 +1257,144 @@ namespace OpenTK.Platform.X11 BitsPerRGB = 0x100, All = 0x1FF, } - + + internal enum MouseMask + { + Button1MotionMask = (1 << 8), + Button2MotionMask = (1 << 9), + Button3MotionMask = (1 << 10), + Button4MotionMask = (1 << 11), + Button5MotionMask = (1 << 12), + Button1Mask = (1 << 8), + Button2Mask = (1 << 9), + Button3Mask = (1 << 10), + Button4Mask = (1 << 11), + Button5Mask = (1 << 12), + Button6Mask = (1 << 13), + Button7Mask = (1 << 14), + Button8Mask = (1 << 15), + ShiftMask = (1 << 0), + LockMask = (1 << 1), + ControlMask = (1 << 2), + Mod1Mask = (1 << 3), + Mod2Mask = (1 << 4), + Mod3Mask = (1 << 5), + Mod4Mask = (1 << 6), + Mod5Mask = (1 << 7), + } + internal static partial class Functions { internal const string X11Library = "libX11"; + internal const string XcursorLibrary = "libXcursor.so.1"; + + /// + /// The XCreateWindow function creates an unmapped subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings. + /// + /// Specifies the connection to the X server. + /// Specifies the parent window. + /// Specify the x coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders. + /// Specify the y coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders. + /// Specify the width, which is the created window's inside dimensions and do not include the created window's borders. + /// Specify the height, which is the created window's inside dimensions and do not include the created window's borders. + /// Specifies the width of the created window's border in pixels. + /// Specifies the window's depth. A depth of CopyFromParent means the depth is taken from the parent. + /// Specifies the created window's class. You can pass InputOutput, InputOnly, or CopyFromParent. A class of CopyFromParent means the class is taken from the parent. + /// Specifies the visual type. A visual of CopyFromParent means the visual type is taken from the parent. + /// Specifies which window attributes are defined in the attributes argument. This mask is the bitwise inclusive OR of the valid attribute mask bits. If valuemask is zero, the attributes are ignored and are not referenced. + /// Specifies the structure from which the values (as specified by the value mask) are to be taken. The value mask should have the appropriate bits set to indicate which attributes have been set in the structure. + /// The window ID of the created window. + /// + /// The coordinate system has the X axis horizontal and the Y axis vertical with the origin [0, 0] at the upper-left corner. Coordinates are integral, in terms of pixels, and coincide with pixel centers. Each window and pixmap has its own coordinate system. For a window, the origin is inside the border at the inside, upper-left corner. + /// The border_width for an InputOnly window must be zero, or a BadMatch error results. For class InputOutput, the visual type and depth must be a combination supported for the screen, or a BadMatch error results. The depth need not be the same as the parent, but the parent must not be a window of class InputOnly, or a BadMatch error results. For an InputOnly window, the depth must be zero, and the visual must be one supported by the screen. If either condition is not met, a BadMatch error results. The parent window, however, may have any depth and class. If you specify any invalid window attribute for a window, a BadMatch error results. + /// The created window is not yet displayed (mapped) on the user's display. To display the window, call XMapWindow(). The new window initially uses the same cursor as its parent. A new cursor can be defined for the new window by calling XDefineCursor(). The window will not be visible on the screen unless it and all of its ancestors are mapped and it is not obscured by any of its ancestors. + /// XCreateWindow can generate BadAlloc BadColor, BadCursor, BadMatch, BadPixmap, BadValue, and BadWindow errors. + /// The XCreateSimpleWindow function creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings. Any part of the window that extends outside its parent window is clipped. The border_width for an InputOnly window must be zero, or a BadMatch error results. XCreateSimpleWindow inherits its depth, class, and visual from its parent. All other window attributes, except background and border, have their default values. + /// XCreateSimpleWindow can generate BadAlloc, BadMatch, BadValue, and BadWindow errors. + /// + public static Window XCreateWindow(Display display, Window parent, + int x, int y, int width, int height, int border_width, int depth, + CreateWindowArgs @class, IntPtr visual, SetWindowValuemask valuemask, + XSetWindowAttributes? attributes) + { + unsafe + { + if (attributes.HasValue) + { + XSetWindowAttributes attr = attributes.Value; + return XCreateWindow(display, parent, x, y, width, height, border_width, depth, + (int)@class, visual, (IntPtr)valuemask, &attr); + } + else + { + return XCreateWindow(display, parent, x, y, width, height, border_width, depth, + (int)@class, visual, (IntPtr)valuemask, null); + } + } + } + + [DllImport(X11Library)] + internal static extern void XChangeWindowAttributes(Display display, Window w, UIntPtr valuemask, ref XSetWindowAttributes attributes); + + internal static void XChangeWindowAttributes(Display display, Window w, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes) + { + XChangeWindowAttributes(display, w, (UIntPtr)valuemask, ref attributes); + } + + [DllImport(XcursorLibrary)] + internal static unsafe extern XcursorImage* XcursorImageCreate(int width, int height); + + [DllImport(XcursorLibrary)] + internal static unsafe extern void XcursorImageDestroy(XcursorImage* image); + + [DllImport(XcursorLibrary)] + internal static unsafe extern Cursor XcursorImageLoadCursor(Display dpy, XcursorImage* image); + + /* + /// + /// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N. + /// + /// Specifies the connection to the X server. + /// Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard. + /// Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen. + [DllImport(_dll_name, EntryPoint = "XQueryKeymap")] + extern public static void XQueryKeymap(IntPtr display, [MarshalAs(UnmanagedType.LPArray, SizeConst = 32), In, Out] Keymap keys); + */ + + /// + /// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N. + /// + /// Specifies the connection to the X server. + /// Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard. + /// Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen. + [DllImport(X11Library, EntryPoint = "XQueryKeymap")] + extern public static void XQueryKeymap(IntPtr display, byte[] keys); + + /// + /// The XMaskEvent() function searches the event queue for the events associated with the specified mask. When it finds a match, XMaskEvent() removes that event and copies it into the specified XEvent structure. The other events stored in the queue are not discarded. If the event you requested is not in the queue, XMaskEvent() flushes the output buffer and blocks until one is received. + /// + /// Specifies the connection to the X server. + /// Specifies the event mask. + /// Returns the matched event's associated structure. + [DllImport(X11Library, EntryPoint = "XMaskEvent")] + extern public static void XMaskEvent(IntPtr display, EventMask event_mask, ref XEvent e); + + /// + /// The XPutBackEvent() function pushes an event back onto the head of the display's event queue by copying the event into the queue. This can be useful if you read an event and then decide that you would rather deal with it later. There is no limit to the number of times in succession that you can call XPutBackEvent(). + /// + /// Specifies the connection to the X server. + /// Specifies the event. + [DllImport(X11Library, EntryPoint = "XPutBackEvent")] + public static extern void XPutBackEvent(IntPtr display, ref XEvent @event); private const string XrandrLibrary = "libXrandr.so.2"; + [DllImport(XrandrLibrary)] + public static extern Bool XRRQueryExtension(Display dpy, ref int event_basep, ref int error_basep); + + [DllImport(XrandrLibrary)] + public static extern Status XRRQueryVersion(Display dpy, ref int major_versionp, ref int minor_versionp); + [DllImport(XrandrLibrary)] public static extern XRRScreenConfiguration XRRGetScreenInfo(Display dpy, Drawable draw); @@ -345,12 +1405,56 @@ namespace OpenTK.Platform.X11 public static extern Status XRRSetScreenConfig(Display dpy, XRRScreenConfiguration config, Drawable draw, int size_index, Rotation rotation, Time timestamp); + [DllImport(XrandrLibrary)] + public static extern Status XRRSetScreenConfigAndRate(Display dpy, XRRScreenConfiguration config, + Drawable draw, int size_index, Rotation rotation, short rate, Time timestamp); + + [DllImport(XrandrLibrary)] + public static extern Rotation XRRConfigRotations(XRRScreenConfiguration config, ref Rotation current_rotation); + + [DllImport(XrandrLibrary)] + public static extern Time XRRConfigTimes(XRRScreenConfiguration config, ref Time config_timestamp); + + [DllImport(XrandrLibrary)] + [return: MarshalAs(UnmanagedType.LPStruct)] + public static extern XRRScreenSize XRRConfigSizes(XRRScreenConfiguration config, int[] nsizes); + + [DllImport(XrandrLibrary)] + unsafe public static extern short* XRRConfigRates(XRRScreenConfiguration config, int size_index, int[] nrates); + [DllImport(XrandrLibrary)] public static extern SizeID XRRConfigCurrentConfiguration(XRRScreenConfiguration config, out Rotation rotation); [DllImport(XrandrLibrary)] public static extern short XRRConfigCurrentRate(XRRScreenConfiguration config); + [DllImport(XrandrLibrary)] + public static extern int XRRRootToScreen(Display dpy, Window root); + + [DllImport(XrandrLibrary)] + public static extern XRRScreenConfiguration XRRScreenConfig(Display dpy, int screen); + + [DllImport(XrandrLibrary)] + public static extern XRRScreenConfiguration XRRConfig(ref Screen screen); + + [DllImport(XrandrLibrary)] + public static extern void XRRSelectInput(Display dpy, Window window, int mask); + + /* + * intended to take RRScreenChangeNotify, or + * ConfigureNotify (on the root window) + * returns 1 if it is an event type it understands, 0 if not + */ + [DllImport(XrandrLibrary)] + public static extern int XRRUpdateConfiguration(ref XEvent @event); + + /* + * the following are always safe to call, even if RandR is + * not implemented on a screen + */ + [DllImport(XrandrLibrary)] + public static extern Rotation XRRRotations(Display dpy, int screen, ref Rotation current_rotation); + [DllImport(XrandrLibrary)] private unsafe static extern IntPtr XRRSizes(Display dpy, int screen, int* nsizes); @@ -431,7 +1535,50 @@ namespace OpenTK.Platform.X11 return depths; } } + + public static Pixmap XCreateBitmapFromData(Display display, Window d, byte[,] data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + unsafe + { + fixed (byte* pdata = data) + { + return XCreateBitmapFromData(display, d, pdata, data.GetLength(0), data.GetLength(1)); + } + } + } + + [DllImport(X11Library)] + unsafe public static extern Pixmap XCreateBitmapFromData(Display display, Window d, byte* data, int width, int height); + + [DllImport("libX11", EntryPoint = "XAllocColor")] + public static extern Status XAllocNamedColor(Display display, Colormap colormap, string color_name, out XColor screen_def_return, out XColor exact_def_return); } + /* + [StructLayout(LayoutKind.Sequential)] + internal struct Keymap + { + unsafe fixed byte bits[32]; + + public bool this[KeyCode key] + { + get + { + unsafe + { + fixed (Keymap* ptr = &this) + { + return ((ptr->bits[key / 8] >> (key % 8)) & 0x01) != 0; + } + } + } + } + } + */ // Helper structure for calling XLock/UnlockDisplay internal struct XLock : IDisposable diff --git a/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs b/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs index 4d38307..39450f8 100644 --- a/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs @@ -139,6 +139,19 @@ namespace OpenTK.Platform.X11 HYPERPIPE_PIXEL_AVERAGE_SGIX = 0x00000004, } + internal enum GLXStringName : int + { + EXTENSIONS = 0x3, + VERSION = 0x2, + VENDOR = 0x1, + } + + internal enum GLXEventMask : int + { + PBUFFER_CLOBBER_MASK = 0x08000000, + BUFFER_CLOBBER_MASK_SGIX = 0x08000000, + } + internal enum GLXRenderTypeMask : int { COLOR_INDEX_BIT_SGIX = 0x00000002, @@ -148,6 +161,67 @@ namespace OpenTK.Platform.X11 COLOR_INDEX_BIT = 0x00000002, } + internal enum GLXHyperpipeTypeMask : int + { + HYPERPIPE_RENDER_PIPE_SGIX = 0x00000002, + HYPERPIPE_DISPLAY_PIPE_SGIX = 0x00000001, + } + + internal enum GLXPbufferClobberMask : int + { + ACCUM_BUFFER_BIT_SGIX = 0x00000080, + FRONT_LEFT_BUFFER_BIT = 0x00000001, + BACK_RIGHT_BUFFER_BIT = 0x00000008, + FRONT_RIGHT_BUFFER_BIT_SGIX = 0x00000002, + STENCIL_BUFFER_BIT_SGIX = 0x00000040, + SAMPLE_BUFFERS_BIT_SGIX = 0x00000100, + STENCIL_BUFFER_BIT = 0x00000040, + BACK_RIGHT_BUFFER_BIT_SGIX = 0x00000008, + BACK_LEFT_BUFFER_BIT_SGIX = 0x00000004, + AUX_BUFFERS_BIT = 0x00000010, + DEPTH_BUFFER_BIT_SGIX = 0x00000020, + ACCUM_BUFFER_BIT = 0x00000080, + AUX_BUFFERS_BIT_SGIX = 0x00000010, + DEPTH_BUFFER_BIT = 0x00000020, + FRONT_LEFT_BUFFER_BIT_SGIX = 0x00000001, + BACK_LEFT_BUFFER_BIT = 0x00000004, + FRONT_RIGHT_BUFFER_BIT = 0x00000002, + } + + internal enum GLXHyperpipeMisc : int + { + HYPERPIPE_PIPE_NAME_LENGTH_SGIX = 80, + } + + internal enum GLXErrorCode : int + { + BAD_CONTEXT = 5, + NO_EXTENSION = 3, + BAD_HYPERPIPE_SGIX = 92, + BAD_ENUM = 7, + BAD_SCREEN = 1, + BAD_VALUE = 6, + BAD_ATTRIBUTE = 2, + BAD_VISUAL = 4, + BAD_HYPERPIPE_CONFIG_SGIX = 91, + } + + internal enum GLXSyncType : int + { + SYNC_SWAP_SGIX = 0x00000001, + SYNC_FRAME_SGIX = 0x00000000, + } + + internal enum GLXDrawableTypeMask : int + { + WINDOW_BIT = 0x00000001, + PIXMAP_BIT = 0x00000002, + PBUFFER_BIT_SGIX = 0x00000004, + PBUFFER_BIT = 0x00000004, + WINDOW_BIT_SGIX = 0x00000001, + PIXMAP_BIT_SGIX = 0x00000002, + } + internal enum ArbCreateContext : int { DebugBit = 0x0001, @@ -266,7 +340,7 @@ namespace OpenTK.Platform.X11 public delegate int SwapIntervalMESA(uint interval); public static SwapIntervalMESA glXSwapIntervalMESA; - + public delegate int GetSwapIntervalMESA(); public static GetSwapIntervalMESA glXGetSwapIntervalMESA; @@ -356,8 +430,6 @@ namespace OpenTK.Platform.X11 // Returns a pointer to an XVisualInfo structure. [DllImport(Library, EntryPoint = "glXGetVisualFromFBConfig")] - public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig); + public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig); } -} - -#pragma warning restore 1591 \ No newline at end of file +} \ No newline at end of file diff --git a/GLWidget/OpenTK/Platform/X11/Bindings/Xkb.cs b/GLWidget/OpenTK/Platform/X11/Bindings/Xkb.cs new file mode 100644 index 0000000..9270e08 --- /dev/null +++ b/GLWidget/OpenTK/Platform/X11/Bindings/Xkb.cs @@ -0,0 +1,304 @@ +// +// Xkb.cs +// +// Author: +// Stefanos Apostolopoulos +// +// Copyright (c) 2006-2014 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +#pragma warning disable 0169 + +namespace OpenTK.Platform.X11 +{ + using Atom = IntPtr; + using KeyCode = Byte; + using XkbControlsPtr = IntPtr; + using XkbServerMapPtr = IntPtr; + using XkbClientMapPtr = IntPtr; + using XkbIndicatorPtr = IntPtr; + using XkbCompatMapPtr = IntPtr; + using XkbGeometryPtr = IntPtr; + + internal class Xkb + { + private const string lib = "libX11"; + + internal const int KeyNameLength = 4; + internal const int NumModifiers = 8; + internal const int NumVirtualMods = 16; + internal const int NumIndicators = 32; + internal const int NumKbdGroups = 4; + internal const int UseCoreKeyboard = 0x0100; + + [DllImport(lib, EntryPoint = "XkbFreeKeyboard")] + unsafe internal extern static void FreeKeyboard(XkbDesc* descr, int which, bool free); + + [DllImport(lib, EntryPoint = "XkbAllocKeyboard")] + unsafe internal extern static XkbDesc* AllocKeyboard(IntPtr display); + + [DllImport(lib, EntryPoint = "XkbGetKeyboard")] + internal extern static IntPtr GetKeyboard(IntPtr display, XkbKeyboardMask which, int device_id); + + [DllImport(lib, EntryPoint = "XkbGetMap")] + internal extern static IntPtr GetMap(IntPtr display, XkbKeyboardMask which, int device_spec); + + [DllImport(lib, EntryPoint = "XkbGetNames")] + unsafe internal extern static IntPtr GetNames(IntPtr display, XkbNamesMask which, XkbDesc* xkb); + + [DllImport(lib, EntryPoint = "XkbKeycodeToKeysym")] + internal extern static XKey KeycodeToKeysym(IntPtr display, int keycode, int group, int level); + + [DllImport(lib, EntryPoint = "XkbQueryExtension")] + internal extern static bool QueryExtension(IntPtr display, out int opcode_rtrn, out int event_rtrn, + out int error_rtrn, ref int major_in_out, ref int minor_in_out); + + [DllImport(lib, EntryPoint = "XkbSetDetectableAutoRepeat")] + internal extern static bool SetDetectableAutoRepeat(IntPtr display, bool detectable, out bool supported); + + internal static bool IsSupported(IntPtr display) + { + // The XkbQueryExtension manpage says that we cannot + // use XQueryExtension with XKB. + int opcode, error, ev; + int major = 1; + int minor = 0; + bool supported = QueryExtension(display, out opcode, out ev, out error, ref major, ref minor); + Debug.Print("XKB extension is {0}.", supported ? "supported" : "not supported"); + if (supported) + { + Debug.Print("XKB version is {0}.{1}", major, minor); + } + return supported; + } + } + + [Flags] + internal enum XkbKeyboardMask + { + Controls = 1 << 0, + ServerMap = 1 << 1, + IClientMap = 1 << 2, + IndicatorMap = 1 << 3, + Names = 1 << 4, + CompatibilityMap = 1 << 5, + Geometry = 1 << 6, + AllComponents = 1 << 7, + } + + [Flags] + internal enum XkbNamesMask + { + Keycodes = 1 << 0, + Geometry = 1 << 1, + Symbols = 1 << 2, + PhysSymbols = 1 << 3, + Types = 1 << 4, + Compat = 1 << 5, + KeyType = 1 << 6, + KTLevel = 1 << 7, + Indicator = 1 << 8, + Key = 1 << 9, + KeyAliasesMask = 1 << 10, + VirtualMod = 1 << 11, + Group = 1 << 12, + RG = 1 << 13, + Component = 0x3f, + All = 0x3fff + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XkbDesc + { + internal IntPtr dpy; + internal ushort flags; + internal ushort device_spec; + internal KeyCode min_key_code; + internal KeyCode max_key_code; + + internal XkbControlsPtr ctrls; + internal XkbServerMapPtr server; + internal XkbClientMapPtr map; + internal XkbIndicatorPtr indicators; + internal XkbNames* names; + internal XkbCompatMapPtr compat; + internal XkbGeometryPtr geom; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XkbKeyAlias + { + internal fixed byte real[Xkb.KeyNameLength]; + internal fixed byte alias[Xkb.KeyNameLength]; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XkbKeyName + { + internal fixed byte name[Xkb.KeyNameLength]; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct XkbNames + { + [StructLayout(LayoutKind.Sequential)] + internal struct Groups + { + private Atom groups0; + private Atom groups1; + private Atom groups2; + private Atom groups3; + internal Atom this[int i] + { + get + { + if (i < 0 || i > 3) + { + throw new IndexOutOfRangeException(); + } + + unsafe + { + fixed (Atom* ptr = &groups0) + { + return *(ptr + i); + } + } + } + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct Indicators + { + private Atom indicators0; + private Atom indicators1; + private Atom indicators2; + private Atom indicators3; + private Atom indicators4; + private Atom indicators5; + private Atom indicators6; + private Atom indicators7; + private Atom indicators8; + private Atom indicators9; + private Atom indicators10; + private Atom indicators11; + private Atom indicators12; + private Atom indicators13; + private Atom indicators14; + private Atom indicators15; + private Atom indicators16; + private Atom indicators17; + private Atom indicators18; + private Atom indicators19; + private Atom indicators20; + private Atom indicators21; + private Atom indicators22; + private Atom indicators23; + private Atom indicators24; + private Atom indicators25; + private Atom indicators26; + private Atom indicators27; + private Atom indicators28; + private Atom indicators29; + private Atom indicators30; + private Atom indicators31; + internal Atom this[int i] + { + get + { + if (i < 0 || i > 31) + { + throw new IndexOutOfRangeException(); + } + + unsafe + { + fixed (Atom* ptr = &indicators0) + { + return *(ptr + i); + } } + } + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct VMods + { + private Atom vmods0; + private Atom vmods1; + private Atom vmods2; + private Atom vmods3; + private Atom vmods4; + private Atom vmods5; + private Atom vmods6; + private Atom vmods7; + private Atom vmods8; + private Atom vmods9; + private Atom vmods10; + private Atom vmods11; + private Atom vmods12; + private Atom vmods13; + private Atom vmods14; + private Atom vmods15; + internal Atom this[int i] + { + get + { + if (i < 0 || i > 15) + { + throw new IndexOutOfRangeException(); + } + + unsafe + { + fixed (Atom* ptr = &vmods0) + { + return *(ptr + i); + } + } + } + } + } + + internal Atom keycodes; + internal Atom geometry; + internal Atom symbols; + internal Atom types; + internal Atom compat; + internal VMods vmods; + internal Indicators indicators; + internal Groups groups; + internal XkbKeyName* keys; + internal XkbKeyAlias* key_aliases; + internal Atom *radio_groups; + internal Atom phys_symbols; + + internal byte num_keys; + internal byte num_key_aliases; + internal byte num_rg; + } +} + diff --git a/GLWidget/OpenTK/Platform/X11/Functions.cs b/GLWidget/OpenTK/Platform/X11/Functions.cs index e25603a..288e306 100644 --- a/GLWidget/OpenTK/Platform/X11/Functions.cs +++ b/GLWidget/OpenTK/Platform/X11/Functions.cs @@ -5,8 +5,14 @@ */ using System; +#if !MINIMAL using System.Drawing; +#endif +#if ANDROID || IPHONE || MINIMAL +using OpenTK.Minimal; +#else using System.Drawing.Imaging; +#endif using System.Text; using System.Runtime.InteropServices; @@ -61,7 +67,7 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XCreateWindow")] public unsafe extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, IntPtr valuemask, XSetWindowAttributes* attributes); - [DllImport("libX11", EntryPoint = "XCreateSimpleWindow")]//] + [DllImport("libX11", EntryPoint = "XCreateSimpleWindow")]//, CLSCompliant(false)] public extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background); [DllImport("libX11", EntryPoint = "XCreateSimpleWindow")] public extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, IntPtr border, IntPtr background); @@ -151,10 +157,10 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XRaiseWindow")] public extern static int XRaiseWindow(IntPtr display, IntPtr window); - [DllImport("libX11", EntryPoint = "XLowerWindow")]//] + [DllImport("libX11", EntryPoint = "XLowerWindow")]//, CLSCompliant(false)] public extern static uint XLowerWindow(IntPtr display, IntPtr window); - [DllImport("libX11", EntryPoint = "XConfigureWindow")]//] + [DllImport("libX11", EntryPoint = "XConfigureWindow")]//, CLSCompliant(false)] public extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowAttributes value_mask, ref XWindowChanges values); [DllImport("libX11", EntryPoint = "XInternAtom")] @@ -222,7 +228,7 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XGetGeometry")] public extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth); - [DllImport("libX11", EntryPoint = "XWarpPointer")]//] + [DllImport("libX11", EntryPoint = "XWarpPointer")]//, CLSCompliant(false)] public extern static uint XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y); [DllImport("libX11", EntryPoint = "XClearWindow")] @@ -241,7 +247,7 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XDefaultVisual")] public extern static IntPtr XDefaultVisual(IntPtr display, int screen_number); - [DllImport("libX11", EntryPoint = "XDefaultDepth")]//] + [DllImport("libX11", EntryPoint = "XDefaultDepth")]//, CLSCompliant(false)] public extern static uint XDefaultDepth(IntPtr display, int screen_number); [DllImport("libX11", EntryPoint = "XDefaultScreen")] @@ -250,10 +256,10 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XDefaultColormap")] public extern static IntPtr XDefaultColormap(IntPtr display, int screen_number); - [DllImport("libX11", EntryPoint = "XLookupColor")]//] + [DllImport("libX11", EntryPoint = "XLookupColor")]//, CLSCompliant(false)] public extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color); - [DllImport("libX11", EntryPoint = "XAllocColor")]//] + [DllImport("libX11", EntryPoint = "XAllocColor")]//, CLSCompliant(false)] public extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def); [DllImport("libX11", EntryPoint = "XSetTransientForHint")] @@ -262,15 +268,15 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XChangeProperty")] public extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements); - [DllImport("libX11", EntryPoint = "XChangeProperty")]//] + [DllImport("libX11", EntryPoint = "XChangeProperty")]//, CLSCompliant(false)] public extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements); [DllImport("libX11", EntryPoint = "XChangeProperty")] public extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref int value, int nelements); - [DllImport("libX11", EntryPoint = "XChangeProperty")]//] + [DllImport("libX11", EntryPoint = "XChangeProperty")]//, CLSCompliant(false)] public extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements); - [DllImport("libX11", EntryPoint = "XChangeProperty")]//] + [DllImport("libX11", EntryPoint = "XChangeProperty")]//, CLSCompliant(false)] public extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements); [DllImport("libX11", EntryPoint = "XChangeProperty")] @@ -337,7 +343,7 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XCreateFontCursor")] public extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape); - [DllImport("libX11", EntryPoint = "XCreatePixmapCursor")]//] + [DllImport("libX11", EntryPoint = "XCreatePixmapCursor")]//, CLSCompliant(false)] public extern static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot); [DllImport("libX11", EntryPoint = "XCreatePixmapFromBitmapData")] @@ -409,12 +415,12 @@ namespace OpenTK.Platform.X11 [DllImport("libX11", EntryPoint = "XSetPlaneMask")] public extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask); - [DllImport("libX11", EntryPoint = "XSetForeground")]//] + [DllImport("libX11", EntryPoint = "XSetForeground")]//, CLSCompliant(false)] public extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground); [DllImport("libX11", EntryPoint = "XSetForeground")] public extern static int XSetForeground(IntPtr display, IntPtr gc, IntPtr foreground); - [DllImport("libX11", EntryPoint = "XSetBackground")]//] + [DllImport("libX11", EntryPoint = "XSetBackground")]//, CLSCompliant(false)] public extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background); [DllImport("libX11", EntryPoint = "XSetBackground")] public extern static int XSetBackground(IntPtr display, IntPtr gc, IntPtr background); diff --git a/GLWidget/OpenTK/Platform/X11/X11DisplayDevice.cs b/GLWidget/OpenTK/Platform/X11/X11DisplayDevice.cs index 7d1f095..e00de2d 100644 --- a/GLWidget/OpenTK/Platform/X11/X11DisplayDevice.cs +++ b/GLWidget/OpenTK/Platform/X11/X11DisplayDevice.cs @@ -26,7 +26,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +#if !MINIMAL using System.Drawing; +#endif using System.Runtime.InteropServices; namespace OpenTK.Platform.X11 @@ -111,13 +113,13 @@ namespace OpenTK.Platform.X11 private static DisplayDevice FindDefaultDevice(IEnumerable devices) { - foreach (DisplayDevice dev in devices) + foreach (DisplayDevice dev in devices) + { + if (dev.IsPrimary) { - if (dev.IsPrimary) - { - return dev; - } + return dev; } + } throw new InvalidOperationException("No primary display found. Please file a bug at https://github.com/opentk/opentk/issues"); } @@ -318,7 +320,7 @@ namespace OpenTK.Platform.X11 { return (int)Functions.XDefaultDepth(API.DefaultDisplay, screen); } - + private static class NativeMethods { private const string Xinerama = "libXinerama"; @@ -326,6 +328,9 @@ namespace OpenTK.Platform.X11 [DllImport(Xinerama)] public static extern bool XineramaQueryExtension(IntPtr dpy, out int event_basep, out int error_basep); + [DllImport(Xinerama)] + public static extern int XineramaQueryVersion(IntPtr dpy, out int major_versionp, out int minor_versionp); + [DllImport(Xinerama)] public static extern bool XineramaIsActive(IntPtr dpy); @@ -362,4 +367,4 @@ namespace OpenTK.Platform.X11 public short Height; } } -} +} \ No newline at end of file diff --git a/GLWidget/OpenTK/Platform/X11/X11Factory.cs b/GLWidget/OpenTK/Platform/X11/X11Factory.cs index b2d6435..b7273ce 100644 --- a/GLWidget/OpenTK/Platform/X11/X11Factory.cs +++ b/GLWidget/OpenTK/Platform/X11/X11Factory.cs @@ -26,18 +26,18 @@ using System; using System.Diagnostics; using OpenTK.Graphics; - namespace OpenTK.Platform.X11 { internal class X11Factory : PlatformFactoryBase { + public X11Factory() { int result = Functions.XInitThreads(); Debug.Print("Initializing threaded X: {0}.", result != 0 ? "success" : "failed"); } - - public override IDisplayDeviceDriver CreateDisplayDeviceDriver() + + public override IDisplayDeviceDriver CreateDisplayDeviceDriver() { return new X11DisplayDevice(); } @@ -59,10 +59,5 @@ namespace OpenTK.Platform.X11 return new ContextHandle(Glx.GetCurrentContext()); }; } - - protected override void Dispose(bool manual) - { - base.Dispose(manual); - } } } diff --git a/GLWidget/OpenTK/Platform/X11/X11GLContext.cs b/GLWidget/OpenTK/Platform/X11/X11GLContext.cs index 895a489..3da0cf9 100644 --- a/GLWidget/OpenTK/Platform/X11/X11GLContext.cs +++ b/GLWidget/OpenTK/Platform/X11/X11GLContext.cs @@ -184,13 +184,13 @@ namespace OpenTK.Platform.X11 using (new XLock(display)) { - fixed (int* attribs_ptr = attributes.ToArray()) + fixed (int* attrib = attributes.ToArray()) { - context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attribs_ptr); + context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attrib); if (context == IntPtr.Zero) { Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct)); - context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attribs_ptr); + context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attrib); } } } @@ -306,63 +306,60 @@ namespace OpenTK.Platform.X11 public override void MakeCurrent(IWindowInfo window) { - using (new XLock(Display)) + if (window == currentWindow && IsCurrent) { - if (window == currentWindow && IsCurrent) + return; + } + + if (window != null && ((X11WindowInfo)window).Display != Display) + { + throw new InvalidOperationException("MakeCurrent() may only be called on windows originating from the same display that spawned this GL context."); + } + + if (window == null) + { + Debug.Write(String.Format("Releasing context {0} from thread {1} (Display: {2})... ", + Handle, System.Threading.Thread.CurrentThread.ManagedThreadId, Display)); + + bool result; + result = Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero); + if (result) { - return; + currentWindow = null; } - if (window != null && ((X11WindowInfo)window).Display != Display) + Debug.Print("{0}", result ? "done!" : "failed."); + } + else + { + X11WindowInfo w = (X11WindowInfo)window; + bool result; + + Debug.Write(String.Format("Making context {0} current on thread {1} (Display: {2}, Screen: {3}, Window: {4})... ", + Handle, System.Threading.Thread.CurrentThread.ManagedThreadId, Display, w.Screen, w.Handle)); + + if (Display == IntPtr.Zero || w.Handle == IntPtr.Zero || Handle == ContextHandle.Zero) { - throw new InvalidOperationException("MakeCurrent() may only be called on windows originating from the same display that spawned this GL context."); + throw new InvalidOperationException("Invalid display, window or context."); } - if (window == null) + result = Glx.MakeCurrent(Display, w.Handle, Handle); + if (result) { - Debug.Write(String.Format("Releasing context {0} from thread {1} (Display: {2})... ", - Handle, System.Threading.Thread.CurrentThread.ManagedThreadId, Display)); + currentWindow = w; + } - bool result; - result = Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero); - if (result) - { - currentWindow = null; - } - - Debug.Print("{0}", result ? "done!" : "failed."); + if (!result) + { + throw new GraphicsContextException("Failed to make context current."); } else { - X11WindowInfo w = (X11WindowInfo)window; - bool result; - - Debug.Write(String.Format("Making context {0} current on thread {1} (Display: {2}, Screen: {3}, Window: {4})... ", - Handle, System.Threading.Thread.CurrentThread.ManagedThreadId, Display, w.Screen, w.Handle)); - - if (Display == IntPtr.Zero || w.Handle == IntPtr.Zero || Handle == ContextHandle.Zero) - { - throw new InvalidOperationException("Invalid display, window or context."); - } - - result = Glx.MakeCurrent(Display, w.Handle, Handle); - if (result) - { - currentWindow = w; - } - - if (!result) - { - throw new GraphicsContextException("Failed to make context current."); - } - else - { - Debug.WriteLine("done!"); - } + Debug.WriteLine("done!"); } - - currentWindow = (X11WindowInfo)window; } + + currentWindow = (X11WindowInfo)window; } public override bool IsCurrent @@ -429,7 +426,7 @@ namespace OpenTK.Platform.X11 } else if (vsync_sgi_supported) { - error_code = (ErrorCode)Glx.glXSwapIntervalMESA((uint)value); + error_code = (ErrorCode)Glx.glXSwapIntervalSGI(value); } } @@ -465,7 +462,7 @@ namespace OpenTK.Platform.X11 Debug.Print("Context supports adaptive vsync: {0}.", vsync_tear_supported); - GTKBindingHelper.InitializeGlBindings(); + base.LoadAll(); } public override IntPtr GetAddress(IntPtr function) diff --git a/GLWidgetTestGTK3/MainWindow.cs b/GLWidgetTestGTK3/MainWindow.cs index e6f83b1..5bd4e31 100644 --- a/GLWidgetTestGTK3/MainWindow.cs +++ b/GLWidgetTestGTK3/MainWindow.cs @@ -134,6 +134,8 @@ namespace GLWidgetTestGTK3 this.GLInit = false; ResetCamera(); + OpenTK.Toolkit.Init(); + this.MainGLWidget = new GLWidget(GraphicsMode.Default) { CanFocus = true,