From 2870532c78e6a9e19428de583ba883b2bfa45fe1 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 20:14:14 +0000 Subject: [PATCH 1/5] 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; From 42a0200cc66933ecbfa3360ea7023af5bad8ebeb Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 22:41:38 +0000 Subject: [PATCH 2/5] Updated ignore rules. From 5fdf830e2c0595af13302b03ffda22fe0674d087 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 22:42:54 +0000 Subject: [PATCH 3/5] Updated ignore rules. From 4e191bc9285fb55eb8b4c9a9817ed972d7bf2c66 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 23:39:27 +0000 Subject: [PATCH 4/5] Fixed keyfile handling in Visual Studio. --- Build.exe | Bin 270336 -> 270336 bytes Source/Build/Build.cs | 145 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 117 insertions(+), 28 deletions(-) diff --git a/Build.exe b/Build.exe index 3f3425d04aadcb22c570d5fdb0ab10ed34045e4c..706254cc03286d1fded44d24fdc7f7b7fe7db18d 100644 GIT binary patch delta 5847 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 LX!<%OLL+mJ delta 4707 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 diff --git a/Source/Build/Build.cs b/Source/Build/Build.cs index 77ea9ef4..c6a5d18f 100644 --- a/Source/Build/Build.cs +++ b/Source/Build/Build.cs @@ -21,13 +21,14 @@ namespace OpenTK.Build { class Project { - static string RootPath; + static string RootPath = Directory.GetCurrentDirectory(); + static string SourcePath = Path.Combine(RootPath, "Source"); const string bindings = "Generator.Prebuild.xml"; const string opentk = "OpenTK.Prebuild.xml"; const string quickstart = "QuickStart.Prebuild.xml"; - const string keyfile = "OpenTK.snk"; + const string keyfile = "OpenTK.snk"; // Do not change const string Usage = @"Usage: Build.exe target target: one of vs, vs9, clean, distclean, help"; @@ -52,6 +53,7 @@ Assembly signing: enum BuildTarget { + None = 0, VS2005, VS2008, Mono, @@ -60,8 +62,6 @@ Assembly signing: DistClean, } - static BuildTarget target = BuildTarget.VS2005; - static void PrintUsage() { Console.WriteLine(Usage); @@ -85,18 +85,61 @@ Assembly signing: args[0] = "vs"; } - RootPath = Directory.GetCurrentDirectory(); + try + { + PreparePrebuildFiles(); + PrepareEnvironment(); - //string sign_assembly = CheckKeyFile(keyfile) ? "SIGN_ASSEMBLY" : ""; - string sign_assembly = CheckKeyFile(keyfile) ? @"../../" + keyfile + @"" : ""; + BuildTarget target = SelectTarget(args); + if (target != BuildTarget.None) + { + Build(target); + foreach (string file in Directory.GetFiles("Source", "*.csproj", SearchOption.AllDirectories)) + ApplyMonoDevelopWorkarounds(file); + } + } + finally + { + // Wait until Prebuild releases the input files. + System.Threading.Thread.Sleep(2000); + DeletePrebuildFiles(); + } - File.WriteAllText(bindings, String.Format(Resources.Generator, sign_assembly)); - File.WriteAllText(opentk, String.Format(Resources.OpenTK, sign_assembly)); - File.WriteAllText(quickstart, String.Format(Resources.QuickStart,sign_assembly)); + WaitForExit(); + } + private static void PrepareEnvironment() + { // Workaroung for nant on x64 windows (safe for other platforms too, as this affects only the current process). Environment.SetEnvironmentVariable("CommonProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("ProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process); + } + + private static void PreparePrebuildFiles() + { + //string sign_assembly = CheckKeyFile(keyfile) ? "SIGN_ASSEMBLY" : ""; + string sign_assembly = CheckKeyFile(keyfile) ? @"" + keyfile + @"" : ""; + if (sign_assembly != "") + DistributeKeyFile(keyfile); + + File.WriteAllText(bindings, String.Format(Resources.Generator, sign_assembly)); + File.WriteAllText(opentk, String.Format(Resources.OpenTK, sign_assembly)); + File.WriteAllText(quickstart, String.Format(Resources.QuickStart, sign_assembly)); + } + + // Copies keyfile to the various source directories. This is necessary + // as Visual Studio won't pick up the file otherwise. + static void DistributeKeyFile(string keyfile) + { + foreach (string dir in Directory.GetDirectories("Source")) + { + File.Copy(keyfile, Path.Combine(dir, keyfile), true); + } + } + + static BuildTarget SelectTarget(string[] args) + { + BuildTarget target = BuildTarget.None; foreach (string s in args) { @@ -108,7 +151,7 @@ Assembly signing: case "help": PrintHelp(); - return; + break; case "mono": case "xbuild": @@ -142,10 +185,15 @@ Assembly signing: default: Console.WriteLine("Unknown command: {0}", s); PrintUsage(); - return; + break; } } + return target; + } + + static void Build(BuildTarget target) + { switch (target) { //case BuildTarget.Mono: @@ -181,22 +229,24 @@ Assembly signing: ExecutePrebuild("/target", "vs2008", "/file", opentk); ExecutePrebuild("/target", "vs2008", "/file", quickstart); break; - + case BuildTarget.Clean: Console.WriteLine("Cleaning intermediate object files."); ExecutePrebuild("/clean", "/yes", "/file", bindings); ExecutePrebuild("/clean", "/yes", "/file", opentk); ExecutePrebuild("/clean", "/yes", "/file", quickstart); DeleteDirectories(RootPath, "obj"); + DeleteFiles(SourcePath, keyfile); break; case BuildTarget.DistClean: Console.WriteLine("Cleaning intermediate and final object files."); ExecutePrebuild("/clean", "/yes", "/file", bindings); ExecutePrebuild("/clean", "/yes", "/file", opentk); - ExecutePrebuild("/clean", "/yes", "/file", quickstart); + ExecutePrebuild("/clean", "/yes", "/file", quickstart); DeleteDirectories(RootPath, "obj"); DeleteDirectories(RootPath, "bin"); + DeleteFiles(SourcePath, keyfile); string binaries_path = Path.Combine(RootPath, "Binaries"); if (Directory.Exists(binaries_path)) @@ -207,19 +257,12 @@ Assembly signing: default: Console.WriteLine("Unknown target: {0}", target); PrintUsage(); - return; + break; } + } - // Wait until Prebuild releases the input files. - System.Threading.Thread.Sleep(1000); - - File.Delete(bindings); - File.Delete(opentk); - File.Delete(quickstart); - - foreach (string file in Directory.GetFiles("Source", "*.csproj", SearchOption.AllDirectories)) - ApplyMonoDevelopWorkarounds(file); - + static void WaitForExit() + { if (Debugger.IsAttached) { Console.WriteLine("Press any key to continue..."); @@ -227,11 +270,27 @@ Assembly signing: } } + static void DeletePrebuildFiles() + { + try + { + File.Delete(bindings); + File.Delete(opentk); + File.Delete(quickstart); + } + catch (IOException e) + { + Console.WriteLine("[Warning] Failed to delete prebuild files, error follows:"); + Console.WriteLine(e.ToString()); + } + } + static void ApplyMonoDevelopWorkarounds(string solution) { - File.WriteAllText(solution, File.ReadAllText(solution) - .Replace("AssemblyOriginatorKeyFile", "AssemblyKeyFile")); - //.Replace(@"..\", @"../")); // Causes problems in visual studio + // Both workarounds cause problems in visual studio... + //File.WriteAllText(solution, File.ReadAllText(solution) + // .Replace("AssemblyOriginatorKeyFile", "AssemblyKeyFile")); + // .Replace(@"..\", @"../")); } static void DeleteDirectories(string root_path, string search) @@ -245,6 +304,17 @@ Assembly signing: } } + static void DeleteFiles(string root_path, string search) + { + Console.WriteLine("Deleting {0} files", search); + List matches = new List(); + FindDirectories(root_path, search, matches); + foreach (string m in matches) + { + File.Delete(m); + } + } + static void FindDirectories(string directory, string search, List matches) { try @@ -264,6 +334,25 @@ Assembly signing: } } + static void FindFiles(string directory, string search, List matches) + { + try + { + foreach (string d in Directory.GetDirectories(directory)) + { + foreach (string f in Directory.GetFiles(d, search)) + { + matches.Add(f); + } + FindFiles(d, search, matches); + } + } + catch (System.Exception e) + { + Console.WriteLine(e.Message); + } + } + static void FileCopy(string srcdir, string destdir, Regex match) { //DirectoryInfo dir; From 6ed8474797427e97fb10ba1aac0a52f3d35beddf Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Mon, 9 Nov 2009 23:40:57 +0000 Subject: [PATCH 5/5] Added keyfiles to ignore list.