/*
 *	PostScript driver initialization functions
 *
 *	Copyright 1998 Huw D M Davies
 *	Copyright 2001 Marcus Meissner
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "gdi.h"
#include "psdrv.h"
#include "wine/debug.h"
#include "winreg.h"
#include "winspool.h"
#include "winerror.h"
#include "wownt32.h"
#include "heap.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);

#ifdef HAVE_CUPS_CUPS_H
#include <cups/cups.h>

#ifndef SONAME_LIBCUPS
#define SONAME_LIBCUPS "libcups.so"
#endif

static void *cupshandle = NULL;
#endif

static PSDRV_DEVMODEA DefaultDevmode =
{
  { /* dmPublic */
/* dmDeviceName */	"Wine PostScript Driver",
/* dmSpecVersion */	0x30a,
/* dmDriverVersion */	0x001,
/* dmSize */		sizeof(DEVMODEA),
/* dmDriverExtra */	sizeof(PSDRV_DEVMODEA)-sizeof(DEVMODEA),
/* dmFields */		DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE |
			DM_COPIES | DM_DEFAULTSOURCE | DM_COLOR |
		        DM_YRESOLUTION | DM_TTOPTION,
   { /* u1 */
     { /* s1 */
/* dmOrientation */	DMORIENT_PORTRAIT,
/* dmPaperSize */	DMPAPER_LETTER,
/* dmPaperLength */	2794,
/* dmPaperWidth */      2159
     }
   },
/* dmScale */		100, /* ?? */
/* dmCopies */		1,
/* dmDefaultSource */	DMBIN_AUTO,
/* dmPrintQuality */	0,
/* dmColor */		DMCOLOR_COLOR,
/* dmDuplex */		DMDUP_SIMPLEX,
/* dmYResolution */	0,
/* dmTTOption */	DMTT_SUBDEV,
/* dmCollate */		0,
/* dmFormName */	"",
/* dmUnusedPadding */   0,
/* dmBitsPerPel */	0,
/* dmPelsWidth */	0,
/* dmPelsHeight */	0,
/* dmDisplayFlags */	0,
/* dmDisplayFrequency */ 0,
/* dmICMMethod */       0,
/* dmICMIntent */       0,
/* dmMediaType */       0,
/* dmDitherType */      0,
/* dmReserved1 */       0,
/* dmReserved2 */       0,
/* dmPanningWidth */    0,
/* dmPanningHeight */   0
  },
  { /* dmDocPrivate */
    /* dummy */ 0
  },
  { /* dmDrvPrivate */
    /* numInstalledOptions */ 0
  }
};

HANDLE PSDRV_Heap = 0;

static HANDLE PSDRV_DefaultFont = 0;
static LOGFONTA DefaultLogFont = {
    100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0,
    DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, ""
};

/*********************************************************************
 *	     DllMain
 *
 * Initializes font metrics and registers driver. wineps dll entry point.
 *
 */
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
    TRACE("(%p, 0x%08lx, %p)\n", hinst, reason, reserved);

    switch(reason) {

	case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinst);

	    PSDRV_Heap = HeapCreate(0, 0x10000, 0);
	    if (PSDRV_Heap == NULL)
		return FALSE;

	    if (PSDRV_GetFontMetrics() == FALSE) {
		HeapDestroy(PSDRV_Heap);
		return FALSE;
	    }

	    PSDRV_DefaultFont = CreateFontIndirectA(&DefaultLogFont);
	    if (PSDRV_DefaultFont == NULL) {
		HeapDestroy(PSDRV_Heap);
		return FALSE;
	    }
#ifdef HAVE_CUPS_CUPS_H
	    /* dynamically load CUPS if not yet loaded */
	    if (!cupshandle) {
		cupshandle = wine_dlopen(SONAME_LIBCUPS, RTLD_NOW, NULL, 0);
		if (!cupshandle) cupshandle = (void*)-1;
	    }
#endif
            break;

	case DLL_PROCESS_DETACH:

	    DeleteObject( PSDRV_DefaultFont );
	    HeapDestroy( PSDRV_Heap );
#ifdef HAVE_CUPS_CUPS_H
	    if (cupshandle && (cupshandle != (void*)-1)) {
		wine_dlclose(cupshandle, NULL, 0);
		cupshandle = NULL;
	    }
#endif
            break;
    }

    return TRUE;
}


static void PSDRV_UpdateDevCaps( PSDRV_PDEVICE *physDev )
{
    PAGESIZE *page;
    INT width = 0, height = 0;

    if(physDev->Devmode->dmPublic.dmFields & DM_PAPERSIZE) {
        for(page = physDev->pi->ppd->PageSizes; page; page = page->next) {
	    if(page->WinPage == physDev->Devmode->dmPublic.u1.s1.dmPaperSize)
	        break;
	}

	if(!page) {
	    FIXME("Can't find page\n");
	    physDev->ImageableArea.left = 0;
	    physDev->ImageableArea.right = 0;
	    physDev->ImageableArea.bottom = 0;
	    physDev->ImageableArea.top = 0;
	    physDev->PageSize.cx = 0;
	    physDev->PageSize.cy = 0;
	} else if(page->ImageableArea) {
	  /* physDev sizes in device units; ppd sizes in 1/72" */
	    physDev->ImageableArea.left = page->ImageableArea->llx *
	      physDev->logPixelsX / 72;
	    physDev->ImageableArea.right = page->ImageableArea->urx *
	      physDev->logPixelsX / 72;
	    physDev->ImageableArea.bottom = page->ImageableArea->lly *
	      physDev->logPixelsY / 72;
	    physDev->ImageableArea.top = page->ImageableArea->ury *
	      physDev->logPixelsY / 72;
	    physDev->PageSize.cx = page->PaperDimension->x *
	      physDev->logPixelsX / 72;
	    physDev->PageSize.cy = page->PaperDimension->y *
	      physDev->logPixelsY / 72;
	} else {
	    physDev->ImageableArea.left = physDev->ImageableArea.bottom = 0;
	    physDev->ImageableArea.right = physDev->PageSize.cx =
	      page->PaperDimension->x * physDev->logPixelsX / 72;
	    physDev->ImageableArea.top = physDev->PageSize.cy =
	      page->PaperDimension->y * physDev->logPixelsY / 72;
	}
    } else if((physDev->Devmode->dmPublic.dmFields & DM_PAPERLENGTH) &&
	      (physDev->Devmode->dmPublic.dmFields & DM_PAPERWIDTH)) {
      /* physDev sizes in device units; Devmode sizes in 1/10 mm */
        physDev->ImageableArea.left = physDev->ImageableArea.bottom = 0;
	physDev->ImageableArea.right = physDev->PageSize.cx =
	  physDev->Devmode->dmPublic.u1.s1.dmPaperWidth *
	  physDev->logPixelsX / 254;
	physDev->ImageableArea.top = physDev->PageSize.cy =
	  physDev->Devmode->dmPublic.u1.s1.dmPaperLength *
	  physDev->logPixelsY / 254;
    } else {
        FIXME("Odd dmFields %lx\n", physDev->Devmode->dmPublic.dmFields);
	physDev->ImageableArea.left = 0;
	physDev->ImageableArea.right = 0;
	physDev->ImageableArea.bottom = 0;
	physDev->ImageableArea.top = 0;
	physDev->PageSize.cx = 0;
	physDev->PageSize.cy = 0;
    }

    TRACE("ImageableArea = %ld,%ld - %ld,%ld: PageSize = %ldx%ld\n",
	  physDev->ImageableArea.left, physDev->ImageableArea.bottom,
	  physDev->ImageableArea.right, physDev->ImageableArea.top,
	  physDev->PageSize.cx, physDev->PageSize.cy);

    /* these are in device units */
    width = physDev->ImageableArea.right - physDev->ImageableArea.left;
    height = physDev->ImageableArea.top - physDev->ImageableArea.bottom;

    if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT) {
        physDev->horzRes = width;
        physDev->vertRes = height;
    } else {
        physDev->horzRes = height;
        physDev->vertRes = width;
    }

    /* these are in mm */
    physDev->horzSize = (physDev->horzRes * 25.4) / physDev->logPixelsX;
    physDev->vertSize = (physDev->vertRes * 25.4) / physDev->logPixelsY;

    TRACE("devcaps: horzSize = %dmm, vertSize = %dmm, "
	  "horzRes = %d, vertRes = %d\n",
	  physDev->horzSize, physDev->vertSize,
	  physDev->horzRes, physDev->vertRes);
}


