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);
VOID
HEAP_free(LPVOID memory);
-VOID
+VOID
FASTCALL
FONT_TextMetricWToA(
- const TEXTMETRICW *ptmW,
+ const TEXTMETRICW *ptmW,
LPTEXTMETRICA ptmA
);
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 );
+UINT FASTCALL DIB_BitmapBitsSize( CONST BITMAPINFO* );
int
WINAPI
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;
+}
+
/* EOF */