2 * PostScript driver initialization functions
4 * Copyright 1998 Huw D M Davies
5 * Copyright 2001 Marcus Meissner
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "ddk/winddi.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
39 static const PSDRV_DEVMODE DefaultDevmode
=
42 /* dmDeviceName */ L
"Wine PostScript Driver",
43 /* dmSpecVersion */ 0x30a,
44 /* dmDriverVersion */ 0x001,
45 /* dmSize */ sizeof(DEVMODEW
),
46 /* dmDriverExtra */ sizeof(PSDRV_DEVMODE
)-sizeof(DEVMODEW
),
47 /* dmFields */ DM_ORIENTATION
| DM_PAPERSIZE
| DM_PAPERLENGTH
| DM_PAPERWIDTH
|
48 DM_SCALE
| DM_COPIES
| DM_DEFAULTSOURCE
| DM_PRINTQUALITY
|
49 DM_COLOR
| DM_DUPLEX
| DM_YRESOLUTION
| DM_TTOPTION
|
50 DM_COLLATE
| DM_FORMNAME
,
53 /* dmOrientation */ DMORIENT_PORTRAIT
,
54 /* dmPaperSize */ DMPAPER_LETTER
,
55 /* dmPaperLength */ 2794,
56 /* dmPaperWidth */ 2159,
59 /* dmDefaultSource */ DMBIN_AUTO
,
60 /* dmPrintQuality */ 300
63 /* dmColor */ DMCOLOR_COLOR
,
64 /* dmDuplex */ DMDUP_SIMPLEX
,
65 /* dmYResolution */ 300,
66 /* dmTTOption */ DMTT_SUBDEV
,
67 /* dmCollate */ DMCOLLATE_FALSE
,
68 /* dmFormName */ L
"Letter",
74 /* dmDisplayFlags */ 0
76 /* dmDisplayFrequency */ 0,
83 /* dmPanningWidth */ 0,
84 /* dmPanningHeight */ 0
88 HINSTANCE PSDRV_hInstance
= 0;
89 HANDLE PSDRV_Heap
= 0;
91 static BOOL
import_ntf_from_reg(void)
93 struct import_ntf_params params
;
94 HANDLE hfile
, hmap
= NULL
;
103 if (RegOpenKeyW(HKEY_CURRENT_USER
, L
"Software\\Wine\\Fonts", &hkey
))
105 status
= RegQueryValueExW(hkey
, L
"NTFFile", NULL
, NULL
, (BYTE
*)path
, &len
);
110 hfile
= CreateFileW(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
111 if (hfile
!= INVALID_HANDLE_VALUE
)
113 if (!GetFileSizeEx(hfile
, &size
))
115 hmap
= CreateFileMappingW(hfile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
120 data
= MapViewOfFile(hmap
, FILE_MAP_READ
, 0, 0, 0);
125 WARN("Error loading NTF file: %s\n", debugstr_w(path
));
130 params
.size
= size
.QuadPart
;
131 ret
= WINE_UNIX_CALL(unix_import_ntf
, ¶ms
);
132 UnmapViewOfFile(data
);
136 static BOOL
convert_afm_to_ntf(void)
138 int i
, count
, size
, off
, metrics_size
;
139 struct import_ntf_params params
;
140 struct width_range
*width_range
;
141 struct glyph_set
*glyph_set
;
142 struct ntf_header
*header
;
143 struct font_mtx
*font_mtx
;
144 struct list_entry
*list
;
145 struct code_page
*cp
;
146 char glyph_set_name
[9];
147 char *data
, *new_data
;
153 for (family
= PSDRV_AFMFontList
; family
; family
= family
->next
)
155 for(afmle
= family
->afmlist
; afmle
; afmle
= afmle
->next
)
158 size
= sizeof(*header
) + sizeof(*list
) * count
* 2;
159 data
= calloc(size
, 1);
163 header
= (void *)data
;
164 header
->glyph_set_count
= count
;
165 header
->glyph_set_off
= sizeof(*header
);
166 header
->font_mtx_count
= count
;
167 header
->font_mtx_off
= header
->glyph_set_off
+ sizeof(*list
) * count
;
171 for (family
= PSDRV_AFMFontList
; family
; family
= family
->next
)
173 for(afmle
= family
->afmlist
; afmle
; afmle
= afmle
->next
)
175 sprintf(glyph_set_name
, "%x", count
);
177 list
= (void *)(data
+ header
->glyph_set_off
+ sizeof(*list
) * count
);
178 list
->name_off
= off
+ sizeof(*glyph_set
);
179 list
->size
= sizeof(*glyph_set
) + strlen(glyph_set_name
) + 1 + sizeof(*cp
) +
180 sizeof(short) * afmle
->afm
->NumofMetrics
;
183 new_data
= realloc(data
, size
);
190 header
= (void *)data
;
191 memset(data
+ off
, 0, size
- off
);
193 glyph_set
= (void *)(data
+ off
);
194 glyph_set
->size
= size
- off
;
195 glyph_set
->flags
= 1;
196 glyph_set
->name_off
= sizeof(*glyph_set
);
197 glyph_set
->glyph_count
= afmle
->afm
->NumofMetrics
;
198 glyph_set
->cp_count
= 1;
199 glyph_set
->cp_off
= glyph_set
->name_off
+ strlen(glyph_set_name
) + 1;
200 glyph_set
->glyph_set_off
= glyph_set
->cp_off
+ sizeof(*cp
);
201 strcpy(data
+ off
+ glyph_set
->name_off
, glyph_set_name
);
202 cp
= (void *)(data
+ off
+ glyph_set
->cp_off
);
204 for (i
= 0; i
< afmle
->afm
->NumofMetrics
; i
++)
205 *(WCHAR
*)(data
+ off
+ glyph_set
->glyph_set_off
+ i
* sizeof(short)) = afmle
->afm
->Metrics
[i
].UV
;
208 metrics_size
= sizeof(IFIMETRICS
) +
209 (wcslen(afmle
->afm
->FamilyName
) + 1) * sizeof(WCHAR
);
210 list
= (void *)(data
+ header
->font_mtx_off
+ sizeof(*list
) * count
);
211 list
->name_off
= off
+ sizeof(*font_mtx
);
212 list
->size
= sizeof(*font_mtx
) + strlen(afmle
->afm
->FontName
) + 1 +
213 strlen(glyph_set_name
) + 1 + metrics_size
+
214 (afmle
->afm
->IsFixedPitch
? 0 : sizeof(*width_range
) * afmle
->afm
->NumofMetrics
);
217 new_data
= realloc(data
, size
);
224 header
= (void *)data
;
225 memset(data
+ off
, 0, size
- off
);
227 font_mtx
= (void *)(data
+ off
);
228 font_mtx
->size
= size
- off
;
229 font_mtx
->name_off
= sizeof(*font_mtx
);
230 font_mtx
->glyph_set_name_off
= font_mtx
->name_off
+ strlen(afmle
->afm
->FontName
) + 1;
231 font_mtx
->glyph_count
= afmle
->afm
->NumofMetrics
;
232 font_mtx
->metrics_off
= font_mtx
->glyph_set_name_off
+ strlen(glyph_set_name
) + 1;
233 font_mtx
->width_count
= afmle
->afm
->IsFixedPitch
? 0 : afmle
->afm
->NumofMetrics
;
234 font_mtx
->width_off
= font_mtx
->metrics_off
+ metrics_size
;
235 font_mtx
->def_width
= afmle
->afm
->Metrics
[0].WX
;
236 strcpy(data
+ off
+ font_mtx
->name_off
, afmle
->afm
->FontName
);
237 strcpy(data
+ off
+ font_mtx
->glyph_set_name_off
, glyph_set_name
);
238 metrics
= (void *)(data
+ off
+ font_mtx
->metrics_off
);
239 metrics
->cjThis
= metrics_size
;
240 metrics
->dpwszFamilyName
= sizeof(*metrics
);
241 if (afmle
->afm
->IsFixedPitch
)
242 metrics
->jWinPitchAndFamily
|= FIXED_PITCH
;
243 metrics
->usWinWeight
= afmle
->afm
->Weight
;
244 if (afmle
->afm
->ItalicAngle
!= 0.0)
245 metrics
->fsSelection
|= FM_SEL_ITALIC
;
246 if (afmle
->afm
->Weight
== FW_BOLD
)
247 metrics
->fsSelection
|= FM_SEL_BOLD
;
248 metrics
->fwdUnitsPerEm
= afmle
->afm
->WinMetrics
.usUnitsPerEm
;
249 metrics
->fwdWinAscender
= afmle
->afm
->WinMetrics
.usWinAscent
;
250 metrics
->fwdWinDescender
= afmle
->afm
->WinMetrics
.usWinDescent
;
251 metrics
->fwdMacAscender
= afmle
->afm
->WinMetrics
.sAscender
;
252 metrics
->fwdMacDescender
= afmle
->afm
->WinMetrics
.sDescender
;
253 metrics
->fwdMacLineGap
= afmle
->afm
->WinMetrics
.sLineGap
;
254 metrics
->fwdAveCharWidth
= afmle
->afm
->WinMetrics
.sAvgCharWidth
;
255 metrics
->rclFontBox
.left
= afmle
->afm
->FontBBox
.llx
;
256 metrics
->rclFontBox
.top
= afmle
->afm
->FontBBox
.ury
;
257 metrics
->rclFontBox
.right
= afmle
->afm
->FontBBox
.urx
;
258 metrics
->rclFontBox
.bottom
= afmle
->afm
->FontBBox
.lly
;
259 wcscpy((WCHAR
*)((char *)metrics
+ metrics
->dpwszFamilyName
), afmle
->afm
->FamilyName
);
260 width_range
= (void *)(data
+ off
+ font_mtx
->width_off
);
261 for (i
= 0; i
< font_mtx
->width_count
; i
++)
263 width_range
[i
].first
= i
;
264 width_range
[i
].count
= 1;
265 width_range
[i
].width
= afmle
->afm
->Metrics
[i
].WX
;
275 return WINE_UNIX_CALL(unix_import_ntf
, ¶ms
);
278 /*********************************************************************
281 * Initializes font metrics and registers driver. wineps dll entry point.
284 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
286 TRACE("(%p, %ld, %p)\n", hinst
, reason
, reserved
);
290 case DLL_PROCESS_ATTACH
:
292 PSDRV_hInstance
= hinst
;
293 DisableThreadLibraryCalls(hinst
);
295 if (__wine_init_unix_call())
298 PSDRV_Heap
= HeapCreate(0, 0x10000, 0);
299 if (PSDRV_Heap
== NULL
)
302 if (PSDRV_GetFontMetrics() == FALSE
) {
303 HeapDestroy(PSDRV_Heap
);
307 if (!convert_afm_to_ntf() || !import_ntf_from_reg())
309 WINE_UNIX_CALL(unix_free_printer_info
, NULL
);
310 HeapDestroy(PSDRV_Heap
);
316 case DLL_PROCESS_DETACH
:
318 WINE_UNIX_CALL(unix_free_printer_info
, NULL
);
319 HeapDestroy( PSDRV_Heap
);
326 static void dump_fields(DWORD fields
)
330 #define CHECK_FIELD(flag) \
335 if (add_space++) TRACE(" "); \
342 CHECK_FIELD(DM_ORIENTATION
);
343 CHECK_FIELD(DM_PAPERSIZE
);
344 CHECK_FIELD(DM_PAPERLENGTH
);
345 CHECK_FIELD(DM_PAPERWIDTH
);
346 CHECK_FIELD(DM_SCALE
);
347 CHECK_FIELD(DM_POSITION
);
349 CHECK_FIELD(DM_DISPLAYORIENTATION
);
350 CHECK_FIELD(DM_COPIES
);
351 CHECK_FIELD(DM_DEFAULTSOURCE
);
352 CHECK_FIELD(DM_PRINTQUALITY
);
353 CHECK_FIELD(DM_COLOR
);
354 CHECK_FIELD(DM_DUPLEX
);
355 CHECK_FIELD(DM_YRESOLUTION
);
356 CHECK_FIELD(DM_TTOPTION
);
357 CHECK_FIELD(DM_COLLATE
);
358 CHECK_FIELD(DM_FORMNAME
);
359 CHECK_FIELD(DM_LOGPIXELS
);
360 CHECK_FIELD(DM_BITSPERPEL
);
361 CHECK_FIELD(DM_PELSWIDTH
);
362 CHECK_FIELD(DM_PELSHEIGHT
);
363 CHECK_FIELD(DM_DISPLAYFLAGS
);
364 CHECK_FIELD(DM_DISPLAYFREQUENCY
);
365 CHECK_FIELD(DM_ICMMETHOD
);
366 CHECK_FIELD(DM_ICMINTENT
);
367 CHECK_FIELD(DM_MEDIATYPE
);
368 CHECK_FIELD(DM_DITHERTYPE
);
369 CHECK_FIELD(DM_PANNINGWIDTH
);
370 CHECK_FIELD(DM_PANNINGHEIGHT
);
371 if (fields
) TRACE(" %#lx", fields
);
376 /* Dump DEVMODE structure without a device specific part.
377 * Some applications and drivers fail to specify correct field
378 * flags (like DM_FORMNAME), so dump everything.
380 static void dump_devmode(const DEVMODEW
*dm
)
382 if (!TRACE_ON(psdrv
)) return;
384 TRACE("dmDeviceName: %s\n", debugstr_w(dm
->dmDeviceName
));
385 TRACE("dmSpecVersion: 0x%04x\n", dm
->dmSpecVersion
);
386 TRACE("dmDriverVersion: 0x%04x\n", dm
->dmDriverVersion
);
387 TRACE("dmSize: 0x%04x\n", dm
->dmSize
);
388 TRACE("dmDriverExtra: 0x%04x\n", dm
->dmDriverExtra
);
389 TRACE("dmFields: 0x%04lx\n", dm
->dmFields
);
390 dump_fields(dm
->dmFields
);
391 TRACE("dmOrientation: %d\n", dm
->dmOrientation
);
392 TRACE("dmPaperSize: %d\n", dm
->dmPaperSize
);
393 TRACE("dmPaperLength: %d\n", dm
->dmPaperLength
);
394 TRACE("dmPaperWidth: %d\n", dm
->dmPaperWidth
);
395 TRACE("dmScale: %d\n", dm
->dmScale
);
396 TRACE("dmCopies: %d\n", dm
->dmCopies
);
397 TRACE("dmDefaultSource: %d\n", dm
->dmDefaultSource
);
398 TRACE("dmPrintQuality: %d\n", dm
->dmPrintQuality
);
399 TRACE("dmColor: %d\n", dm
->dmColor
);
400 TRACE("dmDuplex: %d\n", dm
->dmDuplex
);
401 TRACE("dmYResolution: %d\n", dm
->dmYResolution
);
402 TRACE("dmTTOption: %d\n", dm
->dmTTOption
);
403 TRACE("dmCollate: %d\n", dm
->dmCollate
);
404 TRACE("dmFormName: %s\n", debugstr_w(dm
->dmFormName
));
405 TRACE("dmLogPixels %u\n", dm
->dmLogPixels
);
406 TRACE("dmBitsPerPel %lu\n", dm
->dmBitsPerPel
);
407 TRACE("dmPelsWidth %lu\n", dm
->dmPelsWidth
);
408 TRACE("dmPelsHeight %lu\n", dm
->dmPelsHeight
);
411 print_ctx
*create_print_ctx( HDC hdc
, const WCHAR
*device
,
412 const DEVMODEW
*devmode
)
414 PRINTERINFO
*pi
= PSDRV_FindPrinterInfo( device
);
417 if (!pi
) return NULL
;
420 RASTERIZER_STATUS status
;
421 if (!GetRasterizerCaps( &status
, sizeof(status
) ) ||
422 !(status
.wFlags
& TT_AVAILABLE
) ||
423 !(status
.wFlags
& TT_ENABLED
))
425 MESSAGE( "Disabling printer %s since it has no builtin fonts and "
426 "there are no TrueType fonts available.\n", debugstr_w(device
) );
431 ctx
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ctx
) );
432 if (!ctx
) return NULL
;
434 ctx
->Devmode
= HeapAlloc( GetProcessHeap(), 0,
435 pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
438 HeapFree( GetProcessHeap(), 0, ctx
);
442 memcpy( ctx
->Devmode
, pi
->Devmode
,
443 pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
449 dump_devmode( devmode
);
450 PSDRV_MergeDevmodes( ctx
->Devmode
, devmode
, pi
);
453 SelectObject( hdc
, GetStockObject( DEVICE_DEFAULT_FONT
));
457 /**********************************************************************
460 BOOL
PSDRV_ResetDC( print_ctx
*ctx
, const DEVMODEW
*devmode
)
464 dump_devmode( devmode
);
465 PSDRV_MergeDevmodes( ctx
->Devmode
, devmode
, ctx
->pi
);
470 static PRINTER_ENUM_VALUESW
*load_font_sub_table( HANDLE printer
, DWORD
*num_entries
)
472 DWORD res
, needed
, num
;
473 PRINTER_ENUM_VALUESW
*table
= NULL
;
474 static const WCHAR fontsubkey
[] = L
"PrinterDriverData\\FontSubTable";
478 res
= EnumPrinterDataExW( printer
, fontsubkey
, NULL
, 0, &needed
, &num
);
479 if (res
!= ERROR_MORE_DATA
) return NULL
;
481 table
= HeapAlloc( PSDRV_Heap
, 0, needed
);
482 if (!table
) return NULL
;
484 res
= EnumPrinterDataExW( printer
, fontsubkey
, (LPBYTE
)table
, needed
, &needed
, &num
);
485 if (res
!= ERROR_SUCCESS
)
487 HeapFree( PSDRV_Heap
, 0, table
);
495 static PSDRV_DEVMODE
*get_printer_devmode( HANDLE printer
, int size
)
497 DWORD needed
, dm_size
;
499 PRINTER_INFO_9W
*info
;
502 GetPrinterW( printer
, 9, NULL
, 0, &needed
);
503 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) return NULL
;
505 info
= HeapAlloc( PSDRV_Heap
, 0, max(needed
, size
) );
506 res
= GetPrinterW( printer
, 9, (BYTE
*)info
, needed
, &needed
);
507 if (!res
|| !info
->pDevMode
)
509 HeapFree( PSDRV_Heap
, 0, info
);
513 /* sanity check the sizes */
514 dm_size
= info
->pDevMode
->dmSize
+ info
->pDevMode
->dmDriverExtra
;
515 if ((char *)info
->pDevMode
- (char *)info
+ dm_size
> needed
)
517 HeapFree( PSDRV_Heap
, 0, info
);
521 dm
= (PSDRV_DEVMODE
*)info
;
522 memmove( dm
, info
->pDevMode
, dm_size
);
526 static PSDRV_DEVMODE
*get_devmode( HANDLE printer
, const WCHAR
*name
, BOOL
*is_default
, int size
)
528 PSDRV_DEVMODE
*dm
= get_printer_devmode( printer
, size
);
532 if (dm
&& (dm
->dmPublic
.dmFields
& DefaultDevmode
.dmPublic
.dmFields
) ==
533 DefaultDevmode
.dmPublic
.dmFields
)
535 TRACE( "Retrieved devmode from winspool\n" );
539 TRACE( "Using default devmode\n" );
541 dm
= HeapAlloc( PSDRV_Heap
, 0, size
);
544 memcpy( dm
, &DefaultDevmode
, min(sizeof(DefaultDevmode
), size
) );
545 lstrcpynW( (WCHAR
*)dm
->dmPublic
.dmDeviceName
, name
, CCHDEVICENAME
);
551 static BOOL
set_devmode( HANDLE printer
, PSDRV_DEVMODE
*dm
)
553 PRINTER_INFO_9W info
;
554 info
.pDevMode
= &dm
->dmPublic
;
556 return SetPrinterW( printer
, 9, (BYTE
*)&info
, 0 );
559 static WCHAR
*get_ppd_filename( HANDLE printer
)
562 DRIVER_INFO_2W
*info
;
565 GetPrinterDriverW( printer
, NULL
, 2, NULL
, 0, &needed
);
566 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) return NULL
;
567 info
= HeapAlloc( GetProcessHeap(), 0, needed
);
568 if (!info
) return NULL
;
569 GetPrinterDriverW( printer
, NULL
, 2, (BYTE
*)info
, needed
, &needed
);
570 name
= (WCHAR
*)info
;
571 memmove( name
, info
->pDataFile
, (lstrlenW( info
->pDataFile
) + 1) * sizeof(WCHAR
) );
575 static struct list printer_list
= LIST_INIT( printer_list
);
577 /**********************************************************************
578 * PSDRV_FindPrinterInfo
580 PRINTERINFO
*PSDRV_FindPrinterInfo(LPCWSTR name
)
586 WCHAR
*ppd_filename
= NULL
;
588 BOOL using_default_devmode
= FALSE
;
589 int i
, len
, input_slots
, resolutions
, page_sizes
, font_subs
, installed_fonts
, size
;
590 struct input_slot
*dm_slot
;
591 struct resolution
*dm_res
;
592 struct page_size
*dm_page
;
593 struct font_sub
*dm_sub
;
594 struct installed_font
*dm_font
;
599 TRACE("%s\n", debugstr_w(name
));
601 LIST_FOR_EACH_ENTRY( pi
, &printer_list
, PRINTERINFO
, entry
)
603 if (!wcscmp( pi
->friendly_name
, name
))
607 pi
= HeapAlloc( PSDRV_Heap
, HEAP_ZERO_MEMORY
, sizeof(*pi
) );
608 if (pi
== NULL
) return NULL
;
610 if (!(pi
->friendly_name
= HeapAlloc( PSDRV_Heap
, 0, (lstrlenW(name
)+1)*sizeof(WCHAR
) ))) goto fail
;
611 lstrcpyW( pi
->friendly_name
, name
);
613 if (OpenPrinterW( pi
->friendly_name
, &hPrinter
, NULL
) == 0) {
614 ERR ("OpenPrinter failed with code %li\n", GetLastError ());
618 len
= WideCharToMultiByte( CP_ACP
, 0, name
, -1, NULL
, 0, NULL
, NULL
);
619 nameA
= HeapAlloc( GetProcessHeap(), 0, len
);
620 WideCharToMultiByte( CP_ACP
, 0, name
, -1, nameA
, len
, NULL
, NULL
);
622 ppd_filename
= get_ppd_filename( hPrinter
);
623 if (!ppd_filename
) goto fail
;
625 pi
->ppd
= PSDRV_ParsePPD( ppd_filename
, hPrinter
);
628 WARN( "Couldn't parse PPD file %s\n", debugstr_w(ppd_filename
) );
632 pi
->FontSubTable
= load_font_sub_table( hPrinter
, &pi
->FontSubTableSize
);
634 input_slots
= list_count( &pi
->ppd
->InputSlots
);
635 resolutions
= list_count( &pi
->ppd
->Resolutions
);
636 page_sizes
= list_count( &pi
->ppd
->PageSizes
);
637 font_subs
= pi
->FontSubTableSize
;
638 installed_fonts
= list_count( &pi
->ppd
->InstalledFonts
);
639 size
= FIELD_OFFSET(PSDRV_DEVMODE
, data
[
640 input_slots
* sizeof(struct input_slot
) +
641 resolutions
* sizeof(struct resolution
) +
642 page_sizes
* sizeof(struct page_size
) +
643 font_subs
* sizeof(struct font_sub
) +
644 installed_fonts
* sizeof(struct installed_font
)]);
646 pi
->Devmode
= get_devmode( hPrinter
, name
, &using_default_devmode
, size
);
647 if (!pi
->Devmode
) goto fail
;
649 if(using_default_devmode
) {
652 if(GetLocaleInfoW(LOCALE_USER_DEFAULT
, LOCALE_IPAPERSIZE
| LOCALE_RETURN_NUMBER
,
653 (LPWSTR
)&papersize
, sizeof(papersize
)/sizeof(WCHAR
))) {
655 memset(&dm
, 0, sizeof(dm
));
656 dm
.dmFields
= DM_PAPERSIZE
;
657 dm
.dmPaperSize
= papersize
;
658 PSDRV_MergeDevmodes(pi
->Devmode
, &dm
, pi
);
662 if(pi
->ppd
->DefaultPageSize
) { /* We'll let the ppd override the devmode */
664 memset(&dm
, 0, sizeof(dm
));
665 dm
.dmFields
= DM_PAPERSIZE
;
666 dm
.dmPaperSize
= pi
->ppd
->DefaultPageSize
->WinPage
;
667 PSDRV_MergeDevmodes(pi
->Devmode
, &dm
, pi
);
670 if (pi
->Devmode
->dmPublic
.dmDriverExtra
!= size
- pi
->Devmode
->dmPublic
.dmSize
)
672 pi
->Devmode
->dmPublic
.dmDriverExtra
= size
- pi
->Devmode
->dmPublic
.dmSize
;
673 pi
->Devmode
->default_resolution
= pi
->ppd
->DefaultResolution
;
674 pi
->Devmode
->landscape_orientation
= pi
->ppd
->LandscapeOrientation
;
675 pi
->Devmode
->duplex
= pi
->ppd
->DefaultDuplex
? pi
->ppd
->DefaultDuplex
->WinDuplex
: 0;
676 pi
->Devmode
->input_slots
= input_slots
;
677 pi
->Devmode
->resolutions
= resolutions
;
678 pi
->Devmode
->page_sizes
= page_sizes
;
679 pi
->Devmode
->font_subs
= font_subs
;
680 pi
->Devmode
->installed_fonts
= installed_fonts
;
682 dm_slot
= (struct input_slot
*)pi
->Devmode
->data
;
683 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
685 dm_slot
->win_bin
= slot
->WinBin
;
689 dm_res
= (struct resolution
*)dm_slot
;
690 LIST_FOR_EACH_ENTRY( res
, &pi
->ppd
->Resolutions
, RESOLUTION
, entry
)
692 dm_res
->x
= res
->resx
;
693 dm_res
->y
= res
->resy
;
697 dm_page
= (struct page_size
*)dm_res
;
698 LIST_FOR_EACH_ENTRY( page
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
700 lstrcpynW(dm_page
->name
, page
->FullName
, CCHFORMNAME
);
701 if (page
->ImageableArea
)
703 dm_page
->imageable_area
.left
= page
->ImageableArea
->llx
;
704 dm_page
->imageable_area
.bottom
= page
->ImageableArea
->lly
;
705 dm_page
->imageable_area
.right
= page
->ImageableArea
->urx
;
706 dm_page
->imageable_area
.top
= page
->ImageableArea
->ury
;
710 dm_page
->imageable_area
.left
= 0;
711 dm_page
->imageable_area
.bottom
= 0;
712 dm_page
->imageable_area
.right
= page
->PaperDimension
->x
;
713 dm_page
->imageable_area
.top
= page
->PaperDimension
->y
;
715 dm_page
->paper_dimension
.x
= page
->PaperDimension
->x
;
716 dm_page
->paper_dimension
.y
= page
->PaperDimension
->y
;
717 dm_page
->win_page
= page
->WinPage
;
721 dm_sub
= (struct font_sub
*)dm_page
;
722 for (i
= 0; i
< font_subs
; i
++)
724 lstrcpynW(dm_sub
->name
, pi
->FontSubTable
[i
].pValueName
, ARRAY_SIZE(dm_sub
->name
));
725 lstrcpynW(dm_sub
->sub
, (WCHAR
*)pi
->FontSubTable
[i
].pData
, ARRAY_SIZE(dm_sub
->sub
));
729 dm_font
= (struct installed_font
*)dm_sub
;
730 LIST_FOR_EACH_ENTRY( font
, &pi
->ppd
->InstalledFonts
, FONTNAME
, entry
)
732 lstrcpynA(dm_font
->name
, font
->Name
, ARRAY_SIZE(dm_font
->name
));
737 /* Duplex is indicated by the setting of the DM_DUPLEX bit in dmFields.
738 WinDuplex == 0 is a special case which means that the ppd has a
739 *DefaultDuplex: NotCapable entry. In this case we'll try not to confuse
740 apps and set dmDuplex to DMDUP_SIMPLEX but leave the DM_DUPLEX clear.
741 PSDRV_WriteHeader understands this and copes. */
742 pi
->Devmode
->dmPublic
.dmFields
&= ~DM_DUPLEX
;
743 if(pi
->ppd
->DefaultDuplex
) {
744 pi
->Devmode
->dmPublic
.dmDuplex
= pi
->ppd
->DefaultDuplex
->WinDuplex
;
745 if(pi
->Devmode
->dmPublic
.dmDuplex
!= 0)
746 pi
->Devmode
->dmPublic
.dmFields
|= DM_DUPLEX
;
748 pi
->Devmode
->dmPublic
.dmDuplex
= DMDUP_SIMPLEX
;
751 set_devmode( hPrinter
, pi
->Devmode
);
753 LIST_FOR_EACH_ENTRY( font
, &pi
->ppd
->InstalledFonts
, FONTNAME
, entry
)
755 afm
= PSDRV_FindAFMinList(PSDRV_AFMFontList
, font
->Name
);
757 TRACE( "Couldn't find AFM file for installed printer font '%s' - "
758 "ignoring\n", font
->Name
);
762 if (PSDRV_AddAFMtoList(&pi
->Fonts
, afm
, &added
) == FALSE
) {
763 PSDRV_FreeAFMList(pi
->Fonts
);
769 ClosePrinter( hPrinter
);
770 HeapFree( GetProcessHeap(), 0, nameA
);
771 HeapFree( GetProcessHeap(), 0, ppd_filename
);
772 list_add_head( &printer_list
, &pi
->entry
);
776 if (hPrinter
) ClosePrinter( hPrinter
);
777 HeapFree(PSDRV_Heap
, 0, pi
->FontSubTable
);
778 HeapFree(PSDRV_Heap
, 0, pi
->friendly_name
);
779 HeapFree(PSDRV_Heap
, 0, pi
->Devmode
);
780 HeapFree(PSDRV_Heap
, 0, pi
);
781 HeapFree( GetProcessHeap(), 0, nameA
);
782 HeapFree( GetProcessHeap(), 0, ppd_filename
);
786 /******************************************************************************
787 * PSDRV_open_printer_dc
789 HDC CDECL
PSDRV_open_printer_dc( const WCHAR
*device
,
790 const DEVMODEW
*devmode
, const WCHAR
*output
)
792 struct open_dc_params params
;
798 pi
= PSDRV_FindPrinterInfo( device
);
802 params
.device
= pi
->friendly_name
;
803 params
.devmode
= devmode
;
804 params
.output
= output
;
805 params
.def_devmode
= pi
->Devmode
;
807 if (!WINE_UNIX_CALL( unix_open_dc
, ¶ms
))