PATCH: CUPS printing

Marcus Meissner Marcus.Meissner at caldera.de
Thu Apr 26 12:06:02 CDT 2001


Hiho,

I have implemented CUPS support in WINE.

Rerun autoconf ; autoheader -l include

The only dangerous option currently is that in win.ini it modifies the line:
	[windows]
	device=...
marking the default printer.

I used a hack with 'CUPS:CupsPrinterName' to pass the information
on which printer to use down to the spooling code, since this appears to
be otherwise impossible.

I have also added some gotos to get rid of the huge unnecessary code
duplication in PSDRV_FindPrinterInfo().

I have tested it with:
	notepad.exe
	mspaint.exe
	winhelp.exe
	uedit32.exe

Printing now works out of the box, if you have [afmdirs] set up and .afms
available.

Ciao, Marcus

Changelog:
	Added CUPS printing support.

Index: configure.in
===================================================================
RCS file: /home/wine/wine/configure.in,v
retrieving revision 1.195
diff -u -r1.195 configure.in
--- configure.in	2001/04/16 19:36:12	1.195
+++ configure.in	2001/04/26 16:46:13
@@ -368,6 +368,14 @@
     fi
 fi
 
+CUPSLIBS=""
+dnl **** Check for CUPS ****
+AC_CHECK_LIB(cups,cupsGetPPD,
+	AC_DEFINE(HAVE_CUPS)
+	CUPSLIBS="-lcups"
+)
+AC_SUBST(CUPSLIBS)
+
 dnl **** Check for IPX (currently Linux only) ****
 AC_CACHE_CHECK("for GNU style IPX support", ac_cv_c_ipx_gnu,
  AC_TRY_COMPILE(
Index: dlls/commdlg/printdlg.c
===================================================================
RCS file: /home/wine/wine/dlls/commdlg/printdlg.c,v
retrieving revision 1.38
diff -u -r1.38 printdlg.c
--- dlls/commdlg/printdlg.c	2001/02/26 22:32:35	1.38
+++ dlls/commdlg/printdlg.c	2001/04/26 16:46:14
@@ -1554,7 +1554,7 @@
  */
 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
 	FIXME("(%p), stub!\n",setupdlg);
-	return FALSE;
+	return TRUE;
 }
 /***********************************************************************
  *            PageSetupDlgW  (COMDLG32.16)
Index: dlls/gdi/printdrv.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/printdrv.c,v
retrieving revision 1.8
diff -u -r1.8 printdrv.c
--- dlls/gdi/printdrv.c	2001/01/06 00:35:37	1.8
+++ dlls/gdi/printdrv.c	2001/04/26 16:46:14
@@ -7,6 +7,8 @@
  * Copyright 1999 Klaas van Gend
  */
 
+#include "config.h"
+
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -453,7 +455,10 @@
     if (pszOutput == NULL || *pszOutput == '\0')
       return -1;
 
-    PROFILE_GetWineIniString( "spooler", pszOutput, "", psCmd, sizeof(psCmd) );
+    if (!strncmp("CUPS:",pszOutput,5))
+      sprintf(psCmd,"|lpr -P%s",pszOutput+5);
+    else
+      PROFILE_GetWineIniString("spooler",pszOutput,"",psCmd,sizeof(psCmd));
     TRACE("Got printerSpoolCommand '%s' for output device '%s'\n",
 	  psCmd, pszOutput);
     if (!*psCmd)
Index: dlls/wineps/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/wineps/Makefile.in,v
retrieving revision 1.9
diff -u -r1.9 Makefile.in
--- dlls/wineps/Makefile.in	2001/04/20 18:30:38	1.9
+++ dlls/wineps/Makefile.in	2001/04/26 16:46:15
@@ -6,6 +6,7 @@
 SOVERSION = 1.0
 ALTNAMES  = wineps16
 IMPORTS   = user32 gdi32 winspool.drv kernel32 ntdll
+EXTRALIBS = @CUPSLIBS@
 
 C_SRCS = \
 	afm.c \
Index: dlls/wineps/init.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/init.c,v
retrieving revision 1.12
diff -u -r1.12 init.c
--- dlls/wineps/init.c	2001/04/16 19:34:21	1.12
+++ dlls/wineps/init.c	2001/04/26 16:46:15
@@ -2,6 +2,7 @@
  *	PostScript driver initialization functions
  *
  *	Copyright 1998 Huw D M Davies
+ *	Copyright 2001 Marcus Meissner
  *
  */
 #include <string.h>
@@ -15,6 +16,10 @@
 #include "winerror.h"
 #include "options.h"
 
+#ifdef HAVE_CUPS
+# include <cups/cups.h>
+#endif
+
 DEFAULT_DEBUG_CHANNEL(psdrv);
 
 static BOOL PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
@@ -187,7 +192,7 @@
 /* dmCopies */		1,
 /* dmDefaultSource */	DMBIN_AUTO,
 /* dmPrintQuality */	0,
-/* dmColor */		DMCOLOR_MONOCHROME,
+/* dmColor */		DMCOLOR_COLOR,
 /* dmDuplex */		0,
 /* dmYResolution */	0,
 /* dmTTOption */	DMTT_SUBDEV,
@@ -427,13 +432,13 @@
     FONTNAME *font;
     AFM *afm;
     HANDLE hPrinter;
+    const char *ppd = NULL;
 
     TRACE("'%s'\n", name);
     
-    for( ; pi; last = &pi->next, pi = pi->next) {
+    for( ; pi; last = &pi->next, pi = pi->next)
         if(!strcmp(pi->FriendlyName, name))
 	    return pi;
-    }
 
     pi = *last = HeapAlloc( PSDRV_Heap, 0, sizeof(*pi) );
     pi->FriendlyName = HEAP_strdupA( PSDRV_Heap, 0, name );
@@ -443,6 +448,7 @@
     if(res == ERROR_INVALID_PRINTER_NAME || needed != sizeof(DefaultDevmode)) {
         pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) );
 	memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) );
