X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Drawing%2FSystem.Drawing.Printing%2FPrintingServicesUnix.cs;h=afcf9b29c8d22f5a95a02ccc738791d3c72a7671;hb=b1dab8b8bef3f6ba081603c8af3977d08dc630c7;hp=09ec7d2a63a8df626b9c4195bb425001c5497ca2;hpb=c4a3b30460c7ea1a1fb3c97cfc8478555714af2f;p=mono.git diff --git a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs index 09ec7d2a63a..afcf9b29c8d 100644 --- a/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs +++ b/mcs/class/System.Drawing/System.Drawing.Printing/PrintingServicesUnix.cs @@ -39,6 +39,8 @@ namespace System.Drawing.Printing { private Hashtable doc_info = new Hashtable (); private bool cups_installed; + private string printer_name; + private bool is_printer_valid; internal PrintingServicesUnix () { @@ -58,6 +60,21 @@ namespace System.Drawing.Printing cups_installed = true; } + + internal override bool IsPrinterValid(string printer, bool force) + { + if (!cups_installed || printer == null | printer == String.Empty) + return false; + + if (!force && this.printer_name != null && String.Intern(this.printer_name).Equals(printer)) + return is_printer_valid; + + IntPtr ptr = cupsGetPPD (printer); + string ppd_filename = Marshal.PtrToStringAnsi (ptr); + is_printer_valid = ppd_filename != null; + this.printer_name = printer; + return is_printer_valid; + } // Methods internal override void LoadPrinterSettings (string printer, PrinterSettings settings) @@ -136,7 +153,6 @@ namespace System.Drawing.Printing PPD_FILE ppd; PPD_SIZE size; PaperSize ps; - PaperKind kind = PaperKind.Custom; settings.PaperSizes.Clear (); @@ -154,8 +170,7 @@ namespace System.Drawing.Printing w = size.width * 100 / 72; h = size.length * 100 / 72; ps = new PaperSize (real_name, (int) w, (int) h); - // TODO: Convert from name to paper kind enum - ps.SetKind (kind); + ps.SetKind (GetPaperKind ((int) w, (int) h)); settings.PaperSizes.Add (ps); } @@ -214,7 +229,12 @@ namespace System.Drawing.Printing DOCINFO doc = (DOCINFO) doc_info[gr.Hdc]; gr.Graphics.Dispose (); // Dispose object to force surface finish - cupsPrintFile (doc.settings.PrinterName, doc.filename, doc.title, 0, IntPtr.Zero); + + 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); } @@ -230,7 +250,9 @@ namespace System.Drawing.Printing return true; } - internal override IntPtr CreateGraphicsContext (PrinterSettings settings) + // 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; @@ -245,19 +267,37 @@ namespace System.Drawing.Printing name = settings.PrintFileName; GdipGetPostScriptGraphicsContext (name, - settings.DefaultPageSettings.PaperSize.Width / 100 * 72, - settings.DefaultPageSettings.PaperSize.Height / 100 * 72, + default_page_settings.PaperSize.Width / 100 * 72, + default_page_settings.PaperSize.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; } + internal 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; + + 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); + + return cupsParseOptions (options_string, 0, ref options); + } + // Properties internal override PrinterSettings.StringCollection InstalledPrinters { @@ -293,7 +333,9 @@ namespace System.Drawing.Printing return string.Empty; str = cupsGetDefault (); - return Marshal.PtrToStringAnsi (str); + if (str == IntPtr.Zero) + return Marshal.PtrToStringAnsi (str); + return String.Empty; } } @@ -319,17 +361,143 @@ namespace System.Drawing.Printing 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)) { - rslt = choice.text; + // Special case for custom size (cups returns NULL for it) + if (name == "Custom" && choice.text == null) + rslt = "Custom"; + else + rslt = choice.text; + break; } } return rslt; } - // TODO + private PaperKind GetPaperKind (int width, int height) + { + if (width == 827 && height == 1169) + return PaperKind.A4; + if (width == 583 && height == 827) + return PaperKind.A5; + if (width == 717 && height == 1012) + return PaperKind.B5; + if (width == 693 && height == 984) + return PaperKind.B5Envelope; + if (width == 638 && height == 902) + return PaperKind.C5Envelope; + if (width == 449 && height == 638) + return PaperKind.C6Envelope; + if (width == 1700 && height == 2200) + return PaperKind.CSheet; + if (width == 433 && height == 866) + return PaperKind.DLEnvelope; + if (width == 2200 && height == 3400) + return PaperKind.DSheet; + if (width == 3400 && height == 4400) + return PaperKind.ESheet; + if (width == 725 && height == 1050) + return PaperKind.Executive; + if (width == 850 && height == 1300) + return PaperKind.Folio; + if (width == 850 && height == 1200) + return PaperKind.GermanStandardFanfold; + if (width == 1700 && height == 1100) + return PaperKind.Ledger; + if (width == 850 && height == 1400) + return PaperKind.Legal; + if (width == 927 && height == 1500) + return PaperKind.LegalExtra; + if (width == 850 && height == 1100) + return PaperKind.Letter; + if (width == 927 && height == 1200) + return PaperKind.LetterExtra; + if (width == 850 && height == 1269) + return PaperKind.LetterPlus; + if (width == 387 && height == 750) + return PaperKind.MonarchEnvelope; + if (width == 387 && height == 887) + return PaperKind.Number9Envelope; + if (width == 413 && height == 950) + return PaperKind.Number10Envelope; + if (width == 450 && height == 1037) + return PaperKind.Number11Envelope; + if (width == 475 && height == 1100) + return PaperKind.Number12Envelope; + if (width == 500 && height == 1150) + return PaperKind.Number14Envelope; + if (width == 363 && height == 650) + return PaperKind.PersonalEnvelope; + if (width == 1000 && height == 1100) + return PaperKind.Standard10x11; + if (width == 1000 && height == 1400) + return PaperKind.Standard10x14; + if (width == 1100 && height == 1700) + return PaperKind.Standard11x17; + if (width == 1200 && height == 1100) + return PaperKind.Standard12x11; + if (width == 1500 && height == 1100) + return PaperKind.Standard15x11; + if (width == 900 && height == 1100) + return PaperKind.Standard9x11; + if (width == 550 && height == 850) + return PaperKind.Statement; + if (width == 1100 && height == 1700) + return PaperKind.Tabloid; + if (width == 1487 && height == 1100) + return PaperKind.USStandardFanfold; + + return PaperKind.Custom; + } + internal override void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment) { - status = "Ready"; + int printers, state = -1; + CUPS_DESTS cups_dests; + CUPS_OPTIONS options; + string str; + IntPtr dests = IntPtr.Zero, ptr_printers, ptr_printer, ptr_options; + + if (cups_installed == false) + return; + + printers = cupsGetDests (ref dests); + + 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 () + 20 /*size of CUPS_DEST*/); + 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 () + 8 /*size of CUPS_DEST*/); + } + + } + + Marshal.FreeHGlobal (dests); + + if (state == 4) { + status = "Printing"; + } + else { + if (state == 5) { + status = "Stopped"; + } + else { + status = "Ready"; + } + } } // @@ -360,6 +528,12 @@ namespace System.Drawing.Printing [DllImport("libcups")] static extern void ppdClose (IntPtr ppd); + [DllImport ("libcups", CharSet=CharSet.Ansi)] + static extern int cupsParseOptions (string arg, int number_of_options, ref IntPtr options); + + [DllImport("libcups")] + static extern void cupsFreeOptions (int number_options, IntPtr options); + [DllImport("gdiplus.dll", CharSet=CharSet.Ansi)] static extern int GdipGetPostScriptGraphicsContext (string filename, int with, int height, double dpix, double dpiy, ref IntPtr graphics); @@ -371,6 +545,7 @@ namespace System.Drawing.Printing public struct DOCINFO { public PrinterSettings settings; + public PageSettings default_page_settings; public string title; public string filename; } @@ -460,6 +635,22 @@ namespace System.Drawing.Printing /* There is more data after this that we are not using*/ } + + + public struct CUPS_OPTIONS + { + public IntPtr name; + public IntPtr val; + } + + public struct CUPS_DESTS + { + public IntPtr name; + public IntPtr instance; + public int is_default; + public int num_options; + public IntPtr options; + } } }