2007-02-28 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Drawing / System.Drawing / gdipFunctions.cs
index 62c68bec94a53d5a23e0ce6c4b743bcdaa77471d..e58b6cc4a332904ce27cac67bd60de0d246fe0f7 100644 (file)
@@ -6,8 +6,10 @@
 //     Jordi Mas i Hernandez (jordi@ximian.com)
 //     Sanjay Gupta (gsanjay@novell.com)
 //     Ravindra (rkumar@novell.com)
+//     Peter Dennis Bartok (pbartok@novell.com)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004 - 2007 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
@@ -36,19 +38,27 @@ using System.Text;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.Drawing.Text;
+using System.Security;
+#if NET_2_0
+using System.Runtime.InteropServices.ComTypes;
+#else
+using IStream = System.Runtime.InteropServices.UCOMIStream;
+#endif
 
 namespace System.Drawing
 {
        /// <summary>
        /// GDI+ API Functions
        /// </summary>
+       [SuppressUnmanagedCodeSecurity]
        internal class GDIPlus
        {
                public const int FACESIZE = 32;
                public const int LANG_NEUTRAL = 0;
                public static IntPtr Display = IntPtr.Zero;
-               public static bool UseX11Drawable = (Environment.OSVersion.Platform == (PlatformID) 128);
+               public static bool UseX11Drawable;
                public static bool UseQuartzDrawable = (Environment.GetEnvironmentVariable ("MONO_MWF_USE_QUARTZ_BACKEND") != null);
+               public static bool UseCocoaDrawable = (Environment.GetEnvironmentVariable ("MONO_GDIP_USE_COCOA_BACKEND") != null);
 
                #region gdiplus.dll functions
 
@@ -58,25 +68,63 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                static internal extern void GdiplusShutdown(ref ulong token);
                
-               static ulong GdiPlusToken;
+               internal static ulong GdiPlusToken = 0;
 
                static void ProcessExit (object sender, EventArgs e)
-               {                       
-                       GdiplusShutdown (ref GdiPlusToken);
+               {               
+                       // Called all pending objects and claim any pending handle before
+                       // shutting down
+                       GC.Collect ();  
+                       GC.WaitForPendingFinalizers ();
+                       
+                       GdiPlusToken = 0;
 
-                       if (UseX11Drawable && Display != IntPtr.Zero) {
-                               XCloseDisplay (Display);
-                       }
+                       // This causes crashes in MS GDI+ because this call occurs before
+                       // all managed GDI objects are finalized. When they are finalized they call
+                       // into a shutdown GDI+ and we crash.
+                       //GdiplusShutdown (ref GdiPlusToken);
+
+                       // This causes crashes in Mono libgdiplus because this call
+                       // occurs before all managed GDI objects are finalized
+                       // When they are finalized they use the closed display and
+                       // crash
+                       //if (UseX11Drawable && Display != IntPtr.Zero) {
+                       //      XCloseDisplay (Display);
+                       //}
 
                }
 
                static GDIPlus ()
                {
+                       // check for Unix platforms - see FAQ for more details
+                       // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F
+                       int platform = (int) Environment.OSVersion.Platform;
+                       UseX11Drawable = ((platform == 4) || (platform == 128));
+
                        GdiplusStartupInput input = GdiplusStartupInput.MakeGdiplusStartupInput();
                        GdiplusStartupOutput output = GdiplusStartupOutput.MakeGdiplusStartupOutput();
-                       GdiplusStartup (ref GdiPlusToken, ref input, ref output);
+                       try {
+                               GdiplusStartup (ref GdiPlusToken, ref input, ref output);
+                       }
+                       catch (TypeInitializationException) {
+                               Console.Error.WriteLine (
+                                       "* ERROR: Can not initialize GDI+ library\n" +
+                                       "\n" +
+                                       "Please check http://www.mono-project.com/Problem:GDIPlusInit for details");
+                       }
+                       
                        AppDomain.CurrentDomain.ProcessExit += new EventHandler (ProcessExit);
                }
+
+               static public bool RunningOnWindows ()
+               {
+                       return !UseX11Drawable;
+               }
+
+               static public bool RunningOnUnix ()
+               {
+                       return UseX11Drawable;
+               }
                
                // Copies a Ptr to an array of Points and releases the memory
                static public void FromUnManagedMemoryToPointI(IntPtr prt, Point [] pts)
@@ -178,6 +226,12 @@ namespace System.Drawing
                                case Status.WrongState:
                                        throw new ArgumentException ("Properties not set properly.");
 
+                               case Status.FontFamilyNotFound:
+                                       throw new ArgumentException ("FontFamily wasn't found.");
+
+                               case Status.ValueOverflow:
+                                       throw new OverflowException ("Argument out of range.");
+
                                default:
                                        throw new Exception ("Unknown Error.");
                        }
@@ -204,6 +258,9 @@ namespace System.Drawing
                 [DllImport("gdiplus.dll")]
                static internal extern Status GdipCreateRegion (out IntPtr region);
 
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipCreateRegionRgnData (byte[] data, int size, out IntPtr region);
+
                 [DllImport("gdiplus.dll")]
                static internal extern Status GdipDeleteRegion (IntPtr region);
 
@@ -295,7 +352,13 @@ namespace System.Drawing
                
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipFillRegion(IntPtr graphics, IntPtr brush, IntPtr region);
-               
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipGetRegionHRgn (IntPtr region, IntPtr graphics, ref IntPtr hRgn);
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipCreateRegionHrgn (IntPtr hRgn, out IntPtr region);
+
                // Solid brush functions
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipCreateSolidFill (int color, out IntPtr brush);
@@ -545,7 +608,7 @@ namespace System.Drawing
                [DllImport("gdiplus.dll", CharSet=CharSet.Unicode)]
                static internal extern Status GdipDrawString (IntPtr graphics, string text, int len, IntPtr font, ref RectangleF rc, IntPtr format, IntPtr brush);
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipGetDC (IntPtr graphics, out int hdc);
+               static internal extern Status GdipGetDC (IntPtr graphics, out IntPtr hdc);
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipReleaseDC (IntPtr graphics, IntPtr hdc);
                [DllImport("gdiplus.dll")]
@@ -601,7 +664,7 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]      
                internal static extern Status GdipResetClip(IntPtr graphics);           
                [DllImport("gdiplus.dll")]      
-               internal static extern Status GdipEndContainer(IntPtr graphics, int state);
+               internal static extern Status GdipEndContainer(IntPtr graphics, uint state);
                [DllImport("gdiplus.dll")]      
                internal static extern Status GdipGetClip (IntPtr graphics, IntPtr region);
 
@@ -711,6 +774,11 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]                   
                internal static extern Status GdipFlush(IntPtr graphics, FlushIntention intention);
 
