From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 85 +++++++++++++++++++++++++---- dlls/wineps.drv/psdrv.h | 9 ++- dlls/wineps.drv/unixlib.c | 112 +++++++++++++++++++------------------- dlls/wineps.drv/unixlib.h | 32 +++++++++++ 4 files changed, 169 insertions(+), 69 deletions(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 49a87e1c74e..c5f97c85073 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -411,7 +411,7 @@ static PRINTER_ENUM_VALUESW *load_font_sub_table( HANDLE printer, DWORD *num_ent return table; }
-static PSDRV_DEVMODE *get_printer_devmode( HANDLE printer ) +static PSDRV_DEVMODE *get_printer_devmode( HANDLE printer, int size ) { DWORD needed, dm_size; BOOL res; @@ -421,7 +421,7 @@ static PSDRV_DEVMODE *get_printer_devmode( HANDLE printer ) GetPrinterW( printer, 9, NULL, 0, &needed ); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL;
- info = HeapAlloc( PSDRV_Heap, 0, needed ); + info = HeapAlloc( PSDRV_Heap, 0, max(needed, size) ); res = GetPrinterW( printer, 9, (BYTE *)info, needed, &needed ); if (!res || !info->pDevMode) { @@ -442,24 +442,23 @@ static PSDRV_DEVMODE *get_printer_devmode( HANDLE printer ) return dm; }
-static PSDRV_DEVMODE *get_devmode( HANDLE printer, const WCHAR *name, BOOL *is_default ) +static PSDRV_DEVMODE *get_devmode( HANDLE printer, const WCHAR *name, BOOL *is_default, int size ) { - PSDRV_DEVMODE *dm = get_printer_devmode( printer ); + PSDRV_DEVMODE *dm = get_printer_devmode( printer, size );
*is_default = FALSE;
- if (dm && dm->dmPublic.dmSize + dm->dmPublic.dmDriverExtra >= sizeof(DefaultDevmode)) + if (dm) { TRACE( "Retrieved devmode from winspool\n" ); return dm; } - HeapFree( PSDRV_Heap, 0, dm );
TRACE( "Using default devmode\n" ); - dm = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) ); + dm = HeapAlloc( PSDRV_Heap, 0, size ); if (dm) { - *dm = DefaultDevmode; + memcpy( dm, &DefaultDevmode, min(sizeof(DefaultDevmode), size) ); lstrcpynW( (WCHAR *)dm->dmPublic.dmDeviceName, name, CCHDEVICENAME ); *is_default = TRUE; } @@ -504,7 +503,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) WCHAR *ppd_filename = NULL; char *nameA = NULL; BOOL using_default_devmode = FALSE; - int len; + int len, input_slots, resolutions, page_sizes, size; + struct input_slot *dm_slot; + struct resolution *dm_res; + struct page_size *dm_page; + INPUTSLOT *slot; + RESOLUTION *res; + PAGESIZE *page;
TRACE("%s\n", debugstr_w(name));
@@ -529,9 +534,6 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) nameA = HeapAlloc( GetProcessHeap(), 0, len ); WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, len, NULL, NULL );
- pi->Devmode = get_devmode( hPrinter, name, &using_default_devmode ); - if (!pi->Devmode) goto fail; - ppd_filename = get_ppd_filename( hPrinter ); if (!ppd_filename) goto fail;
@@ -542,6 +544,15 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) goto fail; }
+ input_slots = list_count( &pi->ppd->InputSlots ); + resolutions = list_count( &pi->ppd->Resolutions ); + page_sizes = list_count( &pi->ppd->PageSizes ); + size = FIELD_OFFSET(PSDRV_DEVMODE, data[input_slots * sizeof(struct input_slot) + + resolutions * sizeof(struct resolution) + page_sizes * sizeof(struct page_size)]); + + pi->Devmode = get_devmode( hPrinter, name, &using_default_devmode, size ); + if (!pi->Devmode) goto fail; + if(using_default_devmode) { DWORD papersize;
@@ -563,6 +574,56 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) PSDRV_MergeDevmodes(pi->Devmode, &dm, pi); }
+ if (pi->Devmode->dmPublic.dmDriverExtra != size - pi->Devmode->dmPublic.dmSize) + { + pi->Devmode->dmPublic.dmDriverExtra = size - pi->Devmode->dmPublic.dmSize; + pi->Devmode->default_resolution = pi->ppd->DefaultResolution; + pi->Devmode->landscape_orientation = pi->ppd->LandscapeOrientation; + pi->Devmode->duplex = pi->ppd->DefaultDuplex ? pi->ppd->DefaultDuplex->WinDuplex : 0; + pi->Devmode->input_slots = input_slots; + pi->Devmode->resolutions = resolutions; + pi->Devmode->page_sizes = page_sizes; + + dm_slot = (struct input_slot *)pi->Devmode->data; + LIST_FOR_EACH_ENTRY( slot, &pi->ppd->InputSlots, INPUTSLOT, entry ) + { + dm_slot->win_bin = slot->WinBin; + dm_slot++; + } + + dm_res = (struct resolution *)dm_slot; + LIST_FOR_EACH_ENTRY( res, &pi->ppd->Resolutions, RESOLUTION, entry ) + { + dm_res->x = res->resx; + dm_res->y = res->resy; + dm_res++; + } + + dm_page = (struct page_size *)dm_res; + LIST_FOR_EACH_ENTRY( page, &pi->ppd->PageSizes, PAGESIZE, entry ) + { + lstrcpynW(dm_page->name, page->FullName, CCHFORMNAME); + if (page->ImageableArea) + { + dm_page->imageable_area.left = page->ImageableArea->llx; + dm_page->imageable_area.bottom = page->ImageableArea->lly; + dm_page->imageable_area.right = page->ImageableArea->urx; + dm_page->imageable_area.top = page->ImageableArea->ury; + } + else + { + dm_page->imageable_area.left = 0; + dm_page->imageable_area.bottom = 0; + dm_page->imageable_area.right = page->PaperDimension->x; + dm_page->imageable_area.top = page->PaperDimension->y; + } + dm_page->paper_dimension.x = page->PaperDimension->x; + dm_page->paper_dimension.y = page->PaperDimension->y; + dm_page->win_page = page->WinPage; + dm_page++; + } + } + /* Duplex is indicated by the setting of the DM_DUPLEX bit in dmFields. WinDuplex == 0 is a special case which means that the ppd has a *DefaultDuplex: NotCapable entry. In this case we'll try not to confuse diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index 331e88a9ef9..30ca6755cc6 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -220,7 +220,14 @@ typedef struct { } PPD;
typedef struct { - DEVMODEW dmPublic; + DEVMODEW dmPublic; + int default_resolution; + int landscape_orientation; + int duplex; + int input_slots; + int resolutions; + int page_sizes; + BYTE data[1]; } PSDRV_DEVMODE;
typedef struct diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index 8f56e4d2dcc..1ca87461d17 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -252,7 +252,7 @@ static INT CDECL get_device_caps(PHYSDEV dev, INT cap) case PHYSICALOFFSETX: if (pdev->devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) { - if (pdev->pi->pi->ppd->LandscapeOrientation == -90) + if (pdev->devmode->landscape_orientation == -90) return pdev->page_size.cy - pdev->imageable_area.top; else return pdev->imageable_area.bottom; @@ -262,7 +262,7 @@ static INT CDECL get_device_caps(PHYSDEV dev, INT cap) case PHYSICALOFFSETY: if (pdev->devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) { - if (pdev->pi->pi->ppd->LandscapeOrientation == -90) + if (pdev->devmode->landscape_orientation == -90) return pdev->page_size.cx - pdev->imageable_area.right; else return pdev->imageable_area.left; @@ -280,25 +280,34 @@ static inline int paper_size_from_points(float size) return size * 254 / 72; }
-static INPUTSLOT *unix_find_slot(PPD *ppd, const DEVMODEW *dm) +static const struct input_slot *unix_find_slot(const struct printer_info *pi, + const DEVMODEW *dm) { - INPUTSLOT *slot; - - LIST_FOR_EACH_ENTRY(slot, &ppd->InputSlots, INPUTSLOT, entry) - if (slot->WinBin == dm->dmDefaultSource) - return slot; + const struct input_slot *slot = (const struct input_slot *)pi->pi->Devmode->data; + int i;
+ for (i = 0; i < pi->pi->Devmode->input_slots; i++) + { + if (slot[i].win_bin == dm->dmDefaultSource) + return slot + i; + } return NULL; }
-static PAGESIZE *unix_find_pagesize(PPD *ppd, const DEVMODEW *dm) +static const struct page_size *unix_find_pagesize(const struct printer_info *pi, + const DEVMODEW *dm) { - PAGESIZE *page; - - LIST_FOR_EACH_ENTRY(page, &ppd->PageSizes, PAGESIZE, entry) - if (page->WinPage == dm->dmPaperSize) - return page; + const struct page_size *page; + int i;
+ page = (const struct page_size *)(pi->pi->Devmode->data + + pi->pi->Devmode->input_slots * sizeof(struct input_slot) + + pi->pi->Devmode->resolutions * sizeof(struct resolution)); + for (i = 0; i < pi->pi->Devmode->page_sizes; i++) + { + if (page[i].win_page == dm->dmPaperSize) + return page + i; + } return NULL; }
@@ -321,21 +330,21 @@ static void merge_devmodes(PSDRV_DEVMODE *dm1, const DEVMODEW *dm2, /* NB PaperWidth is always < PaperLength */ if (dm2->dmFields & DM_PAPERSIZE) { - PAGESIZE *page = unix_find_pagesize(pi->pi->ppd, dm2); + const struct page_size *page = unix_find_pagesize(pi, dm2);
if (page) { dm1->dmPublic.dmPaperSize = dm2->dmPaperSize; - dm1->dmPublic.dmPaperWidth = paper_size_from_points(page->PaperDimension->x); - dm1->dmPublic.dmPaperLength = paper_size_from_points(page->PaperDimension->y); + dm1->dmPublic.dmPaperWidth = paper_size_from_points(page->paper_dimension.x); + dm1->dmPublic.dmPaperLength = paper_size_from_points(page->paper_dimension.y); dm1->dmPublic.dmFields |= DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH; - TRACE("Changing page to %s %d x %d\n", debugstr_w(page->FullName), + TRACE("Changing page to %s %d x %d\n", debugstr_w(page->name), dm1->dmPublic.dmPaperWidth, dm1->dmPublic.dmPaperLength);
if (dm1->dmPublic.dmSize >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR)) { - lstrcpynW(dm1->dmPublic.dmFormName, page->FullName, CCHFORMNAME); + memcpy(dm1->dmPublic.dmFormName, page->name, sizeof(page->name)); dm1->dmPublic.dmFields |= DM_FORMNAME; } } @@ -378,17 +387,12 @@ static void merge_devmodes(PSDRV_DEVMODE *dm1, const DEVMODEW *dm2,
if (dm2->dmFields & DM_DEFAULTSOURCE) { - INPUTSLOT *slot = unix_find_slot(pi->pi->ppd, dm2); + const struct input_slot *slot = unix_find_slot(pi, dm2);
if (slot) - { dm1->dmPublic.dmDefaultSource = dm2->dmDefaultSource; - TRACE("Changing bin to '%s'\n", slot->FullName); - } else - { TRACE("Trying to change to unsupported bin %d\n", dm2->dmDefaultSource); - } }
if (dm2->dmFields & DM_DEFAULTSOURCE) @@ -397,7 +401,7 @@ static void merge_devmodes(PSDRV_DEVMODE *dm1, const DEVMODEW *dm2, dm1->dmPublic.dmPrintQuality = dm2->dmPrintQuality; if (dm2->dmFields & DM_COLOR) dm1->dmPublic.dmColor = dm2->dmColor; - if (dm2->dmFields & DM_DUPLEX && pi->pi->ppd->DefaultDuplex && pi->pi->ppd->DefaultDuplex->WinDuplex != 0) + if (dm2->dmFields & DM_DUPLEX && pi->pi->Devmode->duplex) dm1->dmPublic.dmDuplex = dm2->dmDuplex; if (dm2->dmFields & DM_YRESOLUTION) dm1->dmPublic.dmYResolution = dm2->dmYResolution; @@ -438,8 +442,9 @@ static void merge_devmodes(PSDRV_DEVMODE *dm1, const DEVMODEW *dm2, static void update_dev_caps(PSDRV_PDEVICE *pdev) { INT width = 0, height = 0, resx = 0, resy = 0; - RESOLUTION *res; - PAGESIZE *page; + const struct resolution *res; + const struct page_size *page; + int i;
dump_devmode(&pdev->devmode->dmPublic);
@@ -454,9 +459,11 @@ static void update_dev_caps(PSDRV_PDEVICE *pdev) if (pdev->devmode->dmPublic.dmFields & DM_LOGPIXELS) resx = resy = pdev->devmode->dmPublic.dmLogPixels;
- LIST_FOR_EACH_ENTRY(res, &pdev->pi->pi->ppd->Resolutions, RESOLUTION, entry) + res = (const struct resolution *)(pdev->devmode->data + + pdev->devmode->input_slots * sizeof(struct input_slot)); + for (i = 0; i < pdev->devmode->resolutions; i++) { - if (res->resx == resx && res->resy == resy) + if (res[i].x == resx && res[i].y == resy) { pdev->log_pixels_x = resx; pdev->log_pixels_y = resy; @@ -464,47 +471,40 @@ static void update_dev_caps(PSDRV_PDEVICE *pdev) } }
- if (&res->entry == &pdev->pi->pi->ppd->Resolutions) + if (i == pdev->devmode->resolutions) { WARN("Requested resolution %dx%d is not supported by device\n", resx, resy); - pdev->log_pixels_x = pdev->pi->pi->ppd->DefaultResolution; + pdev->log_pixels_x = pdev->devmode->default_resolution; pdev->log_pixels_y = pdev->log_pixels_x; } } else { - WARN("Using default device resolution %d\n", pdev->pi->pi->ppd->DefaultResolution); - pdev->log_pixels_x = pdev->pi->pi->ppd->DefaultResolution; + WARN("Using default device resolution %d\n", pdev->devmode->default_resolution); + pdev->log_pixels_x = pdev->devmode->default_resolution; pdev->log_pixels_y = pdev->log_pixels_x; }
if (pdev->devmode->dmPublic.dmFields & DM_PAPERSIZE) { - LIST_FOR_EACH_ENTRY(page, &pdev->pi->pi->ppd->PageSizes, PAGESIZE, entry) { - if (page->WinPage == pdev->devmode->dmPublic.dmPaperSize) - break; - } + page = unix_find_pagesize(pdev->pi, &pdev->devmode->dmPublic);
- if (&page->entry == &pdev->pi->pi->ppd->PageSizes) { + if (!page) + { FIXME("Can't find page\n"); SetRectEmpty(&pdev->imageable_area); pdev->page_size.cx = 0; pdev->page_size.cy = 0; - } else if (page->ImageableArea) { + } + else + { /* pdev sizes in device units; ppd sizes in 1/72" */ - SetRect(&pdev->imageable_area, page->ImageableArea->llx * pdev->log_pixels_x / 72, - page->ImageableArea->ury * pdev->log_pixels_y / 72, - page->ImageableArea->urx * pdev->log_pixels_x / 72, - page->ImageableArea->lly * pdev->log_pixels_y / 72); - pdev->page_size.cx = page->PaperDimension->x * - pdev->log_pixels_x / 72; - pdev->page_size.cy = page->PaperDimension->y * - pdev->log_pixels_y / 72; - } else { - pdev->imageable_area.left = pdev->imageable_area.bottom = 0; - pdev->imageable_area.right = pdev->page_size.cx = - page->PaperDimension->x * pdev->log_pixels_x / 72; - pdev->imageable_area.top = pdev->page_size.cy = - page->PaperDimension->y * pdev->log_pixels_y / 72; + SetRect(&pdev->imageable_area, + page->imageable_area.left * pdev->log_pixels_x / 72, + page->imageable_area.top * pdev->log_pixels_y / 72, + page->imageable_area.right * pdev->log_pixels_x / 72, + page->imageable_area.bottom * pdev->log_pixels_y / 72); + pdev->page_size.cx = page->paper_dimension.x * pdev->log_pixels_x / 72; + pdev->page_size.cy = page->paper_dimension.y * pdev->log_pixels_y / 72; } } else if ((pdev->devmode->dmPublic.dmFields & DM_PAPERLENGTH) && (pdev->devmode->dmPublic.dmFields & DM_PAPERWIDTH)) { @@ -1318,8 +1318,8 @@ static PSDRV_PDEVICE *create_physdev(HDC hdc, const WCHAR *device, memcpy(pdev->devmode, pi->pi->Devmode, pi->pi->Devmode->dmPublic.dmSize + pi->pi->Devmode->dmPublic.dmDriverExtra); pdev->pi = pi; - pdev->log_pixels_x = pi->pi->ppd->DefaultResolution; - pdev->log_pixels_y = pi->pi->ppd->DefaultResolution; + pdev->log_pixels_x = pdev->devmode->default_resolution; + pdev->log_pixels_y = pdev->devmode->default_resolution;
if (devmode) { diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index 09ba9d3c662..1c71d758a91 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -19,6 +19,7 @@ #include "ntuser.h" #include "wine/unixlib.h"
+/* escapes */ #define PSDRV_GET_GLYPH_NAME 0x10000 #define PSDRV_GET_BUILTIN_FONT_INFO 0x10001
@@ -29,6 +30,37 @@ struct font_info int escapement; };
+/* devmode */ +struct input_slot +{ + int win_bin; +}; + +struct resolution +{ + int x; + int y; +}; + +struct page_size +{ + WCHAR name[CCHFORMNAME]; + struct + { + float left; + float bottom; + float right; + float top; + } imageable_area; + struct + { + float x; + float y; + } paper_dimension; + short win_page; +}; + +/* Unix calls */ enum wineps_funcs { unix_init_dc,