From 2870532c78e6a9e19428de583ba883b2bfa45fe1 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 20:14:14 +0000 Subject: [PATCH] Branched for 1.0 release. --- Source/Examples/OpenGL/1.1/ImmediateMode.cs | 10 +- Source/Examples/OpenTK/Test/Multithreading.cs | 30 +- Source/OpenTK/Icon.cs | 935 ------------------ Source/OpenTK/IconConverter.cs | 94 -- Source/OpenTK/Platform/X11/API.cs | 21 +- Source/OpenTK/Platform/X11/X11GLNative.cs | 354 ++++--- Source/OpenTK/Platform/X11/X11Input.cs | 2 +- 7 files changed, 249 insertions(+), 1197 deletions(-) delete mode 100644 Source/OpenTK/Icon.cs delete mode 100644 Source/OpenTK/IconConverter.cs diff --git a/Source/Examples/OpenGL/1.1/ImmediateMode.cs b/Source/Examples/OpenGL/1.1/ImmediateMode.cs index 4f46df18..dc65a70d 100644 --- a/Source/Examples/OpenGL/1.1/ImmediateMode.cs +++ b/Source/Examples/OpenGL/1.1/ImmediateMode.cs @@ -1,4 +1,4 @@ -#region --- License --- +#region --- License --- /* Licensed under the MIT/X11 license. * Copyright (c) 2006-2008 the OpenTK Team. * This notice may not be removed from any source distribution. @@ -41,7 +41,7 @@ namespace Examples.Tutorial { } #endregion - + #region OnLoad protected override void OnLoad(EventArgs e) @@ -65,6 +65,8 @@ namespace Examples.Tutorial /// protected override void OnResize(EventArgs e) { + base.OnResize(e); + GL.Viewport(0, 0, Width, Height); double aspect_ratio = Width / (double)Height; @@ -87,6 +89,8 @@ namespace Examples.Tutorial /// protected override void OnUpdateFrame(FrameEventArgs e) { + base.OnUpdateFrame(e); + if (Keyboard[OpenTK.Input.Key.Escape]) { this.Exit(); @@ -103,6 +107,8 @@ namespace Examples.Tutorial /// protected override void OnRenderFrame(FrameEventArgs e) { + base.OnRenderFrame(e); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Matrix4 lookat = Matrix4.LookAt(0, 5, 5, 0, 0, 0, 0, 1, 0); diff --git a/Source/Examples/OpenTK/Test/Multithreading.cs b/Source/Examples/OpenTK/Test/Multithreading.cs index 62a468ba..cf056831 100644 --- a/Source/Examples/OpenTK/Test/Multithreading.cs +++ b/Source/Examples/OpenTK/Test/Multithreading.cs @@ -37,20 +37,13 @@ namespace Examples.Tests { public static void Main() { - const int ThreadCount = 4; + const int ThreadCount = 2; List threads = new List(); // launch threads for (int i = 0; i < ThreadCount; i++) { - Thread t = new Thread(delegate() - { - using (Tutorial.T03_Immediate_Mode_Cube game = new Examples.Tutorial.T03_Immediate_Mode_Cube()) - { - Utilities.SetWindowTitle(game); - game.Run(30.0); - } - }); + Thread t = new Thread(RunGame); t.IsBackground = true; t.Priority = ThreadPriority.BelowNormal; t.Start(); @@ -63,5 +56,24 @@ namespace Examples.Tests t.Join(); } } + + static void RunGame() + { + using (Tutorial.T03_Immediate_Mode_Cube game = new Examples.Tutorial.T03_Immediate_Mode_Cube()) + { + Utilities.SetWindowTitle(game); + game.Keyboard.KeyUp += delegate(object sender, OpenTK.Input.KeyboardKeyEventArgs e) + { + if (e.Key == OpenTK.Input.Key.Space) + { + if (game.WindowState == OpenTK.WindowState.Fullscreen) + game.WindowState = OpenTK.WindowState.Normal; + else + game.WindowState = OpenTK.WindowState.Fullscreen; + } + }; + game.Run(30.0); + } + } } } diff --git a/Source/OpenTK/Icon.cs b/Source/OpenTK/Icon.cs deleted file mode 100644 index d2687b23..00000000 --- a/Source/OpenTK/Icon.cs +++ /dev/null @@ -1,935 +0,0 @@ -#define NET_2_0 - -// -// Icon.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// Sanjay Gupta (gsanjay@novell.com) -// Peter Dennis Bartok (pbartok@novell.com) -// Sebastien Pouliot -// -// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2008 Novell, Inc (http://www.novell.com) -// -// 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.Collections; -using System.ComponentModel; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.InteropServices; -using System.Security.Permissions; -using System.Reflection; - -namespace OpenTK -{ -#if EXPERIMENTAL - #if !NET_2_0 - [ComVisible(false)] - #endif - [Serializable] - //[Editor("Design.IconEditor, " + Consts.AssemblySystem_Drawing_Design, typeof(Design.UITypeEditor))] - [TypeConverter(typeof(IconConverter))] - public sealed class Icon : MarshalByRefObject, ISerializable, ICloneable, IDisposable - { - [StructLayout(LayoutKind.Sequential)] - internal struct IconDirEntry - { - internal byte width; - // Width of icon - internal byte height; - // Height of icon - internal byte colorCount; - // colors in icon - internal byte reserved; - // Reserved - internal ushort planes; - // Color Planes - internal ushort bitCount; - // Bits per pixel - internal uint bytesInRes; - // bytes in resource - internal uint imageOffset; - // position in file - } - - [StructLayout(LayoutKind.Sequential)] - internal struct IconDir - { - internal ushort idReserved; - // Reserved - internal ushort idType; - // resource type (1 for icons) - internal ushort idCount; - // how many images? - internal IconDirEntry[] idEntries; - // the entries for each image - } - - [StructLayout(LayoutKind.Sequential)] - internal struct BitmapInfoHeader - { - internal uint biSize; - internal int biWidth; - internal int biHeight; - internal ushort biPlanes; - internal ushort biBitCount; - internal uint biCompression; - internal uint biSizeImage; - internal int biXPelsPerMeter; - internal int biYPelsPerMeter; - internal uint biClrUsed; - internal uint biClrImportant; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct IconImage - { - internal BitmapInfoHeader iconHeader; - //image header - internal uint[] iconColors; - //colors table - internal byte[] iconXOR; - // bits for XOR mask - internal byte[] iconAND; - //bits for AND mask - } - - [StructLayout(LayoutKind.Sequential)] - internal struct IconInfo - { - int fIcon; - public int xHotspot; - public int yHotspot; - public IntPtr hbmMask; - public IntPtr hbmColor; - - public bool IsIcon - { - get { return (fIcon == 1); } - set { fIcon = (value) ? 1 : 0; } - } - } - - [DllImport("user32.dll", SetLastError=true)] - static extern bool GetIconInfo(IntPtr hIcon, out IconInfo iconinfo); - [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, SetLastError=true)] - internal static extern IntPtr CreateIconIndirect([In] ref IconInfo piconinfo); - [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, SetLastError=true)] - internal static extern bool DestroyIcon(IntPtr hIcon); - - private Size iconSize; - private IntPtr handle = IntPtr.Zero; - private IconDir iconDir; - private ushort id; - private IconImage[] imageData; - private bool undisposable; - private bool disposed; - private Bitmap bitmap; - - private Icon() - { - } - - private Icon(IntPtr handle) - { - this.handle = handle; - if (Configuration.RunningOnUnix) - { - bitmap = Bitmap.FromHicon(handle); - iconSize = new Size(bitmap.Width, bitmap.Height); - // FIXME: we need to convert the bitmap into an icon - } - else - { - IconInfo ii; - GetIconInfo(handle, out ii); - if (!ii.IsIcon) - throw new NotImplementedException("Handle doesn't represent an ICON."); - - // If this structure defines an icon, the hot spot is always in the center of the icon - iconSize = new Size(ii.xHotspot * 2, ii.yHotspot * 2); - bitmap = (Bitmap)Image.FromHbitmap(ii.hbmColor); - } - undisposable = true; - } - - public Icon(Icon original, int width, int height) : this(original, new Size(width, height)) - { - } - - public Icon(Icon original, Size size) - { - if (original == null) - throw new ArgumentException("original"); - - iconSize = size; - iconDir = original.iconDir; - - int count = iconDir.idCount; - if (count > 0) - { - imageData = original.imageData; - id = UInt16.MaxValue; - - for (ushort i = 0; i < count; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if ((ide.height == size.Height) || (ide.width == size.Width)) - { - id = i; - break; - } - } - - // if a perfect match isn't found we look for the biggest icon *smaller* than specified - if (id == UInt16.MaxValue) - { - int requested = Math.Min(size.Height, size.Width); - IconDirEntry best = iconDir.idEntries[0]; - for (ushort i = 1; i < count; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if ((ide.height < requested) || (ide.width < requested)) - { - if ((ide.height > best.height) || (ide.width > best.width)) - id = i; - } - } - } - - // last one, if nothing better can be found - if (id == UInt16.MaxValue) - id = (ushort)(count - 1); - - iconSize.Height = iconDir.idEntries[id].height; - iconSize.Width = iconDir.idEntries[id].width; - } else - { - iconSize.Height = size.Height; - iconSize.Width = size.Width; - } - - if (original.bitmap != null) - bitmap = (Bitmap)original.bitmap.Clone(); - } - - public Icon(Stream stream) : this(stream, 32, 32) - { - } - - public Icon(Stream stream, int width, int height) - { - InitFromStreamWithSize(stream, width, height); - } - - public Icon(string fileName) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, 32, 32); - } - } - - public Icon(Type type, string resource) - { - if (resource == null) - throw new ArgumentException("resource"); - - using (Stream s = type.Assembly.GetManifestResourceStream(type, resource)) - { - if (s == null) - { - string msg = String.Format("Resource '{0}' was not found.", resource); - throw new FileNotFoundException(msg); - } - InitFromStreamWithSize(s, 32, 32); - // 32x32 is default - } - } - - private Icon(SerializationInfo info, StreamingContext context) - { - MemoryStream dataStream = null; - int width = 0; - int height = 0; - foreach (SerializationEntry serEnum in info) - { - if (String.Compare(serEnum.Name, "IconData", true) == 0) - { - dataStream = new MemoryStream((byte[])serEnum.Value); - } - if (String.Compare(serEnum.Name, "IconSize", true) == 0) - { - Size iconSize = (Size)serEnum.Value; - width = iconSize.Width; - height = iconSize.Height; - } - } - if ((dataStream != null) && (width == height)) - { - dataStream.Seek(0, SeekOrigin.Begin); - InitFromStreamWithSize(dataStream, width, height); - } - } - - internal Icon(string resourceName, bool undisposable) - { - using (Stream s = typeof(Icon).Assembly.GetManifestResourceStream(resourceName)) - { - if (s == null) - { - string msg = String.Format("Resource '{0}' was not found.", resourceName); - throw new FileNotFoundException(msg); - } - InitFromStreamWithSize(s, 32, 32); - // 32x32 is default - } - this.undisposable = true; - } - - void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) - { - MemoryStream ms = new MemoryStream(); - Save(ms); - si.AddValue("IconSize", this.Size, typeof(Size)); - si.AddValue("IconData", ms.ToArray()); - } - - #if NET_2_0 - public Icon(Stream stream, Size size) : this(stream, size.Width, size.Height) - { - } - - public Icon(string fileName, int width, int height) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, width, height); - } - } - - public Icon(string fileName, Size size) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, size.Width, size.Height); - } - } - /* - [MonoLimitation("The same icon, SystemIcons.WinLogo, is returned for all file types.")] - public static Icon ExtractAssociatedIcon(string filePath) - { - if (String.IsNullOrEmpty(filePath)) - throw new ArgumentException(Locale.GetText("Null or empty path."), "filePath"); - if (!File.Exists(filePath)) - throw new FileNotFoundException(Locale.GetText("Couldn't find specified file."), filePath); - - return SystemIcons.WinLogo; - } - */ - #endif - - public void Dispose() - { - // SystemIcons requires this - if (undisposable) - return; - - if (!disposed) - { - if (Configuration.RunningOnWindows && (handle != IntPtr.Zero)) - { - DestroyIcon(handle); - handle = IntPtr.Zero; - } - if (bitmap != null) - { - bitmap.Dispose(); - bitmap = null; - } - GC.SuppressFinalize(this); - } - disposed = true; - } - - public object Clone() - { - return new Icon(this, Size); - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public static Icon FromHandle(IntPtr handle) - { - if (handle == IntPtr.Zero) - throw new ArgumentException("handle"); - - return new Icon(handle); - } - - private void SaveIconImage(BinaryWriter writer, IconImage ii) - { - BitmapInfoHeader bih = ii.iconHeader; - writer.Write(bih.biSize); - writer.Write(bih.biWidth); - writer.Write(bih.biHeight); - writer.Write(bih.biPlanes); - writer.Write(bih.biBitCount); - writer.Write(bih.biCompression); - writer.Write(bih.biSizeImage); - writer.Write(bih.biXPelsPerMeter); - writer.Write(bih.biYPelsPerMeter); - writer.Write(bih.biClrUsed); - writer.Write(bih.biClrImportant); - - //now write color table - int colCount = ii.iconColors.Length; - for (int j = 0; j < colCount; j++) - writer.Write(ii.iconColors[j]); - - //now write XOR Mask - writer.Write(ii.iconXOR); - - //now write AND Mask - writer.Write(ii.iconAND); - } - - private void SaveIconDirEntry(BinaryWriter writer, IconDirEntry ide, uint offset) - { - writer.Write(ide.width); - writer.Write(ide.height); - writer.Write(ide.colorCount); - writer.Write(ide.reserved); - writer.Write(ide.planes); - writer.Write(ide.bitCount); - writer.Write(ide.bytesInRes); - writer.Write((offset == UInt32.MaxValue) ? ide.imageOffset : offset); - } - - private void SaveAll(BinaryWriter writer) - { - writer.Write(iconDir.idReserved); - writer.Write(iconDir.idType); - ushort count = iconDir.idCount; - writer.Write(count); - - for (int i = 0; i < (int)count; i++) - { - SaveIconDirEntry(writer, iconDir.idEntries[i], UInt32.MaxValue); - } - - for (int i = 0; i < (int)count; i++) - { - SaveIconImage(writer, imageData[i]); - } - } - - private void SaveBestSingleIcon(BinaryWriter writer, int width, int height) - { - writer.Write(iconDir.idReserved); - writer.Write(iconDir.idType); - writer.Write((ushort)1); - - // find best entry and save it - int best = 0; - int bitCount = 0; - for (int i = 0; i < iconDir.idCount; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if ((width == ide.width) && (height == ide.height)) - { - if (ide.bitCount >= bitCount) - { - bitCount = ide.bitCount; - best = i; - } - } - } - - SaveIconDirEntry(writer, iconDir.idEntries[best], 22); - SaveIconImage(writer, imageData[best]); - } - - private void SaveBitmapAsIcon(BinaryWriter writer) - { - writer.Write((ushort)0); - // idReserved must be 0 - writer.Write((ushort)1); - // idType must be 1 - writer.Write((ushort)1); - // only one icon - // when transformed into a bitmap only a single image exists - IconDirEntry ide = new IconDirEntry(); - ide.width = (byte)bitmap.Width; - ide.height = (byte)bitmap.Height; - ide.colorCount = 0; - // 32 bbp == 0, for palette size - ide.reserved = 0; - // always 0 - ide.planes = 0; - ide.bitCount = 32; - ide.imageOffset = 22; - // 22 is the first icon position (for single icon files) - BitmapInfoHeader bih = new BitmapInfoHeader(); - bih.biSize = (uint)Marshal.SizeOf(typeof(BitmapInfoHeader)); - bih.biWidth = bitmap.Width; - bih.biHeight = 2 * bitmap.Height; - // include both XOR and AND images - bih.biPlanes = 1; - bih.biBitCount = 32; - bih.biCompression = 0; - bih.biSizeImage = 0; - bih.biXPelsPerMeter = 0; - bih.biYPelsPerMeter = 0; - bih.biClrUsed = 0; - bih.biClrImportant = 0; - - IconImage ii = new IconImage(); - ii.iconHeader = bih; - ii.iconColors = new uint[0]; - // no palette - int xor_size = (((bih.biBitCount * bitmap.Width + 31) & ~31) >> 3) * bitmap.Height; - ii.iconXOR = new byte[xor_size]; - int p = 0; - for (int y = bitmap.Height - 1; y >= 0; y--) - { - for (int x = 0; x < bitmap.Width; x++) - { - Color c = bitmap.GetPixel(x, y); - ii.iconXOR[p++] = c.B; - ii.iconXOR[p++] = c.G; - ii.iconXOR[p++] = c.R; - ii.iconXOR[p++] = c.A; - } - } - int and_line_size = (((Width + 31) & ~31) >> 3); - // must be a multiple of 4 bytes - int and_size = and_line_size * bitmap.Height; - ii.iconAND = new byte[and_size]; - - ide.bytesInRes = (uint)(bih.biSize + xor_size + and_size); - - SaveIconDirEntry(writer, ide, UInt32.MaxValue); - SaveIconImage(writer, ii); - } - - private void Save(Stream outputStream, int width, int height) - { - BinaryWriter writer = new BinaryWriter(outputStream); - // if we have the icon information then save from this - if (iconDir.idEntries != null) - { - if ((width == -1) && (height == -1)) - SaveAll(writer); - else - SaveBestSingleIcon(writer, width, height); - } else if (bitmap != null) - { - // if the icon was created from a bitmap then convert it - SaveBitmapAsIcon(writer); - } - writer.Flush(); - } - - public void Save(Stream outputStream) - { - if (outputStream == null) - throw new NullReferenceException("outputStream"); - - // save every icons available - Save(outputStream, -1, -1); - } - - internal Bitmap BuildBitmapOnWin32() - { - Bitmap bmp; - - if (imageData == null) - return new Bitmap(32, 32); - - IconImage ii = imageData[id]; - BitmapInfoHeader bih = ii.iconHeader; - int biHeight = bih.biHeight / 2; - - int ncolors = (int)bih.biClrUsed; - if ((ncolors == 0) && (bih.biBitCount < 24)) - ncolors = (int)(1 << bih.biBitCount); - - switch (bih.biBitCount) { - case 1: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format1bppIndexed); - break; - case 4: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format4bppIndexed); - break; - case 8: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format8bppIndexed); - break; - case 24: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format24bppRgb); - break; - case 32: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format32bppArgb); - break; - default: - string msg = String.Format("Unexpected number of bits: {0}", bih.biBitCount); - throw new Exception(msg); - } - - if (bih.biBitCount < 24) - { - ColorPalette pal = bmp.Palette; - // Managed palette - for (int i = 0; i < ii.iconColors.Length; i++) - { - pal.Entries[i] = Color.FromArgb((int)ii.iconColors[i] | unchecked((int)0xff000000u)); - } - bmp.Palette = pal; - } - - int bytesPerLine = (int)((((bih.biWidth * bih.biBitCount) + 31) & ~31) >> 3); - BitmapData bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); - - for (int y = 0; y < biHeight; y++) - { - Marshal.Copy(ii.iconXOR, bytesPerLine * y, (IntPtr)(bits.Scan0.ToInt64() + bits.Stride * (biHeight - 1 - y)), bytesPerLine); - } - - bmp.UnlockBits(bits); - - bmp = new Bitmap(bmp); - // This makes a 32bpp image out of an indexed one - // Apply the mask to make properly transparent - bytesPerLine = (int)((((bih.biWidth) + 31) & ~31) >> 3); - for (int y = 0; y < biHeight; y++) - { - for (int x = 0; x < bih.biWidth / 8; x++) - { - for (int bit = 7; bit >= 0; bit--) - { - if (((ii.iconAND[y * bytesPerLine + x] >> bit) & 1) != 0) - { - bmp.SetPixel(x * 8 + 7 - bit, biHeight - y - 1, Color.Transparent); - } - } - } - } - - return bmp; - } - - internal Bitmap GetInternalBitmap() - { - if (bitmap == null) - { - if (Configuration.RunningOnUnix) - { - // Mono's libgdiplus doesn't require to keep the stream alive when loading images - using (MemoryStream ms = new MemoryStream()) - { - // save the current icon - Save(ms, Width, Height); - ms.Position = 0; - - // libgdiplus can now decode icons - //bitmap = (Bitmap)Image.LoadFromStream(ms, false); - bitmap = (Bitmap)Image.FromStream(ms); - } - } else - { - // MS GDI+ ICO codec is more limited than the MS Icon class - // so we can't, reliably, get bitmap using it. We need to do this the "slow" way - bitmap = BuildBitmapOnWin32(); - } - } - - return bitmap; - } - - // note: all bitmaps are 32bits ARGB - no matter what the icon format (bitcount) was - public Bitmap ToBitmap() - { - if (disposed) - throw new ObjectDisposedException(GetType().Name); - - // note: we can't return the original image because - // (a) we have no control over the bitmap instance we return (i.e. it could be disposed) - // (b) the palette, flags won't match MS results. See MonoTests.Imaging.IconCodecTest. - // Image16 for the differences - return new Bitmap(GetInternalBitmap()); - } - - public override string ToString() - { - //is this correct, this is what returned by .Net - return ""; - } - - [Browsable(false)] - public IntPtr Handle - { - get - { - // note: this handle doesn't survive the lifespan of the icon instance - if (!disposed && (handle == IntPtr.Zero)) - { - if (Configuration.RunningOnUnix) - { - // Hack: access Mono internals to retrieve the NativeObject handle. - // handle = GetInternalBitmap().NativeObject; - Bitmap bmp = GetInternalBitmap(); - FieldInfo field = bmp.GetType().GetField("NativeObject", - BindingFlags.Instance | BindingFlags.NonPublic); - if (field == null) - throw new NotSupportedException("Internal OpenTK error. Please report this error at http://www.opentk.com/node/add/project-issue, attaching the stacktrace of the exception."); - handle = (IntPtr)field.GetValue(bmp); - } - else - { - // remember that this block executes only with MS GDI+ - IconInfo ii = new IconInfo(); - ii.IsIcon = true; - ii.hbmColor = ToBitmap().GetHbitmap(); - ii.hbmMask = ii.hbmColor; - handle = CreateIconIndirect(ref ii); - } - } - return handle; - } - } - - [Browsable(false)] - public int Height - { - get { return iconSize.Height; } - } - - public Size Size - { - get { return iconSize; } - } - - [Browsable(false)] - public int Width - { - get { return iconSize.Width; } - } - - ~Icon() - { - Dispose(); - } - - private void InitFromStreamWithSize(Stream stream, int width, int height) - { - //read the icon header - if (stream == null || stream.Length == 0) - throw new System.ArgumentException("The argument 'stream' must be a picture that can be used as a Icon", "stream"); - - BinaryReader reader = new BinaryReader(stream); - - //iconDir = new IconDir (); - iconDir.idReserved = reader.ReadUInt16(); - if (iconDir.idReserved != 0) - //must be 0 - throw new System.ArgumentException("Invalid Argument", "stream"); - - iconDir.idType = reader.ReadUInt16(); - if (iconDir.idType != 1) - //must be 1 - throw new System.ArgumentException("Invalid Argument", "stream"); - - ushort dirEntryCount = reader.ReadUInt16(); - ArrayList entries = new ArrayList(dirEntryCount); - bool sizeObtained = false; - // now read in the IconDirEntry structures - for (int i = 0; i < dirEntryCount; i++) - { - IconDirEntry ide; - ide.width = reader.ReadByte(); - ide.height = reader.ReadByte(); - ide.colorCount = reader.ReadByte(); - ide.reserved = reader.ReadByte(); - ide.planes = reader.ReadUInt16(); - ide.bitCount = reader.ReadUInt16(); - ide.bytesInRes = reader.ReadUInt32(); - ide.imageOffset = reader.ReadUInt32(); - #if false - Console.WriteLine("Entry: {0}", i); - Console.WriteLine("\tide.width: {0}", ide.width); - Console.WriteLine("\tide.height: {0}", ide.height); - Console.WriteLine("\tide.colorCount: {0}", ide.colorCount); - Console.WriteLine("\tide.reserved: {0}", ide.reserved); - Console.WriteLine("\tide.planes: {0}", ide.planes); - Console.WriteLine("\tide.bitCount: {0}", ide.bitCount); - Console.WriteLine("\tide.bytesInRes: {0}", ide.bytesInRes); - Console.WriteLine("\tide.imageOffset: {0}", ide.imageOffset); - #endif - - // 256x256 icons are decoded as 0x0 (width and height are encoded as BYTE) - // and we ignore them just like MS does (at least up to fx 2.0) - if ((ide.width == 0) && (ide.height == 0)) - continue; - - int index = entries.Add(ide); - - //is this is the best fit?? - if (!sizeObtained) - { - if ((ide.height == height) || (ide.width == width)) - { - this.id = (ushort)index; - sizeObtained = true; - this.iconSize.Height = ide.height; - this.iconSize.Width = ide.width; - } - } - } - - // Vista 256x256 icons points directly to a PNG bitmap - dirEntryCount = (ushort)entries.Count; - if (dirEntryCount == 0) - throw new Win32Exception(0, "No valid icon entry were found."); - - iconDir.idCount = dirEntryCount; - imageData = new IconImage[dirEntryCount]; - iconDir.idEntries = new IconDirEntry[dirEntryCount]; - entries.CopyTo(iconDir.idEntries); - - //if we havent found the best match, return the one with the - //largest size. Is this approach correct?? - if (!sizeObtained) - { - uint largestSize = 0; - for (int j = 0; j < dirEntryCount; j++) - { - if (iconDir.idEntries[j].bytesInRes >= largestSize) - { - largestSize = iconDir.idEntries[j].bytesInRes; - this.id = (ushort)j; - this.iconSize.Height = iconDir.idEntries[j].height; - this.iconSize.Width = iconDir.idEntries[j].width; - } - } - } - - //now read in the icon data - for (int j = 0; j < dirEntryCount; j++) - { - IconImage iidata = new IconImage(); - BitmapInfoHeader bih = new BitmapInfoHeader(); - stream.Seek(iconDir.idEntries[j].imageOffset, SeekOrigin.Begin); - byte[] buffer = new byte[iconDir.idEntries[j].bytesInRes]; - stream.Read(buffer, 0, buffer.Length); - BinaryReader bihReader = new BinaryReader(new MemoryStream(buffer)); - bih.biSize = bihReader.ReadUInt32(); - bih.biWidth = bihReader.ReadInt32(); - bih.biHeight = bihReader.ReadInt32(); - bih.biPlanes = bihReader.ReadUInt16(); - bih.biBitCount = bihReader.ReadUInt16(); - bih.biCompression = bihReader.ReadUInt32(); - bih.biSizeImage = bihReader.ReadUInt32(); - bih.biXPelsPerMeter = bihReader.ReadInt32(); - bih.biYPelsPerMeter = bihReader.ReadInt32(); - bih.biClrUsed = bihReader.ReadUInt32(); - bih.biClrImportant = bihReader.ReadUInt32(); - #if false - Console.WriteLine("Entry: {0}", j); - Console.WriteLine("\tbih.biSize: {0}", bih.biSize); - Console.WriteLine("\tbih.biWidth: {0}", bih.biWidth); - Console.WriteLine("\tbih.biHeight: {0}", bih.biHeight); - Console.WriteLine("\tbih.biPlanes: {0}", bih.biPlanes); - Console.WriteLine("\tbih.biBitCount: {0}", bih.biBitCount); - Console.WriteLine("\tbih.biCompression: {0}", bih.biCompression); - Console.WriteLine("\tbih.biSizeImage: {0}", bih.biSizeImage); - Console.WriteLine("\tbih.biXPelsPerMeter: {0}", bih.biXPelsPerMeter); - Console.WriteLine("\tbih.biYPelsPerMeter: {0}", bih.biYPelsPerMeter); - Console.WriteLine("\tbih.biClrUsed: {0}", bih.biClrUsed); - Console.WriteLine("\tbih.biClrImportant: {0}", bih.biClrImportant); - #endif - iidata.iconHeader = bih; - //Read the number of colors used and corresponding memory occupied by - //color table. Fill this memory chunk into rgbquad[] - int numColors; - switch (bih.biBitCount) { - case 1: - numColors = 2; - break; - case 4: - numColors = 16; - break; - case 8: - numColors = 256; - break; - default: - numColors = 0; - break; - } - - iidata.iconColors = new uint[numColors]; - for (int i = 0; i < numColors; i++) - iidata.iconColors[i] = bihReader.ReadUInt32(); - - //XOR mask is immediately after ColorTable and its size is - //icon height* no. of bytes per line - - //icon height is half of BITMAPINFOHEADER.biHeight, since it contains - //both XOR as well as AND mask bytes - int iconHeight = bih.biHeight / 2; - - //bytes per line should should be uint aligned - int numBytesPerLine = ((((bih.biWidth * bih.biPlanes * bih.biBitCount) + 31) >> 5) << 2); - - //Determine the XOR array Size - int xorSize = numBytesPerLine * iconHeight; - iidata.iconXOR = new byte[xorSize]; - int nread = bihReader.Read(iidata.iconXOR, 0, xorSize); - if (nread != xorSize) - { - string msg = String.Format("{0} data length expected {1}, read {2}", "XOR", xorSize, nread); - throw new ArgumentException(msg, "stream"); - } - - //Determine the AND array size - numBytesPerLine = (int)((((bih.biWidth) + 31) & ~31) >> 3); - int andSize = numBytesPerLine * iconHeight; - iidata.iconAND = new byte[andSize]; - nread = bihReader.Read(iidata.iconAND, 0, andSize); - if (nread != andSize) - { - string msg = String.Format("{0} data length expected {1}, read {2}", "AND", andSize, nread); - throw new ArgumentException(msg, "stream"); - } - - imageData[j] = iidata; - bihReader.Close(); - } - - reader.Close(); - } - } -#endif -} diff --git a/Source/OpenTK/IconConverter.cs b/Source/OpenTK/IconConverter.cs deleted file mode 100644 index 3d4ffe2a..00000000 --- a/Source/OpenTK/IconConverter.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// System.Drawing.IconConverter.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// Sanjay Gupta (gsanjay@novell.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// 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.ComponentModel; -using System.Globalization; -using System.IO; - -namespace OpenTK -{ -#if EXPERIMENTAL - /// - /// Summary description for IconConverter. - /// - public class IconConverter : ExpandableObjectConverter - { - public IconConverter() - { - } - - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(System.Byte[])) - return true; - else - return false; - } - - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if ((destinationType == typeof(System.Byte[])) || (destinationType == typeof(System.String))) - return true; - else - return false; - } - - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - byte[] bytes = value as byte[]; - if (bytes == null) - return base.ConvertFrom(context, culture, value); - - MemoryStream ms = new MemoryStream(bytes); - - return new Icon(ms); - } - - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if ((value is Icon) && (destinationType == typeof(string))) - return value.ToString(); else if (value == null && destinationType == typeof(string)) - return "(none)"; else if (CanConvertTo(null, destinationType)) - { - //came here means destType is byte array ; - MemoryStream ms = new MemoryStream(); - ((Icon)value).Save(ms); - return ms.GetBuffer(); - } else - return new NotSupportedException("IconConverter can not convert from " + value.GetType()); - } - } -#endif -} diff --git a/Source/OpenTK/Platform/X11/API.cs b/Source/OpenTK/Platform/X11/API.cs index 8be467f9..068934df 100644 --- a/Source/OpenTK/Platform/X11/API.cs +++ b/Source/OpenTK/Platform/X11/API.cs @@ -1590,15 +1590,32 @@ XF86VidModeGetGammaRampSize( } */ + // Helper structure for calling XLock/UnlockDisplay struct XLock : IDisposable { - readonly IntPtr Display; + IntPtr _display; + + public IntPtr Display + { + get + { + if (_display == IntPtr.Zero) + throw new InvalidOperationException("Internal error (XLockDisplay with IntPtr.Zero). Please report this at http://www.opentk.com/node/add/project-issue/opentk"); + return _display; + } + set + { + if (value == IntPtr.Zero) + throw new ArgumentException(); + _display = value; + } + } public XLock(IntPtr display) : this() { - Functions.XLockDisplay(display); Display = display; + Functions.XLockDisplay(Display); } public void Dispose() diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 03ab8d29..67ab8fb8 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -178,7 +178,7 @@ namespace OpenTK.Platform.X11 } driver = new X11Input(window); - + Debug.WriteLine(String.Format("X11GLNative window created successfully (id: {0}).", Handle)); Debug.Unindent(); @@ -280,7 +280,10 @@ namespace OpenTK.Platform.X11 IntPtr dummy; XSizeHints hints = new XSizeHints(); - Functions.XGetWMNormalHints(window.Display, window.WindowHandle, ref hints, out dummy); + using (new XLock(window.Display)) + { + Functions.XGetWMNormalHints(window.Display, window.WindowHandle, ref hints, out dummy); + } if (min_width > 0 || min_height > 0) { @@ -300,13 +303,15 @@ namespace OpenTK.Platform.X11 else hints.flags = (IntPtr)((int)hints.flags & ~(int)XSizeHintsFlags.PMaxSize); - if (hints.flags != IntPtr.Zero) { // The Metacity team has decided that they won't care about this when clicking the maximize // icon, will maximize the window to fill the screen/parent no matter what. // http://bugzilla.ximian.com/show_bug.cgi?id=80021 - Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints); + using (new XLock(window.Display)) + { + Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints); + } } } @@ -325,21 +330,24 @@ namespace OpenTK.Platform.X11 IntPtr prop = IntPtr.Zero; IntPtr atom; //XWindowAttributes attributes; - - Functions.XGetWindowProperty(window.Display, window.WindowHandle, - _atom_net_wm_allowed_actions, IntPtr.Zero, new IntPtr(256), false, - IntPtr.Zero, out actual_atom, out actual_format, out nitems, - out bytes_after, ref prop); - if ((long)nitems > 0 && prop != IntPtr.Zero) + + using (new XLock(window.Display)) { - for (int i = 0; i < (long)nitems; i++) + Functions.XGetWindowProperty(window.Display, window.WindowHandle, + _atom_net_wm_allowed_actions, IntPtr.Zero, new IntPtr(256), false, + IntPtr.Zero, out actual_atom, out actual_format, out nitems, + out bytes_after, ref prop); + if ((long)nitems > 0 && prop != IntPtr.Zero) { - atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size); - - if (atom == _atom_net_wm_action_resize) - return true; + for (int i = 0; i < (long)nitems; i++) + { + atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size); + + if (atom == _atom_net_wm_action_resize) + return true; + } + Functions.XFree(prop); } - Functions.XFree(prop); } return false; @@ -362,24 +370,27 @@ namespace OpenTK.Platform.X11 //IntPtr atom; //XWindowAttributes attributes; - // Test if decorations have been disabled through Motif. - IntPtr motif_hints_atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); - if (motif_hints_atom != IntPtr.Zero) + using (new XLock(window.Display)) { - // TODO: How to check if MotifWMHints decorations have been really disabled? - if (_decorations_hidden) + // Test if decorations have been disabled through Motif. + IntPtr motif_hints_atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); + if (motif_hints_atom != IntPtr.Zero) + { + // TODO: How to check if MotifWMHints decorations have been really disabled? + if (_decorations_hidden) + return true; + } + + // Some WMs remove decorations when the transient_for hint is set. Most new ones do not (but those + // should obey the Motif hint). Anyway, if this hint is set, we say the decorations have been remove + // although there is a slight chance this is not the case. + IntPtr transient_for_parent; + Functions.XGetTransientForHint(window.Display, window.WindowHandle, out transient_for_parent); + if (transient_for_parent != IntPtr.Zero) return true; + + return false; } - - // Some WMs remove decorations when the transient_for hint is set. Most new ones do not (but those - // should obey the Motif hint). Anyway, if this hint is set, we say the decorations have been remove - // although there is a slight chance this is not the case. - IntPtr transient_for_parent; - Functions.XGetTransientForHint(window.Display, window.WindowHandle, out transient_for_parent); - if (transient_for_parent != IntPtr.Zero) - return true; - - return false; } } @@ -395,15 +406,18 @@ namespace OpenTK.Platform.X11 _decorations_hidden = true; } - // Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); - - // Some WMs remove decorations when this hint is set. Doesn't hurt to try. - Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); - - if (_decorations_hidden) + using (new XLock(window.Display)) { - Functions.XUnmapWindow(this.window.Display, this.Handle); - Functions.XMapWindow(this.window.Display, this.Handle); + // Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); + + // Some WMs remove decorations when this hint is set. Doesn't hurt to try. + Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); + + if (_decorations_hidden) + { + Functions.XUnmapWindow(this.window.Display, this.Handle); + Functions.XMapWindow(this.window.Display, this.Handle); + } } } @@ -459,12 +473,15 @@ namespace OpenTK.Platform.X11 //if (EnableGnomeDecorations()) { Debug.Print("Activated decorations through gnome."); activated = true; } - Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero); - - if (!_decorations_hidden) + using (new XLock(window.Display)) { - Functions.XUnmapWindow(this.window.Display, this.Handle); - Functions.XMapWindow(this.window.Display, this.Handle); + Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero); + + if (!_decorations_hidden) + { + Functions.XUnmapWindow(this.window.Display, this.Handle); + Functions.XMapWindow(this.window.Display, this.Handle); + } } } @@ -472,19 +489,22 @@ namespace OpenTK.Platform.X11 bool EnableMotifDecorations() { - IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); - if (atom != IntPtr.Zero) + using (new XLock(window.Display)) { - //Functions.XDeleteProperty(this.window.Display, this.Handle, atom); - MotifWmHints hints = new MotifWmHints(); - hints.flags = (IntPtr)MotifFlags.Decorations; - hints.decorations = (IntPtr)MotifDecorations.All; - Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, - ref hints, Marshal.SizeOf(hints) / IntPtr.Size); - - return true; + IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); + if (atom != IntPtr.Zero) + { + //Functions.XDeleteProperty(this.window.Display, this.Handle, atom); + MotifWmHints hints = new MotifWmHints(); + hints.flags = (IntPtr)MotifFlags.Decorations; + hints.decorations = (IntPtr)MotifDecorations.All; + Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, + ref hints, Marshal.SizeOf(hints) / IntPtr.Size); + + return true; + } + return false; } - return false; } #endregion @@ -493,23 +513,26 @@ namespace OpenTK.Platform.X11 bool EnableGnomeDecorations() { - // Restore window layer. - //XEvent xev = new XEvent(); - //xev.ClientMessageEvent.window = this.window.Handle; - //xev.ClientMessageEvent.type = XEventName.ClientMessage; - //xev.ClientMessageEvent.message_type = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_LAYER, false); - //xev.ClientMessageEvent.format = 32; - //xev.ClientMessageEvent.ptr1 = (IntPtr)WindowLayer.AboveDock; - //Functions.XSendEvent(this.window.Display, this.window.RootWindow, false, (IntPtr)EventMask.SubstructureNotifyMask, ref xev); - - IntPtr atom = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_HINTS, true); - if (atom != IntPtr.Zero) + using (new XLock(window.Display)) { - Functions.XDeleteProperty(this.window.Display, this.Handle, atom); - return true; + // Restore window layer. + //XEvent xev = new XEvent(); + //xev.ClientMessageEvent.window = this.window.Handle; + //xev.ClientMessageEvent.type = XEventName.ClientMessage; + //xev.ClientMessageEvent.message_type = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_LAYER, false); + //xev.ClientMessageEvent.format = 32; + //xev.ClientMessageEvent.ptr1 = (IntPtr)WindowLayer.AboveDock; + //Functions.XSendEvent(this.window.Display, this.window.RootWindow, false, (IntPtr)EventMask.SubstructureNotifyMask, ref xev); + + IntPtr atom = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_HINTS, true); + if (atom != IntPtr.Zero) + { + Functions.XDeleteProperty(this.window.Display, this.Handle, atom); + return true; + } + + return false; } - - return false; } #endregion @@ -520,27 +543,30 @@ namespace OpenTK.Platform.X11 static void DeleteIconPixmaps(IntPtr display, IntPtr window) { - IntPtr wmHints_ptr = Functions.XGetWMHints(display, window); - - if (wmHints_ptr != IntPtr.Zero) + using (new XLock(display)) { - XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints)); - XWMHintsFlags flags = (XWMHintsFlags)wmHints.flags.ToInt32(); - - if ((flags & XWMHintsFlags.IconPixmapHint) != 0) + IntPtr wmHints_ptr = Functions.XGetWMHints(display, window); + + if (wmHints_ptr != IntPtr.Zero) { - wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconPixmapHint)); - Functions.XFreePixmap(display, wmHints.icon_pixmap); + XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints)); + XWMHintsFlags flags = (XWMHintsFlags)wmHints.flags.ToInt32(); + + if ((flags & XWMHintsFlags.IconPixmapHint) != 0) + { + wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconPixmapHint)); + Functions.XFreePixmap(display, wmHints.icon_pixmap); + } + + if ((flags & XWMHintsFlags.IconMaskHint) != 0) + { + wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconMaskHint)); + Functions.XFreePixmap(display, wmHints.icon_mask); + } + + Functions.XSetWMHints(display, window, ref wmHints); + Functions.XFree(wmHints_ptr); } - - if ((flags & XWMHintsFlags.IconMaskHint) != 0) - { - wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconMaskHint)); - Functions.XFreePixmap(display, wmHints.icon_mask); - } - - Functions.XSetWMHints(display, window, ref wmHints); - Functions.XFree(wmHints_ptr); } } @@ -863,8 +889,11 @@ namespace OpenTK.Platform.X11 // For this reason, we'll also set the icon using XSetWMHints. if (value == null) { - Functions.XDeleteProperty(window.Display, window.WindowHandle, _atom_net_wm_icon); - DeleteIconPixmaps(window.Display, window.WindowHandle); + using (new XLock(window.Display)) + { + Functions.XDeleteProperty(window.Display, window.WindowHandle, _atom_net_wm_icon); + DeleteIconPixmaps(window.Display, window.WindowHandle); + } } else { @@ -880,28 +909,34 @@ namespace OpenTK.Platform.X11 for (int y = 0; y < bitmap.Height; y++) for (int x = 0; x < bitmap.Width; x++) data[index++] = (IntPtr)bitmap.GetPixel(x, y).ToArgb(); - - Functions.XChangeProperty(window.Display, window.WindowHandle, - _atom_net_wm_icon, _atom_xa_cardinal, 32, - PropertyMode.Replace, data, size); + + using (new XLock(window.Display)) + { + Functions.XChangeProperty(window.Display, window.WindowHandle, + _atom_net_wm_icon, _atom_xa_cardinal, 32, + PropertyMode.Replace, data, size); + } // Set XWMHints DeleteIconPixmaps(window.Display, window.WindowHandle); - IntPtr wmHints_ptr = Functions.XGetWMHints(window.Display, window.WindowHandle); - - if (wmHints_ptr == IntPtr.Zero) - wmHints_ptr = Functions.XAllocWMHints(); - - XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints)); - - wmHints.flags = new IntPtr(wmHints.flags.ToInt32() | (int)(XWMHintsFlags.IconPixmapHint | XWMHintsFlags.IconMaskHint)); - wmHints.icon_pixmap = Functions.CreatePixmapFromImage(window.Display, bitmap); - wmHints.icon_mask = Functions.CreateMaskFromImage(window.Display, bitmap); - - Functions.XSetWMHints(window.Display, window.WindowHandle, ref wmHints); - Functions.XFree (wmHints_ptr); - - Functions.XSync(window.Display, false); + using (new XLock(window.Display)) + { + IntPtr wmHints_ptr = Functions.XGetWMHints(window.Display, window.WindowHandle); + + if (wmHints_ptr == IntPtr.Zero) + wmHints_ptr = Functions.XAllocWMHints(); + + XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints)); + + wmHints.flags = new IntPtr(wmHints.flags.ToInt32() | (int)(XWMHintsFlags.IconPixmapHint | XWMHintsFlags.IconMaskHint)); + wmHints.icon_pixmap = Functions.CreatePixmapFromImage(window.Display, bitmap); + wmHints.icon_mask = Functions.CreateMaskFromImage(window.Display, bitmap); + + Functions.XSetWMHints(window.Display, window.WindowHandle, ref wmHints); + Functions.XFree (wmHints_ptr); + + Functions.XSync(window.Display, false); + } } icon = value; @@ -941,9 +976,12 @@ namespace OpenTK.Platform.X11 int maximized = 0; bool minimized = false; - Functions.XGetWindowProperty(window.Display, window.WindowHandle, - _atom_net_wm_state, IntPtr.Zero, new IntPtr(256), false, - IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop); + using (new XLock(window.Display)) + { + Functions.XGetWindowProperty(window.Display, window.WindowHandle, + _atom_net_wm_state, IntPtr.Zero, new IntPtr(256), false, + IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop); + } if ((long)nitems > 0 && prop != IntPtr.Zero) { @@ -959,7 +997,10 @@ namespace OpenTK.Platform.X11 else if (atom == _atom_net_wm_state_fullscreen) fullscreen = true; } - Functions.XFree(prop); + using (new XLock(window.Display)) + { + Functions.XFree(prop); + } } if (minimized) @@ -986,19 +1027,21 @@ namespace OpenTK.Platform.X11 Debug.Print("GameWindow {0} changing WindowState from {1} to {2}.", window.WindowHandle.ToString(), current_state.ToString(), value.ToString()); - if (current_state == OpenTK.WindowState.Minimized) - Functions.XMapWindow(window.Display, window.WindowHandle); - else if (current_state == OpenTK.WindowState.Fullscreen) - Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_remove, - _atom_net_wm_state_fullscreen, - IntPtr.Zero); - else if (current_state == OpenTK.WindowState.Maximized) - Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_toggle, - _atom_net_wm_state_maximized_horizontal, - _atom_net_wm_state_maximized_vertical); - - Functions.XSync(window.Display, false); - + using (new XLock(window.Display)) + { + if (current_state == OpenTK.WindowState.Minimized) + Functions.XMapWindow(window.Display, window.WindowHandle); + else if (current_state == OpenTK.WindowState.Fullscreen) + Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_remove, + _atom_net_wm_state_fullscreen, + IntPtr.Zero); + else if (current_state == OpenTK.WindowState.Maximized) + Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_toggle, + _atom_net_wm_state_maximized_horizontal, + _atom_net_wm_state_maximized_vertical); + + Functions.XSync(window.Display, false); + } // We can't resize the window if its border is fixed, so make it resizable first. bool temporary_resizable = false; WindowBorder previous_state = WindowBorder; @@ -1008,35 +1051,38 @@ namespace OpenTK.Platform.X11 WindowBorder = WindowBorder.Resizable; } - switch (value) + using (new XLock(window.Display)) { - case OpenTK.WindowState.Normal: - Functions.XRaiseWindow(window.Display, window.WindowHandle); - - break; - - case OpenTK.WindowState.Maximized: - Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, - _atom_net_wm_state_maximized_horizontal, - _atom_net_wm_state_maximized_vertical); - Functions.XRaiseWindow(window.Display, window.WindowHandle); - - break; - - case OpenTK.WindowState.Minimized: - // Todo: multiscreen support - Functions.XIconifyWindow(window.Display, window.WindowHandle, window.Screen); - - break; - - case OpenTK.WindowState.Fullscreen: - //_previous_window_border = this.WindowBorder; - //this.WindowBorder = WindowBorder.Hidden; - Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, - _atom_net_wm_state_fullscreen, IntPtr.Zero); - Functions.XRaiseWindow(window.Display, window.WindowHandle); - - break; + switch (value) + { + case OpenTK.WindowState.Normal: + Functions.XRaiseWindow(window.Display, window.WindowHandle); + + break; + + case OpenTK.WindowState.Maximized: + Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, + _atom_net_wm_state_maximized_horizontal, + _atom_net_wm_state_maximized_vertical); + Functions.XRaiseWindow(window.Display, window.WindowHandle); + + break; + + case OpenTK.WindowState.Minimized: + // Todo: multiscreen support + Functions.XIconifyWindow(window.Display, window.WindowHandle, window.Screen); + + break; + + case OpenTK.WindowState.Fullscreen: + //_previous_window_border = this.WindowBorder; + //this.WindowBorder = WindowBorder.Hidden; + Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, + _atom_net_wm_state_fullscreen, IntPtr.Zero); + Functions.XRaiseWindow(window.Display, window.WindowHandle); + + break; + } } if (temporary_resizable) diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs index a0d597b2..8f7ecae2 100644 --- a/Source/OpenTK/Platform/X11/X11Input.cs +++ b/Source/OpenTK/Platform/X11/X11Input.cs @@ -53,7 +53,7 @@ namespace OpenTK.Platform.X11 //window = new X11WindowInfo(attach); X11WindowInfo window = (X11WindowInfo)attach; - + // Init mouse mouse.Description = "Default X11 mouse"; mouse.DeviceID = IntPtr.Zero;