+               [DllImport("gdiplus.dll", CharSet=CharSet.Unicode)]
+               internal static extern Status GdipAddPathString (IntPtr path, string s, int lenght, IntPtr family, int style, float emSize, ref RectangleF layoutRect, IntPtr format);
+               [DllImport("gdiplus.dll", CharSet=CharSet.Unicode)]
+               internal static extern Status GdipAddPathStringI (IntPtr path, string s, int lenght, IntPtr family, int style, float emSize, ref Rectangle layoutRect, IntPtr format);
+
                                
                // Pen functions
                [DllImport("gdiplus.dll")]
@@ -881,16 +949,11 @@ namespace System.Drawing
                internal static extern Status GdipCreateBitmapFromGraphics (int width, int height, IntPtr target, out IntPtr bitmap);
 
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipBitmapLockBits (IntPtr bmp, ref Rectangle rc, ImageLockMode flags, PixelFormat format, [In, Out] IntPtr bmpData);
+               internal static extern Status GdipBitmapLockBits (IntPtr bmp, ref Rectangle rc, ImageLockMode flags, PixelFormat format, [In, Out] BitmapData bmpData);
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipBitmapSetResolution(IntPtr bmp, float xdpi, float ydpi);
-
-               
-               // This an internal GDIPlus Cairo function, not part GDIPlus interface
-               //[DllImport("gdiplus.dll")]
-               //(internal static extern Status ____BitmapLockBits (IntPtr bmp, ref GpRect  rc, ImageLockMode flags, PixelFormat format, ref int width, ref int height, ref int stride, ref int format2, ref int reserved, ref IntPtr scan0);
-               
+                               
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipBitmapUnlockBits (IntPtr bmp, [In,Out] BitmapData bmpData);
                
@@ -903,7 +966,16 @@ namespace System.Drawing
                // Image functions
                [DllImport("gdiplus.dll", CharSet=CharSet.Auto)]
                internal static extern Status GdipLoadImageFromFile ( [MarshalAs(UnmanagedType.LPWStr)] string filename, out IntPtr image );
