diff --git a/Build.exe b/Build.exe
index 3f3425d0..706254cc 100644
Binary files a/Build.exe and b/Build.exe differ
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;
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
-}