Author: jimtabor
Date: Wed May 27 08:49:29 2009
New Revision: 41135
URL:
http://svn.reactos.org/svn/reactos?rev=41135&view=rev
Log:
- Implementation of gdi printing support. Work in progress. Added StartDocW plus others
and fixed some defines. Found the initialization bug again, yes it was never fixed, but
worked around. The debug spam has a purpose, just read it.
Modified:
trunk/reactos/dll/win32/gdi32/include/gdi32p.h
trunk/reactos/dll/win32/gdi32/misc/misc.c
trunk/reactos/dll/win32/gdi32/objects/dc.c
trunk/reactos/dll/win32/gdi32/objects/printdrv.c
trunk/reactos/include/reactos/win32k/ntgdihdl.h
Modified: trunk/reactos/dll/win32/gdi32/include/gdi32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/include/gd…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] Wed May 27 08:49:29 2009
@@ -104,7 +104,8 @@
DWORD dwDriverCount; // After init should be 2
DWORD WOW64_UMPDev;
DWORD WOW64_hMod;
- WCHAR String[188];
+ DWORD Unknown;
+ PVOID apfn[INDEX_LAST]; // Print Driver pfn
} UMPDEV, *PUMPDEV;
#define LOCALFONT_COUNT 10
@@ -128,7 +129,7 @@
typedef BOOL WINAPI (*OPENPRINTERW) (LPWSTR,PHANDLE,LPPRINTER_DEFAULTSW);
typedef BOOL WINAPI (*READPRINTER) (HANDLE,PVOID,DWORD,PDWORD);
typedef BOOL WINAPI (*RESETPRINTERW) (HANDLE,LPPRINTER_DEFAULTSW);
-typedef BOOL WINAPI (*STARTDOCDLGW) (HANDLE,DOCINFOW *);
+typedef LPWSTR WINAPI (*STARTDOCDLGW) (HANDLE,DOCINFOW *);
typedef DWORD WINAPI (*STARTDOCPRINTERW) (HANDLE,DWORD,PBYTE);
typedef BOOL WINAPI (*STARTPAGEPRINTER) (HANDLE);
// ddk/winsplp.h
@@ -145,6 +146,8 @@
typedef DWORD WINAPI (*QUERYSPOOLMODE) (HANDLE,DWORD,DWORD);
typedef DWORD WINAPI (*QUERYREMOTEFONTS) (DWORD,DWORD,DWORD);
+extern CLOSEPRINTER fpClosePrinter;
+
/* FUNCTIONS *****************************************************************/
PVOID
@@ -195,6 +198,7 @@
);
PLDC
+FASTCALL
GdiGetLDC(HDC hDC);
HGDIOBJ
@@ -277,6 +281,7 @@
VOID GdiSAPCallback(PLDC pldc);
int FASTCALL DocumentEventEx(PVOID,HANDLE,HDC,int,ULONG,PVOID,ULONG,PVOID);
+BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
BOOL FASTCALL LoadTheSpoolerDrv(VOID);
/* EOF */
Modified: trunk/reactos/dll/win32/gdi32/misc/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/misc/misc.…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] Wed May 27 08:49:29 2009
@@ -28,6 +28,9 @@
#include "precomp.h"
+#define NDEBUG
+#include <debug.h>
+
PGDI_TABLE_ENTRY GdiHandleTable = NULL;
PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
HANDLE CurrentProcessId = NULL;
@@ -121,47 +124,93 @@
BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
{
- PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
- if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
- ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
+ if ( GdiHandleTable )
+ {
+ PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
+ if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
+ ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
GDI_HANDLE_GET_TYPE(hGdiObj))
- {
- HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
- if(pid == NULL || pid == CurrentProcessId)
- {
- //
- // Need to test if we have Read & Write access to the VM address space.
- //
- BOOL Result = TRUE;
- if(Entry->UserData)
- {
- volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
- _SEH2_TRY
+ {
+ HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
+ if(pid == NULL || pid == CurrentProcessId)
+ {
+ //
+ // Need to test if we have Read & Write access to the VM address space.
+ //
+ BOOL Result = TRUE;
+ if(Entry->UserData)
{
- *Current = *Current;
+ volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
+ _SEH2_TRY
+ {
+ *Current = *Current;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Result = FALSE;
+ }
+ _SEH2_END
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
+ else
+ Result = FALSE; // Can not be zero.
+ if (Result) *UserData = Entry->UserData;
+ return Result;
+ }
+ }
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ else
+ {
+ DPRINT1("!GGHUD: Warning System Initialization Error!!!! GdiHandleTable == 0x%x
!!!\n",GdiHandleTable);
+ *UserData = NULL;
+ }
+ return FALSE;
+}
+
+PLDC
+FASTCALL
+GdiGetLDC(HDC hDC)
+{
+ if ( GdiHandleTable )
+ {
+ PDC_ATTR Dc_Attr;
+ PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX((HGDIOBJ) hDC);
+ HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
+ // Don't check the mask, just the object type.
+ if ( Entry->ObjectType == GDIObjType_DC_TYPE &&
+ (pid == NULL || pid == CurrentProcessId) )
+ {
+ BOOL Result = TRUE;
+ if (Entry->UserData)
+ {
+ volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
+ _SEH2_TRY
+ {
+ *Current = *Current;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Result = FALSE;
+ }
+ _SEH2_END
+ }
+ else
Result = FALSE;
- }
- _SEH2_END
- }
- else
- Result = FALSE; // Can not be zero.
- if (Result) *UserData = Entry->UserData;
- return Result;
- }
- }
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
-}
-
-PLDC GdiGetLDC(HDC hDC)
-{
- PDC_ATTR Dc_Attr;
- if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
- return NULL;
- return Dc_Attr->pvLDC;
+
+ if (Result)
+ {
+ Dc_Attr = (PDC_ATTR)Entry->UserData;
+ return Dc_Attr->pvLDC;
+ }
+ }
+ return NULL;
+ }
+ else
+ {
+ DPRINT1("!LDC: Warning System Initialization Error!!!! GdiHandleTable == 0x%x
!!!\n",GdiHandleTable);
+ }
+ return NULL;
}
VOID GdiSAPCallback(PLDC pldc)
Modified: trunk/reactos/dll/win32/gdi32/objects/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/dc…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] Wed May 27 08:49:29 2009
@@ -275,25 +275,37 @@
DeleteDC(HDC hDC)
{
BOOL Ret = TRUE;
-#if 0
- PDC_ATTR Dc_Attr;
- PLDC pLDC;
-
- if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
return FALSE;
-
- if ( Dc_Attr )
- {
- pLDC = Dc_Attr->pvLDC;
-
- if ( pLDC )
- {
- DPRINT1("Delete the Local DC structure\n");
- LocalFree( pLDC );
- }
- }
-#endif
+ PLDC pLDC = NULL;
+ HANDLE hPrinter = NULL;
+ ULONG hType = GDI_HANDLE_GET_TYPE(hDC);
+
+ pLDC = GdiGetLDC(hDC);
+
+ if (hType != GDILoObjType_LO_DC_TYPE)
+ {
+
+ if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hDC);
+ if (pLDC->hPrinter)
+ {
+ DocumentEventEx(NULL, pLDC->hPrinter, hDC, DOCUMENTEVENT_DELETEDC, 0, NULL, 0,
NULL);
+ hPrinter = pLDC->hPrinter;
+ pLDC->hPrinter = NULL;
+ }
+ }
+
Ret = NtGdiDeleteObjectApp(hDC);
+ if (Ret && pLDC )
+ {
+ DPRINT1("Delete the Local DC structure\n");
+ LocalFree( pLDC );
+ }
+ if (hPrinter) fpClosePrinter(hPrinter);
return Ret;
}
Modified: trunk/reactos/dll/win32/gdi32/objects/printdrv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/pr…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/printdrv.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/printdrv.c [iso-8859-1] Wed May 27 08:49:29
2009
@@ -40,7 +40,7 @@
HANDLE ghSpooler = NULL;
static ABORTPRINTER fpAbortPrinter;
-static CLOSEPRINTER fpClosePrinter;
+CLOSEPRINTER fpClosePrinter;
static CLOSESPOOLFILEHANDLE fpCloseSpoolFileHandle;
static COMMITSPOOLDATA fpCommitSpoolData;
//static fpConnectToLd64In32Server;
@@ -92,10 +92,60 @@
return SP_ERROR;
}
+ if (pldc->Flags & LDC_ATENDPAGE) return 1;
+
+ if (pldc->Flags & LDC_META_PRINT)
+ {
+ if ( Form )
+ {
+ // Do MF EndPageForm
+ }
+ else
+ {
+ // Do MF EndPage
+ }
+ return Ret;
+ }
+
+ if (pldc->Flags & LDC_KILL_DOCUMENT || pldc->Flags & LDC_INIT_PAGE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return SP_ERROR;
+ }
+
+ if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc);
+
+ pldc->Flags &= ~LDC_INIT_PAGE;
+
+ DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDPAGE, 0, NULL, 0,
NULL);
+
+ ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
+
+ if ( NtGdiEndPage(hdc) )
+ {
+ BOOL Good;
+// if (pldc->pUMPDev)
+ Good = EndPagePrinterEx(NULL,pldc->hPrinter);
+
+ if (Good) pldc->Flags |= LDC_STARTPAGE;
+ Ret = 1;
+ }
+ else
+ SetLastError(ERROR_INVALID_PARAMETER);
return Ret;
}
/* FUNCTIONS *****************************************************************/
+
+BOOL
+FASTCALL
+AbortPrinterEx(
+ PVOID pvUMPDev,
+ HANDLE hPrinter
+ )
+{
+ return fpAbortPrinter(hPrinter);
+}
int
FASTCALL
@@ -128,11 +178,11 @@
EndPagePrinterEx(
PVOID pvUMPDev,
HANDLE hPrinter
- )
+ )
{
return fpEndPagePrinter(hPrinter);
}
-
+
BOOL
FASTCALL
LoadTheSpoolerDrv(VOID)
@@ -169,7 +219,7 @@
fpSeekPrinter = GetProcAddress(hModWinSpoolDrv, "SeekPrinter");
fpSplDriverUnloadComplete = GetProcAddress(hModWinSpoolDrv,
"SplDriverUnloadComplete");
fpSplReadPrinter = GetProcAddress(hModWinSpoolDrv, (LPCSTR)205);
- fpStartDocDlgW = GetProcAddress(hModWinSpoolDrv, "StartDocDlgW");
+ fpStartDocDlgW = (PVOID)GetProcAddress(hModWinSpoolDrv,
"StartDocDlgW");
fpStartDocPrinterW = (PVOID)GetProcAddress(hModWinSpoolDrv,
"StartDocPrinterW");
fpStartPagePrinter = GetProcAddress(hModWinSpoolDrv,
"StartPagePrinter");
@@ -213,6 +263,31 @@
return (ghSpooler != NULL);
}
+/*
+ Note from msdn:
+
+ The sequence for a print job is as follows:
+
+ 1. To begin a print job, call StartDocPrinter.
+ 2. To begin each page, call StartPagePrinter.
+ 3. To write data to a page, call WritePrinter.
+ 4. To end each page, call EndPagePrinter.
+ 5. Repeat 2, 3, and 4 for as many pages as necessary.
+ 6. To end the print job, call EndDocPrinter.
+
+ */
+DWORD
+FASTCALL
+StartDocPrinterWEx(
+ PVOID pvUMPDev,
+ HANDLE hPrinter,
+ DWORD Level,
+ LPBYTE pDocInfo
+ )
+{
+ return fpStartDocPrinterW(hPrinter,Level,pDocInfo);
+}
+
BOOL
FASTCALL
StartPagePrinterEx(
@@ -312,7 +387,7 @@
if (pldc->Flags & LDC_INIT_DOCUMENT)
{
BOOL Good;
- if (pldc->Flags & LDC_ENDPAGE_MFDC) EndPage(hdc);
+ if (pldc->Flags & LDC_INIT_PAGE) EndPage(hdc);
DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDDOC, 0, NULL, 0,
NULL);
@@ -320,7 +395,7 @@
Good = NtGdiEndDoc(hdc);
- if (Good)
+// if (pldc->pUMPDev)
Good = EndDocPrinterEx(NULL,pldc->hPrinter);
if (Good)
@@ -348,9 +423,7 @@
*/
int
WINAPI
-EndPage(
- HDC hdc
- )
+EndPage(HDC hdc )
{
return IntEndPage(hdc,FALSE);
}
@@ -404,22 +477,116 @@
)
{
PLDC pldc;
+ DOCINFOW diW;
+ DOC_INFO_1W di1W;
+ LPWSTR lpwstrRet = NULL;
+ BOOL Banding;
+ int PrnJobNo, Ret = SP_ERROR;
ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return SP_ERROR;
- }
+ return SP_ERROR;
pldc = GdiGetLDC(hdc);
- if ( !pldc )
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return SP_ERROR;
- }
-
- return NtGdiStartDoc ( hdc, (DOCINFOW *)lpdi, NULL, 0);
+ if ( !pldc || pldc->Flags & LDC_ATENDPAGE)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return SP_ERROR;
+ }
+
+ if (!pldc->hPrinter) return SP_ERROR;
+
+ pldc->Flags &= ~LDC_KILL_DOCUMENT;
+
+ if (lpdi)
+ RtlCopyMemory(&diW, lpdi, sizeof(DOCINFOW));
+ else
+ {
+ diW.cbSize = sizeof(DOCINFOW);
+ diW.lpszDocName = NULL;
+ diW.lpszOutput = NULL;
+ diW.lpszDatatype = NULL;
+ diW.fwType = 0;
+ }
+
+ if (!diW.lpszOutput)
+ if (pldc->pwszPort) diW.lpszOutput = pldc->pwszPort;
+
+ lpwstrRet = fpStartDocDlgW(pldc->hPrinter, &diW);
+ if (lpwstrRet == (LPWSTR)SP_APPABORT)
+ {
+ pldc->Flags |= LDC_KILL_DOCUMENT;
+ return SP_ERROR;
+ }
+ if (lpwstrRet == (LPWSTR)SP_ERROR) return SP_ERROR;
+
+ if (lpwstrRet != 0) diW.lpszOutput = lpwstrRet;
+
+ Ret = DocumentEventEx( NULL,
+ pldc->hPrinter,
+ hdc,
+ DOCUMENTEVENT_STARTDOC,
+ sizeof(ULONG),
+ &diW,
+ 0,
+ NULL);
+
+ if (Ret == SP_APPABORT)
+ {
+ pldc->Flags |= LDC_KILL_DOCUMENT;
+ Ret = SP_ERROR;
+ }
+ if (Ret == SP_ERROR)
+ {
+ if (lpwstrRet) LocalFree(lpwstrRet);
+ return Ret;
+ }
+
+ di1W.pDocName = (LPWSTR)diW.lpszDocName;
+ di1W.pOutputFile = (LPWSTR)diW.lpszOutput;
+ di1W.pDatatype = (LPWSTR)diW.lpszDatatype;
+
+ Ret = SP_ERROR;
+
+ PrnJobNo = StartDocPrinterWEx(NULL, pldc->hPrinter, 1, (LPBYTE)&di1W);
+ if (PrnJobNo <= 0)
+ {
+ Ret = NtGdiStartDoc( hdc, &diW, &Banding, PrnJobNo);
+ if (Ret)
+ {
+ if (pldc->pAbortProc)
+ {
+ GdiSAPCallback(pldc);
+ pldc->Flags |= LDC_SAPCALLBACK;
+ pldc->CallBackTick = GetTickCount();
+ }
+ pldc->Flags |= LDC_INIT_DOCUMENT;
+ if (!Banding) pldc->Flags |= LDC_STARTPAGE;
+ }
+ }
+ if (Ret == SP_ERROR)
+ {
+ //if ( pldc->pUMPDev )
+ AbortPrinterEx(NULL, pldc->hPrinter);
+ DPRINT1("StartDoc Died!!!\n");
+ }
+ else
+ {
+ if ( DocumentEventEx( NULL,
+ pldc->hPrinter,
+ hdc,
+ DOCUMENTEVENT_STARTDOCPOST,
+ sizeof(ULONG),
+ &Ret,
+ 0,
+ NULL) == SP_ERROR)
+ {
+ AbortDoc(hdc);
+ Ret = SP_ERROR;
+ }
+ }
+ if (lpwstrRet) LocalFree(lpwstrRet);
+ return Ret;
}
/*
@@ -502,9 +669,9 @@
return SP_ERROR;
}
- pldc->Flags &= ~(LDC_STARTPAGE);
-
- if (pldc->Flags & LDC_ENDPAGE_MFDC) return 1;
+ pldc->Flags &= ~(LDC_ATENDPAGE|LDC_STARTPAGE);
+
+ if (pldc->Flags & LDC_INIT_PAGE) return 1;
if (DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_STARTPAGE, 0, NULL, 0,
NULL) != SP_ERROR)
{
Modified: trunk/reactos/include/reactos/win32k/ntgdihdl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntg…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] Wed May 27 08:49:29 2009
@@ -186,7 +186,6 @@
#define LDC_INFODC 0x01000000 /* If CreateIC was passed. */
#define LDC_DEVCAPS 0x02000000
#define LDC_ATENDPAGE 0x10000000
-#define LDC_ENDPAGE_MFDC 0x80000000
/* DC_ATTR Xform Flags */
#define METAFILE_TO_WORLD_IDENTITY 0x00000001