* OleDbParameterCollectionTest.cs: Fix compile error in 1.1 profile.
[mono.git] / mcs / class / System.Drawing / System.Drawing.Printing / PrintingServicesWin32.cs
1 //
2 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Author:
24 //
25 //      Jordi Mas i Hernandez, jordimash@gmail.com
26 //
27
28 using System.Runtime.InteropServices;
29 using System.Collections;
30 using System.Drawing.Printing;
31 using System.ComponentModel;
32 using System.Text;
33
34 namespace System.Drawing.Printing
35 {
36         internal class PrintingServicesWin32 : PrintingServices
37         {
38                 private string printer_name;
39                 private bool is_printer_valid;
40
41                 internal PrintingServicesWin32 ()
42                 {
43
44                 }
45
46                 internal override bool IsPrinterValid(string printer)
47                 {
48                         if (printer == null | printer == String.Empty)
49                                 return false;
50
51                         int ret = Win32DocumentProperties (IntPtr.Zero, IntPtr.Zero, printer, IntPtr.Zero, IntPtr.Zero, 0);
52                         is_printer_valid = (ret > 0);
53                         this.printer_name = printer; 
54                         return is_printer_valid;
55                 }
56
57                 internal override void LoadPrinterSettings (string printer, PrinterSettings settings)
58                 {
59                         int ret;
60                         DEVMODE devmode;
61                         IntPtr hPrn = IntPtr.Zero;
62                         IntPtr ptr_dev = IntPtr.Zero;
63
64                         settings.maximum_copies = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_COPIES, IntPtr.Zero, IntPtr.Zero);
65
66                         ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_DUPLEX, IntPtr.Zero, IntPtr.Zero);
67                         settings.can_duplex = (ret == 1) ? true : false;
68
69                         ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_COLORDEVICE, IntPtr.Zero, IntPtr.Zero);
70                         settings.supports_color = (ret == 1) ? true : false;
71
72                         ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_ORIENTATION, IntPtr.Zero, IntPtr.Zero);
73                         if (ret != -1)
74                                 settings.landscape_angle = ret;
75                         
76                         IntPtr dc = IntPtr.Zero;
77                         dc = Win32CreateIC (null, printer, null, IntPtr.Zero /* DEVMODE */);
78                         ret = Win32GetDeviceCaps (dc, (int)DevCapabilities.TECHNOLOGY);
79                         settings.is_plotter = ret == (int)PrinterType.DT_PLOTTER;
80                         Win32DeleteDC (dc);
81
82                         try {
83                                 Win32OpenPrinter (printer, out hPrn, IntPtr.Zero);
84                                 ret = Win32DocumentProperties (IntPtr.Zero, hPrn, null, IntPtr.Zero, IntPtr.Zero, 2);
85
86                                 if (ret < 0)
87                                         return;
88
89                                 ptr_dev =  Marshal.AllocHGlobal (ret);
90                                 ret = Win32DocumentProperties (IntPtr.Zero, hPrn, null, ptr_dev, IntPtr.Zero, 2);
91
92                                 devmode = (DEVMODE) Marshal.PtrToStructure (ptr_dev, typeof(DEVMODE));
93
94                                 LoadPrinterPaperSizes (printer, settings);
95                         foreach (PaperSize paper_size in settings.PaperSizes) {
96                                         if ((int) paper_size.Kind ==  devmode.dmPaperSize) {
97                                                 settings.DefaultPageSettings.PaperSize = paper_size;
98                                                 break;
99                                         }
100                                 }
101
102                                 LoadPrinterPaperSources (printer, settings);
103                                 foreach (PaperSource paper_source in settings.PaperSources) {
104                                         if ((int) paper_source.Kind ==  devmode.dmDefaultSource) {
105                                                 settings.DefaultPageSettings.PaperSource = paper_source;
106                                                 break;
107                                         }
108                                 }
109                         }
110                         finally {
111                                 Win32ClosePrinter (hPrn);
112
113                                 if (ptr_dev != IntPtr.Zero)
114                                                 Marshal.FreeHGlobal (ptr_dev);
115                         }
116
117
118                 }
119
120                 internal override void LoadPrinterResolutions (string printer, PrinterSettings settings)
121                 {
122                         int ret;
123                         IntPtr ptr, buff = IntPtr.Zero;
124
125                         settings.PrinterResolutions.Clear ();
126                         LoadDefaultResolutions (settings.PrinterResolutions);
127                         ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_ENUMRESOLUTIONS, IntPtr.Zero, IntPtr.Zero);
128
129                         if (ret == -1)
130                                 return;
131
132                         ptr = buff = Marshal.AllocHGlobal (ret * 2 * Marshal.SizeOf (buff));
133                         ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_ENUMRESOLUTIONS, buff, IntPtr.Zero);
134                         int x, y;
135                         if (ret != -1) {
136                                 for (int i = 0; i < ret; i++) {
137                                         x = Marshal.ReadInt32 (ptr);
138                                         ptr = new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (x));
139                                         y = Marshal.ReadInt32 (ptr);
140                                         ptr = new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (y));
141                                         settings.PrinterResolutions.Add (new PrinterResolution
142                                                 (x,y, PrinterResolutionKind.Custom));
143                                 }
144                         }
145                         Marshal.FreeHGlobal (buff);
146                 }
147
148                 void LoadPrinterPaperSizes (string printer, PrinterSettings settings)
149                 {
150                         int items, ret;
151                         IntPtr ptr_names, buff_names = IntPtr.Zero;
152                         IntPtr ptr_sizes, buff_sizes = IntPtr.Zero;
153                         IntPtr ptr_sizes_enum, buff_sizes_enum = IntPtr.Zero;
154                         string name;
155
156                         if (settings.PaperSizes == null)
157                                 settings.paper_sizes = new PrinterSettings.PaperSizeCollection (new PaperSize [0]);
158                         else
159                                 settings.PaperSizes.Clear ();
160
161                         items = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_PAPERSIZE, IntPtr.Zero, IntPtr.Zero);
162
163                         if (items == -1)
164                                 return;
165
166                         try {
167                                 ptr_sizes = buff_sizes = Marshal.AllocHGlobal (items * 2 * 4);
168                                 ptr_names = buff_names = Marshal.AllocHGlobal (items * 64 * 2);
169                                 ptr_sizes_enum = buff_sizes_enum = Marshal.AllocHGlobal (items * 2);
170                                 ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_PAPERSIZE, buff_sizes, IntPtr.Zero);
171
172                                 if (ret == -1) {
173                                         // the finally clause will free the unmanaged memory before returning
174                                         return;
175                                 }
176
177                                 ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_PAPERS, buff_sizes_enum, IntPtr.Zero);
178                                 ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_PAPERNAMES, buff_names, IntPtr.Zero);
179
180                                 int x, y;
181                                 PaperSize ps;
182                                 PaperKind kind;
183                                 for (int i = 0; i < ret; i++) {
184                                         x = Marshal.ReadInt32 (ptr_sizes, i * 8);
185                                         y = Marshal.ReadInt32 (ptr_sizes, (i * 8) + 4);
186
187                                         x = PrinterUnitConvert.Convert (x, PrinterUnit.TenthsOfAMillimeter,
188                                               PrinterUnit.Display);
189
190                                         y = PrinterUnitConvert.Convert (y, PrinterUnit.TenthsOfAMillimeter,
191                                               PrinterUnit.Display);
192
193                                         name  = Marshal.PtrToStringUni (ptr_names);
194                                         ptr_names = new IntPtr (ptr_names.ToInt64 () + 64 * 2);
195
196                                         kind = (PaperKind) Marshal.ReadInt16 (ptr_sizes_enum);
197                                         ptr_sizes_enum = new IntPtr (ptr_sizes_enum.ToInt64 () + 2);
198
199                                         ps = new PaperSize (name, x,y);
200                                         ps.SetKind (kind);
201                                         settings.PaperSizes.Add (ps);
202                                 }
203                         }
204                         finally {
205                                 if (buff_names != IntPtr.Zero)
206                                         Marshal.FreeHGlobal (buff_names);
207                                 if (buff_sizes != IntPtr.Zero)
208                                         Marshal.FreeHGlobal (buff_sizes);
209                                 if (buff_sizes_enum != IntPtr.Zero)
210                                         Marshal.FreeHGlobal (buff_sizes_enum);
211                         }
212                 }
213
214                 internal static bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file)
215                 {
216                         DOCINFO di = new DOCINFO ();
217                         int ret;
218
219                         di.cbSize = Marshal.SizeOf (di);
220                         di.lpszDocName = Marshal.StringToHGlobalUni (doc_name);
221                         di.lpszOutput = IntPtr.Zero;
222                         di.lpszDatatype = IntPtr.Zero;
223                         di.fwType = 0;
224
225                         ret = Win32StartDoc (gr.Hdc, ref di);
226                         Marshal.FreeHGlobal (di.lpszDocName);
227                         return (ret > 0) ? true : false;
228                 }
229
230                 void LoadPrinterPaperSources (string printer, PrinterSettings settings)
231                 {
232                         int items, ret;
233                         IntPtr ptr_names, buff_names = IntPtr.Zero;
234                         IntPtr ptr_bins, buff_bins = IntPtr.Zero;
235                         PaperSourceKind kind;
236                         string name;
237
238                         if (settings.PaperSources == null)
239                                 settings.paper_sources = new PrinterSettings.PaperSourceCollection (new PaperSource [0]);
240                         else
241                                 settings.PaperSources.Clear ();
242
243                         items = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_BINNAMES, IntPtr.Zero, IntPtr.Zero);
244
245                         if (items == -1)
246                                 return;
247
248                         try {
249                                 ptr_names = buff_names = Marshal.AllocHGlobal (items * 2 * 24);
250                                 ptr_bins = buff_bins = Marshal.AllocHGlobal (items * 2);
251
252                                 ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_BINNAMES, buff_names, IntPtr.Zero);
253
254                                 if (ret == -1) {
255                                         // the finally clause will free the unmanaged memory before returning
256                                         return;
257                                 }
258
259                                 ret = Win32DeviceCapabilities (printer, null, DCCapabilities.DC_BINS, buff_bins, IntPtr.Zero);
260
261                                 for (int i = 0; i < ret; i++) {
262                                         name  = Marshal.PtrToStringUni (ptr_names);
263                                         kind = (PaperSourceKind) Marshal.ReadInt16 (ptr_bins);
264                                         settings.PaperSources.Add (new PaperSource (name, kind));
265
266                                         ptr_names = new IntPtr (ptr_names.ToInt64 () + 24 * 2);
267                                         ptr_bins = new IntPtr (ptr_bins.ToInt64 () + 2);
268                                 }
269
270                         }
271                         finally {
272                                 if (buff_names != IntPtr.Zero)
273                                         Marshal.FreeHGlobal (buff_names);
274
275                                 if (buff_bins != IntPtr.Zero)
276                                         Marshal.FreeHGlobal (buff_bins);
277
278                         }
279
280                 }
281
282                 internal static bool StartPage (GraphicsPrinter gr)
283                 {
284                         int ret = Win32StartPage (gr.Hdc);
285                         return (ret > 0) ? true : false;
286                 }
287
288                 internal static bool EndPage (GraphicsPrinter gr)
289                 {
290                         int ret = Win32EndPage (gr.Hdc);
291                         return (ret > 0) ? true : false;
292                 }
293
294                 internal static bool EndDoc (GraphicsPrinter gr)
295                 {
296                         int ret = Win32EndDoc (gr.Hdc);
297                         Win32DeleteDC (gr.Hdc);
298                         gr.Graphics.Dispose ();
299                         return (ret > 0) ? true : false;
300                 }
301
302                 internal static IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings)
303                 {
304                         IntPtr dc = IntPtr.Zero;
305                         dc = Win32CreateDC (null, settings.PrinterName, null, IntPtr.Zero /* DEVMODE */);
306                         return dc;
307                 }
308
309                 // Properties
310                 internal override string DefaultPrinter {
311                         get {
312                                 StringBuilder name = new StringBuilder (1024);
313                                 int length = name.Capacity;
314
315                                 if (Win32GetDefaultPrinter (name, ref length) > 0)
316                                         if (IsPrinterValid(name.ToString()))
317                                                 return name.ToString ();
318                                 return String.Empty;
319                         }
320                 }
321
322                 internal static PrinterSettings.StringCollection InstalledPrinters {
323                         get {
324                                 PrinterSettings.StringCollection col = new PrinterSettings.StringCollection (new string[] {});
325                                 PRINTER_INFO printer_info;
326                                 uint cbNeeded = 0, printers = 0;
327                                 IntPtr ptr, buff;
328                                 string s;
329
330                                 // Determine space need it
331                         Win32EnumPrinters (2 /* PRINTER_ENUM_LOCAL */,
332                                 null, 2, IntPtr.Zero, 0, ref cbNeeded, ref printers);
333
334                                 if (cbNeeded <= 0)
335                                         return col;
336
337                         ptr = buff = Marshal.AllocHGlobal ((int) cbNeeded);
338
339                                 try {
340                                         // Give us the printer list
341                                         Win32EnumPrinters (2 /* PRINTER_ENUM_LOCAL */,
342                                                 null, 2, buff, (uint)cbNeeded, ref cbNeeded, ref printers);
343
344                                         for (int i = 0; i < printers; i++) {
345                                                 printer_info = (PRINTER_INFO) Marshal.PtrToStructure (ptr, typeof (PRINTER_INFO));
346                                                 s  = Marshal.PtrToStringUni (printer_info.pPrinterName);
347                                                 col.Add (s);
348                                                 ptr = new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (printer_info));
349                                         }
350                                 }
351                                 finally {
352                                         Marshal.FreeHGlobal (buff);
353                                 }
354                                 return col;
355                         }
356                 }
357
358                 internal override void GetPrintDialogInfo (string printer, ref string port, ref string type, ref string status, ref string comment)
359                 {
360                         IntPtr hPrn;
361                         PRINTER_INFO printer_info = new PRINTER_INFO ();
362                         int needed = 0;
363                         IntPtr ptr;
364
365                         Win32OpenPrinter (printer, out hPrn, IntPtr.Zero);
366
367                         if (hPrn == IntPtr.Zero)
368                                 return;
369
370                         Win32GetPrinter (hPrn, 2, IntPtr.Zero, 0, ref needed);
371                         ptr = Marshal.AllocHGlobal (needed);
372
373                         Win32GetPrinter (hPrn, 2, ptr, needed, ref needed);
374                         printer_info = (PRINTER_INFO) Marshal.PtrToStructure (ptr, typeof (PRINTER_INFO));
375                         Marshal.FreeHGlobal (ptr);
376
377                         port  = Marshal.PtrToStringUni (printer_info.pPortName);
378                         comment  = Marshal.PtrToStringUni (printer_info.pComment);
379                         type  = Marshal.PtrToStringUni (printer_info.pDriverName);
380                         status = GetPrinterStatusMsg (printer_info.Status);
381
382                         Win32ClosePrinter (hPrn);
383                 }
384
385                 private string GetPrinterStatusMsg (uint status)
386                 {
387                         string rslt = string.Empty;
388
389                         if (status == 0)
390                                 return "Ready";
391
392                         if ((status & (uint) PrinterStatus.PS_PAUSED) != 0) rslt += "Paused; ";
393                         if ((status & (uint) PrinterStatus.PS_ERROR) != 0) rslt += "Error; ";
394                         if ((status & (uint) PrinterStatus.PS_PENDING_DELETION) != 0) rslt += "Pending deletion; ";
395                         if ((status & (uint) PrinterStatus.PS_PAPER_JAM) != 0) rslt += "Paper jam; ";
396                         if ((status & (uint) PrinterStatus.PS_PAPER_OUT) != 0) rslt += "Paper out; ";
397                         if ((status & (uint) PrinterStatus.PS_MANUAL_FEED) != 0) rslt += "Manual feed; ";
398                         if ((status & (uint) PrinterStatus.PS_PAPER_PROBLEM) != 0) rslt += "Paper problem; ";
399                         if ((status & (uint) PrinterStatus.PS_OFFLINE) != 0) rslt += "Offline; ";
400                         if ((status & (uint) PrinterStatus.PS_IO_ACTIVE) != 0) rslt += "I/O active; ";
401                         if ((status & (uint) PrinterStatus.PS_BUSY) != 0) rslt += "Busy; ";
402                         if ((status & (uint) PrinterStatus.PS_PRINTING) != 0) rslt += "Printing; ";
403                         if ((status & (uint) PrinterStatus.PS_OUTPUT_BIN_FULL) != 0) rslt += "Output bin full; ";
404                         if ((status & (uint) PrinterStatus.PS_NOT_AVAILABLE) != 0) rslt += "Not available; ";
405                         if ((status & (uint) PrinterStatus.PS_WAITING) != 0) rslt += "Waiting; ";
406                         if ((status & (uint) PrinterStatus.PS_PROCESSING) != 0) rslt += "Processing; ";
407                         if ((status & (uint) PrinterStatus.PS_INITIALIZING) != 0) rslt += "Initializing; ";
408                         if ((status & (uint) PrinterStatus.PS_WARMING_UP) != 0) rslt += "Warming up; ";
409                         if ((status & (uint) PrinterStatus.PS_TONER_LOW) != 0) rslt += "Toner low; ";
410                         if ((status & (uint) PrinterStatus.PS_NO_TONER) != 0) rslt += "No toner; ";
411                         if ((status & (uint) PrinterStatus.PS_PAGE_PUNT) != 0) rslt += "Page punt; ";
412                         if ((status & (uint) PrinterStatus.PS_USER_INTERVENTION) != 0) rslt += "User intervention; ";
413                         if ((status & (uint) PrinterStatus.PS_OUT_OF_MEMORY) != 0) rslt += "Out of memory; ";
414                         if ((status & (uint) PrinterStatus.PS_DOOR_OPEN) != 0) rslt += "Door open; ";
415                         if ((status & (uint) PrinterStatus.PS_SERVER_UNKNOWN) != 0) rslt += "Server unkown; ";
416                         if ((status & (uint) PrinterStatus.PS_POWER_SAVE) != 0) rslt += "Power save; ";
417
418                         return rslt;
419                 }
420
421                 //
422                 // DllImports
423                 //
424
425                 [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="OpenPrinter", SetLastError=true)]
426                 static extern int Win32OpenPrinter (string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);
427
428                 [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="GetPrinter", SetLastError=true)]
429                 static extern int Win32GetPrinter (IntPtr hPrinter, int level, IntPtr dwBuf, int size, ref int dwNeeded);
430
431                 [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="ClosePrinter", SetLastError=true)]
432                 static extern int Win32ClosePrinter (IntPtr hPrinter);
433
434                 [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="DeviceCapabilities", SetLastError=true)]
435                 static extern int Win32DeviceCapabilities (string device, string port, DCCapabilities cap, IntPtr outputBuffer, IntPtr deviceMode);
436
437                 [DllImport("winspool.drv", CharSet=CharSet.Unicode, EntryPoint="EnumPrinters", SetLastError=true)]
438                 static extern int Win32EnumPrinters (int Flags, string Name, uint Level, IntPtr pPrinterEnum, uint cbBuf,
439                         ref uint pcbNeeded, ref uint pcReturned);
440
441         [DllImport("winspool.drv", EntryPoint="GetDefaultPrinter", CharSet=CharSet.Unicode, SetLastError=true)]
442         private static extern int Win32GetDefaultPrinter (StringBuilder buffer, ref int bufferSize);
443
444                 [DllImport("winspool.drv", EntryPoint="DocumentProperties", CharSet=CharSet.Unicode, SetLastError=true)]
445                 private static extern int Win32DocumentProperties (IntPtr hwnd, IntPtr hPrinter, string pDeviceName,
446                         IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);
447
448         [DllImport("gdi32.dll", EntryPoint="CreateDC")]
449                 static extern IntPtr Win32CreateDC (string lpszDriver, string lpszDevice,
450                         string lpszOutput, IntPtr lpInitData);
451
452         [DllImport("gdi32.dll", EntryPoint="CreateIC")]
453                 static extern IntPtr Win32CreateIC (string lpszDriver, string lpszDevice,
454                         string lpszOutput, IntPtr lpInitData);
455
456                 [DllImport("gdi32.dll", CharSet=CharSet.Unicode, EntryPoint="StartDoc")]
457                 static extern int Win32StartDoc (IntPtr hdc, [In] ref DOCINFO lpdi);
458
459                 [DllImport("gdi32.dll", EntryPoint="StartPage")]
460                 static extern int Win32StartPage (IntPtr hDC);
461
462                 [DllImport("gdi32.dll", EntryPoint="EndPage")]
463                 static extern int Win32EndPage (IntPtr hdc);
464
465                 [DllImport("gdi32.dll", EntryPoint="EndDoc")]
466                 static extern int Win32EndDoc (IntPtr hdc);
467
468                 [DllImport("gdi32.dll", EntryPoint="DeleteDC")]
469                 public static extern IntPtr Win32DeleteDC (IntPtr hDc);
470
471                 [DllImport("gdi32.dll", EntryPoint="GetDeviceCaps")]
472                 public static extern int Win32GetDeviceCaps (IntPtr hDc, int index);
473
474                 //
475                 // Structs
476                 //
477                 [StructLayout (LayoutKind.Sequential)]
478                 internal struct PRINTER_INFO
479                 {
480                         public IntPtr   pServerName;
481                         public IntPtr   pPrinterName;
482                         public IntPtr   pShareName;
483                         public IntPtr   pPortName;
484                         public IntPtr   pDriverName;
485                         public IntPtr   pComment;
486                         public IntPtr   pLocation;
487                         public IntPtr   pDevMode;
488                         public IntPtr   pSepFile;
489                         public IntPtr   pPrintProcessor;
490                         public IntPtr   pDatatype;
491                         public IntPtr   pParameters;
492                         public IntPtr   pSecurityDescriptor;
493                         public uint     Attributes;
494                         public uint     Priority;
495                         public uint     DefaultPriority;
496                         public uint     StartTime;
497                         public uint     UntilTime;
498                         public uint     Status;
499                         public uint     cJobs;
500                         public uint     AveragePPM;
501         }
502
503         [StructLayout (LayoutKind.Sequential)]
504                 internal struct DOCINFO
505                 {
506                         public int      cbSize;
507                         public IntPtr   lpszDocName;
508                         public IntPtr   lpszOutput;
509                         public IntPtr   lpszDatatype;
510                         public int      fwType;
511                 }
512
513                 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
514                 internal struct DEVMODE
515                 {
516                         [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
517                         public string   dmDeviceName;
518                         public short    dmSpecVersion;
519                         public short    dmDriverVersion;
520                         public short    dmSize;
521                         public short    dmDriverExtra;
522                         public int      dmFields;
523
524                         public short    dmOrientation;
525                         public short    dmPaperSize;
526                         public short    dmPaperLength;
527                         public short    dmPaperWidth;
528
529                         public short    dmScale;
530                         public short    dmCopies;
531                         public short    dmDefaultSource;
532                         public short    dmPrintQuality;
533                         public short    dmColor;
534                         public short    dmDuplex;
535                         public short    dmYResolution;
536                         public short    dmTTOption;
537                         public short    dmCollate;
538                         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
539                         public string   dmFormName;
540                         public short    dmLogPixels;
541                         public short    dmBitsPerPel;
542                         public int      dmPelsWidth;
543                         public int      dmPelsHeight;
544                         public int      dmDisplayFlags;
545                         public int      dmDisplayFrequency;
546                         public int      dmICMMethod;
547                         public int      dmICMIntent;
548                         public int      dmMediaType;
549                         public int      dmDitherType;
550                         public int      dmReserved1;
551                         public int      dmReserved2;
552                         public int      dmPanningWidth;
553                         public int      dmPanningHeight;
554                 }
555
556                 // Enums
557                 internal enum DCCapabilities : short
558                 {
559                         DC_FIELDS = 1,
560                         DC_PAPERS = 2,
561                         DC_PAPERSIZE = 3,
562                         DC_MINEXTENT = 4,
563                         DC_MAXEXTENT = 5,
564                         DC_BINS = 6,
565                         DC_DUPLEX = 7,
566                         DC_SIZE = 8,
567                         DC_EXTRA = 9,
568                         DC_VERSION = 10,
569                         DC_DRIVER = 11,
570                         DC_BINNAMES = 12,
571                         DC_ENUMRESOLUTIONS = 13,
572                         DC_FILEDEPENDENCIES = 14,
573                         DC_TRUETYPE = 15,
574                         DC_PAPERNAMES = 16,
575                         DC_ORIENTATION = 17,
576                         DC_COPIES = 18,
577                         DC_BINADJUST = 19,
578                         DC_EMF_COMPLIANT = 20,
579                         DC_DATATYPE_PRODUCED = 21,
580                         DC_COLLATE = 22,
581                         DC_MANUFACTURER = 23,
582                         DC_MODEL = 24,
583                         DC_PERSONALITY = 25,
584                         DC_PRINTRATE = 26,
585                         DC_PRINTRATEUNIT = 27,
586                         DC_PRINTERMEM = 28,
587                         DC_MEDIAREADY = 29,
588                         DC_STAPLE = 30,
589                         DC_PRINTRATEPPM = 31,
590                         DC_COLORDEVICE = 32,
591                         DC_NUP = 33
592                 }
593
594                 [Flags]
595                 internal enum PrinterStatus : uint
596                 {
597                         PS_PAUSED =             0x00000001,
598                         PS_ERROR =              0x00000002,
599                         PS_PENDING_DELETION =   0x00000004,
600                         PS_PAPER_JAM =          0x00000008,
601                         PS_PAPER_OUT =          0x00000010,
602                         PS_MANUAL_FEED =        0x00000020,
603                         PS_PAPER_PROBLEM =      0x00000040,
604                         PS_OFFLINE =            0x00000080,
605                         PS_IO_ACTIVE =          0x00000100,
606                         PS_BUSY =               0x00000200,
607                         PS_PRINTING     =       0x00000400,
608                         PS_OUTPUT_BIN_FULL =    0x00000800,
609                         PS_NOT_AVAILABLE =      0x00001000,
610                         PS_WAITING =            0x00002000,
611                         PS_PROCESSING =         0x00004000,
612                         PS_INITIALIZING =       0x00008000,
613                         PS_WARMING_UP =         0x00010000,
614                         PS_TONER_LOW =          0x00020000,
615                         PS_NO_TONER =           0x00040000,
616                         PS_PAGE_PUNT =          0x00080000,
617                         PS_USER_INTERVENTION =  0x00100000,
618                         PS_OUT_OF_MEMORY =      0x00200000,
619                         PS_DOOR_OPEN =          0x00400000,
620                         PS_SERVER_UNKNOWN =     0x00800000,
621                         PS_POWER_SAVE =         0x01000000
622                 }
623                 
624                 // for use in GetDeviceCaps
625                 internal enum DevCapabilities
626                 {
627                         TECHNOLOGY      = 2,
628                 }
629                 
630                 internal enum PrinterType
631                 {
632                         DT_PLOTTER              = 0, // Vector Plotter
633                         DT_RASDIPLAY    = 1, // Raster Display
634                         DT_RASPRINTER   = 2, // Raster printer
635                         DT_RASCAMERA    = 3, // Raster camera
636                         DT_CHARSTREAM   = 4, // Character-stream, PLP
637                         DT_METAFILE             = 5, // Metafile, VDM
638                         DT_DISPFILE             = 6, // Display-file
639                 }
640
641         }
642
643         class GlobalPrintingServicesWin32 : GlobalPrintingServices
644         {
645                 internal override PrinterSettings.StringCollection InstalledPrinters {
646                         get {
647                                 return PrintingServicesWin32.InstalledPrinters;
648                         }
649                 }
650
651                 internal override IntPtr CreateGraphicsContext (PrinterSettings settings, PageSettings default_page_settings)
652                 {
653                         return PrintingServicesWin32.CreateGraphicsContext (settings, default_page_settings);
654                 }
655
656                 internal override bool StartDoc (GraphicsPrinter gr, string doc_name, string output_file)
657                 {
658                         return PrintingServicesWin32.StartDoc (gr, doc_name, output_file);
659                 }
660
661                 internal override bool EndDoc (GraphicsPrinter gr)
662                 {
663                         return PrintingServicesWin32.EndDoc (gr);
664                 }
665
666                 internal override bool StartPage (GraphicsPrinter gr)
667                 {
668                         return PrintingServicesWin32.StartPage (gr);
669                 }
670
671                 internal override bool EndPage (GraphicsPrinter gr)
672                 {
673                         return PrintingServicesWin32.EndPage (gr);
674                 }
675         }
676 }
677
678
679