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

Reply via email to