Commit aa3699dd authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

wineps: Store data from PPD file used in unixlib in DEVMODE.

parent 5b166890
......@@ -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
......
......@@ -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
......
......@@ -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)
{
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment