On Mon, 05 Feb 2001, you wrote: > > Well, I couldn't get GetPrinterData to work. The driver would compile > > OK, > > but Wine was unable to load the driver, because it couldn't resolve the > > 'GetPrinterData' symbol. (Probably something I did wrong.) > > You'd need to add the line > import winspool.drv > to wineps.spec > I *think* that I tried that. I'll doublecheck when I have a chance. > Actually since you're storing the data as many values under a separate > key would you mind moving the key to [..\Printers\<name>\FontSubTable] > (i.e. get rid of the PrinterDriverData elememt), this will mean the > GetPrinterDataEx will still be able to access the data (I really think > that we should eventually use these APIs as hard coding the > ..\Printers\<name> bit into the driver offends me ;) ). What part offends you? I have not hardcoded the name of the printer into the driver. It do my setup in PSDRV_GetPrinterInfo, so I have the name available. Does GetPrinterDataEx allow one to enumerate the values in a key? Keep in mind that with this setup we don't know the value names. Here is my initial patch. It doesn't include any of the changes you suggest in your most recent note, but take a look and tell me what you think.
diff -u ../wine-20010203cvs/dlls/wineps/font.c dlls/wineps/font.c --- ../wine-20010203cvs/dlls/wineps/font.c Wed Jan 24 13:38:56 2001 +++ dlls/wineps/font.c Sun Feb 4 23:53:08 2001 @@ -72,6 +72,22 @@ } } + if (physDev->pi->FontSubTable != NULL) + { + int i; + + for (i = 0; physDev->pi->FontSubTable[i].winFont != NULL; ++i) + { + if (!strcasecmp (FaceName, physDev->pi->FontSubTable[i].winFont)) + { + TRACE ("substituting facename '%s' for '%s'\n", + physDev->pi->FontSubTable[i].psFont, FaceName); + strcpy (FaceName, physDev->pi->FontSubTable[i].psFont); + break; + } + } + } + TRACE("Trying to find facename '%s'\n", FaceName); /* Look for a matching font family */ diff -u ../wine-20010203cvs/dlls/wineps/init.c dlls/wineps/init.c --- ../wine-20010203cvs/dlls/wineps/init.c Sun Jan 28 17:13:45 2001 +++ dlls/wineps/init.c Mon Feb 5 08:46:11 2001 @@ -5,6 +5,8 @@ * */ #include <string.h> +#include <stdio.h> +#include <stdlib.h> #include "gdi.h" #include "psdrv.h" @@ -223,6 +225,11 @@ DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }; +/* Registry key for printer driver data */ + +static const char SUBKEY_PRINTERS[] = + "System\\CurrentControlSet\\Control\\Print\\Printers\\"; + /********************************************************************* * PSDRV_Init * @@ -414,7 +421,146 @@ } - +/********************************************************************** + * PSDRV_GetPrnDrvDataHandle + * + * Get registry key handle for HKLM\System\CurrentControlSet\Control\Print\ + * Printers\<printer name>\PrinterDriverData + * + */ +static HKEY PSDRV_GetPrnDrvDataHandle (LPCSTR name) +{ + LPSTR subkey; + LONG result; + HKEY hkReturn; + + subkey = (LPSTR) alloca (strlen (name) + sizeof (SUBKEY_PRINTERS) + + sizeof ("\\PrinterDriverData") - 1); + if (subkey == NULL) + return (HKEY) NULL; + + sprintf (subkey, "%s%s%s", SUBKEY_PRINTERS, name, "\\PrinterDriverData"); + + result = RegOpenKeyExA (HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hkReturn); + if (result != ERROR_SUCCESS) + return (HKEY) NULL; + + return hkReturn; +} + + +/********************************************************************** + * PSDRV_FreeFontSubTable + */ +static void PSDRV_FreeFontSubTable (FONTSUBST *table, DWORD size) +{ + DWORD i; + + for (i = 0; i < size; ++i) + { + if (table[i].winFont != NULL) + HeapFree (PSDRV_Heap, 0, (char *) table[i].winFont); + if (table[i].psFont != NULL) + HeapFree (PSDRV_Heap, 0, (char *) table[i].psFont); + } + + HeapFree (PSDRV_Heap, 0, table); +} + + +/********************************************************************** + * PSDRV_BuildFontSubTable + * + * Read font substitution table from HKLM\System\CurrentControlSet\Control\ + * Print\Printers\<printer name>\PrinterDriverData\FontSubTable + * + */ +static FONTSUBST *PSDRV_BuildFontSubTable (HKEY hkPrnDriverData) +{ + HKEY hkFontSubTable; + LONG result; + DWORD cValues, cbMaxValueNameLen, cbMaxValueLen, cbValueNameLen, + cbValueLen, dwIndex; + LPSTR lpValueName, lpValue; + FONTSUBST *FontSubTable; + + result = RegOpenKeyExA (hkPrnDriverData, "FontSubTable", 0, KEY_READ, + &hkFontSubTable); + if (result != ERROR_SUCCESS) + { + TRACE ("Couldn't get registry key handle for FontSubTable; assuming " + "there isn't one\n"); + return NULL; + } + + result = RegQueryInfoKeyA (hkFontSubTable, NULL, NULL, NULL, NULL, NULL, + NULL, &cValues, &cbMaxValueNameLen, &cbMaxValueLen, NULL, NULL); + if (result != ERROR_SUCCESS) + { + ERR ("RegQueryInfoKeyA (hkFontSubTable) failed\n"); + RegCloseKey (hkFontSubTable); + return NULL; + } + + cbMaxValueNameLen +=2; cbMaxValueLen += 2; + lpValueName = alloca (cbMaxValueNameLen); lpValue = alloca (cbMaxValueLen); + if (lpValueName == NULL || lpValue == NULL) + { + ERR ("Stack allocation failure\n"); + RegCloseKey (hkFontSubTable); + return NULL; + } + + FontSubTable = HeapAlloc (PSDRV_Heap, HEAP_ZERO_MEMORY, + (cValues + 1) * sizeof (FONTSUBST)); + if (FontSubTable == NULL) + { + ERR ("Memory allocation failure\n"); + RegCloseKey (hkFontSubTable); + return NULL; + } + + for (dwIndex = 0; dwIndex < cValues; ++dwIndex) + { + cbValueNameLen = cbMaxValueNameLen; cbValueLen = cbMaxValueLen; + result = RegEnumValueA (hkFontSubTable, dwIndex, lpValueName, + &cbValueNameLen, NULL, NULL, lpValue, &cbValueLen); + if (result != ERROR_SUCCESS) + { + ERR ("RegEnumValueA (hkFontSubTable, %li) failed\n", dwIndex); + PSDRV_FreeFontSubTable (FontSubTable, cValues); + RegCloseKey (hkFontSubTable); + return NULL; + } + + FontSubTable[dwIndex].winFont = + HEAP_strdupA (PSDRV_Heap, 0, lpValueName); + FontSubTable[dwIndex].psFont = HEAP_strdupA (PSDRV_Heap, 0, lpValue); + if (FontSubTable[dwIndex].winFont == NULL || + FontSubTable[dwIndex].psFont == NULL) + { + ERR ("Memory allocation failure\n"); + PSDRV_FreeFontSubTable (FontSubTable, cValues); + RegCloseKey (hkFontSubTable); + return NULL; + } + + TRACE ("%s -> %s\n", FontSubTable[dwIndex].winFont, + FontSubTable[dwIndex].psFont); + + if (strlen (FontSubTable[dwIndex].psFont) >= LF_FACESIZE) + { + WARN ("facename '%s' is too long; disabling this substitution\n", + FontSubTable[dwIndex].psFont); + *FontSubTable[dwIndex].winFont = '\0'; + } + } + + FontSubTable[cValues].winFont = FontSubTable[cValues].psFont = NULL; + RegCloseKey (hkFontSubTable); + + return FontSubTable; +} /********************************************************************** * PSDRV_FindPrinterInfo @@ -426,6 +572,7 @@ PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList; FONTNAME *font; AFM *afm; + HKEY hkPrnData; TRACE("'%s'\n", name); @@ -452,8 +599,34 @@ (LPBYTE)pi->Devmode, needed, &needed); } - PROFILE_GetWineIniString("psdrv", "ppdfile", "default.ppd", - pi->Devmode->dmDrvPrivate.ppdFileName, 256); + if ((hkPrnData = PSDRV_GetPrnDrvDataHandle (name)) == (HKEY) NULL) + { + HeapFree(PSDRV_Heap, 0, pi->FriendlyName); + HeapFree(PSDRV_Heap, 0, pi->Devmode); + HeapFree(PSDRV_Heap, 0, pi); + *last = NULL; + ERR ("Couldn't get registry key handle for HKLM\\%s%s%s\n", + SUBKEY_PRINTERS, name, "\\PrinterDriverData"); + return NULL; + } + + needed = 255; + if (RegQueryValueExA (hkPrnData, "PPD File", NULL, NULL, + pi->Devmode->dmDrvPrivate.ppdFileName, &needed) != ERROR_SUCCESS) + { + RegCloseKey (hkPrnData); + HeapFree(PSDRV_Heap, 0, pi->FriendlyName); + HeapFree(PSDRV_Heap, 0, pi->Devmode); + HeapFree(PSDRV_Heap, 0, pi); + *last = NULL; + ERR ("No 'PPD File' specified in HKLM\\%s%s%s\n", SUBKEY_PRINTERS, + name, "\\PrinterDriverData"); + return NULL; + } + + pi->FontSubTable = PSDRV_BuildFontSubTable (hkPrnData); + RegCloseKey (hkPrnData); + pi->ppd = PSDRV_ParsePPD(pi->Devmode->dmDrvPrivate.ppdFileName); if(!pi->ppd) { HeapFree(PSDRV_Heap, 0, pi->FriendlyName); diff -u ../wine-20010203cvs/dlls/wineps/psdrv.h dlls/wineps/psdrv.h --- ../wine-20010203cvs/dlls/wineps/psdrv.h Sun Jan 28 17:13:45 2001 +++ dlls/wineps/psdrv.h Mon Feb 5 08:43:53 2001 @@ -162,11 +162,16 @@ } PSDRV_DEVMODEA; +/* Font substitution table entry */ + +typedef struct { char *winFont, *psFont; } FONTSUBST; + typedef struct _tagPI { char *FriendlyName; PPD *ppd; PSDRV_DEVMODEA *Devmode; FONTFAMILY *Fonts; + FONTSUBST *FontSubTable; struct _tagPI *next; } PRINTERINFO; @@ -380,6 +385,7 @@ WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpdm); VOID PSDRV_DrawLine( DC *dc ); + #endif Only in dlls/wineps/: rsrc.res Only in dlls/wineps/: wineps.spec.c Only in dlls/wineps/: wineps16.spec.c