-               
+
+#if !TEST
+               // Stream functions for Win32 (original Win32 ones)
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipLoadImageFromStream([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, out IntPtr image);
+               
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipSaveImageToStream(HandleRef image, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, [In()] ref Guid clsidEncoder, HandleRef encoderParams);
+#endif                 
+                               
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipCloneImage(IntPtr image, out IntPtr imageclone);
  
@@ -919,6 +991,9 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetImageFlags(IntPtr image, out int flag);
 
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetImageType (IntPtr image, out ImageType type);
+
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipImageGetFrameDimensionsCount ( IntPtr image, out uint count );
                                                                                                   
@@ -926,7 +1001,7 @@ namespace System.Drawing
                internal static extern Status GdipImageGetFrameDimensionsList ( IntPtr image, [Out] Guid [] dimensionIDs, uint count );
  
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipGetImageHeight (IntPtr image, out int height);
+               internal static extern Status GdipGetImageHeight (IntPtr image, out uint height);
                                                                                                   
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetImageHorizontalResolution ( IntPtr image, out float resolution );
@@ -965,7 +1040,7 @@ namespace System.Drawing
                internal static extern Status GdipGetImageVerticalResolution ( IntPtr image, out float resolution );
                
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipGetImageWidth ( IntPtr image, out int width);
+               internal static extern Status GdipGetImageWidth (IntPtr image, out uint width);
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetImageBounds ( IntPtr image, out RectangleF source, ref GraphicsUnit unit );
@@ -977,7 +1052,7 @@ namespace System.Drawing
                internal static extern Status GdipGetEncoderParameterList ( IntPtr image, ref Guid encoder, uint size, IntPtr buffer );
                
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipImageGetFrameCount (IntPtr image, ref Guid guidDimension, out int count );
+               internal static extern Status GdipImageGetFrameCount (IntPtr image, ref Guid guidDimension, out uint count );
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipImageSelectActiveFrame (IntPtr image, ref Guid guidDimension, int frameIndex);
@@ -1015,16 +1090,13 @@ namespace System.Drawing
                internal static extern Status GdipGetImageGraphicsContext (IntPtr image, out IntPtr graphics);          
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipDrawImage (IntPtr graphics, IntPtr image, float x, float y);
-               [DllImport("gdiplus.dll")]      
-               internal static extern Status GdipBeginContainer (IntPtr graphics,  RectangleF dstrect,
-                   RectangleF srcrect, GraphicsUnit unit, out int  state);
 
-               [DllImport("gdiplus.dll")]      
-               internal static extern Status GdipBeginContainerI (IntPtr graphics, Rectangle dstrect,
-                    Rectangle srcrect, GraphicsUnit unit, out int state);
-
-               [DllImport("gdiplus.dll")]      
-               internal static extern Status GdipBeginContainer2 (IntPtr graphics, out int state); 
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipBeginContainer (IntPtr graphics, ref RectangleF dstrect, ref RectangleF srcrect, GraphicsUnit unit, out uint state);
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipBeginContainerI (IntPtr graphics, ref Rectangle dstrect, ref Rectangle srcrect, GraphicsUnit unit, out uint state);
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipBeginContainer2 (IntPtr graphics, out uint state); 
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipDrawImagePoints (IntPtr graphics, IntPtr image, PointF [] destPoints, int count);
@@ -1071,6 +1143,12 @@ namespace System.Drawing
                
                [DllImport("gdiplus.dll")]              
                internal static extern Status GdipCreateHBITMAPFromBitmap (IntPtr bmp, out IntPtr HandleBmp, int clrbackground);
+
+               [DllImport("gdiplus.dll", CharSet=CharSet.Auto)]
+               internal static extern Status GdipCreateBitmapFromFile ([MarshalAs (UnmanagedType.LPWStr)] string filename, out IntPtr bitmap);
+
+               [DllImport("gdiplus.dll", CharSet=CharSet.Auto)]
+               internal static extern Status GdipCreateBitmapFromFileICM ([MarshalAs (UnmanagedType.LPWStr)] string filename, out IntPtr bitmap);
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipCreateHICONFromBitmap (IntPtr bmp, out IntPtr HandleIcon);
@@ -1088,9 +1166,9 @@ namespace System.Drawing
                 [DllImport ("gdiplus.dll")]
                 internal static extern Status GdipCreateMatrix2 (float m11, float m12, float m21, float m22, float dx, float dy, out IntPtr matrix);
                 [DllImport ("gdiplus.dll")]
-                internal static extern Status GdipCreateMatrix3 (RectangleF rect, PointF [] dstplg, out IntPtr matrix);
+                internal static extern Status GdipCreateMatrix3 (ref RectangleF rect, PointF [] dstplg, out IntPtr matrix);
                 [DllImport ("gdiplus.dll")]                
-                internal static extern Status GdipCreateMatrix3I (Rectangle rect, Point [] dstplg, out IntPtr matrix);
+                internal static extern Status GdipCreateMatrix3I (ref Rectangle rect, Point [] dstplg, out IntPtr matrix);
                 [DllImport ("gdiplus.dll")]
                 internal static extern Status GdipDeleteMatrix (IntPtr matrix);
 
@@ -1171,6 +1249,10 @@ namespace System.Drawing
                 internal static extern Status GdipGetPathLastPoint (IntPtr path, out PointF lastPoint);
                 [DllImport ("gdiplus.dll")]                                                
                 internal static extern Status GdipAddPathLine (IntPtr path, float x1, float y1, float x2, float y2);
+                [DllImport ("gdiplus.dll")]
+                internal static extern Status GdipAddPathLine2 (IntPtr path, PointF[] points, int count);
+                [DllImport ("gdiplus.dll")]
+                internal static extern Status GdipAddPathLine2I (IntPtr path, Point[] points, int count);
                 [DllImport ("gdiplus.dll")]                                                
                 internal static extern Status GdipAddPathArc (IntPtr path, float x, float y, float width, float height, float startAngle, float sweepAngle);
                 [DllImport ("gdiplus.dll")]                                                                
@@ -1249,9 +1331,9 @@ namespace System.Drawing
                 [DllImport ("gdiplus.dll")]                
                 internal static extern Status GdipIsVisiblePathPointI (IntPtr path, int x, int y, IntPtr graphics, out bool result); 
                 [DllImport ("gdiplus.dll")]                
-                internal static extern Status GdipIsOutlineVisiblePathPoint (IntPtr path, float x, float y, IntPtr graphics, out bool result);
+                internal static extern Status GdipIsOutlineVisiblePathPoint (IntPtr path, float x, float y, IntPtr pen, IntPtr graphics, out bool result);
                 [DllImport ("gdiplus.dll")]                
-                internal static extern Status GdipIsOutlineVisiblePathPointI (IntPtr path, int x, int y, IntPtr graphics, out bool result); 
+                internal static extern Status GdipIsOutlineVisiblePathPointI (IntPtr path, int x, int y, IntPtr pen, IntPtr graphics, out bool result); 
 
                // GraphicsPathIterator
                [DllImport("gdiplus.dll")]
@@ -1294,8 +1376,8 @@ namespace System.Drawing
                                
                 [DllImport ("gdiplus.dll")]     
                 internal static extern Status GdipSetImageAttributesColorMatrix (IntPtr imageattr,
-                                ColorAdjustType type, bool enableFlag, ColorMatrix colorMatrix,
-                                ColorMatrix grayMatrix,  ColorMatrixFlag flags);                                
+                                ColorAdjustType type, bool enableFlag, IntPtr colorMatrix,
+                                IntPtr grayMatrix,  ColorMatrixFlag flags);                                
 
                [DllImport ("gdiplus.dll")]     
                internal static extern Status GdipSetImageAttributesGamma (IntPtr imageattr, 
@@ -1339,29 +1421,45 @@ namespace System.Drawing
                internal static extern Status GdipCreateFont (IntPtr fontFamily, float emSize, FontStyle style, GraphicsUnit  unit,  out IntPtr font);
                [DllImport("gdiplus.dll")]                   
                internal static extern Status GdipDeleteFont (IntPtr font);             
-               [DllImport("gdiplus.dll")]                   
-               internal static extern Status GdipGetLogFontA(IntPtr font, IntPtr graphics, ref LOGFONTA logfontA);
+               [DllImport("gdiplus.dll", CharSet=CharSet.Auto)]
+               internal static extern Status GdipGetLogFont(IntPtr font, IntPtr graphics, [MarshalAs(UnmanagedType.AsAny), Out] object logfontA);
+
                [DllImport("gdiplus.dll")]                   
                internal static extern Status GdipCreateFontFromDC(IntPtr hdc, out IntPtr font);
-               [DllImport("gdiplus.dll", SetLastError=true)]
-               internal static extern Status GdipCreateFontFromLogfontA(IntPtr hdc, ref LOGFONTA lf, out IntPtr ptr);
+               [DllImport("gdiplus.dll", SetLastError=true, CharSet=CharSet.Auto)]
+               internal static extern Status GdipCreateFontFromLogfont(IntPtr hdc, ref LOGFONT lf, out IntPtr ptr);
 
                // These are our private functions, they exists in our own libgdiplus library, this way we
                // avoid relying on wine in System.Drawing
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetHfont (IntPtr font, out IntPtr Hfont);     
-               [DllImport("gdiplus.dll")]                   
-               internal static extern Status GdipCreateFontFromHfont(IntPtr hdc, out IntPtr font, ref LOGFONTA lf);
+               [DllImport("gdiplus.dll", CharSet=CharSet.Ansi)]                   
+               internal static extern Status GdipCreateFontFromHfont(IntPtr hdc, out IntPtr font, ref LOGFONT lf);
 
                // This is win32/gdi, not gdiplus, but it's easier to keep in here, also see above comment
-               [DllImport("gdi32.dll", EntryPoint="CreateFontIndirectA", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
-               internal static extern IntPtr CreateFontIndirectA (ref LOGFONTA logfontA);      
+               [DllImport("gdi32.dll", CallingConvention=CallingConvention.StdCall, CharSet = CharSet.Auto)]
+               internal static extern IntPtr CreateFontIndirect (ref LOGFONT logfont); 
                [DllImport("user32.dll", EntryPoint="GetDC", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
                internal static extern IntPtr GetDC(IntPtr hwnd);       
                [DllImport("user32.dll", EntryPoint="ReleaseDC", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
-               internal static extern int ReleaseDC(IntPtr hdc);
+               internal static extern int ReleaseDC (IntPtr hWnd, IntPtr hDC);
                [DllImport("gdi32.dll", EntryPoint="SelectObject", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
                internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj);     
+               [DllImport("user32.dll", SetLastError=true)]
+               internal 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);
+               [DllImport("gdi32.dll")]
+               internal static extern bool DeleteObject (IntPtr hObject);
+               [DllImport("user32.dll")]
+               internal static extern IntPtr GetDesktopWindow ();
+
+               [DllImport("gdi32.dll", SetLastError=true)]
+               public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, 
+                       int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
+
 
                // Some special X11 stuff
                [DllImport("libX11", EntryPoint="XOpenDisplay")]
@@ -1370,12 +1468,39 @@ namespace System.Drawing
                [DllImport("libX11", EntryPoint="XCloseDisplay")]
                internal extern static int XCloseDisplay(IntPtr display);       
 
+               [DllImport ("libX11", EntryPoint="XRootWindow")]
+               internal extern static IntPtr XRootWindow(IntPtr display, int screen);
+                       
+               [DllImport ("libX11", EntryPoint="XDefaultDepth")]
+               internal extern static uint XDefaultDepth(IntPtr display, int screen);
+
+               [DllImport ("libX11", EntryPoint="XGetImage")]
+               internal extern static IntPtr XGetImage(IntPtr display, IntPtr drawable, int src_x, int src_y, int width, int height, int pane, int format);
+
+               [DllImport ("libX11", EntryPoint="XGetPixel")]
+               internal extern static int XGetPixel(IntPtr image, int x, int y);
+
+               [DllImport ("libX11", EntryPoint="XDestroyImage")]
+               internal extern static int XDestroyImage(IntPtr image);
+
+               [DllImport ("libX11", EntryPoint="XDefaultVisual")]
+               internal extern static IntPtr XDefaultVisual(IntPtr display, int screen);
+
+               [DllImport ("libX11", EntryPoint="XGetVisualInfo")]
+               internal extern static IntPtr XGetVisualInfo (IntPtr display, int vinfo_mask, ref XVisualInfo vinfo_template, ref int nitems);
+
+               [DllImport ("libX11", EntryPoint="XVisualIDFromVisual")]
+               internal extern static int XVisualIDFromVisual(IntPtr visual);
+
+               [DllImport ("libX11", EntryPoint="XFree")]
+               internal extern static void XFree (IntPtr data);        
+               
                // FontCollection
                [DllImport ("gdiplus.dll")]
                internal static extern Status GdipGetFontCollectionFamilyCount (IntPtr collection, out int found);
                
                [DllImport ("gdiplus.dll")]
-               internal static extern Status GdipGetFontCollectionFamilyList (IntPtr collection, int getCount, IntPtr dest, out int retCount);
+               internal static extern Status GdipGetFontCollectionFamilyList (IntPtr collection, int getCount, IntPtr[] dest, out int retCount);
                //internal static extern Status GdipGetFontCollectionFamilyList( IntPtr collection, int getCount, [Out] FontFamily [] familyList, out int retCount );
                
                [DllImport ("gdiplus.dll")]
@@ -1385,7 +1510,7 @@ namespace System.Drawing
                internal static extern Status GdipNewPrivateFontCollection (out IntPtr collection);
                
                [DllImport ("gdiplus.dll")]
-               internal static extern Status GdipDeletePrivateFontCollection (IntPtr collection);
+               internal static extern Status GdipDeletePrivateFontCollection (ref IntPtr collection);
                
                [DllImport ("gdiplus.dll", CharSet=CharSet.Auto)]
                internal static extern Status GdipPrivateAddFontFile (IntPtr collection,
@@ -1400,7 +1525,7 @@ namespace System.Drawing
                         [MarshalAs(UnmanagedType.LPWStr)] string fName, IntPtr collection, out IntPtr fontFamily);
 
                [DllImport ("gdiplus.dll", CharSet=CharSet.Unicode)]
-               internal static extern Status GdipGetFamilyName(IntPtr family, StringBuilder fName, int language);
+               internal static extern Status GdipGetFamilyName(IntPtr family, StringBuilder name, int language);
 
                [DllImport ("gdiplus.dll")]
                internal static extern Status GdipGetGenericFontFamilySansSerif (out IntPtr fontFamily);
@@ -1429,6 +1554,16 @@ namespace System.Drawing
                [DllImport ("gdiplus.dll")]
                internal static extern Status GdipDeleteFontFamily (IntPtr fontFamily);
                
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetFontSize (IntPtr font, out float size);
+               
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetFontHeight (IntPtr font, IntPtr graphics, out float height);
+               
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetFontHeightGivenDPI (IntPtr font, float dpi, out float height);
+               
+               
                // String Format
                [DllImport ("gdiplus.dll")]
                internal static extern Status GdipCreateStringFormat(int formatAttributes, int language, out IntPtr  format);
@@ -1471,6 +1606,35 @@ namespace System.Drawing
                 [DllImport ("gdiplus.dll")]
                 internal static extern Status GdipGetStringFormatTabStops(IntPtr format, int count, out float firstTabOffset, [In, Out] float [] tabStops);
                                
+               // metafile
+               [DllImport ("gdiplus.dll", CharSet = CharSet.Auto)]
+               internal static extern Status GdipCreateMetafileFromFile ([MarshalAs (UnmanagedType.LPWStr)] string filename, out IntPtr metafile);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipCreateMetafileFromEmf (IntPtr hEmf, bool deleteEmf, out IntPtr metafile);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipCreateMetafileFromWmf (IntPtr hWmf, bool deleteWmf, WmfPlaceableFileHeader wmfPlaceableFileHeader, out IntPtr metafile);
+               [DllImport ("gdiplus.dll", CharSet = CharSet.Auto)]
+               internal static extern Status GdipGetMetafileHeaderFromFile ([MarshalAs (UnmanagedType.LPWStr)] string filename, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromMetafile (IntPtr metafile, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromEmf (IntPtr hEmf, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromWmf (IntPtr hWmf, IntPtr wmfPlaceableFileHeader, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetHemfFromMetafile (IntPtr metafile, out IntPtr hEmf);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileDownLevelRasterizationLimit (IntPtr metafile, ref uint metafileRasterizationLimitDpi);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipSetMetafileDownLevelRasterizationLimit (IntPtr metafile, uint metafileRasterizationLimitDpi);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipPlayMetafileRecord (IntPtr metafile, EmfPlusRecordType recordType, int flags, int dataSize, byte[] data);
+#if !TEST
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipCreateMetafileFromStream([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, out IntPtr metafile);
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipGetMetafileHeaderFromStream([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, IntPtr header);
+#endif
                //ImageCodecInfo functions
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipGetImageDecodersSize (out int decoderNums, out int arraySize);
@@ -1504,9 +1668,13 @@ namespace System.Drawing
                        private byte[]  start_buf;
                        private int     start_buf_pos;
                        private int     start_buf_len;
+                       private byte[]  managedBuf;
+                       private const int default_bufsize = 4096;
                        
                        public GdiPlusStreamHelper (Stream s) 
                        { 
+                               managedBuf = new byte [default_bufsize];
+                               
                                stream = s;
                                if (stream != null && stream.CanSeek) {
                                        stream.Seek (0, SeekOrigin.Begin);
@@ -1552,7 +1720,8 @@ namespace System.Drawing
                                        return -1;
                                }
 
-                               byte[] managedBuf = new byte[bufsz];
+                               if (bufsz > managedBuf.Length)
+                                       managedBuf = new byte[bufsz];
                                int bytesRead = 0;
                                long streamPosition = 0;
 
@@ -1619,18 +1788,31 @@ namespace System.Drawing
 
                        public long StreamSeekImpl (int offset, int whence) 
                        {
-                               long retOffset;
-                               if (whence == 0) {
-                                       retOffset = stream.Seek ((long) offset, SeekOrigin.Begin);
-                               } else if (whence == 1) {
-                                       retOffset = stream.Seek ((long) offset, SeekOrigin.Current);
-                               } else if (whence == 2) {
-                                       retOffset = stream.Seek ((long) offset, SeekOrigin.End);
-                               } else {
-                                       retOffset = -1;
+                               // Make sure we have a valid 'whence'.
+                               if ((whence < 0) || (whence > 2))
+                                       return -1;
+
+                               // Invalidate the start_buf if we're actually going to call a Seek method.
+                               start_buf_pos += start_buf_len;
+                               start_buf_len = 0;
+
+                               SeekOrigin origin;
+
+                               // Translate 'whence' into a SeekOrigin enum member.
+                               switch (whence)
+                               {
+                                       case 0: origin = SeekOrigin.Begin;   break;
+                                       case 1: origin = SeekOrigin.Current; break;
+                                       case 2: origin = SeekOrigin.End;     break;
+
+                                       // The following line is redundant but necessary to avoid a
+                                       // "Use of unassigned local variable" error without actually
+                                       // initializing 'origin' to a dummy value.
+                                       default: return -1;
                                }
-                       
-                               return retOffset;
+
+                               // Do the actual seek operation and return its result.
+                               return stream.Seek ((long) offset, origin);
                        }
 
                        public StreamSeekDelegate SeekDelegate {
@@ -1647,7 +1829,8 @@ namespace System.Drawing
 
                        public int StreamPutBytesImpl (IntPtr buf, int bufsz) 
                        {
-                               byte[] managedBuf = new byte[bufsz];
+                               if (bufsz > managedBuf.Length)
+                                       managedBuf = new byte[bufsz];
                                Marshal.Copy (buf, managedBuf, 0, bufsz);
                                stream.Write (managedBuf, 0, bufsz);
                                return bufsz;
@@ -1684,7 +1867,11 @@ namespace System.Drawing
                        
                        public long StreamSizeImpl ()
                        {
-                               return stream.Length;
+                               try {
+                                       return stream.Length;
+                               } catch {
+                                       return -1;
+                               }
                        }
 
                        public StreamSizeDelegate SizeDelegate {
@@ -1712,13 +1899,26 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipCreateFromXDrawable_linux (IntPtr drawable, IntPtr display, out IntPtr graphics);
                
+               // Stream functions for non-Win32 (libgdiplus specific)
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipLoadImageFromDelegate_linux ( StreamGetHeaderDelegate getHeader, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 
-                                                       StreamSeekDelegate doSeek, StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image);
+               static internal extern Status GdipLoadImageFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image);
+
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipSaveImageToDelegate_linux ( IntPtr image, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 
-                       StreamSeekDelegate doSeek, StreamCloseDelegate close, StreamSizeDelegate size, ref Guid encoderClsID, IntPtr encoderParameters );
-               
+               static internal extern Status GdipSaveImageToDelegate_linux (IntPtr image, StreamGetBytesDelegate getBytes, 
+                       StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, StreamCloseDelegate close, 
+                       StreamSizeDelegate size, ref Guid encoderClsID, IntPtr encoderParameters);              
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipCreateMetafileFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr metafile);
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipGetMetafileHeaderFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, IntPtr header);
 #endregion
        }
 }