From e792bd80fe74685e9c237feddef5b7e584463448 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Thu, 4 May 2017 23:03:50 +0300 Subject: [PATCH 01/15] Add initial d&d support for GameWindow. Add SDL2 d&d support --- src/OpenTK/INativeWindow.cs | 1 + src/OpenTK/Input/DropEventArgs.cs | 51 ++++++++++++++++++++ src/OpenTK/NativeWindow.cs | 14 ++++++ src/OpenTK/OpenTK.csproj | 1 + src/OpenTK/Platform/NativeWindowBase.cs | 10 ++++ src/OpenTK/Platform/SDL2/Sdl2.cs | 10 ++++ src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 22 +++++++++ 7 files changed, 109 insertions(+) create mode 100644 src/OpenTK/Input/DropEventArgs.cs diff --git a/src/OpenTK/INativeWindow.cs b/src/OpenTK/INativeWindow.cs index 881bcc6c..f01ba276 100644 --- a/src/OpenTK/INativeWindow.cs +++ b/src/OpenTK/INativeWindow.cs @@ -285,6 +285,7 @@ namespace OpenTK //event EventHandler MouseClick; //event EventHandler MouseDoubleClick; + event EventHandler Drop; //event EventHandler DragDrop; //event EventHandler DragEnter; //event EventHandler DragOver; diff --git a/src/OpenTK/Input/DropEventArgs.cs b/src/OpenTK/Input/DropEventArgs.cs new file mode 100644 index 00000000..d5a9625f --- /dev/null +++ b/src/OpenTK/Input/DropEventArgs.cs @@ -0,0 +1,51 @@ +#region License +// +// ConfigurationType.cs +// +// Author: +// Stefanos A. +// +// Copyright (c) 2006-2014 Stefanos Apostolopoulos +// +// 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. +// +#endregion + +using System; + +namespace OpenTK.Input +{ + public class DropEventArgs : EventArgs + { + string drop_string; + public DropEventArgs () { } + + public string DropString + { + get + { + return drop_string; + } + set + { + drop_string = value; + } + } + } +} diff --git a/src/OpenTK/NativeWindow.cs b/src/OpenTK/NativeWindow.cs index 78590633..a6980cf3 100644 --- a/src/OpenTK/NativeWindow.cs +++ b/src/OpenTK/NativeWindow.cs @@ -709,6 +709,11 @@ namespace OpenTK /// public event EventHandler MouseWheel = delegate { }; + /// + /// Occurs whenever a file dropped in window; + /// + public event EventHandler Drop = delegate { }; + #endregion #endregion @@ -981,6 +986,11 @@ namespace OpenTK MouseWheel(this, e); } + protected virtual void OnDrop(DropEventArgs e) + { + Drop(this, e); + } + #region OnResize /// @@ -1142,6 +1152,8 @@ namespace OpenTK private void OnMouseMoveInternal(object sender, MouseMoveEventArgs e) { OnMouseMove(e); } private void OnMouseWheelInternal(object sender, MouseWheelEventArgs e) { OnMouseWheel(e); } + private void OnDropInternal(object sender, DropEventArgs e) { OnDrop(e); } + #region OnMoveInternal private void OnMoveInternal(object sender, EventArgs e) { OnMove(e); } @@ -1214,6 +1226,7 @@ namespace OpenTK implementation.VisibleChanged += OnVisibleChangedInternal; implementation.WindowBorderChanged += OnWindowBorderChangedInternal; implementation.WindowStateChanged += OnWindowStateChangedInternal; + implementation.Drop += OnDropInternal; events = true; } else if (events) @@ -1238,6 +1251,7 @@ namespace OpenTK implementation.VisibleChanged -= OnVisibleChangedInternal; implementation.WindowBorderChanged -= OnWindowBorderChangedInternal; implementation.WindowStateChanged -= OnWindowStateChangedInternal; + implementation.Drop -= OnDropInternal; events = false; } else diff --git a/src/OpenTK/OpenTK.csproj b/src/OpenTK/OpenTK.csproj index 63c4345a..febacf34 100644 --- a/src/OpenTK/OpenTK.csproj +++ b/src/OpenTK/OpenTK.csproj @@ -795,6 +795,7 @@ + diff --git a/src/OpenTK/Platform/NativeWindowBase.cs b/src/OpenTK/Platform/NativeWindowBase.cs index 16579e53..ff3701ed 100644 --- a/src/OpenTK/Platform/NativeWindowBase.cs +++ b/src/OpenTK/Platform/NativeWindowBase.cs @@ -53,6 +53,8 @@ namespace OpenTK.Platform readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs(); readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0); + readonly DropEventArgs DropArgs = new DropEventArgs(); + // In order to simplify mouse event implementation, // we can store the current mouse state here. protected MouseState MouseState = new MouseState(); @@ -156,6 +158,13 @@ namespace OpenTK.Platform KeyUp(this, e); } + protected void OnDrop(string s) + { + var e = DropArgs; + DropArgs.DropString = s; + Drop(this, e); + } + /// \internal /// /// Call this method to simulate KeyDown/KeyUp events @@ -318,6 +327,7 @@ namespace OpenTK.Platform public event EventHandler MouseUp = delegate { }; public event EventHandler MouseMove = delegate { }; public event EventHandler MouseWheel = delegate { }; + public event EventHandler Drop = delegate { }; public abstract void Close(); diff --git a/src/OpenTK/Platform/SDL2/Sdl2.cs b/src/OpenTK/Platform/SDL2/Sdl2.cs index 35783957..bb437eeb 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2.cs @@ -1442,6 +1442,8 @@ namespace OpenTK.Platform.SDL2 public ControllerButtonEvent ControllerButton; [FieldOffset(0)] public ControllerDeviceEvent ControllerDevice; + [FieldOffset(0)] + public DropEvent Drop; #if false [FieldOffset(0)] public QuitEvent quit; @@ -1755,6 +1757,14 @@ namespace OpenTK.Platform.SDL2 public Int32 Data2; } + struct DropEvent + { + public UInt32 Type; + public UInt32 Timestamp; + public IntPtr File; + public UInt32 WindowID; + } + #endregion } diff --git a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index 47b6d13c..d75ac170 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -197,6 +197,14 @@ namespace OpenTK.Platform.SDL2 } break; + case EventType.DROPFILE: + if (windows.TryGetValue(ev.Drop.WindowID, out window)) + { + ProcessDropEvent(window, ev.Drop); + processed = true; + } + break; + case EventType.QUIT: Debug.WriteLine("Sdl2 application quit"); break; @@ -293,6 +301,20 @@ namespace OpenTK.Platform.SDL2 window.OnMouseWheel(ev.X, ev.Y); } + static unsafe void ProcessDropEvent(Sdl2NativeWindow window, DropEvent ev) + { + byte* str = (byte*)ev.File; + + int length = 0; + for (; str[length] != 0; length++) + ; + + byte [] byteArray = new byte[length]; + Marshal.Copy(ev.File, byteArray, 0, length); + string dropString = System.Text.Encoding.UTF8.GetString (byteArray); + window.OnDrop(dropString); + } + static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e) { switch (e.Event) From 18dd6036963e35066050264a4ada790f29bb941c Mon Sep 17 00:00:00 2001 From: Vlad K Date: Tue, 9 May 2017 05:36:54 +0300 Subject: [PATCH 02/15] Fix of memory leak --- src/OpenTK/Platform/SDL2/Sdl2.cs | 4 ++++ src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTK/Platform/SDL2/Sdl2.cs b/src/OpenTK/Platform/SDL2/Sdl2.cs index bb437eeb..96bc0994 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2.cs @@ -139,6 +139,10 @@ namespace OpenTK.Platform.SDL2 [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_FreeSurface", ExactSpelling = true)] public static extern void FreeSurface(IntPtr surface); + [SuppressUnmanagedCodeSecurity] + [DllImport (lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_free", ExactSpelling = true)] + public static extern void Free (IntPtr memblock); + #region GameContoller [SuppressUnmanagedCodeSecurity] diff --git a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index d75ac170..22538e69 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -201,6 +201,7 @@ namespace OpenTK.Platform.SDL2 if (windows.TryGetValue(ev.Drop.WindowID, out window)) { ProcessDropEvent(window, ev.Drop); + SDL.Free(ev.Drop.File); processed = true; } break; @@ -311,7 +312,7 @@ namespace OpenTK.Platform.SDL2 byte [] byteArray = new byte[length]; Marshal.Copy(ev.File, byteArray, 0, length); - string dropString = System.Text.Encoding.UTF8.GetString (byteArray); + string dropString = System.Text.Encoding.UTF8.GetString(byteArray); window.OnDrop(dropString); } From 90e9c28cbd627bdc327f3697f6071b135ef57723 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Tue, 9 May 2017 05:23:22 +0300 Subject: [PATCH 03/15] Added Windows D&D support --- src/OpenTK/Platform/Windows/API.cs | 21 ++++++++++++++++ src/OpenTK/Platform/Windows/WinGLNative.cs | 29 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/OpenTK/Platform/Windows/API.cs b/src/OpenTK/Platform/Windows/API.cs index c2580c76..c689f887 100644 --- a/src/OpenTK/Platform/Windows/API.cs +++ b/src/OpenTK/Platform/Windows/API.cs @@ -57,6 +57,8 @@ namespace OpenTK.Platform.Windows using HKEY = System.IntPtr; using PHKEY = System.IntPtr; + using HDROP = System.IntPtr; + using LRESULT = System.IntPtr; using LPVOID = System.IntPtr; using LPCTSTR = System.String; @@ -134,6 +136,25 @@ namespace OpenTK.Platform.Windows { #region Window functions + [DllImport("shell32.dll")] + internal static extern bool DragAcceptFiles( + IntPtr handle, + [MarshalAs(UnmanagedType.Bool)] bool fAccept + ); + + [DllImport("shell32.dll")] + internal static extern uint DragQueryFile( + HDROP hDrop, + uint iFile, + IntPtr lpszFile, + uint cch + ); + + [DllImport("shell32.dll")] + internal static extern void DragFinish( + HDROP hDrop + ); + #region SetWindowPos // WINUSERAPI BOOL WINAPI SetWindowPos(__in HWND hWnd, __in_opt HWND hWndInsertAfter, diff --git a/src/OpenTK/Platform/Windows/WinGLNative.cs b/src/OpenTK/Platform/Windows/WinGLNative.cs index 234c68ac..112f5286 100644 --- a/src/OpenTK/Platform/Windows/WinGLNative.cs +++ b/src/OpenTK/Platform/Windows/WinGLNative.cs @@ -150,6 +150,7 @@ namespace OpenTK.Platform.Windows 0, 0, ClientSize.Width, ClientSize.Height, title, options, device, window.Handle), window); + Functions.DragAcceptFiles(window.Handle, true); exists = true; } @@ -680,6 +681,29 @@ namespace OpenTK.Platform.Windows OnClosed(EventArgs.Empty); } + void HandleDropFiles(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) + { + IntPtr hDrop = wParam; + uint filesCounter = Functions.DragQueryFile(hDrop, 0xFFFFFFFF, IntPtr.Zero, 0); + for (uint i = 0; i < filesCounter; ++i) + { + // Don't forget about \0 at the end + uint fileNameSize = Functions.DragQueryFile(hDrop, i, IntPtr.Zero, 0) + 1; + byte [] byteArray = new byte [fileNameSize]; + IntPtr str = Marshal.AllocHGlobal((int)fileNameSize); + + Functions.DragQueryFile(hDrop, i, str, fileNameSize); + + Marshal.Copy(str, byteArray, 0, (int)(fileNameSize - 1)); + string dropString = System.Text.Encoding.UTF8.GetString(byteArray); + OnDrop(dropString); + + Marshal.FreeHGlobal(str); + } + + Functions.DragFinish(hDrop); + } + #endregion #region WindowProcedure @@ -754,6 +778,7 @@ namespace OpenTK.Platform.Windows return IntPtr.Zero; case WindowMessage.LBUTTONDOWN: + Console.WriteLine("ola"); HandleLButtonDown(handle, message, wParam, lParam); return IntPtr.Zero; @@ -800,6 +825,10 @@ namespace OpenTK.Platform.Windows HandleKillFocus(handle, message, wParam, lParam); break; + case WindowMessage.DROPFILES: + HandleDropFiles(handle, message, wParam, lParam); + break; + #endregion #region Creation / Destruction events From 9062f8ed300d38829c2e9196f4339fdfb9587ca5 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Tue, 9 May 2017 13:11:39 +0300 Subject: [PATCH 04/15] Clean up --- src/OpenTK/Platform/Windows/WinGLNative.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OpenTK/Platform/Windows/WinGLNative.cs b/src/OpenTK/Platform/Windows/WinGLNative.cs index 112f5286..eae8e3ec 100644 --- a/src/OpenTK/Platform/Windows/WinGLNative.cs +++ b/src/OpenTK/Platform/Windows/WinGLNative.cs @@ -778,7 +778,6 @@ namespace OpenTK.Platform.Windows return IntPtr.Zero; case WindowMessage.LBUTTONDOWN: - Console.WriteLine("ola"); HandleLButtonDown(handle, message, wParam, lParam); return IntPtr.Zero; From c65f1fb7bcbade77fd08f838119aa0a2d5460467 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Wed, 17 May 2017 00:03:03 +0300 Subject: [PATCH 05/15] Initial d&d x11 event support --- src/OpenTK/Platform/X11/X11GLNative.cs | 90 +++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/src/OpenTK/Platform/X11/X11GLNative.cs b/src/OpenTK/Platform/X11/X11GLNative.cs index 8cbb25d5..934820c1 100644 --- a/src/OpenTK/Platform/X11/X11GLNative.cs +++ b/src/OpenTK/Platform/X11/X11GLNative.cs @@ -68,7 +68,7 @@ namespace OpenTK.Platform.X11 const string ICON_NET_ATOM = "_NET_WM_ICON"; // The Atom class from Mono might be useful to avoid calling XInternAtom by hand (somewhat error prone). - IntPtr _atom_wm_destroy; + IntPtr _atom_wm_destroy; IntPtr _atom_net_wm_state; IntPtr _atom_net_wm_state_minimized; @@ -76,6 +76,16 @@ namespace OpenTK.Platform.X11 IntPtr _atom_net_wm_state_maximized_horizontal; IntPtr _atom_net_wm_state_maximized_vertical; + // Xdnd atoms + IntPtr _atom_xdnd_enter; + IntPtr _atom_xdnd_position; + IntPtr _atom_xdnd_status; + IntPtr _atom_xdnd_type_list; + IntPtr _atom_xdnd_action_copy; + IntPtr _atom_xdnd_drop; + IntPtr _atom_xdnd_finished; + IntPtr _atom_xdnd_selection; + #pragma warning disable 414 // assigned but never used IntPtr _atom_net_wm_allowed_actions; IntPtr _atom_net_wm_action_resize; @@ -264,6 +274,13 @@ namespace OpenTK.Platform.X11 xi2_version = XI2MouseKeyboard.XIVersion; } + // Alow window recive Xdnd Events + IntPtr xdndAware = Functions.XInternAtom(window.Display, "XdndAware", false); + IntPtr xdndProtocol = new IntPtr(5); + using (new XLock (window.Display)) { + Functions.XChangeProperty(this.window.Display, this.Handle, xdndAware, (IntPtr)AtomName.XA_ATOM, 32, PropertyMode.Replace, ref xdndProtocol, 1); + } + exists = true; } @@ -306,6 +323,22 @@ namespace OpenTK.Platform.X11 #region Private Members + #region Utils + + private void ReadProperty(IntPtr property, IntPtr type, ref IntPtr data, ref IntPtr itemsCount) + { + int format; + IntPtr length = new IntPtr(int.MaxValue); + IntPtr actualType; + IntPtr bytesLeft; + + Functions.XGetWindowProperty(this.window.Display, this.window.Handle, property, IntPtr.Zero, + length, false, type, + out actualType, out format, out itemsCount, out bytesLeft, ref data); + } + + #endregion + #region private void RegisterAtoms() /// @@ -342,6 +375,16 @@ namespace OpenTK.Platform.X11 _atom_net_frame_extents = Functions.XInternAtom(window.Display, "_NET_FRAME_EXTENTS", false); + // Some Xdnd atoms + _atom_xdnd_enter = Functions.XInternAtom(window.Display, "XdndEnter", false); + _atom_xdnd_position = Functions.XInternAtom(window.Display, "XdndPosition", false); + _atom_xdnd_status = Functions.XInternAtom(window.Display, "XdndStatus", false); + _atom_xdnd_type_list = Functions.XInternAtom(window.Display, "XdndTypeList", false); + _atom_xdnd_action_copy = Functions.XInternAtom(window.Display, "XdndActionCopy", false); + _atom_xdnd_drop = Functions.XInternAtom(window.Display, "XdndDrop", false); + _atom_xdnd_finished = Functions.XInternAtom(window.Display, "Xdndfinished", false); + _atom_xdnd_selection = Functions.XInternAtom(window.Display, "XdndSelection", false); + // string[] atom_names = new string[] // { // //"WM_TITLE", @@ -798,7 +841,7 @@ namespace OpenTK.Platform.X11 !Functions.XCheckTypedWindowEvent(window.Display, window.Handle, XEventName.ClientMessage, ref e)) break; } - + // Respond to the event e switch (e.type) { @@ -838,8 +881,46 @@ namespace OpenTK.Platform.X11 OnClosed(EventArgs.Empty); break; } + } else if (e.ClientMessageEvent.message_type == _atom_xdnd_enter) { + // Xdnd started + bool useList = ((e.ClientMessageEvent.ptr2.ToInt64() & 1) == 1); + //long source = e.ClientMessageEvent.ptr1.ToInt64(); + //long version = e.ClientMessageEvent.ptr2.ToInt64() >> 24; + + IntPtr formats = IntPtr.Zero; + int formatCount; + if (useList) { + IntPtr count = IntPtr.Zero; + ReadProperty(_atom_xdnd_type_list, (IntPtr)AtomName.XA_ATOM, ref formats, ref count); + formatCount = count.ToInt32(); + } else { + Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr3); + Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr4); + Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr5); + formatCount = 3; + } + + IntPtr atom = IntPtr.Zero; + for (int i = 0; i < formatCount && atom == IntPtr.Zero; i++) { + IntPtr tempAtom = Marshal.ReadIntPtr(formats, IntPtr.Size * i); + IntPtr atomName = Functions.XGetAtomName(this.window.Display, tempAtom); + + string str = Marshal.PtrToStringUni(atomName); + if (str == "text/uri-list") { + atom = tempAtom; + } + + Functions.XFree(atomName); + } + + if (useList && formats != IntPtr.Zero) { + Functions.XFree(formats); + } + } else if (e.ClientMessageEvent.message_type == _atom_xdnd_position) { + // Ignore for now it handle position of mouse when d&d happens + } else if (e.ClientMessageEvent.message_type == _atom_xdnd_drop) { + // Ignore for now it handle actual d&d } - break; case XEventName.DestroyNotify: @@ -1006,6 +1087,9 @@ namespace OpenTK.Platform.X11 //} break; + case XEventName.SelectionNotify: + break; + default: //Debug.WriteLine(String.Format("{0} event was not handled", e.type)); break; From dc2f4fef21491531c1217bd68dc7e1ce88b06f24 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Mon, 22 May 2017 17:07:31 +0300 Subject: [PATCH 06/15] Add Xdnd support --- src/OpenTK/Platform/X11/API.cs | 7 + src/OpenTK/Platform/X11/X11GLNative.cs | 169 +++++++++++++++++++++---- 2 files changed, 154 insertions(+), 22 deletions(-) diff --git a/src/OpenTK/Platform/X11/API.cs b/src/OpenTK/Platform/X11/API.cs index 9626e617..8274dc7a 100644 --- a/src/OpenTK/Platform/X11/API.cs +++ b/src/OpenTK/Platform/X11/API.cs @@ -52,6 +52,13 @@ namespace OpenTK.Platform.X11 #endregion + // X11 has some defined values + internal static class Consts + { + public static readonly IntPtr None = IntPtr.Zero; + public static readonly IntPtr CurrentTime = IntPtr.Zero; + } + #region internal static class API internal static class API diff --git a/src/OpenTK/Platform/X11/X11GLNative.cs b/src/OpenTK/Platform/X11/X11GLNative.cs index 934820c1..6acb50dc 100644 --- a/src/OpenTK/Platform/X11/X11GLNative.cs +++ b/src/OpenTK/Platform/X11/X11GLNative.cs @@ -76,6 +76,11 @@ namespace OpenTK.Platform.X11 IntPtr _atom_net_wm_state_maximized_horizontal; IntPtr _atom_net_wm_state_maximized_vertical; + + IntPtr xdndFormat; + long sourceXdndVersion; + IntPtr sourceHandler; + // Xdnd atoms IntPtr _atom_xdnd_enter; IntPtr _atom_xdnd_position; @@ -85,6 +90,9 @@ namespace OpenTK.Platform.X11 IntPtr _atom_xdnd_drop; IntPtr _atom_xdnd_finished; IntPtr _atom_xdnd_selection; + IntPtr _atom_xdnd_leave; + + IntPtr _atom_xdnd_primary; #pragma warning disable 414 // assigned but never used IntPtr _atom_net_wm_allowed_actions; @@ -325,18 +333,33 @@ namespace OpenTK.Platform.X11 #region Utils - private void ReadProperty(IntPtr property, IntPtr type, ref IntPtr data, ref IntPtr itemsCount) + private void ReadProperty(IntPtr window, IntPtr property, IntPtr type, ref IntPtr data, ref IntPtr itemsCount) { int format; IntPtr length = new IntPtr(int.MaxValue); IntPtr actualType; IntPtr bytesLeft; - Functions.XGetWindowProperty(this.window.Display, this.window.Handle, property, IntPtr.Zero, + Functions.XGetWindowProperty(this.window.Display, window, property, IntPtr.Zero, length, false, type, out actualType, out format, out itemsCount, out bytesLeft, ref data); } + private string[] parseUriList(string rawString) + { + string[] separator = new string[] {"\r", "\n"}; + string[] splitted = rawString.Split(separator, StringSplitOptions.RemoveEmptyEntries); + + string[] fileNames = new string[splitted.Length]; + for (int i = 0; i < splitted.Length; i++) + { + // Delete start of name - file:// + fileNames[i] = splitted[i].Substring(7); + } + + return fileNames; + } + #endregion #region private void RegisterAtoms() @@ -382,9 +405,12 @@ namespace OpenTK.Platform.X11 _atom_xdnd_type_list = Functions.XInternAtom(window.Display, "XdndTypeList", false); _atom_xdnd_action_copy = Functions.XInternAtom(window.Display, "XdndActionCopy", false); _atom_xdnd_drop = Functions.XInternAtom(window.Display, "XdndDrop", false); - _atom_xdnd_finished = Functions.XInternAtom(window.Display, "Xdndfinished", false); + _atom_xdnd_finished = Functions.XInternAtom(window.Display, "XdndFinished", false); _atom_xdnd_selection = Functions.XInternAtom(window.Display, "XdndSelection", false); + _atom_xdnd_leave = Functions.XInternAtom(window.Display, "XdndLeave", false); + // Selection atoms + _atom_xdnd_primary = Functions.XInternAtom(window.Display, "PRIMARY", false); // string[] atom_names = new string[] // { // //"WM_TITLE", @@ -835,10 +861,12 @@ namespace OpenTK.Platform.X11 // Process all pending events while (Exists && window != null) { + //Functions.XNextEvent(window.Display, ref e); using (new XLock(window.Display)) { if (!Functions.XCheckWindowEvent(window.Display, window.Handle, window.EventMask, ref e) && - !Functions.XCheckTypedWindowEvent(window.Display, window.Handle, XEventName.ClientMessage, ref e)) + !Functions.XCheckTypedWindowEvent(window.Display, window.Handle, XEventName.ClientMessage, ref e) && + !Functions.XCheckTypedWindowEvent(window.Display, window.Handle, XEventName.SelectionNotify, ref e)) break; } @@ -881,45 +909,114 @@ namespace OpenTK.Platform.X11 OnClosed(EventArgs.Empty); break; } - } else if (e.ClientMessageEvent.message_type == _atom_xdnd_enter) { + } + else if (e.ClientMessageEvent.message_type == _atom_xdnd_enter) + { // Xdnd started bool useList = ((e.ClientMessageEvent.ptr2.ToInt64() & 1) == 1); - //long source = e.ClientMessageEvent.ptr1.ToInt64(); - //long version = e.ClientMessageEvent.ptr2.ToInt64() >> 24; + sourceHandler = e.ClientMessageEvent.ptr1; + sourceXdndVersion = e.ClientMessageEvent.ptr2.ToInt64() >> 24; IntPtr formats = IntPtr.Zero; int formatCount; - if (useList) { + if (useList) + { IntPtr count = IntPtr.Zero; - ReadProperty(_atom_xdnd_type_list, (IntPtr)AtomName.XA_ATOM, ref formats, ref count); + ReadProperty(sourceHandler, _atom_xdnd_type_list, (IntPtr)AtomName.XA_ATOM, ref formats, ref count); formatCount = count.ToInt32(); - } else { + } + else + { + // Bad code it will save only 1 format + formats = Marshal.AllocHGlobal(3 * IntPtr.Size); Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr3); - Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr4); - Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr5); + Marshal.WriteIntPtr(formats, IntPtr.Size * 2, e.ClientMessageEvent.ptr4); + Marshal.WriteIntPtr(formats, IntPtr.Size * 3, e.ClientMessageEvent.ptr5); formatCount = 3; } - IntPtr atom = IntPtr.Zero; - for (int i = 0; i < formatCount && atom == IntPtr.Zero; i++) { + xdndFormat = Consts.None; + for (int i = 0; i < formatCount && xdndFormat == Consts.None; ++i) + { IntPtr tempAtom = Marshal.ReadIntPtr(formats, IntPtr.Size * i); IntPtr atomName = Functions.XGetAtomName(this.window.Display, tempAtom); - string str = Marshal.PtrToStringUni(atomName); - if (str == "text/uri-list") { - atom = tempAtom; + string str = Marshal.PtrToStringAnsi(atomName); + if (str == "text/uri-list") + { + xdndFormat = tempAtom; } Functions.XFree(atomName); } - if (useList && formats != IntPtr.Zero) { + if (useList && formats != IntPtr.Zero) + { Functions.XFree(formats); } - } else if (e.ClientMessageEvent.message_type == _atom_xdnd_position) { - // Ignore for now it handle position of mouse when d&d happens - } else if (e.ClientMessageEvent.message_type == _atom_xdnd_drop) { - // Ignore for now it handle actual d&d + else + { + Marshal.FreeHGlobal(formats); + } + } + else if (e.ClientMessageEvent.message_type == _atom_xdnd_position) + { + XEvent reply = new XEvent (); + + reply.ClientMessageEvent.type = XEventName.ClientMessage; + reply.ClientMessageEvent.display = this.window.Display; + reply.ClientMessageEvent.window = sourceHandler; + reply.ClientMessageEvent.message_type = _atom_xdnd_status; + reply.ClientMessageEvent.format = 32; + reply.ClientMessageEvent.ptr1 = this.window.Handle; + if (xdndFormat != Consts.None) + { + reply.ClientMessageEvent.ptr2 = (IntPtr)1; + } + else + { + reply.ClientMessageEvent.ptr2 = (IntPtr)0; + } + reply.ClientMessageEvent.ptr3 = (IntPtr)0; + reply.ClientMessageEvent.ptr4 = (IntPtr)0; + reply.ClientMessageEvent.ptr5 = _atom_xdnd_action_copy; + + Functions.XSendEvent(this.window.Display, sourceHandler, false, (IntPtr)EventMask.NoEventMask, ref reply); + Functions.XFlush(this.window.Display); + } + else if (e.ClientMessageEvent.message_type == _atom_xdnd_drop) + { + if (xdndFormat == Consts.None) + { + XEvent reply = new XEvent (); + + reply.ClientMessageEvent.type = XEventName.ClientMessage; + reply.ClientMessageEvent.display = this.window.Display; + reply.ClientMessageEvent.window = sourceHandler; + reply.ClientMessageEvent.message_type = _atom_xdnd_finished; + reply.ClientMessageEvent.format = 32; + reply.ClientMessageEvent.ptr1 = this.window.Handle; + reply.ClientMessageEvent.ptr2 = (IntPtr)0; + reply.ClientMessageEvent.ptr3 = Consts.None; + + Functions.XSendEvent(this.window.Display, sourceHandler, false, (IntPtr)EventMask.NoEventMask, ref reply); + Functions.XFlush(this.window.Display); + } + else + { + if (sourceXdndVersion >= 1) + { + Functions.XConvertSelection(this.window.Display, _atom_xdnd_selection, xdndFormat, _atom_xdnd_primary, this.window.Handle, e.ClientMessageEvent.ptr3); + } + else + { + Functions.XConvertSelection(this.window.Display, _atom_xdnd_selection, xdndFormat, _atom_xdnd_primary, this.window.Handle, Consts.CurrentTime); + } + } + } + else if (e.ClientMessageEvent.message_type == _atom_xdnd_leave) + { + break; } break; @@ -1088,6 +1185,34 @@ namespace OpenTK.Platform.X11 break; case XEventName.SelectionNotify: + if (e.SelectionEvent.property == _atom_xdnd_primary) + { + IntPtr data = IntPtr.Zero; + IntPtr count = IntPtr.Zero; + ReadProperty(e.SelectionEvent.requestor, e.SelectionEvent.property, e.SelectionEvent.target, ref data, ref count); + + string rawString = Marshal.PtrToStringAnsi(data); + Functions.XFree(data); + string[] fileNames = parseUriList(rawString); + + for (int i = 0; i < fileNames.Length; i++) + { + OnDrop(fileNames[i]); + } + + XEvent reply = new XEvent (); + + reply.ClientMessageEvent.type = XEventName.ClientMessage; + reply.ClientMessageEvent.display = this.window.Display; + reply.ClientMessageEvent.window = sourceHandler; + reply.ClientMessageEvent.message_type = _atom_xdnd_finished; + reply.ClientMessageEvent.format = 32; + reply.ClientMessageEvent.ptr1 = this.window.Handle; + reply.ClientMessageEvent.ptr2 = (IntPtr)1; + reply.ClientMessageEvent.ptr3 = _atom_xdnd_action_copy; + + Functions.XSendEvent(this.window.Display, e.ClientMessageEvent.ptr1, false, (IntPtr)EventMask.NoEventMask, ref reply); + } break; default: From c78b11011060511104ff922f12471f820b604ccd Mon Sep 17 00:00:00 2001 From: Vlad K Date: Wed, 7 Jun 2017 17:56:46 +0300 Subject: [PATCH 07/15] MacOS d&d support --- .../Platform/MacOS/Cocoa/NSDragOperation.cs | 46 ++++++++++++++++ .../Platform/MacOS/CocoaNativeWindow.cs | 55 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs new file mode 100644 index 00000000..8babb01e --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs @@ -0,0 +1,46 @@ +#region License +// +// NSEventType.cs +// +// Author: +// Olle Håkansson +// +// Copyright (c) 2014 Olle Håkansson +// +// 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. +// +#endregion + +using System; + +namespace OpenTK.Platform.MacOS +{ + enum NSDragOperation : int + { + None = 0, + Copy = 1, + Link = 2, + Generic = 4, + Private = 8, + AllObsolete = 15, + Move = 16, + Delete = 32, + Every = Int32.MaxValue, + } +} \ No newline at end of file diff --git a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index 0795e1cb..c1155678 100644 --- a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -38,6 +38,9 @@ using System.Threading; using OpenTK.Graphics; using OpenTK.Input; +//using MonoMac.AppKit; +//using MonoMac.Foundation; + namespace OpenTK.Platform.MacOS { class CocoaNativeWindow : NativeWindowBase @@ -116,6 +119,7 @@ namespace OpenTK.Platform.MacOS static readonly IntPtr NSImage; static readonly IntPtr NSBitmapImageRep; static readonly IntPtr NSDeviceRGBColorSpace = Cocoa.ToNSString("NSDeviceRGBColorSpace"); + static readonly IntPtr NSFilenamesPboardType; static CocoaNativeWindow() { @@ -125,6 +129,7 @@ namespace OpenTK.Platform.MacOS NSCursor = Class.Get("NSCursor"); NSImage = Class.Get("NSImage"); NSBitmapImageRep = Class.Get("NSBitmapImageRep"); + NSFilenamesPboardType = Cocoa.GetStringConstant(Cocoa.AppKitLibrary, "NSFilenamesPboardType"); } private CocoaWindowInfo windowInfo; @@ -165,6 +170,8 @@ namespace OpenTK.Platform.MacOS CanBecomeKeyWindowHandler = CanBecomeKeyWindow; CanBecomeMainWindowHandler = CanBecomeMainWindow; ResetCursorRectsHandler = ResetCursorRects; + PerformDragOperationHandler = PerformDragOperation; + DraggingEnteredHandler = DraggingEntered; // Create the window class int unique_id = Interlocked.Increment(ref UniqueId); @@ -182,6 +189,9 @@ namespace OpenTK.Platform.MacOS Class.RegisterMethod(windowClass, AcceptsFirstResponderHandler, "acceptsFirstResponder", "b@:"); Class.RegisterMethod(windowClass, CanBecomeKeyWindowHandler, "canBecomeKeyWindow", "b@:"); Class.RegisterMethod(windowClass, CanBecomeMainWindowHandler, "canBecomeMainWindow", "b@:"); + Class.RegisterMethod(windowClass, DraggingEnteredHandler, "draggingEntered:", "@@:@"); + Class.RegisterMethod(windowClass, PerformDragOperationHandler, "performDragOperation:", "b@:@"); + Class.RegisterClass(windowClass); IntPtr viewClass = Class.AllocateClass("OpenTK_NSView" + unique_id, "NSView"); @@ -257,6 +267,16 @@ namespace OpenTK.Platform.MacOS exists = true; NSApplication.Quit += ApplicationQuit; + + // Enable drag and drop + Cocoa.SendIntPtr( + windowPtr, + Selector.Get("registerForDraggedTypes:"), + Cocoa.SendIntPtr( + Class.Get("NSArray"), + Selector.Get("arrayWithObjects:"), + NSFilenamesPboardType, + IntPtr.Zero)); } [UnmanagedFunctionPointer(CallingConvention.Winapi)] @@ -287,6 +307,10 @@ namespace OpenTK.Platform.MacOS delegate bool CanBecomeMainWindowDelegate(IntPtr self, IntPtr cmd); [UnmanagedFunctionPointer(CallingConvention.Winapi)] delegate void ResetCursorRectsDelegate(IntPtr self, IntPtr cmd); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + delegate IntPtr DraggingEnteredDelegate(IntPtr self, IntPtr cmd, IntPtr sender); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + delegate bool PerformDragOperationDelegate(IntPtr self, IntPtr cmd, IntPtr sender); WindowKeyDownDelegate WindowKeyDownHandler; WindowDidResizeDelegate WindowDidResizeHandler; @@ -302,6 +326,37 @@ namespace OpenTK.Platform.MacOS CanBecomeKeyWindowDelegate CanBecomeKeyWindowHandler; CanBecomeMainWindowDelegate CanBecomeMainWindowHandler; ResetCursorRectsDelegate ResetCursorRectsHandler; + DraggingEnteredDelegate DraggingEnteredHandler; + PerformDragOperationDelegate PerformDragOperationHandler; + + private IntPtr DraggingEntered(IntPtr self, IntPtr cmd, IntPtr sender) + { + int mask = Cocoa.SendInt(sender, Selector.Get("draggingSourceOperationMask")); + + if ((mask & (int)NSDragOperation.Generic) == (int)NSDragOperation.Generic) + { + return new IntPtr((int)NSDragOperation.Generic); + } + + return new IntPtr((int)NSDragOperation.None); + } + + private bool PerformDragOperation(IntPtr self, IntPtr cmd, IntPtr sender) + { + IntPtr pboard = Cocoa.SendIntPtr(sender, Selector.Get("draggingPasteboard")); + + IntPtr files = Cocoa.SendIntPtr(pboard, Selector.Get("propertyListForType:"), NSFilenamesPboardType); + + int count = Cocoa.SendInt(files, Selector.Get("count")); + for (int i = 0; i < count; ++i) + { + IntPtr obj = Cocoa.SendIntPtr(files, Selector.Get("objectAtIndex:"), new IntPtr(i)); + IntPtr str = Cocoa.SendIntPtr(obj, Selector.Get("cStringUsingEncoding:"), new IntPtr(1)); + OnDrop(Marshal.PtrToStringAnsi(str)); + } + + return true; + } private void WindowKeyDown(IntPtr self, IntPtr cmd, IntPtr notification) { From 77a2a5c8b382082682ec5a746d9b0c95b6c60984 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Fri, 16 Jun 2017 22:38:40 +0300 Subject: [PATCH 08/15] Fix wrong path --- src/OpenTK/OpenTK.csproj | 1 + {Source => src}/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs | 0 2 files changed, 1 insertion(+) rename {Source => src}/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs (100%) diff --git a/src/OpenTK/OpenTK.csproj b/src/OpenTK/OpenTK.csproj index febacf34..d294453c 100644 --- a/src/OpenTK/OpenTK.csproj +++ b/src/OpenTK/OpenTK.csproj @@ -798,6 +798,7 @@ + diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs rename to src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs From 1a20ca5245f86470de25290091b4b56e62274d58 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Sun, 18 Jun 2017 22:37:16 +0300 Subject: [PATCH 09/15] Rename Drop event, remove licenses --- src/OpenTK/INativeWindow.cs | 9 ++-- src/OpenTK/Input/DropEventArgs.cs | 51 ------------------- src/OpenTK/Input/FileDropEventArgs.cs | 30 +++++++++++ src/OpenTK/NativeWindow.cs | 25 ++++++--- src/OpenTK/OpenTK.csproj | 2 +- .../Platform/MacOS/Cocoa/NSDragOperation.cs | 31 +---------- .../Platform/MacOS/CocoaNativeWindow.cs | 5 +- src/OpenTK/Platform/NativeWindowBase.cs | 12 ++--- src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 2 +- src/OpenTK/Platform/Windows/WinGLNative.cs | 2 +- src/OpenTK/Platform/X11/X11GLNative.cs | 2 +- 11 files changed, 64 insertions(+), 107 deletions(-) delete mode 100644 src/OpenTK/Input/DropEventArgs.cs create mode 100644 src/OpenTK/Input/FileDropEventArgs.cs diff --git a/src/OpenTK/INativeWindow.cs b/src/OpenTK/INativeWindow.cs index f01ba276..8dcc7f29 100644 --- a/src/OpenTK/INativeWindow.cs +++ b/src/OpenTK/INativeWindow.cs @@ -285,10 +285,9 @@ namespace OpenTK //event EventHandler MouseClick; //event EventHandler MouseDoubleClick; - event EventHandler Drop; - //event EventHandler DragDrop; - //event EventHandler DragEnter; - //event EventHandler DragOver; - //event EventHandler DragLeave; + /// + /// Occurs whenever file dropped on window. + /// + event EventHandler FileDrop; } } diff --git a/src/OpenTK/Input/DropEventArgs.cs b/src/OpenTK/Input/DropEventArgs.cs deleted file mode 100644 index d5a9625f..00000000 --- a/src/OpenTK/Input/DropEventArgs.cs +++ /dev/null @@ -1,51 +0,0 @@ -#region License -// -// ConfigurationType.cs -// -// Author: -// Stefanos A. -// -// Copyright (c) 2006-2014 Stefanos Apostolopoulos -// -// 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. -// -#endregion - -using System; - -namespace OpenTK.Input -{ - public class DropEventArgs : EventArgs - { - string drop_string; - public DropEventArgs () { } - - public string DropString - { - get - { - return drop_string; - } - set - { - drop_string = value; - } - } - } -} diff --git a/src/OpenTK/Input/FileDropEventArgs.cs b/src/OpenTK/Input/FileDropEventArgs.cs new file mode 100644 index 00000000..fe58f662 --- /dev/null +++ b/src/OpenTK/Input/FileDropEventArgs.cs @@ -0,0 +1,30 @@ +using System; + +namespace OpenTK.Input +{ + /// + /// Defines the event data for events. + /// + public class FileDropEventArgs : EventArgs + { + #region Fields + + string fileName; + + #endregion + + #region Public Members + + /// + /// Gets the name of the file. + /// + /// The name of the file. + public string FileName + { + get; + internal set; + } + + #endregion + } +} diff --git a/src/OpenTK/NativeWindow.cs b/src/OpenTK/NativeWindow.cs index a6980cf3..5a5468e7 100644 --- a/src/OpenTK/NativeWindow.cs +++ b/src/OpenTK/NativeWindow.cs @@ -710,9 +710,9 @@ namespace OpenTK public event EventHandler MouseWheel = delegate { }; /// - /// Occurs whenever a file dropped in window; + /// Occurs whenever a file dropped on window; /// - public event EventHandler Drop = delegate { }; + public event EventHandler FileDrop = delegate { }; #endregion @@ -986,9 +986,16 @@ namespace OpenTK MouseWheel(this, e); } - protected virtual void OnDrop(DropEventArgs e) + /// + /// Raises the event. + /// + /// + /// A instance carrying file name. + /// The information carried by this instance is only valid within this method body. + /// + protected virtual void OnFileDrop(FileDropEventArgs e) { - Drop(this, e); + FileDrop(this, e); } #region OnResize @@ -1152,7 +1159,11 @@ namespace OpenTK private void OnMouseMoveInternal(object sender, MouseMoveEventArgs e) { OnMouseMove(e); } private void OnMouseWheelInternal(object sender, MouseWheelEventArgs e) { OnMouseWheel(e); } - private void OnDropInternal(object sender, DropEventArgs e) { OnDrop(e); } + #region OnFileDropInternal + + private void OnFileDropInternal(object sender, FileDropEventArgs e) { OnFileDrop(e); } + + #endregion #region OnMoveInternal @@ -1226,7 +1237,7 @@ namespace OpenTK implementation.VisibleChanged += OnVisibleChangedInternal; implementation.WindowBorderChanged += OnWindowBorderChangedInternal; implementation.WindowStateChanged += OnWindowStateChangedInternal; - implementation.Drop += OnDropInternal; + implementation.FileDrop += OnFileDropInternal; events = true; } else if (events) @@ -1251,7 +1262,7 @@ namespace OpenTK implementation.VisibleChanged -= OnVisibleChangedInternal; implementation.WindowBorderChanged -= OnWindowBorderChangedInternal; implementation.WindowStateChanged -= OnWindowStateChangedInternal; - implementation.Drop -= OnDropInternal; + implementation.FileDrop -= OnFileDropInternal; events = false; } else diff --git a/src/OpenTK/OpenTK.csproj b/src/OpenTK/OpenTK.csproj index d294453c..d1c7e1d0 100644 --- a/src/OpenTK/OpenTK.csproj +++ b/src/OpenTK/OpenTK.csproj @@ -795,7 +795,7 @@ - + diff --git a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs index 8babb01e..cbcc804f 100644 --- a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs +++ b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs @@ -1,33 +1,4 @@ -#region License -// -// NSEventType.cs -// -// Author: -// Olle Håkansson -// -// Copyright (c) 2014 Olle Håkansson -// -// 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. -// -#endregion - -using System; +using System; namespace OpenTK.Platform.MacOS { diff --git a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index c1155678..0f22ac3e 100644 --- a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -38,9 +38,6 @@ using System.Threading; using OpenTK.Graphics; using OpenTK.Input; -//using MonoMac.AppKit; -//using MonoMac.Foundation; - namespace OpenTK.Platform.MacOS { class CocoaNativeWindow : NativeWindowBase @@ -352,7 +349,7 @@ namespace OpenTK.Platform.MacOS { IntPtr obj = Cocoa.SendIntPtr(files, Selector.Get("objectAtIndex:"), new IntPtr(i)); IntPtr str = Cocoa.SendIntPtr(obj, Selector.Get("cStringUsingEncoding:"), new IntPtr(1)); - OnDrop(Marshal.PtrToStringAnsi(str)); + OnFileDrop(Marshal.PtrToStringAnsi(str)); } return true; diff --git a/src/OpenTK/Platform/NativeWindowBase.cs b/src/OpenTK/Platform/NativeWindowBase.cs index ff3701ed..c6fa960f 100644 --- a/src/OpenTK/Platform/NativeWindowBase.cs +++ b/src/OpenTK/Platform/NativeWindowBase.cs @@ -53,7 +53,7 @@ namespace OpenTK.Platform readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs(); readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0); - readonly DropEventArgs DropArgs = new DropEventArgs(); + readonly FileDropEventArgs FileDropArgs = new FileDropEventArgs(); // In order to simplify mouse event implementation, // we can store the current mouse state here. @@ -158,11 +158,11 @@ namespace OpenTK.Platform KeyUp(this, e); } - protected void OnDrop(string s) + protected void OnFileDrop(string s) { - var e = DropArgs; - DropArgs.DropString = s; - Drop(this, e); + var e = FileDropArgs; + FileDropArgs.FileName = s; + FileDrop(this, e); } /// \internal @@ -327,7 +327,7 @@ namespace OpenTK.Platform public event EventHandler MouseUp = delegate { }; public event EventHandler MouseMove = delegate { }; public event EventHandler MouseWheel = delegate { }; - public event EventHandler Drop = delegate { }; + public event EventHandler FileDrop = delegate { }; public abstract void Close(); diff --git a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index 22538e69..5d0f63c2 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -313,7 +313,7 @@ namespace OpenTK.Platform.SDL2 byte [] byteArray = new byte[length]; Marshal.Copy(ev.File, byteArray, 0, length); string dropString = System.Text.Encoding.UTF8.GetString(byteArray); - window.OnDrop(dropString); + window.OnFileDrop(dropString); } static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e) diff --git a/src/OpenTK/Platform/Windows/WinGLNative.cs b/src/OpenTK/Platform/Windows/WinGLNative.cs index eae8e3ec..b63a9210 100644 --- a/src/OpenTK/Platform/Windows/WinGLNative.cs +++ b/src/OpenTK/Platform/Windows/WinGLNative.cs @@ -696,7 +696,7 @@ namespace OpenTK.Platform.Windows Marshal.Copy(str, byteArray, 0, (int)(fileNameSize - 1)); string dropString = System.Text.Encoding.UTF8.GetString(byteArray); - OnDrop(dropString); + OnFileDrop(dropString); Marshal.FreeHGlobal(str); } diff --git a/src/OpenTK/Platform/X11/X11GLNative.cs b/src/OpenTK/Platform/X11/X11GLNative.cs index 6acb50dc..3926f4b6 100644 --- a/src/OpenTK/Platform/X11/X11GLNative.cs +++ b/src/OpenTK/Platform/X11/X11GLNative.cs @@ -1197,7 +1197,7 @@ namespace OpenTK.Platform.X11 for (int i = 0; i < fileNames.Length; i++) { - OnDrop(fileNames[i]); + OnFileDrop(fileNames[i]); } XEvent reply = new XEvent (); From 527efca0950ef967eb539f7083a05d5d1f9de819 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Sun, 18 Jun 2017 23:44:47 +0300 Subject: [PATCH 10/15] SDL2 rewrite c string to c# shtring + some docs --- src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs | 6 +++++- src/OpenTK/Platform/SDL2/Sdl2.cs | 3 +-- src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 10 +--------- src/OpenTK/Platform/Windows/API.cs | 4 ++++ 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs index cbcc804f..ae16a4b8 100644 --- a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs +++ b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs @@ -2,6 +2,10 @@ namespace OpenTK.Platform.MacOS { + // Values for enum : https://developer.apple.com/documentation/appkit/nsdragoperation?language=objc + // or for Mac users /System/Library/Frameworks/AppKit.framework/Headers + // Used by draggingSourceOperationMask(:) to get permission for dropped object + // also used for respones to drag source enum NSDragOperation : int { None = 0, @@ -14,4 +18,4 @@ namespace OpenTK.Platform.MacOS Delete = 32, Every = Int32.MaxValue, } -} \ No newline at end of file +} diff --git a/src/OpenTK/Platform/SDL2/Sdl2.cs b/src/OpenTK/Platform/SDL2/Sdl2.cs index 96bc0994..e5bfacc9 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2.cs @@ -1461,8 +1461,6 @@ namespace OpenTK.Platform.SDL2 public MultiGestureEvent mgesture; [FieldOffset(0)] public DollarGestureEvent dgesture; - [FieldOffset(0)] - public DropEvent drop; #endif // Ensure the structure is big enough @@ -1761,6 +1759,7 @@ namespace OpenTK.Platform.SDL2 public Int32 Data2; } + // For detailed info look: https://wiki.libsdl.org/SDL_DropEvent struct DropEvent { public UInt32 Type; diff --git a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index 5d0f63c2..a8de18d8 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -304,15 +304,7 @@ namespace OpenTK.Platform.SDL2 static unsafe void ProcessDropEvent(Sdl2NativeWindow window, DropEvent ev) { - byte* str = (byte*)ev.File; - - int length = 0; - for (; str[length] != 0; length++) - ; - - byte [] byteArray = new byte[length]; - Marshal.Copy(ev.File, byteArray, 0, length); - string dropString = System.Text.Encoding.UTF8.GetString(byteArray); + string dropString = Marshal.PtrToStringAuto(ev.File); window.OnFileDrop(dropString); } diff --git a/src/OpenTK/Platform/Windows/API.cs b/src/OpenTK/Platform/Windows/API.cs index c689f887..a3066441 100644 --- a/src/OpenTK/Platform/Windows/API.cs +++ b/src/OpenTK/Platform/Windows/API.cs @@ -136,6 +136,8 @@ namespace OpenTK.Platform.Windows { #region Window functions + #region Drag functions + [DllImport("shell32.dll")] internal static extern bool DragAcceptFiles( IntPtr handle, @@ -155,6 +157,8 @@ namespace OpenTK.Platform.Windows HDROP hDrop ); + #endregion + #region SetWindowPos // WINUSERAPI BOOL WINAPI SetWindowPos(__in HWND hWnd, __in_opt HWND hWndInsertAfter, From aba85d479c1b3652d057b69296b315b80cdb70f6 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Mon, 19 Jun 2017 00:19:11 +0300 Subject: [PATCH 11/15] Some docs --- src/OpenTK/Platform/Windows/WinGLNative.cs | 5 ++--- src/OpenTK/Platform/X11/API.cs | 7 +++++-- src/OpenTK/Platform/X11/X11GLNative.cs | 6 ++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/OpenTK/Platform/Windows/WinGLNative.cs b/src/OpenTK/Platform/Windows/WinGLNative.cs index b63a9210..d068428c 100644 --- a/src/OpenTK/Platform/Windows/WinGLNative.cs +++ b/src/OpenTK/Platform/Windows/WinGLNative.cs @@ -693,9 +693,8 @@ namespace OpenTK.Platform.Windows IntPtr str = Marshal.AllocHGlobal((int)fileNameSize); Functions.DragQueryFile(hDrop, i, str, fileNameSize); - - Marshal.Copy(str, byteArray, 0, (int)(fileNameSize - 1)); - string dropString = System.Text.Encoding.UTF8.GetString(byteArray); + + string dropString = Marshal.PtrToStringAuto(str); OnFileDrop(dropString); Marshal.FreeHGlobal(str); diff --git a/src/OpenTK/Platform/X11/API.cs b/src/OpenTK/Platform/X11/API.cs index 8274dc7a..1f3d3d44 100644 --- a/src/OpenTK/Platform/X11/API.cs +++ b/src/OpenTK/Platform/X11/API.cs @@ -53,10 +53,13 @@ namespace OpenTK.Platform.X11 #endregion // X11 has some defined values + // Whis values are defined with c's #define in X.h internal static class Consts { - public static readonly IntPtr None = IntPtr.Zero; - public static readonly IntPtr CurrentTime = IntPtr.Zero; + // Universal null resource or null atom + public static readonly IntPtr None = IntPtr.Zero; // #define None 0L + // Special time value + public static readonly IntPtr CurrentTime = IntPtr.Zero; // #define CurrentTime 0L } #region internal static class API diff --git a/src/OpenTK/Platform/X11/X11GLNative.cs b/src/OpenTK/Platform/X11/X11GLNative.cs index 3926f4b6..4217b30b 100644 --- a/src/OpenTK/Platform/X11/X11GLNative.cs +++ b/src/OpenTK/Platform/X11/X11GLNative.cs @@ -861,7 +861,6 @@ namespace OpenTK.Platform.X11 // Process all pending events while (Exists && window != null) { - //Functions.XNextEvent(window.Display, ref e); using (new XLock(window.Display)) { if (!Functions.XCheckWindowEvent(window.Display, window.Handle, window.EventMask, ref e) && @@ -910,9 +909,13 @@ namespace OpenTK.Platform.X11 break; } } + // For X11 drag and drop handling use https://freedesktop.org/wiki/Specifications/XDND/#index9h2 else if (e.ClientMessageEvent.message_type == _atom_xdnd_enter) { // Xdnd started + // ptr1 -> source window handler + // ptr2 bit 0 -> set to 1 if source support more than three data formats + // ptr2 third byte contains Xdnd version that source supports bool useList = ((e.ClientMessageEvent.ptr2.ToInt64() & 1) == 1); sourceHandler = e.ClientMessageEvent.ptr1; sourceXdndVersion = e.ClientMessageEvent.ptr2.ToInt64() >> 24; @@ -927,7 +930,6 @@ namespace OpenTK.Platform.X11 } else { - // Bad code it will save only 1 format formats = Marshal.AllocHGlobal(3 * IntPtr.Size); Marshal.WriteIntPtr(formats, e.ClientMessageEvent.ptr3); Marshal.WriteIntPtr(formats, IntPtr.Size * 2, e.ClientMessageEvent.ptr4); From 280fa4b77d4086121868e2200b4652c2b92f5df1 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Mon, 19 Jun 2017 00:20:07 +0300 Subject: [PATCH 12/15] Ansi to Auto --- src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index 0f22ac3e..687f5684 100644 --- a/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/src/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -349,7 +349,7 @@ namespace OpenTK.Platform.MacOS { IntPtr obj = Cocoa.SendIntPtr(files, Selector.Get("objectAtIndex:"), new IntPtr(i)); IntPtr str = Cocoa.SendIntPtr(obj, Selector.Get("cStringUsingEncoding:"), new IntPtr(1)); - OnFileDrop(Marshal.PtrToStringAnsi(str)); + OnFileDrop(Marshal.PtrToStringAuto(str)); } return true; From eb951d85697fe213821b06434b848e806bdca505 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Wed, 21 Jun 2017 22:07:32 +0300 Subject: [PATCH 13/15] Delete region keyword --- src/OpenTK/Input/FileDropEventArgs.cs | 8 -------- src/OpenTK/NativeWindow.cs | 4 ---- src/OpenTK/Platform/Windows/API.cs | 4 ---- src/OpenTK/Platform/X11/X11GLNative.cs | 4 ---- 4 files changed, 20 deletions(-) diff --git a/src/OpenTK/Input/FileDropEventArgs.cs b/src/OpenTK/Input/FileDropEventArgs.cs index fe58f662..27f94b45 100644 --- a/src/OpenTK/Input/FileDropEventArgs.cs +++ b/src/OpenTK/Input/FileDropEventArgs.cs @@ -7,14 +7,8 @@ namespace OpenTK.Input /// public class FileDropEventArgs : EventArgs { - #region Fields - string fileName; - #endregion - - #region Public Members - /// /// Gets the name of the file. /// @@ -24,7 +18,5 @@ namespace OpenTK.Input get; internal set; } - - #endregion } } diff --git a/src/OpenTK/NativeWindow.cs b/src/OpenTK/NativeWindow.cs index 5a5468e7..7f313f59 100644 --- a/src/OpenTK/NativeWindow.cs +++ b/src/OpenTK/NativeWindow.cs @@ -1159,12 +1159,8 @@ namespace OpenTK private void OnMouseMoveInternal(object sender, MouseMoveEventArgs e) { OnMouseMove(e); } private void OnMouseWheelInternal(object sender, MouseWheelEventArgs e) { OnMouseWheel(e); } - #region OnFileDropInternal - private void OnFileDropInternal(object sender, FileDropEventArgs e) { OnFileDrop(e); } - #endregion - #region OnMoveInternal private void OnMoveInternal(object sender, EventArgs e) { OnMove(e); } diff --git a/src/OpenTK/Platform/Windows/API.cs b/src/OpenTK/Platform/Windows/API.cs index a3066441..c689f887 100644 --- a/src/OpenTK/Platform/Windows/API.cs +++ b/src/OpenTK/Platform/Windows/API.cs @@ -136,8 +136,6 @@ namespace OpenTK.Platform.Windows { #region Window functions - #region Drag functions - [DllImport("shell32.dll")] internal static extern bool DragAcceptFiles( IntPtr handle, @@ -157,8 +155,6 @@ namespace OpenTK.Platform.Windows HDROP hDrop ); - #endregion - #region SetWindowPos // WINUSERAPI BOOL WINAPI SetWindowPos(__in HWND hWnd, __in_opt HWND hWndInsertAfter, diff --git a/src/OpenTK/Platform/X11/X11GLNative.cs b/src/OpenTK/Platform/X11/X11GLNative.cs index 4217b30b..afae0bd4 100644 --- a/src/OpenTK/Platform/X11/X11GLNative.cs +++ b/src/OpenTK/Platform/X11/X11GLNative.cs @@ -331,8 +331,6 @@ namespace OpenTK.Platform.X11 #region Private Members - #region Utils - private void ReadProperty(IntPtr window, IntPtr property, IntPtr type, ref IntPtr data, ref IntPtr itemsCount) { int format; @@ -360,8 +358,6 @@ namespace OpenTK.Platform.X11 return fileNames; } - #endregion - #region private void RegisterAtoms() /// From 9486b4963bcd849578a8e17fd25230e643f65708 Mon Sep 17 00:00:00 2001 From: Vlad K Date: Wed, 21 Jun 2017 22:10:11 +0300 Subject: [PATCH 14/15] Code sanity --- src/OpenTK/Platform/SDL2/Sdl2.cs | 2 +- src/OpenTK/Platform/Windows/WinGLNative.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/OpenTK/Platform/SDL2/Sdl2.cs b/src/OpenTK/Platform/SDL2/Sdl2.cs index e5bfacc9..bd6fffe0 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2.cs @@ -141,7 +141,7 @@ namespace OpenTK.Platform.SDL2 [SuppressUnmanagedCodeSecurity] [DllImport (lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_free", ExactSpelling = true)] - public static extern void Free (IntPtr memblock); + public static extern void Free(IntPtr memblock); #region GameContoller diff --git a/src/OpenTK/Platform/Windows/WinGLNative.cs b/src/OpenTK/Platform/Windows/WinGLNative.cs index d068428c..db65cb7c 100644 --- a/src/OpenTK/Platform/Windows/WinGLNative.cs +++ b/src/OpenTK/Platform/Windows/WinGLNative.cs @@ -689,7 +689,6 @@ namespace OpenTK.Platform.Windows { // Don't forget about \0 at the end uint fileNameSize = Functions.DragQueryFile(hDrop, i, IntPtr.Zero, 0) + 1; - byte [] byteArray = new byte [fileNameSize]; IntPtr str = Marshal.AllocHGlobal((int)fileNameSize); Functions.DragQueryFile(hDrop, i, str, fileNameSize); From a3ca40216882ac5389ab73e8e40c80aa1d3ea94a Mon Sep 17 00:00:00 2001 From: Vlad K Date: Wed, 21 Jun 2017 23:08:34 +0300 Subject: [PATCH 15/15] Turn comments into XML docs. Change NSDragOperation visibility --- .../Platform/MacOS/Cocoa/NSDragOperation.cs | 12 +++++++----- src/OpenTK/Platform/SDL2/Sdl2.cs | 4 +++- src/OpenTK/Platform/X11/API.cs | 18 ++++++++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs index ae16a4b8..b067eb2e 100644 --- a/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs +++ b/src/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs @@ -2,11 +2,13 @@ namespace OpenTK.Platform.MacOS { - // Values for enum : https://developer.apple.com/documentation/appkit/nsdragoperation?language=objc - // or for Mac users /System/Library/Frameworks/AppKit.framework/Headers - // Used by draggingSourceOperationMask(:) to get permission for dropped object - // also used for respones to drag source - enum NSDragOperation : int + /// + /// Used by draggingSourceOperationMask() to get permission for dropped object + /// also used for respones to drag source + /// Values for enum can be found here https://developer.apple.com/documentation/appkit/nsdragoperation?language=objc + /// or for Mac users /System/Library/Frameworks/AppKit.framework/Headers + /// + internal enum NSDragOperation : int { None = 0, Copy = 1, diff --git a/src/OpenTK/Platform/SDL2/Sdl2.cs b/src/OpenTK/Platform/SDL2/Sdl2.cs index bd6fffe0..d4042e1f 100644 --- a/src/OpenTK/Platform/SDL2/Sdl2.cs +++ b/src/OpenTK/Platform/SDL2/Sdl2.cs @@ -1759,7 +1759,9 @@ namespace OpenTK.Platform.SDL2 public Int32 Data2; } - // For detailed info look: https://wiki.libsdl.org/SDL_DropEvent + /// + /// Drop event for SDL2 interop. For detailed info look: https://wiki.libsdl.org/SDL_DropEvent + /// struct DropEvent { public UInt32 Type; diff --git a/src/OpenTK/Platform/X11/API.cs b/src/OpenTK/Platform/X11/API.cs index 1f3d3d44..2b6ed193 100644 --- a/src/OpenTK/Platform/X11/API.cs +++ b/src/OpenTK/Platform/X11/API.cs @@ -52,14 +52,20 @@ namespace OpenTK.Platform.X11 #endregion - // X11 has some defined values - // Whis values are defined with c's #define in X.h + /// + /// 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 - public static readonly IntPtr None = IntPtr.Zero; // #define None 0L - // Special time value - public static readonly IntPtr CurrentTime = IntPtr.Zero; // #define CurrentTime 0L + /// + /// 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; // } #region internal static class API