{
private Hashtable doc_info = new Hashtable ();
private bool cups_installed;
+ private string printer_name;
+ private bool is_printer_valid;
internal PrintingServicesUnix ()
{
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)
PPD_FILE ppd;
PPD_SIZE size;
PaperSize ps;
- PaperKind kind = PaperKind.Custom;
settings.PaperSizes.Clear ();
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);
}
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); }
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;
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 {
return string.Empty;
str = cupsGetDefault ();
- return Marshal.PtrToStringAnsi (str);
+ if (str == IntPtr.Zero)
+ return Marshal.PtrToStringAnsi (str);
+ return String.Empty;
}
}
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";
+ }
+ }
}
//
[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);
public struct DOCINFO
{
public PrinterSettings settings;
+ public PageSettings default_page_settings;
public string title;
public string filename;
}
/* 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;
+ }
}
}