/***********************************************************
 *      DEVMODEdupWtoA
 *
 * Creates an ascii copy of supplied devmode on heap
 *
 * Copied from dlls/winspool/info.c until full unicodification
 */
static LPDEVMODEA DEVMODEdupWtoA(HANDLE heap, const DEVMODEW *dmW)
{
    LPDEVMODEA dmA;
    DWORD size;
    BOOL Formname;
    ptrdiff_t off_formname = (char *)dmW->dmFormName - (char *)dmW;

    if(!dmW) return NULL;
    Formname = (dmW->dmSize > off_formname);
    size = dmW->dmSize - CCHDEVICENAME - (Formname ? CCHFORMNAME : 0);
    dmA = HeapAlloc(heap, HEAP_ZERO_MEMORY, size + dmW->dmDriverExtra);
    WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, dmA->dmDeviceName,
			CCHDEVICENAME, NULL, NULL);
    if(!Formname) {
      memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion,
	     dmW->dmSize - CCHDEVICENAME * sizeof(WCHAR));
    } else {
      memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion,
	     off_formname - CCHDEVICENAME * sizeof(WCHAR));
      WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, dmA->dmFormName,
			  CCHFORMNAME, NULL, NULL);
      memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize -
	     (off_formname + CCHFORMNAME * sizeof(WCHAR)));
    }
    dmA->dmSize = size;
    memcpy((char *)dmA + dmA->dmSize, (char *)dmW + dmW->dmSize,
	   dmW->dmDriverExtra);
    return dmA;
}


/**********************************************************************
 *	     PSDRV_CreateDC
 */
BOOL PSDRV_CreateDC( DC *dc, PSDRV_PDEVICE **pdev, LPCWSTR driver, LPCWSTR device,
                     LPCWSTR output, const DEVMODEW* initData )
{
    PSDRV_PDEVICE *physDev;
    PRINTERINFO *pi;
    char deviceA[CCHDEVICENAME];

    /* If no device name was specified, retrieve the device name
     * from the DEVMODE structure from the DC's physDev.
     * (See CreateCompatibleDC) */
    if ( !device && *pdev )
    {
        physDev = *pdev;
        strcpy(deviceA, physDev->Devmode->dmPublic.dmDeviceName);
    }
    else
        WideCharToMultiByte(CP_ACP, 0, device, -1, deviceA, sizeof(deviceA), NULL, NULL);
    pi = PSDRV_FindPrinterInfo(deviceA);

    TRACE("(%s %s %s %p)\n", debugstr_w(driver), debugstr_w(device),
                             debugstr_w(output), initData);

    if(!pi) return FALSE;

    if(!pi->Fonts) {
        MESSAGE("To use WINEPS you need to install some AFM files.\n");
	return FALSE;
    }

    physDev = (PSDRV_PDEVICE *)HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY,
					             sizeof(*physDev) );
    if (!physDev) return FALSE;
    *pdev = physDev;
    physDev->hdc = dc->hSelf;
    physDev->dc = dc;

    physDev->pi = pi;

    physDev->Devmode = (PSDRV_DEVMODEA *)HeapAlloc( PSDRV_Heap, 0,
						     sizeof(PSDRV_DEVMODEA) );
    if(!physDev->Devmode) {
        HeapFree( PSDRV_Heap, 0, physDev );
	return FALSE;
    }

    memcpy( physDev->Devmode, pi->Devmode, sizeof(PSDRV_DEVMODEA) );

    physDev->logPixelsX = physDev->pi->ppd->DefaultResolution;
    physDev->logPixelsY = physDev->pi->ppd->DefaultResolution;

    if (output) {
        physDev->job.output = HEAP_strdupWtoA( PSDRV_Heap, 0, output );
    } else
        physDev->job.output = NULL;
    physDev->job.hJob = 0;

    if(initData) {
        DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, initData);
        PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)devmodeA, pi);
        HeapFree(PSDRV_Heap, 0, devmodeA);
    }

    PSDRV_UpdateDevCaps(physDev);
    dc->hFont = PSDRV_DefaultFont;
    if (GetObjectType(dc->hSelf) != OBJ_MEMDC)
        dc->bitsPerPixel = physDev->pi->ppd->ColorDevice ? 8 : 1;
    return TRUE;
}