+	strcpy(pi->Devmode->dmPublic.dmDeviceName,name);
 	DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE,
 		 REG_BINARY, (LPBYTE)&DefaultDevmode, sizeof(DefaultDevmode) );
 
@@ -453,34 +459,31 @@
 			  (LPBYTE)pi->Devmode, needed, &needed);
     }
 
-    if (OpenPrinterA (pi->FriendlyName, &hPrinter, NULL) == 0)
-    {
+    if (OpenPrinterA (pi->FriendlyName, &hPrinter, NULL) == 0) {
 	ERR ("OpenPrinterA failed with code %li\n", GetLastError ());
-	if (HeapFree (PSDRV_Heap, 0, pi->FriendlyName) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	if (HeapFree (PSDRV_Heap, 0, pi->Devmode) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	if (HeapFree (PSDRV_Heap, 0, pi) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	*last = NULL;
-	return NULL;
+	goto cleanup;
     }
+    pi->Devmode->dmDrvPrivate.ppdFileName[0]='\0';
+#ifdef HAVE_CUPS
+    {
+	ppd = cupsGetPPD(name);
 
-    res = GetPrinterDataA (hPrinter, "PPD File", NULL,
+	if (ppd) {
+		strcpy(pi->Devmode->dmDrvPrivate.ppdFileName,ppd);
+		res = ERROR_SUCCESS;
+		/* we should unlink() that file later */
+	} else {
+		ERR("Did not find ppd for %s\n",name);
+	}
+    }
+#endif
+    if (!pi->Devmode->dmDrvPrivate.ppdFileName[0]) {
+        res = GetPrinterDataA (hPrinter, "PPD File", NULL,
 	    pi->Devmode->dmDrvPrivate.ppdFileName, 256, &needed);
-    if (res != ERROR_SUCCESS)
-    {
+    }
+    if (res != ERROR_SUCCESS) {
 	ERR ("Error %li getting PPD file name for printer '%s'\n", res, name);
-	if (ClosePrinter (hPrinter) == 0)
-	    WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	*last = NULL;
-	return NULL;
+	goto closeprinter;
     }
 
     res = GetPrinterDataA (hPrinter, "Paper Size", NULL, (LPBYTE) &dwPaperSize,
@@ -489,19 +492,9 @@
 	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
-    {
+    else {
 	ERR ("GetPrinterDataA returned %li\n", res);
-	if (ClosePrinter (hPrinter) == 0)
-	    WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	*last = NULL;
-	return NULL;
+	goto closeprinter;
     }
 
     res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL,
@@ -511,83 +504,33 @@
     else if (res == ERROR_MORE_DATA)
     {
 	pi->FontSubTable = HeapAlloc (PSDRV_Heap, 0, needed);
-	if (pi->FontSubTable == NULL)
-	{
+	if (pi->FontSubTable == NULL) {
 	    ERR ("Failed to allocate %li bytes from heap\n", needed);
-	    if (ClosePrinter (hPrinter) == 0)
-		WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-	    *last = NULL;
-	    return NULL;
+	    goto closeprinter;
 	}
 
 	res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable",
 		(LPBYTE) pi->FontSubTable, needed, &needed,
 		&pi->FontSubTableSize);
-	if (res != ERROR_SUCCESS)
-	{
+	if (res != ERROR_SUCCESS) {
 	    ERR ("EnumPrinterDataExA returned %li\n", res);
-	    if (ClosePrinter (hPrinter) == 0)
-		WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-	    if (HeapFree (PSDRV_Heap, 0, pi->FontSubTable) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-            if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-		WARN ("HeapFree failed with code %li\n", GetLastError ());
-	    *last = NULL;
-	    return NULL;
+	    goto closeprinter;
 	}
-    }
-    else	/* error in 1st call to EnumPrinterDataExA */
-    {
-	ERR ("EnumPrinterDataExA returned %li\n", res);
-	if (ClosePrinter (hPrinter) == 0)
-	    WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	*last = NULL;
-	return NULL;
+    } else {
+	FIXME ("EnumPrinterDataExA returned %li\n", res);
+	/* ignore error */
     }
 
-    if (ClosePrinter (hPrinter) == 0)
-    {
+    if (ClosePrinter (hPrinter) == 0) {
 	ERR ("ClosePrinter failed with code %li\n", GetLastError ());
-	if (ClosePrinter (hPrinter) == 0)
-	    WARN ("ClosePrinter failed with code %li\n", GetLastError ());
-	if (HeapFree (PSDRV_Heap, 0, pi->FontSubTable) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->FriendlyName) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi->Devmode) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-        if (HeapFree(PSDRV_Heap, 0, pi) == 0)
-	    WARN ("HeapFree failed with code %li\n", GetLastError ());
-	*last = NULL;
-	return NULL;
+	goto cleanup;
     }
 
     pi->ppd = PSDRV_ParsePPD(pi->Devmode->dmDrvPrivate.ppdFileName);
     if(!pi->ppd) {
-	HeapFree(PSDRV_Heap, 0, pi->FontSubTable);
-        HeapFree(PSDRV_Heap, 0, pi->FriendlyName);
-        HeapFree(PSDRV_Heap, 0, pi->Devmode);
-        HeapFree(PSDRV_Heap, 0, pi);
-	*last = NULL;
 	MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
 	    pi->Devmode->dmDrvPrivate.ppdFileName);
-	return NULL;
+	goto cleanup;
     }
 
     pi->next = NULL;
@@ -595,14 +538,23 @@
 
     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 {
+	if(!afm)
+	    TRACE( "Couldn't find AFM file for installed printer font '%s' - ignoring\n", font->Name);
+	else
 	    PSDRV_AddAFMtoList(&pi->Fonts, afm);
-	}
-    }
 
+    }
+    if (ppd) unlink(ppd);
     return pi;
+
+closeprinter:
+    ClosePrinter(hPrinter);
+cleanup:
+    HeapFree (PSDRV_Heap, 0, pi->FontSubTable);
+    HeapFree(PSDRV_Heap, 0, pi->FriendlyName);
+    HeapFree(PSDRV_Heap, 0, pi->Devmode);
+    HeapFree(PSDRV_Heap, 0, pi);
+    if (ppd) unlink(ppd);
+    *last = NULL;
+    return NULL;
 }
Index: dlls/winspool/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/winspool/Makefile.in,v
retrieving revision 1.12
diff -u -r1.12 Makefile.in
--- dlls/winspool/Makefile.in	2000/11/29 18:38:25	1.12
+++ dlls/winspool/Makefile.in	2001/04/26 16:46:15
@@ -3,6 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = winspool.drv
+EXTRALIBS = @CUPSLIBS@
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
Index: dlls/winspool/info.c
===================================================================
RCS file: /home/wine/wine/dlls/winspool/info.c,v
retrieving revision 1.34
diff -u -r1.34 info.c
--- dlls/winspool/info.c	2001/02/28 05:26:08	1.34
+++ dlls/winspool/info.c	2001/04/26 16:46:15
@@ -5,13 +5,19 @@
  * Copyright 1998 Andreas Mohr
  * Copyright 1999 Klaas van Gend
  * Copyright 1999, 2000 Huw D M Davies
+ * Copyright 2001 Marcus Meissner
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stddef.h>
+#ifdef HAVE_CUPS
+# include <cups/cups.h>
+#endif
 #include "winspool.h"
 #include "winbase.h"
 #include "winerror.h"
@@ -69,6 +75,79 @@
 static WCHAR Share_NameW[] = {'S','h','a','r','e',' ','N','a','m','e',0};
 static WCHAR WinPrintW[] = {'W','i','n','P','r','i','n','t',0};
 
+static HKEY WINSPOOL_OpenDriverReg( LPVOID pEnvironment, BOOL unicode);
+
+#ifdef HAVE_CUPS
+void
+CUPS_LoadPrinters(void) {
+    cups_dest_t		*dests;
+    int			i,nrofdests;
+    PRINTER_INFO_2A	pinfo2a;
+    DRIVER_INFO_3A	di3a;
+    const char*		def = cupsGetDefault();
+
+    nrofdests = cupsGetDests(&dests);
+
+    di3a.cVersion = 0x400;
+    di3a.pName = "PS Driver";
+    di3a.pEnvironment = NULL;	/* NULL means auto */
+    di3a.pDriverPath = "wineps.drv";
+    di3a.pDataFile = "<datafile?>";
+    di3a.pConfigFile = "wineps.drv";
+    di3a.pHelpFile = "<helpfile?>";
+    di3a.pDependentFiles = "<dependend files?>";
+    di3a.pMonitorName = "<monitor name?>";
+    di3a.pDefaultDataType = "RAW";
+
+
+    if (!AddPrinterDriverA(NULL,3,(LPBYTE)&di3a)) {
+	ERR("Failed adding PS Driver (%ld)\n",GetLastError());
+        return;
+    }
+    for (i=0;i<nrofdests;i++) {
+	const char *ppd = cupsGetPPD(dests[i].name);
+	char	*port,*devline;
+
+	if (!ppd)
+		continue;
+	unlink(ppd);
+
+	if (!strcmp(def,dests[i].name)) {
+		char	*buf = HeapAlloc(GetProcessHeap(),0,2*strlen(dests[i].name)+strlen(",WINEPS,CUPS:")+1);
+
+		sprintf(buf,"%s,WINEPS,CUPS:%s",dests[i].name,dests[i].name);
+		WriteProfileStringA("windows","device",buf);
+		HeapFree(GetProcessHeap(),0,buf);
+	}
+	memset(&pinfo2a,0,sizeof(pinfo2a));
+	pinfo2a.pPrinterName	= dests[i].name;
+	pinfo2a.pDatatype	= "RAW";
+	pinfo2a.pPrintProcessor	= "WinPrint";
+	pinfo2a.pDriverName	= "PS Driver";
+	pinfo2a.pComment	= "WINEPS Printer using CUPS";
+	pinfo2a.pLocation	= "<physical location of printer>";
+	port = HeapAlloc(GetProcessHeap(),0,strlen("CUPS:")+strlen(dests[i].name)+1);
+	sprintf(port,"CUPS:%s",dests[i].name);
+	pinfo2a.pPortName	= port;
+	pinfo2a.pParameters	= "<parameters?>";
+	pinfo2a.pShareName	= "<share name?>";
+	pinfo2a.pSepFile	= "<sep file?>";
+
+	devline=HeapAlloc(GetProcessHeap(),0,strlen("WINEPS,")+strlen(port)+1);
+	sprintf(devline,"WINEPS,%s",port);
+	WriteProfileStringA("devices",dests[i].name,devline);
+	HeapFree(GetProcessHeap(),0,devline);
+
+	if (!AddPrinterA(NULL,2,(LPBYTE)&pinfo2a)) {
+	    if (GetLastError()!=ERROR_PRINTER_ALREADY_EXISTS)
+	        ERR("%s not added by AddPrinterA (%ld)\n",dests[i].name,GetLastError());
+	}
+	HeapFree(GetProcessHeap(),0,port);
+    }
+}
+#endif
+
+
 /******************************************************************
  *  WINSPOOL_GetOpenedPrinterEntry
  *  Get the first place empty in the opened printer table
@@ -374,7 +453,10 @@
 
     if(!pDeviceName) {
         LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter);
-        if(!lpNameW) return -1;
+        if(!lpNameW) {
+		ERR("no name from hPrinter?\n");
+		return -1;
+	}
 	lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW);
     }
 
@@ -382,7 +464,10 @@
     {
         GDI_CallExtDeviceMode16 = (void*)GetProcAddress( GetModuleHandleA("gdi32"),
                                                          (LPCSTR)102 );
-        if (!GDI_CallExtDeviceMode16) return -1;
+        if (!GDI_CallExtDeviceMode16) {
+		ERR("No CallExtDeviceMode16?\n");
+		return -1;
+	}
     }
     ret = GDI_CallExtDeviceMode16(hWnd, pDevModeOutput, lpName, "LPT1:",
 				  pDevModeInput, NULL, fMode);
@@ -484,7 +569,7 @@
 
     if(RegOpenKeyW(hkeyPrinters, lpPrinterName, &hkeyPrinter)
        != ERROR_SUCCESS) {
-        WARN("Can't find printer %s in registry\n", debugstr_w(lpPrinterName));
+        ERR("Can't find printer %s in registry\n", debugstr_w(lpPrinterName));
 	RegCloseKey(hkeyPrinters);
         SetLastError(ERROR_INVALID_PARAMETER);
 	return FALSE;
@@ -698,12 +783,12 @@
     TRACE("(%s,%ld,%p)\n", debugstr_w(pName), Level, pPrinter);
     
     if(pName != NULL) {
-        FIXME("pName = %s - unsupported\n", debugstr_w(pName));
+        ERR("pName = %s - unsupported\n", debugstr_w(pName));
 	SetLastError(ERROR_INVALID_PARAMETER);
 	return 0;
     }
     if(Level != 2) {
-        WARN("Level = %ld\n", Level);
+        ERR("Level = %ld, unsupported!\n", Level);
 	SetLastError(ERROR_INVALID_LEVEL);
 	return 0;
     }
@@ -741,7 +826,7 @@
     RegCloseKey(hkeyDrivers);
 
     if(lstrcmpiW(pi->pPrintProcessor, WinPrintW)) {  /* FIXME */
-        WARN("Can't find processor %s\n", debugstr_w(pi->pPrintProcessor));
+        FIXME("Can't find processor %s\n", debugstr_w(pi->pPrintProcessor));
 	SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
 	RegCloseKey(hkeyPrinters);
 	return 0;
@@ -751,20 +836,20 @@
      */
     size = DocumentPropertiesW(0, -1, pi->pPrinterName, NULL, NULL, 0);
     if(size < 0) {
-        WARN("DocumentProperties fails\n");
-	SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER);
-	return 0;
+        FIXME("DocumentProperties fails\n");
+	size = sizeof(DEVMODEW);
     }
     if(pi->pDevMode) {
         dmW = pi->pDevMode;
     } else {
 	dmW = HeapAlloc(GetProcessHeap(), 0, size);
+	dmW->dmSize = size;
 	DocumentPropertiesW(0, -1, pi->pPrinterName, dmW, NULL, DM_OUT_BUFFER);
     }
 
     if(RegCreateKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) !=
        ERROR_SUCCESS) {
-        WARN("Can't create printer %s\n", debugstr_w(pi->pPrinterName));
+        FIXME("Can't create printer %s\n", debugstr_w(pi->pPrinterName));
 	SetLastError(ERROR_INVALID_PRINTER_NAME);
 	RegCloseKey(hkeyPrinters);
 	if(!pi->pDevMode)
@@ -775,7 +860,6 @@
 		   (LPBYTE)&pi->Attributes, sizeof(DWORD));
     RegSetValueExW(hkeyPrinter, DatatypeW, 0, REG_SZ, (LPBYTE)pi->pDatatype,
 		   0);
-
     /* Write DEVMODEA not DEVMODEW into reg.  This is what win9x does
        and we support these drivers.  NT writes DEVMODEW so somehow
        we'll need to distinguish between these when we support NT
@@ -832,7 +916,7 @@
 
     TRACE("(%s,%ld,%p): stub\n", debugstr_a(pName), Level, pPrinter);
     if(Level != 2) {
-        WARN("Level = %ld\n", Level);
+        ERR("Level = %ld, unsupported!\n", Level);
 	SetLastError(ERROR_INVALID_LEVEL);
 	return 0;
     }
@@ -1080,7 +1164,7 @@
     if ((ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA)) sz = 0;
     if (sz < sizeof(DEVMODEA))
     {
-        ERR("corrupted registry for %s\n", debugstr_w(ValueName));
+        ERR("corrupted registry for %s ( size %ld)\n",debugstr_w(ValueName),sz);
         sz = sizeof(DEVMODEA);
     }
     /* ensures that dmSize is not erratically bogus if registry is invalid */
Index: dlls/winspool/wspool.c
===================================================================
RCS file: /home/wine/wine/dlls/winspool/wspool.c,v
retrieving revision 1.4
diff -u -r1.4 wspool.c
--- dlls/winspool/wspool.c	2001/02/28 05:26:09	1.4
+++ dlls/winspool/wspool.c	2001/04/26 16:46:15
@@ -5,6 +5,9 @@
  * Copyright 1999 Thuy Nguyen
  */
 
+
+#include "config.h"
+#include "winspool.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(winspool);
@@ -22,14 +25,16 @@
 {
   switch (reason)
   {
-    case DLL_PROCESS_ATTACH:
+    case DLL_PROCESS_ATTACH: {
+#ifdef HAVE_CUPS
+      extern void CUPS_LoadPrinters();
+      CUPS_LoadPrinters();
+#endif
       break;
-
+    }
     case DLL_PROCESS_DETACH:
       break;
   }
 
   return TRUE;
 }
-
-
Index: include/acconfig.h
===================================================================
RCS file: /home/wine/wine/include/acconfig.h,v
retrieving revision 1.36
diff -u -r1.36 acconfig.h
--- include/acconfig.h	2001/01/19 21:09:09	1.36
+++ include/acconfig.h	2001/04/26 16:46:16
@@ -119,3 +119,6 @@
 
 /* Define if we have linux/input.h AND it contains the INPUT event API */
 #undef HAVE_CORRECT_LINUXINPUT_H
+
+/* Define if we have CUPS */
+#undef HAVE_CUPS




More information about the wine-patches mailing list