diff options
author | Andreia Gaita <avidigal@novell.com> | 2007-02-17 02:10:35 +0300 |
---|---|---|
committer | Andreia Gaita <avidigal@novell.com> | 2007-02-17 02:10:35 +0300 |
commit | 7dda136e2b2a498fd56b6ec84926b2cde67f22aa (patch) | |
tree | 34e669010c351ebef98a4d67d395a19c63e47181 /mcs/class/System.Drawing/System.Drawing.Printing | |
parent | b6e08948975c1f8442c6b905aaf43320011ef78e (diff) |
2007-02-16 Andreia Gaita <avidigal@novell.com>
Redesign how and when cups gets called to minimize
p/invokes, implements caching of printers and printer
settings as per calberto's patch - #79822, plotter detection,
duplex, fixes for image disposing, code modularization,
misc. fixes.
svn path=/trunk/mcs/; revision=73048
Diffstat (limited to 'mcs/class/System.Drawing/System.Drawing.Printing')
9 files changed, 1158 insertions, 692 deletions
diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/ChangeLog b/mcs/class/System.Drawing/System.Drawing.Printing/ChangeLog index 9d19750b7d2..98fe6310761 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/ChangeLog +++ b/mcs/class/System.Drawing/System.Drawing.Printing/ChangeLog @@ -1,3 +1,58 @@ +2007-02-16 Andreia Gaita <avidigal@novell.com> + + Redesign how and when cups gets called to minimize + p/invokes, implements caching of printers and printer + settings as per calberto's patch - #79822, plotter detection, + duplex, fixes for image disposing, code modularization, + misc. fixes. + + * PageSettings.cs: Check and ignore null setter values on + paper sizes, sources and resolutions. + + * PaperSize.cs: Add default paper size flag + + * PaperSource.cs: Add default paper source flag, minor code + beautification + + * PrinterSettings.cs: Add duplex and plotter implementation, + modify calls to PrintingServices to support caching, add + a printer capabilities list to store specific printer options - + only loaded with cups, for now. Move the internal list classes + to the end of the code so as not to clutter. + + * PrintingServices.cs: Separate the PrintingServices class in 2 - + PrintingServices and GlobalPrintingServices (see calberto's patch + in #79822). The PrintingServices class is where all the methods + caching information reside, the GlobalPrintingServices methods do + no caching. + The cached information resides on the Printer class, added to the + SysPrn class. + + * PrintingServicesUnix.cs: Big rewrite. + - Essentially, redesigned and modularized the code to minimize cups + calls. Then, applied the caching so all the cups calls are reduced + to a minimum, by loading a list of printers onto a hashtable, then + loading the settings of the chosen printer and saving that in the + hashtable all in one go. + - Also, fixes for loading the proper default values of the printer, + which are stored in it's global options; + - Modularization of cups/ppd loading methods (LoadPrinterOptions, + LoadOptionList, OpenPrinter, ClosePrinter) so we don't repeat + cups/ppd loading loops everywhere. + - Proper disposing of pointers and structures, calling the proper + cups free calls. + - Add duplex support + + * PrintingServicesWin32.cs: IsPrinterValid is no longer caching the value, + since it should be supporting global caching as well, though that is not + yet complete on win32. Implements plotter detection support, and changes for + the new PrinterSettings/GlobalPrinterSettings structure. Some minor changes + the code to minimize p/invoke calls (load the printer sources and sizes + before accessing the collections) + + * StandardPrintController.cs: PrinterSettings/GlobalPrinterSettings structure + changes + 2007-02-09 Sebastien Pouliot <sebastien@ximian.com> * PrintingServicesUnix.cs: Ensure we free the original pointer in diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PageSettings.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PageSettings.cs index 0d08d76b275..61a61bbf08a 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PageSettings.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PageSettings.cs @@ -77,7 +77,6 @@ namespace System.Drawing.Printing internal PageSettings(PrinterSettings printerSettings, bool color, bool landscape, PaperSize paperSize, PaperSource paperSource, PrinterResolution printerResolution) { PrinterSettings = printerSettings; - this.color = color; this.landscape = landscape; this.paperSize = paperSize; @@ -144,7 +143,8 @@ namespace System.Drawing.Printing return paperSize; } set{ - paperSize = value; + if (value != null) + paperSize = value; } } @@ -155,7 +155,8 @@ namespace System.Drawing.Printing return paperSource; } set{ - paperSource = value; + if (value != null) + paperSource = value; } } @@ -166,7 +167,8 @@ namespace System.Drawing.Printing return printerResolution; } set{ - printerResolution = value; + if (value != null) + printerResolution = value; } } diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PaperSize.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PaperSize.cs index 8ded0d59eaf..7af383022c0 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PaperSize.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PaperSize.cs @@ -46,6 +46,8 @@ namespace System.Drawing.Printing int width; int height; PaperKind kind; + internal bool is_default; + #if NET_2_0 public PaperSize () { @@ -58,7 +60,16 @@ namespace System.Drawing.Printing this.height = height; this.name = name; this.kind = PaperKind.Custom; - } + } + + internal PaperSize(string name, int width, int height, PaperKind kind, bool isDefault) + { + this.width = width; + this.height = height; + this.name = name; + this.kind = PaperKind.Custom; + this.is_default = isDefault; + } public int Width{ get{ @@ -97,7 +108,6 @@ namespace System.Drawing.Printing return kind; } } - internal void SetKind (PaperKind k) {kind = k;} #if NET_2_0 [MonoTODO] public int RawKind { @@ -106,6 +116,14 @@ namespace System.Drawing.Printing }
#endif + + internal bool IsDefault { + get { return this.is_default; } + set { this.is_default = value; } + } + + + internal void SetKind (PaperKind k) {kind = k;} public override string ToString(){ string ret = "[PaperSize {0} Kind={1} Height={2} Width={3}]"; diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PaperSource.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PaperSource.cs index 9523f304977..b44db7bc5b9 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PaperSource.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PaperSource.cs @@ -42,8 +42,9 @@ namespace System.Drawing.Printing #endif public class PaperSource { - PaperSourceKind _Kind; - string _SourceName; + private PaperSourceKind kind; + private string source_name; + internal bool is_default; #if NET_2_0 public PaperSource () @@ -51,30 +52,36 @@ namespace System.Drawing.Printing } #endif - // NOTE:how to construct this class? - // I have added a constructor, but I am not sure of me... + internal PaperSource(string sourceName, PaperSourceKind kind) { - _SourceName = sourceName; - _Kind = kind; + this.source_name = sourceName; + this.kind = kind; + } + + internal PaperSource(string sourceName, PaperSourceKind kind, bool isDefault) + { + this.source_name = sourceName; + this.kind = kind; + this.is_default = IsDefault; } public PaperSourceKind Kind{ get { - return _Kind; + return this.kind; } } public string SourceName{ get { - return _SourceName; + return this.source_name; } #if NET_2_0 set { - _SourceName = value; + this.source_name = value; } #endif } - + #if NET_2_0 [MonoTODO] public int RawKind { @@ -87,9 +94,15 @@ namespace System.Drawing.Printing } #endif
+ internal bool IsDefault { + get { return is_default;} + set { is_default = value;} + } + public override string ToString(){ string ret = "[PaperSource {0} Kind={1}]"; return String.Format(ret, this.SourceName, this.Kind); } + } } diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PrinterSettings.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PrinterSettings.cs index daaa97f69b0..c419f1f4f55 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PrinterSettings.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PrinterSettings.cs @@ -31,6 +31,7 @@ using System.Runtime.InteropServices; using System.Collections; +using System.Collections.Specialized; using System.ComponentModel; using System.Drawing.Imaging; @@ -60,17 +61,22 @@ namespace System.Drawing.Printing internal PrinterSettings.PaperSizeCollection paper_sizes; internal PrinterSettings.PaperSourceCollection paper_sources; private PageSettings default_pagesettings; + private Duplex duplex; + internal bool is_plotter; + private PrintingServices printing_services; - public PrinterSettings() : this (SysPrn.Service.DefaultPrinter) + internal NameValueCollection printer_capabilities; // this stores a list of all the printer options. Used only in cups, but might come in handy on win too. + public PrinterSettings() : this (SysPrn.CreatePrintingService ()) { print_tofile = false; } - internal PrinterSettings (string printer) - { - printer_name = printer; + internal PrinterSettings (PrintingServices printing_services) + { + this.printing_services = printing_services; + printer_name = printing_services.DefaultPrinter; ResetToDefaults (); - SysPrn.Service.LoadPrinterSettings (printer_name, this); + printing_services.LoadPrinterSettings (printer_name, this); } private void ResetToDefaults () @@ -81,190 +87,9 @@ namespace System.Drawing.Printing default_pagesettings = null; maximum_page = 9999; copies = 1; + collate = true; } - - // Public subclasses - - public class PaperSourceCollection : ICollection, IEnumerable - { - ArrayList _PaperSources = new ArrayList(); - - public PaperSourceCollection(PaperSource[] array) { - foreach (PaperSource ps in array) - _PaperSources.Add(ps); - } - - public int Count { get { return _PaperSources.Count; } } - int ICollection.Count { get { return _PaperSources.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } -#if NET_2_0 - [EditorBrowsable(EditorBrowsableState.Never)]
- public int Add (PaperSource paperSource) {return _PaperSources.Add (paperSource); }
- public void CopyTo (PaperSource[] paperSources, int index) {throw new NotImplementedException (); } -#else - internal int Add (PaperSource paperSource) {return _PaperSources.Add (paperSource); } -#endif - - public virtual PaperSource this[int index] { - get { return _PaperSources[index] as PaperSource; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PaperSources.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PaperSources.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PaperSources.CopyTo(array, index); - } - - internal void Clear () - { - _PaperSources.Clear (); - } - - } - - public class PaperSizeCollection : ICollection, IEnumerable - { - ArrayList _PaperSizes = new ArrayList(); - - public PaperSizeCollection(PaperSize[] array) { - foreach (PaperSize ps in array) - _PaperSizes.Add(ps); - } - - public int Count { get { return _PaperSizes.Count; } } - int ICollection.Count { get { return _PaperSizes.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } -#if NET_2_0 - [EditorBrowsable(EditorBrowsableState.Never)]
- public int Add (PaperSize paperSize) {return _PaperSizes.Add (paperSize); } - public void CopyTo (PaperSize[] paperSizes, int index) {throw new NotImplementedException (); }
-#else - internal int Add (PaperSize paperSize) {return _PaperSizes.Add (paperSize); } -#endif
- - public virtual PaperSize this[int index] { - get { return _PaperSizes[index] as PaperSize; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PaperSizes.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PaperSizes.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PaperSizes.CopyTo(array, index); - } - - internal void Clear () - { - _PaperSizes.Clear (); - } - } - - public class PrinterResolutionCollection : ICollection, IEnumerable - { - ArrayList _PrinterResolutions = new ArrayList(); - - public PrinterResolutionCollection(PrinterResolution[] array) { - foreach (PrinterResolution pr in array) - _PrinterResolutions.Add(pr); - } - - public int Count { get { return _PrinterResolutions.Count; } } - int ICollection.Count { get { return _PrinterResolutions.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } -#if NET_2_0 - [EditorBrowsable(EditorBrowsableState.Never)]
- public int Add (PrinterResolution printerResolution) { return _PrinterResolutions.Add (printerResolution); }
- public void CopyTo (PrinterResolution[] printerResolutions, int index) {throw new NotImplementedException (); } -#else - internal int Add (PrinterResolution printerResolution) { return _PrinterResolutions.Add (printerResolution); } -#endif - - public virtual PrinterResolution this[int index] { - get { return _PrinterResolutions[index] as PrinterResolution; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PrinterResolutions.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PrinterResolutions.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PrinterResolutions.CopyTo(array, index); - } - - internal void Clear () - { - _PrinterResolutions.Clear (); - } - } - - public class StringCollection : ICollection, IEnumerable - { - ArrayList _Strings = new ArrayList(); - - public StringCollection(string[] array) { - foreach (string s in array) - _Strings.Add(s); - } - - public int Count { get { return _Strings.Count; } } - int ICollection.Count { get { return _Strings.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } - - public virtual string this[int index] { - get { return _Strings[index] as string; } - } -#if NET_2_0 - [EditorBrowsable(EditorBrowsableState.Never)]
- public int Add (string value) { return _Strings.Add (value); }
- public void CopyTo (string[] strings, int index) {throw new NotImplementedException (); } -#else - internal int Add (string value) { return _Strings.Add (value); } -#endif - - IEnumerator IEnumerable.GetEnumerator() - { - return _Strings.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _Strings.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _Strings.CopyTo(array, index); - } - } - + //properties public bool CanDuplex @@ -298,7 +123,7 @@ namespace System.Drawing.Printing false, // Real defaults are set by LoadPrinterSettings new PaperSize("A4", 827, 1169), - new PaperSource("default", PaperSourceKind.FormSource), + new PaperSource("Tray", PaperSourceKind.FormSource), new PrinterResolution(200, 200, PrinterResolutionKind.Medium)); } @@ -306,11 +131,10 @@ namespace System.Drawing.Printing } } - [MonoTODO("PrinterSettings.Duplex")] public Duplex Duplex { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } + get { return this.duplex; } + set { this.duplex = value; } } public int FromPage @@ -326,23 +150,22 @@ namespace System.Drawing.Printing public static PrinterSettings.StringCollection InstalledPrinters { - get { return SysPrn.Service.InstalledPrinters; } + get { return SysPrn.GlobalService.InstalledPrinters; } } public bool IsDefaultPrinter { - get { return (printer_name == SysPrn.Service.DefaultPrinter); } + get { return (printer_name == printing_services.DefaultPrinter); } } - [MonoTODO("PrinterSettings.IsPlotter")] public bool IsPlotter { - get { return false; } + get { return is_plotter; } } public bool IsValid { - get { return SysPrn.Service.IsPrinterValid(this.printer_name, false); } + get { return printing_services.IsPrinterValid (this.printer_name); } } public int LandscapeAngle @@ -383,10 +206,7 @@ namespace System.Drawing.Printing get { if (!this.IsValid) throw new InvalidPrinterException(this); - if (paper_sizes == null) { - paper_sizes = new PrinterSettings.PaperSizeCollection (new PaperSize [] {}); - SysPrn.Service.LoadPrinterPaperSizes (printer_name, this); - } + return paper_sizes; } } @@ -396,10 +216,7 @@ namespace System.Drawing.Printing get { if (!this.IsValid) throw new InvalidPrinterException(this); - if (paper_sources == null) { - paper_sources = new PrinterSettings.PaperSourceCollection (new PaperSource [] {}); - SysPrn.Service.LoadPrinterPaperSources (printer_name, this); - } + return paper_sources; } } @@ -421,7 +238,7 @@ namespace System.Drawing.Printing return; printer_name = value; - SysPrn.Service.LoadPrinterSettings (printer_name, this); + printing_services.LoadPrinterSettings (printer_name, this); } } @@ -430,10 +247,12 @@ namespace System.Drawing.Printing get { if (!this.IsValid) throw new InvalidPrinterException(this); + if (printer_resolutions == null) { printer_resolutions = new PrinterSettings.PrinterResolutionCollection (new PrinterResolution[] {}); - SysPrn.Service.LoadPrinterResolutions (printer_name, this); + printing_services.LoadPrinterResolutions (printer_name, this); } + return printer_resolutions; } } @@ -471,11 +290,19 @@ namespace System.Drawing.Printing to_page = value; } } + + internal NameValueCollection PrinterCapabilities { + get { + if (this.printer_capabilities == null) + this.printer_capabilities = new NameValueCollection(); + return this.printer_capabilities; + } + } //methods public object Clone () { - PrinterSettings ps = new PrinterSettings (printer_name); + PrinterSettings ps = new PrinterSettings (printing_services); return ps; } @@ -497,7 +324,7 @@ namespace System.Drawing.Printing throw new NotImplementedException(); } - [MonoTODO("PrinterSettings.CreateMeasurementGraphics")]
+ [MonoTODO("PrinterSettings.CreateMeasurementGraphics")] public Graphics CreateMeasurementGraphics (PageSettings pageSettings, bool honorOriginAtMargins) { throw new NotImplementedException(); @@ -530,11 +357,11 @@ namespace System.Drawing.Printing throw new NotImplementedException(); } - [MonoTODO("IsDirectPrintingSupported")]
+ [MonoTODO("IsDirectPrintingSupported")] public bool IsDirectPrintingSupported (ImageFormat imageFormat) { throw new NotImplementedException(); - }
+ } #endif [MonoTODO("PrinterSettings.SetHdevmode")] @@ -553,8 +380,199 @@ namespace System.Drawing.Printing { return "Printer [PrinterSettings " + printer_name + " Copies=" + copies + " Collate=" + collate + " Duplex=" + can_duplex + " FromPage=" + from_page + " LandscapeAngle=" + landscape_angle - + " MaximumCopies=" + maximum_copies + " OutputPort=" + " ToPage=" + to_page + "]";
+ + " MaximumCopies=" + maximum_copies + " OutputPort=" + " ToPage=" + to_page + "]"; + + } + + // Public subclasses + #region Public Subclasses + + + public class PaperSourceCollection : ICollection, IEnumerable + { + ArrayList _PaperSources = new ArrayList(); + + public PaperSourceCollection(PaperSource[] array) { + foreach (PaperSource ps in array) + _PaperSources.Add(ps); + } + + public int Count { get { return _PaperSources.Count; } } + int ICollection.Count { get { return _PaperSources.Count; } } + bool ICollection.IsSynchronized { get { return false; } } + object ICollection.SyncRoot { get { return this; } } +#if NET_2_0 + [EditorBrowsable(EditorBrowsableState.Never)] + public int Add (PaperSource paperSource) {return _PaperSources.Add (paperSource); } + public void CopyTo (PaperSource[] paperSources, int index) {throw new NotImplementedException (); } +#else + internal int Add (PaperSource paperSource) {return _PaperSources.Add (paperSource); } +#endif + + public virtual PaperSource this[int index] { + get { return _PaperSources[index] as PaperSource; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _PaperSources.GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _PaperSources.GetEnumerator(); + } + + void ICollection.CopyTo(Array array, int index) + { + _PaperSources.CopyTo(array, index); + } + + internal void Clear () + { + _PaperSources.Clear (); + } + + } - } + public class PaperSizeCollection : ICollection, IEnumerable + { + ArrayList _PaperSizes = new ArrayList(); + + public PaperSizeCollection(PaperSize[] array) { + foreach (PaperSize ps in array) + _PaperSizes.Add(ps); + } + + public int Count { get { return _PaperSizes.Count; } } + int ICollection.Count { get { return _PaperSizes.Count; } } + bool ICollection.IsSynchronized { get { return false; } } + object ICollection.SyncRoot { get { return this; } } +#if NET_2_0 + [EditorBrowsable(EditorBrowsableState.Never)] + public int Add (PaperSize paperSize) {return _PaperSizes.Add (paperSize); } + public void CopyTo (PaperSize[] paperSizes, int index) {throw new NotImplementedException (); } +#else + internal int Add (PaperSize paperSize) {return _PaperSizes.Add (paperSize); } +#endif + + public virtual PaperSize this[int index] { + get { return _PaperSizes[index] as PaperSize; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _PaperSizes.GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _PaperSizes.GetEnumerator(); + } + + void ICollection.CopyTo(Array array, int index) + { + _PaperSizes.CopyTo(array, index); + } + + internal void Clear () + { + _PaperSizes.Clear (); + } + } + + public class PrinterResolutionCollection : ICollection, IEnumerable + { + ArrayList _PrinterResolutions = new ArrayList(); + + public PrinterResolutionCollection(PrinterResolution[] array) { + foreach (PrinterResolution pr in array) + _PrinterResolutions.Add(pr); + } + + public int Count { get { return _PrinterResolutions.Count; } } + int ICollection.Count { get { return _PrinterResolutions.Count; } } + bool ICollection.IsSynchronized { get { return false; } } + object ICollection.SyncRoot { get { return this; } } +#if NET_2_0 + [EditorBrowsable(EditorBrowsableState.Never)] + public int Add (PrinterResolution printerResolution) { return _PrinterResolutions.Add (printerResolution); } + public void CopyTo (PrinterResolution[] printerResolutions, int index) {throw new NotImplementedException (); } +#else + internal int Add (PrinterResolution printerResolution) { return _PrinterResolutions.Add (printerResolution); } +#endif + + public virtual PrinterResolution this[int index] { + get { return _PrinterResolutions[index] as PrinterResolution; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _PrinterResolutions.GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _PrinterResolutions.GetEnumerator(); + } + + void ICollection.CopyTo(Array array, int index) + { + _PrinterResolutions.CopyTo(array, index); + } + + internal void Clear () + { + _PrinterResolutions.Clear (); + } + } + + public class StringCollection : ICollection, IEnumerable + { + ArrayList _Strings = new ArrayList(); + + public StringCollection(string[] array) { + foreach (string s in array) + _Strings.Add(s); + } + + public int Count { get { return _Strings.Count; } } + int ICollection.Count { get { return _Strings.Count; } } + bool ICollection.IsSynchronized { get { return false; } } + object ICollection.SyncRoot { get { return this; } } + + public virtual string this[int index] { + get { return _Strings[index] as string; } + } +#if NET_2_0 + [EditorBrowsable(EditorBrowsableState.Never)] + public int Add (string value) { return _Strings.Add (value); } + public void CopyTo (string[] strings, int index) {throw new NotImplementedException (); } +#else + internal int Add (string value) { return _Strings.Add (value); } +#endif + + IEnumerator IEnumerable.GetEnumerator() + { + return _Strings.GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _Strings.GetEnumerator(); + } + + void ICollection.CopyTo(Array array, int index) + { + _Strings.CopyTo(array, index); + } + } + + #endregion + + void GetPrintDialogInfo (string printer_name, ref string port, ref string type, ref string status, ref string comment) + { + printing_services.GetPrintDialogInfo (printer_name, ref port, ref type, ref status, ref comment); + } } } diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServices.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServices.cs index e1622ffcaba..99f58349344 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServices.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServices.cs @@ -33,27 +33,23 @@ using System.Drawing.Imaging; namespace System.Drawing.Printing { + /// <summary> + /// This class is designed to cache the values retrieved by the + /// native printing services, as opposed to GlobalPrintingServices, which + /// doesn't cache any values. + /// </summary> internal abstract class PrintingServices { - // Properties - internal abstract PrinterSettings.StringCollection InstalledPrinters { get; } + #region Properties internal abstract string DefaultPrinter { get; } - + #endregion - // Methods - internal abstract bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file); - internal abstract IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings page_settings); - internal abstract bool StartPage (GraphicsPrinter gr); - internal abstract bool EndPage (GraphicsPrinter gr); - internal abstract bool EndDoc (GraphicsPrinter gr); - + #region Methods + internal abstract bool IsPrinterValid(string printer); internal abstract void LoadPrinterSettings (string printer, PrinterSettings settings); internal abstract void LoadPrinterResolutions (string printer, PrinterSettings settings); - internal abstract void LoadPrinterPaperSizes (string printer, PrinterSettings settings); - internal abstract void LoadPrinterPaperSources (string printer, PrinterSettings settings); - internal abstract bool IsPrinterValid(string printer, bool force); - //Used from SWF + // Used from SWF internal abstract void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment); internal void LoadDefaultResolutions (PrinterSettings.PrinterResolutionCollection col) @@ -63,28 +59,70 @@ namespace System.Drawing.Printing col.Add (new PrinterResolution ((int) PrinterResolutionKind.Low, -1, PrinterResolutionKind.Low)); col.Add (new PrinterResolution ((int) PrinterResolutionKind.Draft, -1, PrinterResolutionKind.Draft)); } + #endregion + } + + internal abstract class GlobalPrintingServices + { + #region Properties + internal abstract PrinterSettings.StringCollection InstalledPrinters { get; } + #endregion + + #region Methods + internal abstract IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings page_settings); + + internal abstract bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file); + internal abstract bool StartPage (GraphicsPrinter gr); + internal abstract bool EndPage (GraphicsPrinter gr); + internal abstract bool EndDoc (GraphicsPrinter gr); + #endregion + } internal class SysPrn { - static PrintingServices service; + static GlobalPrintingServices global_printing_services; + static bool is_unix; static SysPrn () { - if (GDIPlus.RunningOnUnix ()) { - service = new PrintingServicesUnix (); - } else { - service = new PrintingServicesWin32 (); - } + is_unix = GDIPlus.RunningOnUnix (); } + + internal static PrintingServices CreatePrintingService () { + if (is_unix) + return new PrintingServicesUnix (); + return new PrintingServicesWin32 (); + } - static internal PrintingServices Service { - get { return service; } + internal static GlobalPrintingServices GlobalService { + get {
+ if (global_printing_services == null) {
+ if (is_unix)
+ global_printing_services = new GlobalPrintingServicesUnix ();
+ else
+ global_printing_services = new GlobalPrintingServicesWin32 ();
+ }
+
+ return global_printing_services;
+ } } - internal static void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment) - { - service.GetPrintDialogInfo (printer, ref port, ref type, ref status, ref comment); + internal class Printer { + public readonly string Name; + public readonly string Comment; + public readonly string Port; + public readonly string Type; + public readonly string Status; + public PrinterSettings Settings; + public bool IsDefault; + + public Printer (string port, string type, string status, string comment) { + Port = port; + Type = type; + Status = status; + Comment = comment; + } } } diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs index bc7e4259d32..dd65135c318 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs @@ -1,3 +1,4 @@ +//#define PrintDebug // // Copyright (C) 2005, 2007 Novell, Inc. http://www.novell.com // @@ -27,6 +28,7 @@ using System.Runtime.InteropServices; using System.Collections; +using System.Collections.Specialized; using System.Drawing.Printing; using System.ComponentModel; using System.Drawing.Imaging; @@ -37,17 +39,60 @@ namespace System.Drawing.Printing { internal class PrintingServicesUnix : PrintingServices { - private Hashtable doc_info = new Hashtable (); - private bool cups_installed; + #region Private Fields + + private static Hashtable doc_info = new Hashtable (); + private static bool cups_installed; + private string printer_name; - private bool is_printer_valid; + + private static Hashtable installed_printers; + private static string default_printer = String.Empty; + + #endregion - internal PrintingServicesUnix () - { + #region Constructor + + internal PrintingServicesUnix () { + installed_printers = new Hashtable (); + } + + static PrintingServicesUnix () { CheckCupsInstalled (); } + + #endregion + + #region Properties + + internal static PrinterSettings.StringCollection InstalledPrinters { + get { + LoadPrinters(); + PrinterSettings.StringCollection list = new PrinterSettings.StringCollection (new string[] {}); + foreach (object key in installed_printers.Keys) { + list.Add (key.ToString()); + } + return list; + } + } + + internal override string DefaultPrinter { + get { + if (installed_printers.Count == 0) + LoadPrinters(); + return default_printer; + } + } + + #endregion - private void CheckCupsInstalled () + + #region Methods + + /// <summary> + /// Do a cups call to check if it is installed + /// </summary> + private static void CheckCupsInstalled () { try { cupsGetDefault (); @@ -60,12 +105,39 @@ namespace System.Drawing.Printing cups_installed = true; } - - internal override bool IsPrinterValid(string printer, bool force) + + /// <summary> + /// Open the printer's PPD file + /// </summary> + /// <param name="printer">Printer name, returned from cupsGetDests</param> + private IntPtr OpenPrinter(string printer) + { + IntPtr ptr = cupsGetPPD (printer); + string ppd_filename = Marshal.PtrToStringAnsi (ptr); + IntPtr ppd_handle = ppdOpenFile (ppd_filename); + return ppd_handle; + } + + /// <summary> + /// Close the printer file + /// </summary> + /// <param name="handle">PPD handle</param> + private void ClosePrinter(IntPtr handle) + { + ppdClose (handle); + } + + /// <summary> + /// Checks if a printer has a valid PPD file. Caches the result unless force is true + /// </summary> + /// <param name="force">Does the check disregarding the last cached value if true</param> + internal override bool IsPrinterValid(string printer) { if (!cups_installed || printer == null | printer == String.Empty) return false; - + + return installed_printers.Contains (printer); +/* if (!force && this.printer_name != null && String.Intern(this.printer_name).Equals(printer)) return is_printer_valid; @@ -74,353 +146,422 @@ namespace System.Drawing.Printing is_printer_valid = ppd_filename != null; this.printer_name = printer; return is_printer_valid; +*/ } - - // Methods + + /// <summary> + /// Loads the printer settings and initializes the PrinterSettings and PageSettings fields + /// </summary> + /// <param name="printer">Printer name</param> + /// <param name="settings">PrinterSettings object to initialize</param> internal override void LoadPrinterSettings (string printer, PrinterSettings settings) { - IntPtr ptr, ppd_handle, ptr_opt, ptr_choice; - string ppd_filename; - PPD_FILE ppd; - PPD_OPTION option; - PPD_CHOICE choice; - if (cups_installed == false || (printer == null) || (printer == String.Empty)) return; - - ptr = cupsGetPPD (printer); - ppd_filename = Marshal.PtrToStringAnsi (ptr); - ppd_handle = ppdOpenFile (ppd_filename); - //Console.WriteLine ("File: {0}", ppd_filename); + if (installed_printers.Count == 0) + LoadPrinters(); + + if (((SysPrn.Printer)installed_printers[printer]).Settings != null) { + SysPrn.Printer p = (SysPrn.Printer) installed_printers[printer]; + settings.can_duplex = p.Settings.can_duplex; + settings.is_plotter = p.Settings.is_plotter; + settings.landscape_angle = p.Settings.landscape_angle; + settings.maximum_copies = p.Settings.maximum_copies; + settings.paper_sizes = p.Settings.paper_sizes; + settings.paper_sources = p.Settings.paper_sources; + settings.printer_capabilities = p.Settings.printer_capabilities; + settings.printer_resolutions = p.Settings.printer_resolutions; + settings.supports_color = p.Settings.supports_color; + return; + } + + settings.PrinterCapabilities.Clear(); + + IntPtr dests = IntPtr.Zero, ptr = IntPtr.Zero, ptr_printer, ppd_handle; + string name = String.Empty; + CUPS_DESTS printer_dest; + PPD_FILE ppd; + int ret, cups_dests_size; + NameValueCollection options, paper_names, paper_sources; + + + ppd_handle = OpenPrinter (printer); + + ret = cupsGetDests(ref dests); + cups_dests_size = Marshal.SizeOf(typeof(CUPS_DESTS)); + ptr = dests; + for (int i = 0; i < ret; i++) + { + ptr_printer = (IntPtr) Marshal.ReadInt32 (ptr); + if (Marshal.PtrToStringAnsi (ptr_printer).Equals(printer)) { + name = printer; + Marshal.FreeHGlobal(ptr_printer); + break; + } + Marshal.FreeHGlobal(ptr_printer); + ptr = (IntPtr) ((long)ptr + cups_dests_size); + } + + if (!name.Equals(printer)) + { + if (ppd_handle != IntPtr.Zero) + ppdClose(ppd_handle); + if (dests != IntPtr.Zero) + cupsFreeDests(ret, dests); + return; + } + printer_dest = (CUPS_DESTS) Marshal.PtrToStructure (ptr, typeof (CUPS_DESTS)); + options = new NameValueCollection(); + paper_names = new NameValueCollection(); + paper_sources = new NameValueCollection(); + LoadPrinterOptions(printer_dest.options, printer_dest.num_options, ppd_handle, options, paper_names, paper_sources); + + if (settings.paper_sizes == null) + settings.paper_sizes = new PrinterSettings.PaperSizeCollection (new PaperSize [] {}); + else + settings.paper_sizes.Clear(); + + if (settings.paper_sources == null) + settings.paper_sources = new PrinterSettings.PaperSourceCollection (new PaperSource [] {}); + else + settings.paper_sources.Clear(); + + string defsource = options["InputSlot"]; + string defsize = options["PageSize"]; + + settings.DefaultPageSettings.PaperSource = LoadPrinterPaperSources (settings, defsource, paper_sources); + settings.DefaultPageSettings.PaperSize = LoadPrinterPaperSizes (ppd_handle, settings, defsize, paper_names); + ppd = (PPD_FILE) Marshal.PtrToStructure (ppd_handle, typeof (PPD_FILE)); settings.landscape_angle = ppd.landscape; settings.supports_color = (ppd.color_device == 0) ? false : true; + settings.can_duplex = options["Duplex"] != null; + + ClosePrinter(ppd_handle); + + installed_printers.Add (printer, settings); + } + + /// <summary> + /// Loads the global options of a printer plus the paper types and trays supported. + /// </summary> + /// <param name="options">The options field of a printer's CUPS_DESTS structure</param> + /// <param name="numOptions">The number of options of the printer</param> + /// <param name="ppd">A ppd handle for the printer, returned by ppdOpen</param> + /// <param name="list">The list of options</param> + /// <param name="paper_names">A list of types of paper (PageSize)</param> + /// <param name="paper_sources">A list of trays(InputSlot) </param> + private static void LoadPrinterOptions(IntPtr options, int numOptions, IntPtr ppd, + NameValueCollection list, + NameValueCollection paper_names, + NameValueCollection paper_sources) + { + CUPS_OPTIONS cups_options; + string option_name, option_value; + int cups_size = Marshal.SizeOf(typeof(CUPS_OPTIONS)); + + for (int j = 0; j < numOptions; j++) + { + cups_options = (CUPS_OPTIONS) Marshal.PtrToStructure(options, typeof(CUPS_OPTIONS)); + option_name = Marshal.PtrToStringAnsi(cups_options.name); + option_value = Marshal.PtrToStringAnsi(cups_options.val); + + #if PrintDebug + Console.WriteLine("{0} = {1}", option_name, option_value); + #endif + + list.Add(option_name, option_value); - // Default paper source - ptr_opt = ppdFindOption (ppd_handle, "InputSlot"); - if (ptr_opt != IntPtr.Zero) { - option = (PPD_OPTION) Marshal.PtrToStructure (ptr_opt, typeof (PPD_OPTION)); - ptr_choice = option.choices; - for (int c = 0; c < option.num_choices; c++) { - choice = (PPD_CHOICE) Marshal.PtrToStructure (ptr_choice, typeof (PPD_CHOICE)); - ptr_choice = new IntPtr (ptr_choice.ToInt64 () + Marshal.SizeOf (choice)); - if (choice.choice == option.defchoice) { - foreach (PaperSource paper_source in settings.PaperSources) { - if (paper_source.SourceName == choice.text) { - settings.DefaultPageSettings.PaperSource = paper_source; - break; - } - } - break; - } - } + options = (IntPtr) ((long)options + cups_size); } - // Default paper size - ptr_opt = ppdFindOption (ppd_handle, "PageSize"); - if (ptr_opt != IntPtr.Zero) { - option = (PPD_OPTION) Marshal.PtrToStructure (ptr_opt, typeof (PPD_OPTION)); - ptr_choice = option.choices; - for (int c = 0; c < option.num_choices; c++) { - choice = (PPD_CHOICE) Marshal.PtrToStructure (ptr_choice, typeof (PPD_CHOICE)); - ptr_choice = new IntPtr (ptr_choice.ToInt64 () + Marshal.SizeOf (choice)); - if (choice.choice == option.defchoice) { - foreach (PaperSize paper_size in settings.PaperSizes) { - if (paper_size.PaperName == choice.text) { - settings.DefaultPageSettings.PaperSize = paper_size; - break; - } - } - break; - } - } + LoadOptionList(ppd, "PageSize", paper_names); + LoadOptionList(ppd, "InputSlot", paper_sources); + } + + /// <summary> + /// Loads the global options of a printer. + /// </summary> + /// <param name="options">The options field of a printer's CUPS_DESTS structure</param> + /// <param name="numOptions">The number of options of the printer</param> + private static NameValueCollection LoadPrinterOptions(IntPtr options, int numOptions) + { + CUPS_OPTIONS cups_options; + string option_name, option_value; + int cups_size = Marshal.SizeOf (typeof(CUPS_OPTIONS)); + NameValueCollection list = new NameValueCollection (); + for (int j = 0; j < numOptions; j++) + { + cups_options = (CUPS_OPTIONS) Marshal.PtrToStructure(options, typeof(CUPS_OPTIONS)); + option_name = Marshal.PtrToStringAnsi (cups_options.name); + option_value = Marshal.PtrToStringAnsi (cups_options.val); + + #if PrintDebug + Console.WriteLine("{0} = {1}", option_name, option_value); + #endif + + list.Add (option_name, option_value); + + options = (IntPtr) ((long)options + cups_size); } + return list; + } + + /// <summary> + /// Loads a printer's options (selection of paper sizes, paper sources, etc) + /// </summary> + /// <param name="ppd">Printer ppd file handle</param> + /// <param name="option_name">Name of the option group to load</param> + /// <param name="list">List of loaded options</param> + private static void LoadOptionList(IntPtr ppd, string option_name, NameValueCollection list) { + + IntPtr ptr = IntPtr.Zero; + PPD_OPTION ppd_option; + PPD_CHOICE choice; + int choice_size = Marshal.SizeOf(typeof(PPD_CHOICE)); - ppdClose (ppd_handle); + ptr = ppdFindOption (ppd, option_name); + if (ptr != IntPtr.Zero) + { + ppd_option = (PPD_OPTION) Marshal.PtrToStructure (ptr, typeof (PPD_OPTION)); + #if PrintDebug + Console.WriteLine (" OPTION key:{0} def:{1} text: {2}", ppd_option.keyword, ppd_option.defchoice, ppd_option.text); + #endif + + ptr = ppd_option.choices; + for (int c = 0; c < ppd_option.num_choices; c++) { + choice = (PPD_CHOICE) Marshal.PtrToStructure (ptr, typeof (PPD_CHOICE)); + list.Add(choice.choice, choice.text); + #if PrintDebug + Console.WriteLine (" choice:{0} - text: {1}", choice.choice, choice.text); + #endif + + ptr = (IntPtr) ((long)ptr + choice_size); + } + } } + /// <summary> + /// Loads a printer's available resolutions + /// </summary> + /// <param name="printer">Printer name</param> + /// <param name="settings">PrinterSettings object to fill</param> internal override void LoadPrinterResolutions (string printer, PrinterSettings settings) { settings.PrinterResolutions.Clear (); LoadDefaultResolutions (settings.PrinterResolutions); } - internal override void LoadPrinterPaperSizes (string printer, PrinterSettings settings) + /// <summary> + /// Loads a printer's paper sizes. Returns the default PaperSize, and fills a list of paper_names for use in dialogues + /// </summary> + /// <param name="ppd_handle">PPD printer file handle</param> + /// <param name="settings">PrinterSettings object to fill</param> + /// <param name="def_size">Default paper size, from the global options of the printer</param> + /// <param name="paper_names">List of available paper sizes that gets filled</param> + private PaperSize LoadPrinterPaperSizes(IntPtr ppd_handle, PrinterSettings settings, + string def_size, NameValueCollection paper_names) { - IntPtr ptr, ppd_handle; - string ppd_filename, real_name; + IntPtr ptr; + string real_name; PPD_FILE ppd; PPD_SIZE size; PaperSize ps; - settings.PaperSizes.Clear (); - - ptr = cupsGetPPD (printer); - ppd_filename = Marshal.PtrToStringAnsi (ptr); - ppd_handle = ppdOpenFile (ppd_filename); - + PaperSize defsize = null; ppd = (PPD_FILE) Marshal.PtrToStructure (ppd_handle, typeof (PPD_FILE)); ptr = ppd.sizes; float w, h; for (int i = 0; i < ppd.num_sizes; i++) { size = (PPD_SIZE) Marshal.PtrToStructure (ptr, typeof (PPD_SIZE)); - real_name = GetPaperSizeName (ppd_handle, size.name); - ptr = new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (size)); + real_name = paper_names[size.name]; w = size.width * 100 / 72; h = size.length * 100 / 72; - ps = new PaperSize (real_name, (int) w, (int) h); + ps = new PaperSize (real_name, (int) w, (int) h, GetPaperKind ((int) w, (int) h), def_size == real_name); + if (def_size == real_name) + defsize = ps; ps.SetKind (GetPaperKind ((int) w, (int) h)); - settings.PaperSizes.Add (ps); + settings.paper_sizes.Add (ps); + ptr = (IntPtr) ((long)ptr + Marshal.SizeOf (size)); } + + return defsize; - ppdClose (ppd_handle); - } + } - internal override void LoadPrinterPaperSources (string printer, PrinterSettings settings) + /// <summary> + /// Loads a printer's paper sources (trays). Returns the default PaperSource, and fills a list of paper_sources for use in dialogues + /// </summary> + /// <param name="settings">PrinterSettings object to fill</param> + /// <param name="def_source">Default paper source, from the global options of the printer</param> + /// <param name="paper_sources">List of available paper sizes that gets filled</param> + private PaperSource LoadPrinterPaperSources (PrinterSettings settings, string def_source, + NameValueCollection paper_sources) { - IntPtr ptr, ppd_handle, ptr_opt, ptr_choice; - string ppd_filename; - PPD_OPTION option; - PPD_CHOICE choice; - - if (cups_installed == false || (printer == null) || (printer == String.Empty)) - return; - - ptr = cupsGetPPD (printer); - ppd_filename = Marshal.PtrToStringAnsi (ptr); - ppd_handle = ppdOpenFile (ppd_filename); - - ptr_opt = ppdFindOption (ppd_handle, "InputSlot"); - - if (ptr_opt == IntPtr.Zero) { - ppdClose (ppd_handle); - return; + PaperSourceKind kind; + PaperSource defsource = null; + foreach(string source in paper_sources) { + switch (source) + { + case "Tray": + kind = PaperSourceKind.AutomaticFeed; + break; + case "Envelope": + kind = PaperSourceKind.Envelope; + break; + case "Manual": + kind = PaperSourceKind.Manual; + break; + default: + kind = PaperSourceKind.Custom; + break; + } + settings.paper_sources.Add (new PaperSource (paper_sources[source], kind, def_source == source)); + if (def_source == source) + defsource = settings.paper_sources[settings.paper_sources.Count-1]; } - option = (PPD_OPTION) Marshal.PtrToStructure (ptr_opt, typeof (PPD_OPTION)); - //Console.WriteLine (" OPTION key:{0} def:{1} text: {2}", option.keyword, option.defchoice, option.text); - - ptr_choice = option.choices; - for (int c = 0; c < option.num_choices; c++) { - choice = (PPD_CHOICE) Marshal.PtrToStructure (ptr_choice, typeof (PPD_CHOICE)); - ptr_choice = new IntPtr (ptr_choice.ToInt64 () + Marshal.SizeOf (choice)); - //Console.WriteLine (" choice:{0} - text: {1}", choice.choice, choice.text); - settings.PaperSources.Add (new PaperSource (choice.text, PaperSourceKind.Custom)); - } - ppdClose (ppd_handle); - } - - internal override bool StartPage (GraphicsPrinter gr) - { - return true; - } - - internal override bool EndPage (GraphicsPrinter gr) - { - GdipGetPostScriptSavePage (gr.Hdc); - return true; + if (defsource == null && settings.paper_sources.Count > 0) + return settings.paper_sources[0]; + return defsource; } - string tmpfile; - - internal override bool EndDoc (GraphicsPrinter gr) + /// <summary> + /// </summary> + /// <param name="load"></param> + /// <param name="def_printer"></param> + private static void LoadPrinters() { - DOCINFO doc = (DOCINFO) doc_info[gr.Hdc]; - - gr.Graphics.Dispose (); // Dispose object to force surface finish - - IntPtr options; - int options_count = GetCupsOptions (doc.settings, doc.default_page_settings, out options); + installed_printers.Clear (); + if (cups_installed == false) + return; + + IntPtr dests = IntPtr.Zero, ptr_printers; + CUPS_DESTS printer; + int n_printers; + int cups_dests_size = Marshal.SizeOf(typeof(CUPS_DESTS)); + string name, first, type, status, comment; + first = type = status = comment = String.Empty; + int state = 0; + + n_printers = cupsGetDests (ref dests); - cupsPrintFile (doc.settings.PrinterName, doc.filename, doc.title, options_count, options); - cupsFreeOptions (options_count, options); - doc_info.Remove (gr.Hdc); - if (tmpfile != null) { - try { File.Delete (tmpfile); } - catch { } - } - return true; - } + ptr_printers = dests; + for (int i = 0; i < n_printers; i++) { + printer = (CUPS_DESTS) Marshal.PtrToStructure (ptr_printers, typeof (CUPS_DESTS)); + name = Marshal.PtrToStringAnsi (printer.name); - internal override bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file) - { - DOCINFO doc = (DOCINFO) doc_info[gr.Hdc]; - doc.title = doc_name; - return true; - } + if (printer.is_default == 1) + default_printer = name; + + if (first.Equals (String.Empty)) + first = name; + + NameValueCollection options = LoadPrinterOptions(printer.options, printer.num_options); + + if (options["printer-state"] != null) + state = Int32.Parse(options["printer-state"]); + + if (options["printer-comment"] != null) + comment = options["printer-state"]; - // Unfortunately, PrinterSettings and PageSettings couldn't be referencing each other, - // thus we need to pass them separately - internal override IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings) - { - IntPtr graphics = IntPtr.Zero; - string name; - if (!settings.PrintToFile) { - StringBuilder sb = new StringBuilder (1024); - int length = sb.Capacity; - cupsTempFile (sb, length); - name = sb.ToString (); - tmpfile = name; - } - else - name = settings.PrintFileName; + switch(state) + { + case 4: + status = "Printing"; + break; + case 5: + status = "Stopped"; + break; + default: + status = "Ready"; + break; + } + + installed_printers.Add (name, new SysPrn.Printer (String.Empty, type, status, comment)); - PaperSize psize = default_page_settings.PaperSize; - int width, height; - if (default_page_settings.Landscape) { // Swap in case of landscape - width = psize.Height; - height = psize.Width; - } else { - width = psize.Width; - height = psize.Height; + ptr_printers = (IntPtr) ((long)ptr_printers + cups_dests_size); } - - GdipGetPostScriptGraphicsContext (name, - width / 100 * 72, - height / 100 * 72, - // Harcoded dpy's - 300, 300, ref graphics); - - DOCINFO doc = new DOCINFO (); - doc.filename = name.ToString(); - doc.settings = settings; - doc.default_page_settings = default_page_settings; - doc_info.Add (graphics, doc); - - return graphics; + + if (dests != IntPtr.Zero) + cupsFreeDests(n_printers, dests); + + + if (default_printer.Equals (String.Empty)) + default_printer = first; } - internal int GetCupsOptions (PrinterSettings printer_settings, PageSettings page_settings, out IntPtr options) + /// <summary> + /// Gets a printer's settings for use in the print dialogue + /// </summary> + /// <param name="printer"></param> + /// <param name="port"></param> + /// <param name="type"></param> + /// <param name="status"></param> + /// <param name="comment"></param> + internal override void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment) { - options = IntPtr.Zero; - - PaperSize size = page_settings.PaperSize; - int width = size.Width * 72 / 100; - int height = size.Height * 72 / 100; - - string options_string = - "copies=" + printer_settings.Copies + " " + - "Collate=" + printer_settings.Collate + " " + - "ColorModel=" + (page_settings.Color ? "Color" : "Black") + " " + - "PageSize=" + String.Format ("Custom.{0}x{1}", width, height) + " " + - "landscape=" + page_settings.Landscape; - - return cupsParseOptions (options_string, 0, ref options); - } - - // Properties - - internal override PrinterSettings.StringCollection InstalledPrinters { - get { - int n_printers; - IntPtr dests = IntPtr.Zero, ptr_printers, ptr_printer; - int cups_dests_size = Marshal.SizeOf(typeof(CUPS_DESTS)); - string str; - PrinterSettings.StringCollection col = new PrinterSettings.StringCollection (new string[] {}); - - if (cups_installed == false) - return col; - - n_printers = cupsGetDests (ref dests); - - ptr_printers = dests; - for (int i = 0; i < n_printers; i++) { - ptr_printer = (IntPtr) Marshal.ReadInt32 (ptr_printers); - str = Marshal.PtrToStringAnsi (ptr_printer); - Marshal.FreeHGlobal (ptr_printer); - ptr_printers = new IntPtr (ptr_printers.ToInt64 () + cups_dests_size); - col.Add (str); - } - Marshal.FreeHGlobal (dests); - return col; - } - } - - internal override string DefaultPrinter { - get { - IntPtr str; - - if (cups_installed == false) - return string.Empty; + int count, state = -1; + bool found = false; + CUPS_DESTS cups_dests; + IntPtr dests = IntPtr.Zero, ptr_printers, ptr_printer; + int cups_dests_size = Marshal.SizeOf(typeof(CUPS_DESTS)); + + if (cups_installed == false) + return; - str = cupsGetDefault (); - if (str != IntPtr.Zero) - return Marshal.PtrToStringAnsi (str); + count = cupsGetDests (ref dests); - return GetAlternativeDefaultPrinter(); - } - } + if (dests == IntPtr.Zero) + return; - // Private functions - - /// <summary>
- /// Due to some weird cups thing, cupsGetDefault does not always return
- /// the default printer, hence this function, that goes through each
- /// printer searching for one that has the is_default flag set.
- /// If there is none with the flag, but there are printers available,
- /// returns the first one. See #80519, #80198
- /// </summary>
- /// <returns></returns> - private string GetAlternativeDefaultPrinter () - { - IntPtr printers = IntPtr.Zero; - string printer_name = String.Empty; + ptr_printers = dests; - int printer_count = cupsGetDests (ref printers); - try { - int cups_dests_size = Marshal.SizeOf (typeof (CUPS_DESTS)); - IntPtr current = printers; - for (int i = 0; i < printer_count; i++) { - CUPS_DESTS printer = (CUPS_DESTS) Marshal.PtrToStructure (current, typeof (CUPS_DESTS)); - - if ((printer.is_default != 0) || (printer_name.Length == 0)) { - printer_name = Marshal.PtrToStringAnsi (printer.name); - if (printer.is_default != 0) - break; - } - current = new IntPtr (current.ToInt64 () + cups_dests_size); + for (int i = 0; i < count; i++) { + ptr_printer = (IntPtr) Marshal.ReadInt32 (ptr_printers); + if (Marshal.PtrToStringAnsi (ptr_printer).Equals(printer)) { + found = true; + break; } + ptr_printers = (IntPtr) ((long)ptr_printers + cups_dests_size); } - finally { - Marshal.FreeHGlobal (printers); - } - - return printer_name; - } - - private string GetPaperSizeName (IntPtr ppd, string name) - { - string rslt = name; - PPD_OPTION option; - PPD_CHOICE choice; - IntPtr ptr_opt, ptr_choice; - ptr_opt = ppdFindOption (ppd, "PageSize"); - - if (ptr_opt == IntPtr.Zero) { - return rslt; - } + if (!found) + return; - option = (PPD_OPTION) Marshal.PtrToStructure (ptr_opt, typeof (PPD_OPTION)); - - ptr_choice = option.choices; - for (int c = 0; c < option.num_choices; c++) { - choice = (PPD_CHOICE) Marshal.PtrToStructure (ptr_choice, typeof (PPD_CHOICE)); - ptr_choice = new IntPtr (ptr_choice.ToInt64 () + Marshal.SizeOf (choice)); - if (name.Equals (choice.choice)) { - // Special case for custom size (cups returns NULL for it) - if (name == "Custom" && choice.text == null) - rslt = "Custom"; - else - rslt = choice.text; + cups_dests = (CUPS_DESTS) Marshal.PtrToStructure (ptr_printers, typeof (CUPS_DESTS)); + + NameValueCollection options = LoadPrinterOptions(cups_dests.options, cups_dests.num_options); - break; - } + if (dests != IntPtr.Zero) + cupsFreeDests(count, dests); + + if (options["printer-state"] != null) + state = Int32.Parse(options["printer-state"]); + + if (options["printer-comment"] != null) + comment = options["printer-state"]; + + switch(state) + { + case 4: + status = "Printing"; + break; + case 5: + status = "Stopped"; + break; + default: + status = "Ready"; + break; } - return rslt; } + /// <summary> + /// Returns the appropriate PaperKind for the width and height + /// </summary> + /// <param name="width"></param> + /// <param name="height"></param> private PaperKind GetPaperKind (int width, int height) { if (width == 827 && height == 1169) @@ -497,67 +638,138 @@ namespace System.Drawing.Printing return PaperKind.Custom; } - internal override void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment) - { - int printers, state = -1; - CUPS_DESTS cups_dests; - CUPS_OPTIONS options; - string str; - IntPtr dests = IntPtr.Zero, ptr_printers, ptr_printer, ptr_options; - int cups_dests_size = Marshal.SizeOf(typeof(CUPS_DESTS)); - int options_size = Marshal.SizeOf(typeof(CUPS_OPTIONS)); + #endregion + + #region Print job methods + + static string tmpfile; + + /// <summary> + /// Gets a pointer to an options list parsed from the printer's current settings, to use when setting up the printing job + /// </summary> + /// <param name="printer_settings"></param> + /// <param name="page_settings"></param> + /// <param name="options"></param> + internal static int GetCupsOptions (PrinterSettings printer_settings, PageSettings page_settings, out IntPtr options) + { + options = IntPtr.Zero; + + PaperSize size = page_settings.PaperSize; + int width = size.Width * 72 / 100; + int height = size.Height * 72 / 100; + + StringBuilder sb = new StringBuilder(); + sb.Append( + "copies=" + printer_settings.Copies + " " + + "Collate=" + printer_settings.Collate + " " + + "ColorModel=" + (page_settings.Color ? "Color" : "Black") + " " + + "PageSize=" + String.Format ("Custom.{0}x{1}", width, height) + " " + + "landscape=" + page_settings.Landscape + ); - if (cups_installed == false) - return; + if (printer_settings.CanDuplex) + { + if (printer_settings.Duplex == Duplex.Simplex) + sb.Append(" Duplex=None"); + else + sb.Append(" Duplex=DuplexNoTumble"); + } - printers = cupsGetDests (ref dests); + return cupsParseOptions (sb.ToString(), 0, ref options); + } - ptr_printers = dests; - for (int i = 0; i < printers; i++) { - cups_dests = (CUPS_DESTS) Marshal.PtrToStructure (ptr_printers, typeof (CUPS_DESTS)); - str = Marshal.PtrToStringAnsi (cups_dests.name); - ptr_printers = new IntPtr (ptr_printers.ToInt64 () + cups_dests_size); - if (str != printer) - continue; - - ptr_options = cups_dests.options; - for (int o = 0; o < cups_dests.num_options; o ++) { - options = (CUPS_OPTIONS) Marshal.PtrToStructure (ptr_options, typeof (CUPS_OPTIONS)); - str = Marshal.PtrToStringAnsi (options.name); - if (str == "printer-state") { - state = Int32.Parse (Marshal.PtrToStringAnsi (options.val)); - } else { - if (str == "printer-info") - comment = Marshal.PtrToStringAnsi (options.val); - } - ptr_options = new IntPtr (ptr_options.ToInt64 () + options_size); - } - + internal static bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file) + { + DOCINFO doc = (DOCINFO) doc_info[gr.Hdc]; + doc.title = doc_name; + return true; + } + + internal static bool EndDoc (GraphicsPrinter gr) + { + DOCINFO doc = (DOCINFO) doc_info[gr.Hdc]; + + gr.Graphics.Dispose (); // Dispose object to force surface finish + + IntPtr options; + int options_count = GetCupsOptions (doc.settings, doc.default_page_settings, out options); + + cupsPrintFile (doc.settings.PrinterName, doc.filename, doc.title, options_count, options); + cupsFreeOptions (options_count, options); + doc_info.Remove (gr.Hdc); + if (tmpfile != null) { + try { File.Delete (tmpfile); } + catch { } } + return true; + } - Marshal.FreeHGlobal (dests); + internal static bool StartPage (GraphicsPrinter gr) + { + return true; + } + + internal static bool EndPage (GraphicsPrinter gr) + { + GdipGetPostScriptSavePage (gr.Hdc); + return true; + } + + // Unfortunately, PrinterSettings and PageSettings couldn't be referencing each other, + // thus we need to pass them separately + internal static IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings) + { + IntPtr graphics = IntPtr.Zero; + string name; + if (!settings.PrintToFile) { + StringBuilder sb = new StringBuilder (1024); + int length = sb.Capacity; + cupsTempFile (sb, length); + name = sb.ToString (); + tmpfile = name; + } + else + name = settings.PrintFileName; - if (state == 4) { - status = "Printing"; + PaperSize psize = default_page_settings.PaperSize; + int width, height; + if (default_page_settings.Landscape) { // Swap in case of landscape + width = psize.Height; + height = psize.Width; + } else { + width = psize.Width; + height = psize.Height; } - else { - if (state == 5) { - status = "Stopped"; - } - else { - status = "Ready"; - } - } + + GdipGetPostScriptGraphicsContext (name, + width / 100 * 72, + height / 100 * 72, + // Harcoded dpy's + 300, 300, ref graphics); + + DOCINFO doc = new DOCINFO (); + doc.filename = name.ToString(); + doc.settings = settings; + doc.default_page_settings = default_page_settings; + doc_info.Add (graphics, doc); + + return graphics; } - // - // DllImports - // + #endregion + + #region DllImports [DllImport("libcups", CharSet=CharSet.Ansi)] static extern int cupsGetDests (ref IntPtr dests); [DllImport("libcups", CharSet=CharSet.Ansi)] + static extern int cupsGetDest (string name, string instance, int num_dests, ref IntPtr dests); + + [DllImport("libcups")] + static extern int cupsFreeDests (int num_dests, IntPtr dests); + + [DllImport("libcups", CharSet=CharSet.Ansi)] static extern IntPtr cupsTempFile (StringBuilder sb, int len); [DllImport("libcups", CharSet=CharSet.Ansi)] @@ -590,8 +802,9 @@ namespace System.Drawing.Printing [DllImport("gdiplus.dll")] static extern int GdipGetPostScriptSavePage (IntPtr graphics); + #endregion - //Struct + #region Struct public struct DOCINFO { public PrinterSettings settings; @@ -701,6 +914,42 @@ namespace System.Drawing.Printing public int num_options; public IntPtr options; } + + #endregion + } + + class GlobalPrintingServicesUnix : GlobalPrintingServices
+ {
+ internal override PrinterSettings.StringCollection InstalledPrinters {
+ get {
+ return PrintingServicesUnix.InstalledPrinters;
+ }
+ }
+
+ internal override IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings)
+ {
+ return PrintingServicesUnix.CreateGraphicsContext (settings, default_page_settings);
+ }
+
+ internal override bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file)
+ {
+ return PrintingServicesUnix.StartDoc (gr, doc_name, output_file);
+ }
+
+ internal override bool EndDoc (GraphicsPrinter gr)
+ {
+ return PrintingServicesUnix.EndDoc (gr);
+ }
+
+ internal override bool StartPage (GraphicsPrinter gr)
+ {
+ return PrintingServicesUnix.StartPage (gr);
+ }
+
+ internal override bool EndPage (GraphicsPrinter gr)
+ {
+ return PrintingServicesUnix.EndPage (gr);
+ }
} } diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesWin32.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesWin32.cs index 326d395505a..978032e7c66 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesWin32.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesWin32.cs @@ -43,14 +43,11 @@ namespace System.Drawing.Printing } - internal override bool IsPrinterValid(string printer, bool force) + internal override bool IsPrinterValid(string printer) { if (printer == null | printer == String.Empty) return false; - if (!force && this.printer_name != null && String.Intern(this.printer_name).Equals(printer)) - return is_printer_valid; - int ret = Win32DocumentProperties (IntPtr.Zero, IntPtr.Zero, printer, IntPtr.Zero, IntPtr.Zero, 0); is_printer_valid = (ret > 0); this.printer_name = printer; @@ -75,6 +72,12 @@ namespace System.Drawing.Printing ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_ORIENTATION, IntPtr.Zero, IntPtr.Zero); if (ret != -1) settings.landscape_angle = ret; + + IntPtr dc = IntPtr.Zero; + dc = Win32CreateIC (null, printer, null, IntPtr.Zero /* DEVMODE */); + ret = Win32GetDeviceCaps (dc, (int)DevCapabilities.TECHNOLOGY); + settings.is_plotter = ret == (int)PrinterType.DT_PLOTTER; + Win32DeleteDC (dc); try { Win32OpenPrinter (printer, out hPrn, IntPtr.Zero); @@ -88,13 +91,15 @@ namespace System.Drawing.Printing devmode = (DEVMODE) Marshal.PtrToStructure (ptr_dev, typeof(DEVMODE)); - foreach (PaperSize paper_size in settings.PaperSizes) { + LoadPrinterPaperSizes (printer, settings); + foreach (PaperSize paper_size in settings.PaperSizes) { if ((int) paper_size.Kind == devmode.dmPaperSize) { settings.DefaultPageSettings.PaperSize = paper_size; break; } } + LoadPrinterPaperSources (printer, settings); foreach (PaperSource paper_source in settings.PaperSources) { if ((int) paper_source.Kind == devmode.dmDefaultSource) { settings.DefaultPageSettings.PaperSource = paper_source; @@ -106,7 +111,7 @@ namespace System.Drawing.Printing Win32ClosePrinter (hPrn); if (ptr_dev != IntPtr.Zero) - Marshal.FreeHGlobal (ptr_dev); + Marshal.FreeHGlobal (ptr_dev); } @@ -140,7 +145,7 @@ namespace System.Drawing.Printing Marshal.FreeHGlobal (buff); } - internal override void LoadPrinterPaperSizes (string printer, PrinterSettings settings) + void LoadPrinterPaperSizes (string printer, PrinterSettings settings) { int items, ret; IntPtr ptr_names, buff_names = IntPtr.Zero; @@ -148,7 +153,11 @@ namespace System.Drawing.Printing IntPtr ptr_sizes_enum, buff_sizes_enum = IntPtr.Zero; string name; - settings.PaperSizes.Clear (); + if (settings.PaperSizes == null) + settings.paper_sizes = new PrinterSettings.PaperSizeCollection (new PaperSize [0]); + else + settings.PaperSizes.Clear (); + items = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_PAPERSIZE, IntPtr.Zero, IntPtr.Zero); if (items == -1) @@ -202,7 +211,7 @@ namespace System.Drawing.Printing } } - internal override bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file) + internal static bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file) { DOCINFO di = new DOCINFO (); int ret; @@ -218,7 +227,7 @@ namespace System.Drawing.Printing return (ret > 0) ? true : false; } - internal override void LoadPrinterPaperSources (string printer, PrinterSettings settings) + void LoadPrinterPaperSources (string printer, PrinterSettings settings) { int items, ret; IntPtr ptr_names, buff_names = IntPtr.Zero; @@ -226,7 +235,11 @@ namespace System.Drawing.Printing PaperSourceKind kind; string name; - settings.PaperSources.Clear (); + if (settings.PaperSources == null) + settings.paper_sources = new PrinterSettings.PaperSourceCollection (new PaperSource [0]); + else + settings.PaperSources.Clear (); + items = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_BINNAMES, IntPtr.Zero, IntPtr.Zero); if (items == -1) @@ -266,19 +279,19 @@ namespace System.Drawing.Printing } - internal override bool StartPage (GraphicsPrinter gr) + internal static bool StartPage (GraphicsPrinter gr) { int ret = Win32StartPage (gr.Hdc); return (ret > 0) ? true : false; } - internal override bool EndPage (GraphicsPrinter gr) + internal static bool EndPage (GraphicsPrinter gr) { int ret = Win32EndPage (gr.Hdc); return (ret > 0) ? true : false; } - internal override bool EndDoc (GraphicsPrinter gr) + internal static bool EndDoc (GraphicsPrinter gr) { int ret = Win32EndDoc (gr.Hdc); Win32DeleteDC (gr.Hdc); @@ -286,7 +299,7 @@ namespace System.Drawing.Printing return (ret > 0) ? true : false; } - internal override IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings) + internal static IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings) { IntPtr dc = IntPtr.Zero; dc = Win32CreateDC (null, settings.PrinterName, null, IntPtr.Zero /* DEVMODE */); @@ -300,13 +313,13 @@ namespace System.Drawing.Printing int length = name.Capacity; if (Win32GetDefaultPrinter (name, ref length) > 0) - if (this.IsPrinterValid(name.ToString(), false)) + if (IsPrinterValid(name.ToString())) return name.ToString (); return String.Empty; } } - internal override PrinterSettings.StringCollection InstalledPrinters { + internal static PrinterSettings.StringCollection InstalledPrinters { get { PrinterSettings.StringCollection col = new PrinterSettings.StringCollection (new string[] {}); PRINTER_INFO printer_info; @@ -409,14 +422,14 @@ namespace System.Drawing.Printing // DllImports // - [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="OpenPrinter", SetLastError=true)]
+ [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="OpenPrinter", SetLastError=true)] static extern int Win32OpenPrinter (string pPrinterName, out IntPtr phPrinter, IntPtr pDefault); [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="GetPrinter", SetLastError=true)] static extern int Win32GetPrinter (IntPtr hPrinter, int level, IntPtr dwBuf, int size, ref int dwNeeded); [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="ClosePrinter", SetLastError=true)] - static extern int Win32ClosePrinter (IntPtr hPrinter);
+ static extern int Win32ClosePrinter (IntPtr hPrinter); [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="DeviceCapabilities", SetLastError=true)] static extern int Win32DeviceCapabilities (string device, string port, DCCapabilities cap, IntPtr outputBuffer, IntPtr deviceMode); @@ -425,17 +438,21 @@ namespace System.Drawing.Printing static extern int Win32EnumPrinters (int Flags, string Name, uint Level, IntPtr pPrinterEnum, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned); - [DllImport("winspool.drv", EntryPoint="GetDefaultPrinter", CharSet=CharSet.Unicode, SetLastError=true)] - private static extern int Win32GetDefaultPrinter (StringBuilder buffer, ref int bufferSize); + [DllImport("winspool.drv", EntryPoint="GetDefaultPrinter", CharSet=CharSet.Unicode, SetLastError=true)] + private static extern int Win32GetDefaultPrinter (StringBuilder buffer, ref int bufferSize); - [DllImport("winspool.drv", EntryPoint="DocumentProperties", CharSet=CharSet.Unicode, SetLastError=true)]
+ [DllImport("winspool.drv", EntryPoint="DocumentProperties", CharSet=CharSet.Unicode, SetLastError=true)] private static extern int Win32DocumentProperties (IntPtr hwnd, IntPtr hPrinter, string pDeviceName, IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode); - [DllImport("gdi32.dll", EntryPoint="CreateDC")] + [DllImport("gdi32.dll", EntryPoint="CreateDC")] static extern IntPtr Win32CreateDC (string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData); + [DllImport("gdi32.dll", EntryPoint="CreateIC")] + static extern IntPtr Win32CreateIC (string lpszDriver, string lpszDevice, + string lpszOutput, IntPtr lpInitData); + [DllImport("gdi32.dll", CharSet=CharSet.Unicode, EntryPoint="StartDoc")] static extern int Win32StartDoc (IntPtr hdc, [In] ref DOCINFO lpdi); @@ -451,9 +468,12 @@ namespace System.Drawing.Printing [DllImport("gdi32.dll", EntryPoint="DeleteDC")] public static extern IntPtr Win32DeleteDC (IntPtr hDc); - // - // Structs - // + [DllImport("gdi32.dll", EntryPoint="GetDeviceCaps")] + public static extern int Win32GetDeviceCaps (IntPtr hDc, int index); + + // + // Structs + // [StructLayout (LayoutKind.Sequential)] internal struct PRINTER_INFO { @@ -478,9 +498,9 @@ namespace System.Drawing.Printing public uint Status; public uint cJobs; public uint AveragePPM; - } + } - [StructLayout (LayoutKind.Sequential)] + [StructLayout (LayoutKind.Sequential)] internal struct DOCINFO { public int cbSize; @@ -490,47 +510,47 @@ namespace System.Drawing.Printing public int fwType; } - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
- internal struct DEVMODE
- {
- [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
- public string dmDeviceName;
- public short dmSpecVersion;
- public short dmDriverVersion;
- public short dmSize;
- public short dmDriverExtra;
- public int dmFields;
-
- public short dmOrientation;
- public short dmPaperSize;
- public short dmPaperLength;
- public short dmPaperWidth;
-
- public short dmScale;
- public short dmCopies;
- public short dmDefaultSource;
- public short dmPrintQuality;
- public short dmColor;
- public short dmDuplex;
- public short dmYResolution;
- public short dmTTOption;
- public short dmCollate;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
- public string dmFormName;
- public short dmLogPixels;
- public short dmBitsPerPel;
- public int dmPelsWidth;
- public int dmPelsHeight;
- public int dmDisplayFlags;
- public int dmDisplayFrequency;
- public int dmICMMethod;
- public int dmICMIntent;
- public int dmMediaType;
- public int dmDitherType;
- public int dmReserved1;
- public int dmReserved2;
- public int dmPanningWidth;
- public int dmPanningHeight;
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] + internal struct DEVMODE + { + [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] + public string dmDeviceName; + public short dmSpecVersion; + public short dmDriverVersion; + public short dmSize; + public short dmDriverExtra; + public int dmFields; + + public short dmOrientation; + public short dmPaperSize; + public short dmPaperLength; + public short dmPaperWidth; + + public short dmScale; + public short dmCopies; + public short dmDefaultSource; + public short dmPrintQuality; + public short dmColor; + public short dmDuplex; + public short dmYResolution; + public short dmTTOption; + public short dmCollate; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string dmFormName; + public short dmLogPixels; + public short dmBitsPerPel; + public int dmPelsWidth; + public int dmPelsHeight; + public int dmDisplayFlags; + public int dmDisplayFrequency; + public int dmICMMethod; + public int dmICMIntent; + public int dmMediaType; + public int dmDitherType; + public int dmReserved1; + public int dmReserved2; + public int dmPanningWidth; + public int dmPanningHeight; } // Enums @@ -574,33 +594,86 @@ namespace System.Drawing.Printing [Flags] internal enum PrinterStatus : uint { - PS_PAUSED = 0x00000001,
- PS_ERROR = 0x00000002,
- PS_PENDING_DELETION = 0x00000004,
- PS_PAPER_JAM = 0x00000008,
- PS_PAPER_OUT = 0x00000010,
- PS_MANUAL_FEED = 0x00000020,
- PS_PAPER_PROBLEM = 0x00000040,
- PS_OFFLINE = 0x00000080,
- PS_IO_ACTIVE = 0x00000100,
- PS_BUSY = 0x00000200,
- PS_PRINTING = 0x00000400,
- PS_OUTPUT_BIN_FULL = 0x00000800,
- PS_NOT_AVAILABLE = 0x00001000,
- PS_WAITING = 0x00002000,
- PS_PROCESSING = 0x00004000,
- PS_INITIALIZING = 0x00008000,
- PS_WARMING_UP = 0x00010000,
- PS_TONER_LOW = 0x00020000,
- PS_NO_TONER = 0x00040000,
- PS_PAGE_PUNT = 0x00080000,
- PS_USER_INTERVENTION = 0x00100000,
- PS_OUT_OF_MEMORY = 0x00200000,
- PS_DOOR_OPEN = 0x00400000,
- PS_SERVER_UNKNOWN = 0x00800000,
+ PS_PAUSED = 0x00000001, + PS_ERROR = 0x00000002, + PS_PENDING_DELETION = 0x00000004, + PS_PAPER_JAM = 0x00000008, + PS_PAPER_OUT = 0x00000010, + PS_MANUAL_FEED = 0x00000020, + PS_PAPER_PROBLEM = 0x00000040, + PS_OFFLINE = 0x00000080, + PS_IO_ACTIVE = 0x00000100, + PS_BUSY = 0x00000200, + PS_PRINTING = 0x00000400, + PS_OUTPUT_BIN_FULL = 0x00000800, + PS_NOT_AVAILABLE = 0x00001000, + PS_WAITING = 0x00002000, + PS_PROCESSING = 0x00004000, + PS_INITIALIZING = 0x00008000, + PS_WARMING_UP = 0x00010000, + PS_TONER_LOW = 0x00020000, + PS_NO_TONER = 0x00040000, + PS_PAGE_PUNT = 0x00080000, + PS_USER_INTERVENTION = 0x00100000, + PS_OUT_OF_MEMORY = 0x00200000, + PS_DOOR_OPEN = 0x00400000, + PS_SERVER_UNKNOWN = 0x00800000, PS_POWER_SAVE = 0x01000000 } + + // for use in GetDeviceCaps + internal enum DevCapabilities + { + TECHNOLOGY = 2, + } + + internal enum PrinterType + { + DT_PLOTTER = 0, // Vector Plotter + DT_RASDIPLAY = 1, // Raster Display + DT_RASPRINTER = 2, // Raster printer + DT_RASCAMERA = 3, // Raster camera + DT_CHARSTREAM = 4, // Character-stream, PLP + DT_METAFILE = 5, // Metafile, VDM + DT_DISPFILE = 6, // Display-file + } + } + + class GlobalPrintingServicesWin32 : GlobalPrintingServices + { + internal override PrinterSettings.StringCollection InstalledPrinters { + get { + return PrintingServicesWin32.InstalledPrinters; + } + } + + internal override IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings) + { + return PrintingServicesWin32.CreateGraphicsContext (settings, default_page_settings); + } + + internal override bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file) + { + return PrintingServicesWin32.StartDoc (gr, doc_name, output_file); + } + + internal override bool EndDoc (GraphicsPrinter gr) + { + return PrintingServicesWin32.EndDoc (gr); + } + + internal override bool StartPage (GraphicsPrinter gr) + { + return PrintingServicesWin32.StartPage (gr); + } + + internal override bool EndPage (GraphicsPrinter gr) + { + return PrintingServicesWin32.EndPage (gr); + } + } } + diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/StandardPrintController.cs b/mcs/class/System.Drawing/System.Drawing.Printing/StandardPrintController.cs index 8f4428b8844..fe108a03464 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/StandardPrintController.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/StandardPrintController.cs @@ -44,24 +44,24 @@ namespace System.Drawing.Printing public override void OnEndPage (PrintDocument document, PrintPageEventArgs e) { - SysPrn.Service.EndPage (e.GraphicsContext); + SysPrn.GlobalService.EndPage (e.GraphicsContext); } public override void OnStartPrint (PrintDocument document, PrintEventArgs e) { - IntPtr dc = SysPrn.Service.CreateGraphicsContext (document.PrinterSettings, document.DefaultPageSettings); + IntPtr dc = SysPrn.GlobalService.CreateGraphicsContext (document.PrinterSettings, document.DefaultPageSettings); e.GraphicsContext = new GraphicsPrinter (null, dc); - SysPrn.Service.StartDoc (e.GraphicsContext, document.DocumentName, string.Empty); + SysPrn.GlobalService.StartDoc (e.GraphicsContext, document.DocumentName, string.Empty); } public override void OnEndPrint (PrintDocument document, PrintEventArgs e) { - SysPrn.Service.EndDoc (e.GraphicsContext); + SysPrn.GlobalService.EndDoc (e.GraphicsContext); } public override Graphics OnStartPage (PrintDocument document, PrintPageEventArgs e) { - SysPrn.Service.StartPage (e.GraphicsContext); + SysPrn.GlobalService.StartPage (e.GraphicsContext); return e.Graphics; } } |