/**********************************************************************
 *	     PSDRV_DeleteDC
 */
BOOL PSDRV_DeleteDC( PSDRV_PDEVICE *physDev )
{
    TRACE("\n");

    HeapFree( PSDRV_Heap, 0, physDev->Devmode );
    if(physDev->job.output)
        HeapFree( PSDRV_Heap, 0, physDev->job.output );
    HeapFree( PSDRV_Heap, 0, physDev );

    return TRUE;
}


/**********************************************************************
 *	     ResetDC   (WINEPS.@)
 */
HDC PSDRV_ResetDC( PSDRV_PDEVICE *physDev, const DEVMODEW *lpInitData )
{
    if(lpInitData) {
        HRGN hrgn;
        DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, lpInitData);
        PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)devmodeA, physDev->pi);
        HeapFree(PSDRV_Heap, 0, devmodeA);
        PSDRV_UpdateDevCaps(physDev);
        hrgn = CreateRectRgn(0, 0, physDev->horzRes, physDev->vertRes);
        SelectVisRgn16(HDC_16(physDev->hdc), HRGN_16(hrgn));
        DeleteObject(hrgn);
    }
    return physDev->hdc;
}

/***********************************************************************
 *           GetDeviceCaps    (WINEPS.@)
 */
INT PSDRV_GetDeviceCaps( PSDRV_PDEVICE *physDev, INT cap )
{
    switch(cap)
    {
    case DRIVERVERSION:
        return 0;
    case TECHNOLOGY:
        return DT_RASPRINTER;
    case HORZSIZE:
        return MulDiv(physDev->horzSize, 100,
		      physDev->Devmode->dmPublic.dmScale);
    case VERTSIZE:
        return MulDiv(physDev->vertSize, 100,
		      physDev->Devmode->dmPublic.dmScale);
    case HORZRES:
        return physDev->horzRes;
    case VERTRES:
        return physDev->vertRes;
    case BITSPIXEL:
        return physDev->pi->ppd->ColorDevice ? 8 : 1;
    case PLANES:
        return 1;
    case NUMBRUSHES:
        return -1;
    case NUMPENS:
        return 10;
    case NUMMARKERS:
        return 0;
    case NUMFONTS:
        return 39;
    case NUMCOLORS:
        return (physDev->pi->ppd->ColorDevice ? 256 : -1);
    case PDEVICESIZE:
        return sizeof(PSDRV_PDEVICE);
    case CURVECAPS:
        return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
                CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
    case LINECAPS:
        return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
                LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
    case POLYGONALCAPS:
        return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
                PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
    case TEXTCAPS:
        return TC_CR_ANY | TC_VA_ABLE; /* psdrv 0x59f7 */
    case CLIPCAPS:
        return CP_RECTANGLE;
    case RASTERCAPS:
        return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DIBTODEV |
                RC_STRETCHBLT | RC_STRETCHDIB); /* psdrv 0x6e99 */
    /* Are aspect[XY] and logPixels[XY] correct? */
    /* Need to handle different res in x and y => fix ppd */
    case ASPECTX:
    case ASPECTY:
        return physDev->pi->ppd->DefaultResolution;
    case ASPECTXY:
        return (int)hypot( (double)physDev->pi->ppd->DefaultResolution,
                           (double)physDev->pi->ppd->DefaultResolution );
    case LOGPIXELSX:
        return MulDiv(physDev->logPixelsX,
		      physDev->Devmode->dmPublic.dmScale, 100);
    case LOGPIXELSY:
        return MulDiv(physDev->logPixelsY,
		      physDev->Devmode->dmPublic.dmScale, 100);
    case SIZEPALETTE:
        return 0;
    case NUMRESERVED:
        return 0;
    case COLORRES:
        return 0;
    case PHYSICALWIDTH:
        return (physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) ?
	  physDev->PageSize.cy : physDev->PageSize.cx;
    case PHYSICALHEIGHT:
        return (physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) ?
	  physDev->PageSize.cx : physDev->PageSize.cy;
    case PHYSICALOFFSETX:
      if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) {
          if(physDev->pi->ppd->LandscapeOrientation == -90)
	      return physDev->PageSize.cy - physDev->ImageableArea.top;
	  else
	      return physDev->ImageableArea.bottom;
      }
      return physDev->ImageableArea.left;

    case PHYSICALOFFSETY:
      if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) {
          if(physDev->pi->ppd->LandscapeOrientation == -90)
	      return physDev->PageSize.cx - physDev->ImageableArea.right;
	  else
	      return physDev->ImageableArea.left;
      }
      return physDev->PageSize.cy - physDev->ImageableArea.top;

    case SCALINGFACTORX:
    case SCALINGFACTORY:
    case VREFRESH:
    case DESKTOPVERTRES:
    case DESKTOPHORZRES:
    case BTLALIGNMENT:
        return 0;
    default:
        FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
        return 0;
    }
}


