/* TYPES *********************************************************************/
// Based on wmfapi.h and Wine.
-typedef struct tagMETAFILEDC {
- PVOID pvMetaBuffer;
- HANDLE hFile;
- DWORD Size;
- METAHEADER mh;
- UINT handles_size, cur_handles;
- HGDIOBJ *handles;
-
- // more DC object stuff.
- HGDIOBJ Pen;
- HGDIOBJ Brush;
- HGDIOBJ Palette;
- HGDIOBJ Font;
-
- WCHAR Filename[MAX_PATH+2];
- // Add more later.
+typedef struct tagMETAFILEDC
+{
+ PVOID pvMetaBuffer;
+ HANDLE hFile;
+ DWORD Size;
+ DWORD dwWritten;
+ METAHEADER mh;
+ WORD reserved;
+ HLOCAL MFObjList;
+ HPEN hPen;
+ HBRUSH hBrush;
+ HDC hDc;
+ HGDIOBJ hMetaDc;
+ HPALETTE hPalette;
+ HFONT hFont;
+ HBITMAP hBitmap;
+ HRGN hRegion;
+ HGDIOBJ hMetafile;
+ HGDIOBJ hMemDc;
+ HPEN hExtPen;
+ HGDIOBJ hEnhMetaDc;
+ HGDIOBJ hEnhMetaFile;
+ HCOLORSPACE hColorSpace;
+ WCHAR Filename[MAX_PATH+2];
} METAFILEDC,*PMETAFILEDC;
// Metafile Entry handle
-typedef struct tagMF_ENTRY {
- LIST_ENTRY List;
- HGDIOBJ hmDC; // Handle return from NtGdiCreateClientObj.
- PMETAFILEDC pmfDC;
+typedef struct tagMF_ENTRY
+{
+ LIST_ENTRY List;
+ HGDIOBJ hmDC; // Handle return from NtGdiCreateClientObj.
+ PMETAFILEDC pmfDC;
} MF_ENTRY, *PMF_ENTRY;
-typedef struct tagENHMETAFILE {
- PVOID pvMetaBuffer;
- HANDLE hFile; /* Handle for disk based MetaFile */
- DWORD Size;
- INT iType;
- PENHMETAHEADER emf;
- UINT handles_size, cur_handles;
- HGDIOBJ *handles;
- INT horzres, vertres;
- INT horzsize, vertsize;
- INT logpixelsx, logpixelsy;
- INT bitspixel;
- INT textcaps;
- INT rastercaps;
- INT technology;
- INT planes;
+typedef struct tagENHMETAFILE
+{
+ PVOID pvMetaBuffer;
+ HANDLE hFile; /* Handle for disk based MetaFile */
+ DWORD Size;
+ INT iType;
+ PENHMETAHEADER emf;
+ UINT handles_size, cur_handles;
+ HGDIOBJ *handles;
+ INT horzres, vertres;
+ INT horzsize, vertsize;
+ INT logpixelsx, logpixelsy;
+ INT bitspixel;
+ INT textcaps;
+ INT rastercaps;
+ INT technology;
+ INT planes;
} ENHMETAFILE,*PENHMETAFILE;
#define UMPDEV_SUPPORT_ESCAPE 0x0004
typedef struct _UMPDEV
{
- DWORD Sig; // Init with PDEV_UMPD_ID
- struct _UMPDEV *pumpdNext;
- PDRIVER_INFO_5W pdi5Info;
- HMODULE hModule;
- DWORD dwFlags;
- DWORD dwDriverAttributes;
- DWORD dwConfigVersion; // Number of times the configuration
- // file for this driver has been upgraded
- // or downgraded since the last spooler restart.
- DWORD dwDriverCount; // After init should be 2
- DWORD WOW64_UMPDev;
- DWORD WOW64_hMod;
- DWORD Unknown;
- PVOID apfn[INDEX_LAST]; // Print Driver pfn
+ DWORD Sig; // Init with PDEV_UMPD_ID
+ struct _UMPDEV *pumpdNext;
+ PDRIVER_INFO_5W pdi5Info;
+ HMODULE hModule;
+ DWORD dwFlags;
+ DWORD dwDriverAttributes;
+ DWORD dwConfigVersion; // Number of times the configuration
+ // file for this driver has been upgraded
+ // or downgraded since the last spooler restart.
+ DWORD dwDriverCount; // After init should be 2
+ DWORD WOW64_UMPDev;
+ DWORD WOW64_hMod;
+ DWORD Unknown;
+ PVOID apfn[INDEX_LAST]; // Print Driver pfn
} UMPDEV, *PUMPDEV;
#define LOCALFONT_COUNT 10
typedef struct _LOCALFONT
{
- FONT_ATTR lfa[LOCALFONT_COUNT];
+ FONT_ATTR lfa[LOCALFONT_COUNT];
} LOCALFONT, *PLOCALFONT;
// sdk/winspool.h
-typedef BOOL WINAPI (*ABORTPRINTER) (HANDLE);
-typedef BOOL WINAPI (*CLOSEPRINTER) (HANDLE);
-typedef BOOL WINAPI (*CLOSESPOOLFILEHANDLE) (HANDLE, HANDLE); // W2k8
-typedef HANDLE WINAPI (*COMMITSPOOLDATA) (HANDLE,HANDLE,DWORD); // W2k8
-typedef LONG WINAPI (*DOCUMENTPROPERTIESW) (HWND,HANDLE,LPWSTR,PDEVMODEW,PDEVMODEW,DWORD);
-typedef BOOL WINAPI (*ENDDOCPRINTER) (HANDLE);
-typedef BOOL WINAPI (*ENDPAGEPRINTER) (HANDLE);
-typedef BOOL WINAPI (*GETPRINTERW) (HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
-typedef BOOL WINAPI (*GETPRINTERDRIVERW) (HANDLE,LPWSTR,DWORD,LPBYTE,DWORD,LPDWORD);
-typedef HANDLE WINAPI (*GETSPOOLFILEHANDLE) (HANDLE); // W2k8
-typedef BOOL WINAPI (*ISVALIDDEVMODEW) (PDEVMODEW,size_t);
-typedef BOOL WINAPI (*OPENPRINTERW) (LPWSTR,PHANDLE,LPPRINTER_DEFAULTSW);
-typedef BOOL WINAPI (*READPRINTER) (HANDLE,PVOID,DWORD,PDWORD);
-typedef BOOL WINAPI (*RESETPRINTERW) (HANDLE,LPPRINTER_DEFAULTSW);
-typedef LPWSTR WINAPI (*STARTDOCDLGW) (HANDLE,DOCINFOW *);
-typedef DWORD WINAPI (*STARTDOCPRINTERW) (HANDLE,DWORD,PBYTE);
-typedef BOOL WINAPI (*STARTPAGEPRINTER) (HANDLE);
+typedef BOOL (WINAPI *ABORTPRINTER) (HANDLE);
+typedef BOOL (WINAPI *CLOSEPRINTER) (HANDLE);
+typedef BOOL (WINAPI *CLOSESPOOLFILEHANDLE) (HANDLE, HANDLE); // W2k8
+typedef HANDLE (WINAPI *COMMITSPOOLDATA) (HANDLE,HANDLE,DWORD); // W2k8
+typedef LONG (WINAPI *DOCUMENTPROPERTIESW) (HWND,HANDLE,LPWSTR,PDEVMODEW,PDEVMODEW,DWORD);
+typedef BOOL (WINAPI *ENDDOCPRINTER) (HANDLE);
+typedef BOOL (WINAPI *ENDPAGEPRINTER) (HANDLE);
+typedef BOOL (WINAPI *GETPRINTERW) (HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
+typedef BOOL (WINAPI *GETPRINTERDRIVERW) (HANDLE,LPWSTR,DWORD,LPBYTE,DWORD,LPDWORD);
+typedef HANDLE (WINAPI *GETSPOOLFILEHANDLE) (HANDLE); // W2k8
+typedef BOOL (WINAPI *ISVALIDDEVMODEW) (PDEVMODEW,size_t);
+typedef BOOL (WINAPI *OPENPRINTERW) (LPWSTR,PHANDLE,LPPRINTER_DEFAULTSW);
+typedef BOOL (WINAPI *READPRINTER) (HANDLE,PVOID,DWORD,PDWORD);
+typedef BOOL (WINAPI *RESETPRINTERW) (HANDLE,LPPRINTER_DEFAULTSW);
+typedef LPWSTR (WINAPI *STARTDOCDLGW) (HANDLE,DOCINFOW *);
+typedef DWORD (WINAPI *STARTDOCPRINTERW) (HANDLE,DWORD,PBYTE);
+typedef BOOL (WINAPI *STARTPAGEPRINTER) (HANDLE);
// ddk/winsplp.h
-typedef BOOL WINAPI (*SEEKPRINTER) (HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL);
-typedef BOOL WINAPI (*SPLREADPRINTER) (HANDLE,LPBYTE *,DWORD);
+typedef BOOL (WINAPI *SEEKPRINTER) (HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL);
+typedef BOOL (WINAPI *SPLREADPRINTER) (HANDLE,LPBYTE *,DWORD);
// Same as ddk/winsplp.h DriverUnloadComplete?
-typedef BOOL WINAPI (*SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
+typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
// Driver support:
// DrvDocumentEvent api/winddiui.h not W2k8 DocumentEventAW
-typedef INT WINAPI (*DOCUMENTEVENT) (HANDLE,HDC,INT,ULONG,PVOID,ULONG,PVOID);
+typedef INT (WINAPI *DOCUMENTEVENT) (HANDLE,HDC,INT,ULONG,PVOID,ULONG,PVOID);
// DrvQueryColorProfile
-typedef BOOL WINAPI (*QUERYCOLORPROFILE) (HANDLE,PDEVMODEW,ULONG,VOID*,ULONG,FLONG);
+typedef BOOL (WINAPI *QUERYCOLORPROFILE) (HANDLE,PDEVMODEW,ULONG,VOID*,ULONG,FLONG);
// Unknown:
-typedef DWORD WINAPI (*QUERYSPOOLMODE) (HANDLE,DWORD,DWORD);
-typedef DWORD WINAPI (*QUERYREMOTEFONTS) (DWORD,DWORD,DWORD);
+typedef DWORD (WINAPI *QUERYSPOOLMODE) (HANDLE,DWORD,DWORD);
+typedef DWORD (WINAPI *QUERYREMOTEFONTS) (DWORD,DWORD,DWORD);
extern CLOSEPRINTER fpClosePrinter;
+extern OPENPRINTERW fpOpenPrinterW;
/* FUNCTIONS *****************************************************************/
VOID
HEAP_free(LPVOID memory);
-BOOL
+VOID
FASTCALL
-TextMetricW2A(
- TEXTMETRICA *tma,
- TEXTMETRICW *tmw
+FONT_TextMetricWToA(
+ const TEXTMETRICW *ptmW,
+ LPTEXTMETRICA ptmA
);
-BOOL
+VOID
FASTCALL
NewTextMetricW2A(
NEWTEXTMETRICA *tma,
NEWTEXTMETRICW *tmw
);
-BOOL
+VOID
FASTCALL
NewTextMetricExW2A(
NEWTEXTMETRICEXA *tma,
BOOL FollowedByData
);
-DEVMODEW *
-NTAPI
-GdiConvertToDevmodeW(DEVMODEA *dm);
-
DWORD
WINAPI
GetAndSetDCDWord( HDC, INT, DWORD, DWORD, DWORD, DWORD );
GdiSetLastError( DWORD dwErrCode );
DWORD WINAPI GdiGetCodePage(HDC);
-UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
int
WINAPI
GdiGetBitmapBitsSize(BITMAPINFO *lpbmi);
VOID GdiSAPCallback(PLDC pldc);
+HGDIOBJ FASTCALL hGetPEBHandle(HANDLECACHETYPE,COLORREF);
int FASTCALL DocumentEventEx(PVOID,HANDLE,HDC,int,ULONG,PVOID,ULONG,PVOID);
BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
BOOL FASTCALL LoadTheSpoolerDrv(VOID);
+FORCEINLINE
+PVOID
+GdiAllocBatchCommand(
+ HDC hdc,
+ USHORT Cmd)
+{
+ PTEB pTeb;
+ ULONG ulSize;
+ PGDIBATCHHDR pHdr;
+
+ /* Get a pointer to the TEB */
+ pTeb = NtCurrentTeb();
+
+ /* Check if we have a valid environment */
+ if (!pTeb || !pTeb->Win32ThreadInfo) return NULL;
+
+ /* Do we use a DC? */
+ if (hdc)
+ {
+ /* If the batch DC is NULL, we set this one as the new one */
+ if (!pTeb->GdiTebBatch.HDC) pTeb->GdiTebBatch.HDC = hdc;
+
+ /* If not, check if the batch DC equal to our DC */
+ else if (pTeb->GdiTebBatch.HDC != hdc) return NULL;
+ }
+
+ /* Get the size of the entry */
+ switch(Cmd)
+ {
+ case GdiBCPatBlt:
+ ulSize = 0;
+ break;
+ case GdiBCPolyPatBlt:
+ ulSize = 0;
+ break;
+ case GdiBCTextOut:
+ ulSize = 0;
+ break;
+ case GdiBCExtTextOut:
+ ulSize = 0;
+ break;
+ case GdiBCSetBrushOrg:
+ ulSize = 0;
+ break;
+ case GdiBCExtSelClipRgn:
+ ulSize = 0;
+ break;
+ case GdiBCSelObj:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ case GdiBCDelRgn:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ case GdiBCDelObj:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ default:
+ return NULL;
+ }
+
+ /* Unsupported operation */
+ if (ulSize == 0) return NULL;
+
+ /* Check if the buffer is full */
+ if ((pTeb->GdiBatchCount >= GDI_BatchLimit) ||
+ ((pTeb->GdiTebBatch.Offset + ulSize) > GDIBATCHBUFSIZE))
+ {
+ /* Call win32k, the kernel will call NtGdiFlushUserBatch to flush
+ the current batch */
+ NtGdiFlush();
+ }
+
+ /* Get the head of the entry */
+ pHdr = (PVOID)((PUCHAR)pTeb->GdiTebBatch.Buffer + pTeb->GdiTebBatch.Offset);
+
+ /* Update Offset and batch count */
+ pTeb->GdiTebBatch.Offset += ulSize;
+ pTeb->GdiBatchCount++;
+
+ /* Fill in the core fields */
+ pHdr->Cmd = Cmd;
+ pHdr->Size = ulSize;
+
+ return pHdr;
+}
+
+FORCEINLINE
+PDC_ATTR
+GdiGetDcAttr(HDC hdc)
+{
+ PDC_ATTR pdcattr;
+
+ if (!GdiGetHandleUserData((HGDIOBJ)hdc, GDI_OBJECT_TYPE_DC, (PVOID*)&pdcattr)) return NULL;
+ return pdcattr;
+}
+
+#ifdef _M_IX86
+FLOATL FASTCALL EFtoF(EFLOAT_S * efp);
+#define FOtoF(pfo) EFtoF((EFLOAT_S*)pfo)
+#else
+#define FOtoF(pfo) (*(pfo))
+#endif
+
+/* This is an inlined version of lrintf. */
+FORCEINLINE
+int
+_lrintf(float f)
+{
+#if defined(_M_IX86) && defined(__GNUC__)
+ int ret;
+ __asm__ __volatile__ ("fistpl %0" : "=m" (ret) : "t" (f) : "st");
+ return ret;
+#elif defined(_M_IX86) && defined(_MSC_VER)
+ int ret;
+ __asm
+ {
+ fld f;
+ fistp ret;
+ }
+#else
+ /* slow, but portable */
+ return (int)(f >= 0 ? f+0.5 : f-0.5);
+#endif
+}
+
/* EOF */