/**********************************************************************
 *		PSDRV_FindPrinterInfo
 */
PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
{
    static PRINTERINFO *PSDRV_PrinterList;
    DWORD type = REG_BINARY, needed, res, dwPaperSize;
    PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList;
    FONTNAME *font;
    const AFM *afm;
    HANDLE hPrinter;
    const char *ppd = NULL;
    DWORD ppdType;
    char* ppdFileName = NULL;
    HKEY hkey;
    BOOL using_default_devmode = FALSE;

    TRACE("'%s'\n", name);

    /*
     *	If this loop completes, last will point to the 'next' element of the
     *	final PRINTERINFO in the list
     */
    for( ; pi; last = &pi->next, pi = pi->next)
        if(!strcmp(pi->FriendlyName, name))
	    return pi;

    pi = *last = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(*pi) );
    if (pi == NULL)
    	return NULL;

    if (!(pi->FriendlyName = HeapAlloc( PSDRV_Heap, 0, strlen(name)+1 ))) goto fail;
    strcpy( pi->FriendlyName, name );

    /* Use Get|SetPrinterDataExA instead? */

    res = DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
			    NULL, 0, &needed );

    if(res == ERROR_INVALID_PRINTER_NAME || needed != sizeof(DefaultDevmode)) {
        pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) );
	if (pi->Devmode == NULL)
	    goto cleanup;
	memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) );
	strcpy(pi->Devmode->dmPublic.dmDeviceName,name);
	using_default_devmode = TRUE;

	/* need to do something here AddPrinter?? */
    }
    else {
        pi->Devmode = HeapAlloc( PSDRV_Heap, 0, needed );
	DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
			  (LPBYTE)pi->Devmode, needed, &needed);
    }

    if (OpenPrinterA (pi->FriendlyName, &hPrinter, NULL) == 0) {
	ERR ("OpenPrinterA failed with code %li\n", GetLastError ());
	goto cleanup;
    }

#ifdef HAVE_CUPS_CUPS_H
    if (cupshandle != (void*)-1) {
	typeof(cupsGetPPD) * pcupsGetPPD = NULL;

	pcupsGetPPD = wine_dlsym(cupshandle, "cupsGetPPD", NULL, 0);
	if (pcupsGetPPD) {
	    ppd = pcupsGetPPD(name);

	    if (ppd) {
		needed=strlen(ppd)+1;
		ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
		memcpy(ppdFileName, ppd, needed);
		ppdType=REG_SZ;
		res = ERROR_SUCCESS;
		/* we should unlink() that file later */
	    } else {
		res = ERROR_FILE_NOT_FOUND;
		WARN("Did not find ppd for %s\n",name);
	    }
	}
    }
#endif
    if (!ppdFileName) {
        res = GetPrinterDataA(hPrinter, "PPD File", NULL, NULL, 0, &needed);
        if ((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)) {
            ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
            res = GetPrinterDataA(hPrinter, "PPD File", &ppdType, ppdFileName, needed, &needed);
        }
    }
    /* Look for a ppd file for this printer in the config file.
     * First look under that printer's name, and then under 'generic'
     */
    if((res != ERROR_SUCCESS) && !RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\ppd", &hkey))
    {
        const char* value_name;

        if (RegQueryValueExA(hkey, name, 0, NULL, NULL, &needed) == ERROR_SUCCESS) {
            value_name=name;
        } else if (RegQueryValueExA(hkey, "generic", 0, NULL, NULL, &needed) == ERROR_SUCCESS) {
            value_name="generic";
        } else {
            value_name=NULL;
        }
        if (value_name) {
            ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
            RegQueryValueExA(hkey, value_name, 0, &ppdType, ppdFileName, &needed);
        }
        RegCloseKey(hkey);
    }

    if (!ppdFileName) {
        res = ERROR_FILE_NOT_FOUND;
        ERR ("Error %li getting PPD file name for printer '%s'\n", res, name);
        goto closeprinter;
    } else {
        res = ERROR_SUCCESS;
        if (ppdType==REG_EXPAND_SZ) {
            char* tmp;

            /* Expand environment variable references */
            needed=ExpandEnvironmentStringsA(ppdFileName,NULL,0);
            tmp=HeapAlloc(PSDRV_Heap, 0, needed);
            ExpandEnvironmentStringsA(ppdFileName,tmp,needed);
            HeapFree(PSDRV_Heap, 0, ppdFileName);
            ppdFileName=tmp;
        }
    }

    pi->ppd = PSDRV_ParsePPD(ppdFileName);
    if(!pi->ppd) {
	MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
	    ppdFileName);
	goto closeprinter;
    }

    /* Some gimp-print ppd files don't contain a DefaultResolution line
       set it to 300 if it's not specified */
    if(pi->ppd->DefaultResolution == 0)
        pi->ppd->DefaultResolution = 300;

    if(using_default_devmode) {
        DWORD papersize;

	if(GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE | LOCALE_RETURN_NUMBER,
			  (LPWSTR)&papersize, sizeof(papersize))) {
	    PSDRV_DEVMODEA dm;
	    memset(&dm, 0, sizeof(dm));
	    dm.dmPublic.dmFields = DM_PAPERSIZE;
	    dm.dmPublic.u1.s1.dmPaperSize = papersize;
	    PSDRV_MergeDevmodes(pi->Devmode, &dm, pi);
	}
	DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE,
		 REG_BINARY, (LPBYTE)pi->Devmode, sizeof(DefaultDevmode) );
    }

    if(pi->ppd->DefaultPageSize) { /* We'll let the ppd override the devmode */
        PSDRV_DEVMODEA dm;
        memset(&dm, 0, sizeof(dm));
        dm.dmPublic.dmFields = DM_PAPERSIZE;
        dm.dmPublic.u1.s1.dmPaperSize = pi->ppd->DefaultPageSize->WinPage;
        PSDRV_MergeDevmodes(pi->Devmode, &dm, pi);
    }

    /*
     *	This is a hack.  The default paper size should be read in as part of
     *	the Devmode structure, but Wine doesn't currently provide a convenient
     *	way to configure printers.
     */
    res = GetPrinterDataA (hPrinter, "Paper Size", NULL, (LPBYTE) &dwPaperSize,
	    sizeof (DWORD), &needed);
    if (res == ERROR_SUCCESS)
	pi->Devmode->dmPublic.u1.s1.dmPaperSize = (SHORT) dwPaperSize;
    else if (res == ERROR_FILE_NOT_FOUND)
	TRACE ("No 'Paper Size' for printer '%s'\n", name);
    else {
	ERR ("GetPrinterDataA returned %li\n", res);
	goto closeprinter;
    }

    /* 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
       apps and set dmDuplex to DMDUP_SIMPLEX but leave the DM_DUPLEX clear.
       PSDRV_WriteHeader understands this and copes. */
    pi->Devmode->dmPublic.dmFields &= ~DM_DUPLEX;
    if(pi->ppd->DefaultDuplex) {
        pi->Devmode->dmPublic.dmDuplex = pi->ppd->DefaultDuplex->WinDuplex;
        if(pi->Devmode->dmPublic.dmDuplex != 0)
            pi->Devmode->dmPublic.dmFields |= DM_DUPLEX;
        else
            pi->Devmode->dmPublic.dmDuplex = DMDUP_SIMPLEX;
    }

    res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL,
	    0, &needed, &pi->FontSubTableSize);
    if (res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND) {
	TRACE ("No 'FontSubTable' for printer '%s'\n", name);
    }
    else if (res == ERROR_MORE_DATA) {
	pi->FontSubTable = HeapAlloc (PSDRV_Heap, 0, needed);
	if (pi->FontSubTable == NULL) {
	    ERR ("Failed to allocate %li bytes from heap\n", needed);
	    goto closeprinter;
	}

	res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable",
		(LPBYTE) pi->FontSubTable, needed, &needed,
		&pi->FontSubTableSize);
	if (res != ERROR_SUCCESS) {
	    ERR ("EnumPrinterDataExA returned %li\n", res);
	    goto closeprinter;
	}
    }
    else {
	ERR("EnumPrinterDataExA returned %li\n", res);
	goto closeprinter;
    }

    if (ClosePrinter (hPrinter) == 0) {
	ERR ("ClosePrinter failed with code %li\n", GetLastError ());
	goto cleanup;
    }

    pi->next = NULL;
    pi->Fonts = NULL;

    for(font = pi->ppd->InstalledFonts; font; font = font->next) {
        afm = PSDRV_FindAFMinList(PSDRV_AFMFontList, font->Name);
	if(!afm) {
	    TRACE( "Couldn't find AFM file for installed printer font '%s' - "
	    	    "ignoring\n", font->Name);
	}
	else {
	    BOOL added;
	    if (PSDRV_AddAFMtoList(&pi->Fonts, afm, &added) == FALSE) {
	    	PSDRV_FreeAFMList(pi->Fonts);
		goto cleanup;
	    }
	}

    }
    if (ppd) unlink(ppd);
    return pi;

closeprinter:
    ClosePrinter(hPrinter);
cleanup:
    if (ppdFileName)
        HeapFree(PSDRV_Heap, 0, ppdFileName);
    if (pi->FontSubTable)
    	HeapFree(PSDRV_Heap, 0, pi->FontSubTable);
    if (pi->FriendlyName)
    	HeapFree(PSDRV_Heap, 0, pi->FriendlyName);
    if (pi->Devmode)
    	HeapFree(PSDRV_Heap, 0, pi->Devmode);
fail:
    HeapFree(PSDRV_Heap, 0, pi);
    if (ppd) unlink(ppd);
    *last = NULL;
    return NULL;
}
