* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dc.c,v 1.113 2003/12/13 23:26:04 gvg Exp $
+/* $Id$
*
* DC.C - Device context functions
*
*/
-#undef WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <ddk/ntddk.h>
-#include <ddk/ntddvid.h>
-
-#include <internal/safe.h>
-#include <win32k/bitmaps.h>
-#include <win32k/brush.h>
-#include <win32k/cliprgn.h>
-#include <win32k/coord.h>
-#include <win32k/driver.h>
-#include <win32k/dc.h>
-#include <win32k/misc.h>
-#include <win32k/print.h>
-#include <win32k/region.h>
-#include <win32k/gdiobj.h>
-#include <win32k/paint.h>
-#include <win32k/pen.h>
-#include <win32k/text.h>
-#include "../eng/clip.h"
-#include "../eng/handle.h"
-#include <include/dce.h>
-#include <include/error.h>
-#include <include/inteng.h>
-#include <include/eng.h>
-#include <include/palette.h>
-#include <include/guicheck.h>
-#include <include/desktop.h>
-#include <include/intgdi.h>
-#include <include/cleanup.h>
+#include <w32k.h>
#define NDEBUG
-#include <win32k/debug1.h>
+#include <debug.h>
-#define TAG_DC TAG('D', 'C', 'D', 'C')
+#ifndef OBJ_COLORSPACE
+#define OBJ_COLORSPACE (14)
+#endif
static GDIDEVICE PrimarySurface;
PDC dc = DC_LockDc( hdc ); \
if (!dc) \
{ \
+ SetLastWin32Error(ERROR_INVALID_HANDLE); \
return 0; \
} \
ft = dc->dc_field; \
- DC_UnlockDc( hdc ); \
+ DC_UnlockDc(dc); \
return ft; \
}
* important that the function has the right signature, for the implementation
* we can do whatever we want.
*/
-#define DC_GET_VAL_EX( NtGdiFuncName, IntFuncName, ret_x, ret_y, type ) \
-VOID FASTCALL IntFuncName ( PDC dc, LP##type pt ) \
-{ \
- ASSERT ( dc ); \
- ASSERT ( pt ); \
- ((LPPOINT)pt)->x = dc->ret_x; \
- ((LPPOINT)pt)->y = dc->ret_y; \
-} \
-BOOL STDCALL NtGdiFuncName ( HDC hdc, LP##type pt ) \
-{ \
- PDC dc = DC_LockDc ( hdc ); \
- if ( !dc ) \
- return FALSE; \
- IntFuncName ( dc, pt ); \
- DC_UnlockDc ( hdc ); \
- return TRUE; \
+#define DC_GET_VAL_EX( FuncName, ret_x, ret_y, type, ax, ay ) \
+VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \
+{ \
+ ASSERT(dc); \
+ ASSERT(pt); \
+ pt->ax = dc->ret_x; \
+ pt->ay = dc->ret_y; \
+} \
+BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \
+{ \
+ NTSTATUS Status = STATUS_SUCCESS; \
+ type Safept; \
+ PDC dc; \
+ if(!pt) \
+ { \
+ SetLastWin32Error(ERROR_INVALID_PARAMETER); \
+ return FALSE; \
+ } \
+ if(!(dc = DC_LockDc(hdc))) \
+ { \
+ SetLastWin32Error(ERROR_INVALID_HANDLE); \
+ return FALSE; \
+ } \
+ Int##FuncName( dc, &Safept); \
+ DC_UnlockDc(dc); \
+ _SEH_TRY \
+ { \
+ ProbeForWrite(pt, \
+ sizeof( type ), \
+ 1); \
+ *pt = Safept; \
+ } \
+ _SEH_HANDLE \
+ { \
+ Status = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
+ if(!NT_SUCCESS(Status)) \
+ { \
+ SetLastNtError(Status); \
+ return FALSE; \
+ } \
+ return TRUE; \
}
#define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
INT prevMode; \
PDC dc; \
if ((mode < min_val) || (mode > max_val)) \
+ { \
+ SetLastWin32Error(ERROR_INVALID_PARAMETER); \
return 0; \
+ } \
dc = DC_LockDc ( hdc ); \
if ( !dc ) \
+ { \
+ SetLastWin32Error(ERROR_INVALID_HANDLE); \
return 0; \
+ } \
prevMode = dc->dc_field; \
dc->dc_field = mode; \
- DC_UnlockDc ( hdc ); \
+ DC_UnlockDc ( dc ); \
return prevMode; \
}
NtGdiCancelDC(HDC hDC)
{
UNIMPLEMENTED;
+ return FALSE;
}
HDC STDCALL
-NtGdiCreateCompatableDC(HDC hDC)
+NtGdiCreateCompatibleDC(HDC hDC)
{
PDC NewDC, OrigDC;
HBITMAP hBitmap;
HDC hNewDC, DisplayDC;
HRGN hVisRgn;
- BITMAPOBJ *pb;
UNICODE_STRING DriverName;
DisplayDC = NULL;
if (hDC == NULL)
{
RtlInitUnicodeString(&DriverName, L"DISPLAY");
- DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+ DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
if (NULL == DisplayDC)
{
return NULL;
if (NULL == hNewDC)
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(OrigDC);
if (NULL != DisplayDC)
{
NtGdiDeleteDC(DisplayDC);
NewDC = DC_LockDc( hNewDC );
/* Copy information from original DC to new DC */
- NewDC->hSelf = NewDC;
+ NewDC->hSelf = hNewDC;
+ NewDC->IsIC = FALSE;
NewDC->PDev = OrigDC->PDev;
- NewDC->DMW = OrigDC->DMW;
memcpy(NewDC->FillPatternSurfaces,
OrigDC->FillPatternSurfaces,
sizeof OrigDC->FillPatternSurfaces);
/* Create default bitmap */
if (!(hBitmap = NtGdiCreateBitmap( 1, 1, 1, NewDC->w.bitsPerPixel, NULL )))
{
- DC_UnlockDc( hDC );
- DC_UnlockDc( hNewDC );
+ DC_UnlockDc( OrigDC );
+ DC_UnlockDc( NewDC );
DC_FreeDC( hNewDC );
if (NULL != DisplayDC)
{
NewDC->w.flags = DC_MEMORY;
NewDC->w.hBitmap = hBitmap;
NewDC->w.hFirstBitmap = hBitmap;
- pb = BITMAPOBJ_LockBitmap(hBitmap);
- NewDC->Surface = BitmapToSurf(pb);
- BITMAPOBJ_UnlockBitmap(hBitmap);
+ NewDC->GDIDevice = OrigDC->GDIDevice;
NewDC->w.hPalette = OrigDC->w.hPalette;
NewDC->w.textColor = OrigDC->w.textColor;
NewDC->w.textAlign = OrigDC->w.textAlign;
NewDC->w.backgroundColor = OrigDC->w.backgroundColor;
NewDC->w.backgroundMode = OrigDC->w.backgroundMode;
- DC_UnlockDc( hDC );
+ NewDC->w.ROPmode = OrigDC->w.ROPmode;
+ DC_UnlockDc(NewDC);
+ DC_UnlockDc(OrigDC);
if (NULL != DisplayDC)
{
NtGdiDeleteDC(DisplayDC);
}
- DC_UnlockDc(hNewDC);
hVisRgn = NtGdiCreateRectRgn(0, 0, 1, 1);
NtGdiSelectVisRgn(hNewDC, hVisRgn);
}
static BOOL FASTCALL
-GetRegistryPath(PUNICODE_STRING RegistryPath)
+GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ WCHAR DeviceNameBuffer[20];
NTSTATUS Status;
+ swprintf(DeviceNameBuffer, L"\\Device\\Video%d", DisplayNumber);
RtlInitUnicodeString(RegistryPath, NULL);
RtlZeroMemory(QueryTable, sizeof(QueryTable));
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].Name = L"\\Device\\Video0";
+ QueryTable[0].Name = DeviceNameBuffer;
QueryTable[0].EntryContext = RegistryPath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
NULL);
if (! NT_SUCCESS(Status))
{
- DPRINT1("No \\Device\\Video0 value in DEVICEMAP\\VIDEO found\n");
+ DPRINT1("No \\Device\\Video%d value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
return FALSE;
}
}
static BOOL FASTCALL
-FindDriverFileNames(PUNICODE_STRING DriverFileNames)
+FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
UNICODE_STRING RegistryPath;
NTSTATUS Status;
- if (! GetRegistryPath(&RegistryPath))
+ if (! GetRegistryPath(&RegistryPath, DisplayNumber))
{
DPRINT("GetRegistryPath failed\n");
return FALSE;
}
static BOOL FASTCALL
-SetupDevMode(PDEVMODEW DevMode)
+SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
{
static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
NTSTATUS Status;
- if (! GetRegistryPath(&RegistryPath))
+ if (! GetRegistryPath(&RegistryPath, DisplayNumber))
{
DPRINT("GetRegistryPath failed\n");
return FALSE;
if (Valid)
{
ProfilePath = ExAllocatePoolWithTag(PagedPool,
- (wcslen(RegistryPath.Buffer) +
+ (wcslen(RegistryPath.Buffer) +
wcslen(Insert) + 1) * sizeof(WCHAR),
TAG_DC);
if (NULL != ProfilePath)
return Valid;
}
-BOOL FASTCALL
-IntCreatePrimarySurface()
+static BOOL FASTCALL
+IntPrepareDriver()
{
- PGD_ENABLEDRIVER GDEnableDriver;
- DRVENABLEDATA DED;
- PSURFOBJ SurfObj;
- PSURFGDI SurfGDI;
- UNICODE_STRING DriverFileNames;
- PWSTR CurrentName;
- BOOL GotDriver;
- BOOL DoDefault;
-
- /* Open the miniport driver */
- if ((PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(L"DISPLAY")) == NULL)
- {
- DPRINT1("FindMPDriver failed\n");
- return FALSE;
- }
+ PGD_ENABLEDRIVER GDEnableDriver;
+ DRVENABLEDATA DED;
+ UNICODE_STRING DriverFileNames;
+ PWSTR CurrentName;
+ BOOL GotDriver;
+ BOOL DoDefault;
+ ULONG DisplayNumber;
- /* Retrieve DDI driver names from registry */
- RtlInitUnicodeString(&DriverFileNames, NULL);
- if (! FindDriverFileNames(&DriverFileNames))
- {
- DPRINT1("FindDriverFileNames failed\n");
- return FALSE;
- }
+ for (DisplayNumber = 0; ; DisplayNumber++)
+ {
+ DPRINT("Trying to load display driver no. %d\n", DisplayNumber);
- /* DriverFileNames may be a list of drivers in REG_SZ_MULTI format, scan all of
- them until a good one found */
- CurrentName = DriverFileNames.Buffer;
- GotDriver = FALSE;
- while (! GotDriver && CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
- {
- /* Get the DDI driver's entry point */
- GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
- if (NULL == GDEnableDriver)
- {
- DPRINT("FindDDIDriver failed for %S\n", CurrentName);
- }
- else
- {
- /* Call DDI driver's EnableDriver function */
- RtlZeroMemory(&DED, sizeof(DED));
+ RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface));
+
+ PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber);
+
+ /* Open the miniport driver */
+ if (PrimarySurface.VideoFileObject == NULL)
+ {
+ DPRINT1("FindMPDriver failed\n");
+ return FALSE;
+ }
+
+ /* Retrieve DDI driver names from registry */
+ RtlInitUnicodeString(&DriverFileNames, NULL);
+ if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
+ {
+ DPRINT1("FindDriverFileNames failed\n");
+ continue;
+ }
- if (! GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED))
+ /*
+ * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
+ * scan all of them until a good one found.
+ */
+ CurrentName = DriverFileNames.Buffer;
+ GotDriver = FALSE;
+ while (!GotDriver &&
+ CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
+ {
+ /* Get the DDI driver's entry point */
+ GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
+ if (NULL == GDEnableDriver)
+ {
+ DPRINT("FindDDIDriver failed for %S\n", CurrentName);
+ }
+ else
+ {
+ /* Call DDI driver's EnableDriver function */
+ RtlZeroMemory(&DED, sizeof(DED));
+
+ if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof(DED), &DED))
{
- DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
+ DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
}
- else
+ else
{
- GotDriver = TRUE;
+ GotDriver = TRUE;
}
- }
+ }
- if (! GotDriver)
- {
- /* Skip to the next name but never get past the Unicode string */
- while (L'\0' != *CurrentName &&
- CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
+ if (! GotDriver)
+ {
+ /* Skip to the next name but never get past the Unicode string */
+ while (L'\0' != *CurrentName &&
+ CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
- CurrentName++;
+ CurrentName++;
}
- if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
+ if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
- CurrentName++;
+ CurrentName++;
}
- }
- }
- RtlFreeUnicodeString(&DriverFileNames);
- if (! GotDriver)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("No suitable DDI driver found\n");
- return FALSE;
- }
+ }
+ }
- DPRINT("Display driver %S loaded\n", CurrentName);
+ RtlFreeUnicodeString(&DriverFileNames);
- DPRINT("Building DDI Functions\n");
+ if (!GotDriver)
+ {
+ ObDereferenceObject(PrimarySurface.VideoFileObject);
+ DPRINT1("No suitable DDI driver found\n");
+ continue;
+ }
- /* Make sure the non existant functions are NULL */
- RtlZeroMemory(&PrimarySurface.DriverFunctions, sizeof(PrimarySurface.DriverFunctions));
+ DPRINT("Display driver %S loaded\n", CurrentName);
- /* Construct DDI driver function dispatch table */
- if (! DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("BuildDDIFunctions failed\n");
- return FALSE;
- }
+ DPRINT("Building DDI Functions\n");
+
+ /* Construct DDI driver function dispatch table */
+ if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
+ {
+ ObDereferenceObject(PrimarySurface.VideoFileObject);
+ DPRINT1("BuildDDIFunctions failed\n");
+ return FALSE;
+ }
+
+ /* Allocate a phyical device handle from the driver */
+ PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
+ if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
+ {
+ PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
+ &PrimarySurface.DMW,
+ L"",
+ HS_DDI_MAX,
+ PrimarySurface.FillPatterns,
+ sizeof(PrimarySurface.GDIInfo),
+ (ULONG *) &PrimarySurface.GDIInfo,
+ sizeof(PrimarySurface.DevInfo),
+ &PrimarySurface.DevInfo,
+ NULL,
+ L"",
+ (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
+ DoDefault = (NULL == PrimarySurface.PDev);
+ if (DoDefault)
+ {
+ DPRINT1("DrvEnablePDev with registry parameters failed\n");
+ }
+ }
+ else
+ {
+ DoDefault = TRUE;
+ }
- /* Allocate a phyical device handle from the driver */
- if (SetupDevMode(&PrimarySurface.DMW))
- {
- PrimarySurface.PDev =
- PrimarySurface.DriverFunctions.EnablePDev(&PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.FillPatterns,
- sizeof(PrimarySurface.GDIInfo),
- (ULONG *) &PrimarySurface.GDIInfo,
- sizeof(PrimarySurface.DevInfo),
- &PrimarySurface.DevInfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
- DoDefault = (NULL == PrimarySurface.PDev);
if (DoDefault)
- {
- DPRINT1("DrvEnablePDev with registry parameters failed\n");
- }
- }
- else
- {
- DoDefault = TRUE;
- }
+ {
+ RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
+ PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
+ PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
+ &PrimarySurface.DMW,
+ L"",
+ HS_DDI_MAX,
+ PrimarySurface.FillPatterns,
+ sizeof(PrimarySurface.GDIInfo),
+ (ULONG *) &PrimarySurface.GDIInfo,
+ sizeof(PrimarySurface.DevInfo),
+ &PrimarySurface.DevInfo,
+ NULL,
+ L"",
+ (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
+
+ if (NULL == PrimarySurface.PDev)
+ {
+ ObDereferenceObject(PrimarySurface.VideoFileObject);
+ DPRINT1("DrvEnablePDEV with default parameters failed\n");
+ DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
+ continue;
+ }
+ }
- if (DoDefault)
- {
- RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
- PrimarySurface.PDev =
- PrimarySurface.DriverFunctions.EnablePDev(&PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.FillPatterns,
- sizeof(PrimarySurface.GDIInfo),
- (ULONG *) &PrimarySurface.GDIInfo,
- sizeof(PrimarySurface.DevInfo),
- &PrimarySurface.DevInfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
-
- if (NULL == PrimarySurface.PDev)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnablePDEV with default parameters failed\n");
- DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
- return FALSE;
- }
- }
+ if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
+ {
+ DPRINT("Adjusting GDIInfo.ulLogPixelsX\n");
+ PrimarySurface.GDIInfo.ulLogPixelsX = 96;
+ }
+ if (0 == PrimarySurface.GDIInfo.ulLogPixelsY)
+ {
+ DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
+ PrimarySurface.GDIInfo.ulLogPixelsY = 96;
+ }
- if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
- {
- DPRINT("Adjusting GDIInfo.ulLogPixelsX\n");
- PrimarySurface.GDIInfo.ulLogPixelsX = 96;
- }
- if (0 == PrimarySurface.GDIInfo.ulLogPixelsY)
- {
- DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
- PrimarySurface.GDIInfo.ulLogPixelsY = 96;
- }
+ PrimarySurface.Pointer.Exclude.right = -1;
- DPRINT("calling completePDev\n");
+ DPRINT("calling completePDev\n");
- /* Complete initialization of the physical device */
- PrimarySurface.DriverFunctions.CompletePDev(PrimarySurface.PDev,
- &PrimarySurface);
+ /* Complete initialization of the physical device */
+ PrimarySurface.DriverFunctions.CompletePDEV(
+ PrimarySurface.PDev,
+ (HDEV)&PrimarySurface);
- DPRINT("calling DRIVER_ReferenceDriver\n");
+ DPRINT("calling DRIVER_ReferenceDriver\n");
- DRIVER_ReferenceDriver(L"DISPLAY");
+ DRIVER_ReferenceDriver(L"DISPLAY");
- DPRINT("calling EnableSurface\n");
+ PrimarySurface.PreparedDriver = TRUE;
+ PrimarySurface.DisplayNumber = DisplayNumber;
- /* Enable the drawing surface */
- PrimarySurface.Handle =
- PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
- if (NULL == PrimarySurface.Handle)
- {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL FASTCALL
+IntPrepareDriverIfNeeded()
+{
+ return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
+}
+
+static BOOL FASTCALL
+PrepareVideoPrt()
+{
+ PIRP Irp;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ BOOL Prepare = TRUE;
+ ULONG Length = sizeof(BOOL);
+ PIO_STACK_LOCATION StackPtr;
+ LARGE_INTEGER StartOffset;
+ PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
+ PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
+
+ DPRINT("PrepareVideoPrt() called\n");
+
+ KeClearEvent(&PrimarySurface.VideoFileObject->Event);
+
+ ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode);
+
+ StartOffset.QuadPart = 0;
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+ DeviceObject,
+ (PVOID) &Prepare,
+ Length,
+ &StartOffset,
+ NULL,
+ &Iosb);
+ if (NULL == Irp)
+ {
+ return FALSE;
+ }
+
+ /* Set up IRP Data */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = KernelMode;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
+ Irp->Flags |= IRP_WRITE_OPERATION;
+
+ /* Setup Stack Data */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = PrimarySurface.VideoFileObject;
+ StackPtr->Parameters.Write.Key = 0;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (STATUS_PENDING == Status)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0);
+ Status = Iosb.Status;
+ }
+
+ return NT_SUCCESS(Status);
+}
+
+BOOL FASTCALL
+IntCreatePrimarySurface()
+{
+ SIZEL SurfSize;
+ RECTL SurfaceRect;
+ SURFOBJ *SurfObj;
+ BOOL calledFromUser;
+
+ if (! IntPrepareDriverIfNeeded())
+ {
+ return FALSE;
+ }
+
+ if (! PrepareVideoPrt())
+ {
+ return FALSE;
+ }
+
+ DPRINT("calling EnableSurface\n");
+ /* Enable the drawing surface */
+ PrimarySurface.Handle =
+ PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
+ if (NULL == PrimarySurface.Handle)
+ {
+/* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
+ PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("DrvEnableSurface failed\n");
return FALSE;
- }
+ }
- SurfObj = (PSURFOBJ)AccessUserObject((ULONG) PrimarySurface.Handle);
- SurfObj->dhpdev = PrimarySurface.PDev;
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle);
- IntShowDesktop(IntGetActiveDesktop(),
- SurfGDI->SurfObj.sizlBitmap.cx,
- SurfGDI->SurfObj.sizlBitmap.cy);
+ PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, TRUE);
- return TRUE;
+ calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock
+ if (!calledFromUser){
+ UserEnterExclusive();
+ }
+
+ /* attach monitor */
+ IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+
+ SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
+ SurfObj->dhpdev = PrimarySurface.PDev;
+ SurfSize = SurfObj->sizlBitmap;
+ SurfaceRect.left = SurfaceRect.top = 0;
+ SurfaceRect.right = SurfObj->sizlBitmap.cx;
+ SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
+ /* FIXME - why does EngEraseSurface() sometimes crash?
+ EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+
+ /* Put the pointer in the center of the screen */
+ GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
+ GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+
+ EngUnlockSurface(SurfObj);
+ co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
+
+ if (!calledFromUser){
+ UserLeave();
+ }
+
+ return TRUE;
}
VOID FASTCALL
IntDestroyPrimarySurface()
{
+ BOOL calledFromUser;
+
DRIVER_UnreferenceDriver(L"DISPLAY");
+ calledFromUser = UserIsEntered();
+ if (!calledFromUser){
+ UserEnterExclusive();
+ }
+
+ /* detach monitor */
+ IntDetachMonitor(&PrimarySurface);
+
+ if (!calledFromUser){
+ UserLeave();
+ }
+
+ /*
+ * FIXME: Hide a mouse pointer there. Also because we have to prevent
+ * memory leaks with the Eng* mouse routines.
+ */
+
DPRINT("Reseting display\n" );
PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);
PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.PDev);
- PrimarySurface.DriverFunctions.DisablePDev(PrimarySurface.PDev);
+ PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+ PrimarySurface.PreparedDriver = FALSE;
DceEmptyCache();
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
- CONST PDEVMODEW InitData)
+ CONST PDEVMODEW InitData,
+ BOOL CreateAsIC)
{
HDC hNewDC;
PDC NewDC;
HDC hDC = NULL;
- PSURFGDI SurfGDI;
HRGN hVisRgn;
UNICODE_STRING StdDriver;
+ BOOL calledFromUser;
RtlInitUnicodeString(&StdDriver, L"DISPLAY");
-
+
if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
{
- if (! IntGraphicsCheck(TRUE))
+ if (CreateAsIC)
{
- DPRINT1("Unable to initialize graphics, returning NULL dc\n");
- return NULL;
+ if (! IntPrepareDriverIfNeeded())
+ {
+ DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
+ return NULL;
+ }
+ }
+ else
+ {
+ calledFromUser = UserIsEntered();
+ if (!calledFromUser){
+ UserEnterExclusive();
+ }
+
+ if (! co_IntGraphicsCheck(TRUE))
+ {
+ if (!calledFromUser){
+ UserLeave();
+ }
+ DPRINT1("Unable to initialize graphics, returning NULL dc\n");
+ return NULL;
+ }
+
+ if (!calledFromUser){
+ UserLeave();
+ }
+
}
}
if ((hNewDC = DC_FindOpenDC(Driver)) != NULL)
{
hDC = hNewDC;
- return NtGdiCreateCompatableDC(hDC);
+ return NtGdiCreateCompatibleDC(hDC);
}
- DPRINT("NAME: %S\n", Driver); // FIXME: Should not crash if NULL
+ if (Driver != NULL && Driver->Buffer != NULL)
+ {
+ DPRINT("NAME: %wZ\n", Driver); // FIXME: Should not crash if NULL
+ }
/* Allocate a DC object */
if ((hNewDC = DC_AllocDC(Driver)) == NULL)
}
NewDC = DC_LockDc( hNewDC );
- ASSERT( NewDC );
+ /* FIXME - NewDC can be NULL!!! Don't assert here! */
+ if ( !NewDC )
+ {
+ DC_FreeDC( hNewDC );
+ return NULL;
+ }
- NewDC->DMW = PrimarySurface.DMW;
+ NewDC->IsIC = CreateAsIC;
NewDC->DevInfo = &PrimarySurface.DevInfo;
NewDC->GDIInfo = &PrimarySurface.GDIInfo;
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
- NewDC->Surface = PrimarySurface.Handle;
+ NewDC->GDIDevice = (HDEV)&PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
+ NewDC->w.hBitmap = PrimarySurface.Handle;
- NewDC->DMW.dmSize = sizeof(NewDC->DMW);
- NewDC->DMW.dmFields = 0x000fc000;
-
- /* FIXME: get mode selection information from somewhere */
-
- NewDC->DMW.dmLogPixels = 96;
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle);
- NewDC->DMW.dmBitsPerPel = SurfGDI->BitsPerPixel;
- NewDC->DMW.dmPelsWidth = SurfGDI->SurfObj.sizlBitmap.cx;
- NewDC->DMW.dmPelsHeight = SurfGDI->SurfObj.sizlBitmap.cy;
- NewDC->DMW.dmDisplayFlags = 0;
- NewDC->DMW.dmDisplayFrequency = 0;
-
- NewDC->w.bitsPerPixel = SurfGDI->BitsPerPixel; // FIXME: set this here??
-
- NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
-
+ NewDC->w.bitsPerPixel = NewDC->GDIInfo->cBitsPixel * NewDC->GDIInfo->cPlanes;
DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
-
- DC_UnlockDc( hNewDC );
- hVisRgn = NtGdiCreateRectRgn(0, 0, SurfGDI->SurfObj.sizlBitmap.cx,
- SurfGDI->SurfObj.sizlBitmap.cy);
- NtGdiSelectVisRgn(hNewDC, hVisRgn);
- NtGdiDeleteObject(hVisRgn);
+ if (! CreateAsIC)
+ {
+ NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
+ NewDC->w.ROPmode = R2_COPYPEN;
+
+ DC_UnlockDc( NewDC );
+
+ hVisRgn = NtGdiCreateRectRgn(0, 0, NewDC->GDIInfo->ulHorzRes,
+ NewDC->GDIInfo->ulVertRes);
+ NtGdiSelectVisRgn(hNewDC, hVisRgn);
+ NtGdiDeleteObject(hVisRgn);
+
+ /* Initialize the DC state */
+ DC_InitDC(hNewDC);
+ NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
+ NtGdiSetTextAlign(hNewDC, TA_TOP);
+ NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
+ NtGdiSetBkMode(hNewDC, OPAQUE);
+ }
+ else
+ {
+ DC_UnlockDc( NewDC );
+ }
- /* Initialize the DC state */
- DC_InitDC(hNewDC);
- NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
- NtGdiSetTextAlign(hNewDC, TA_TOP);
- NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
- NtGdiSetBkMode(hNewDC, OPAQUE);
-
return hNewDC;
}
UNICODE_STRING SafeDriver, SafeDevice;
DEVMODEW SafeInitData;
HDC Ret;
- NTSTATUS Status;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
if(InitData)
{
- Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW));
+ _SEH_TRY
+ {
+ ProbeForRead(InitData,
+ sizeof(DEVMODEW),
+ 1);
+ RtlCopyMemory(&SafeInitData,
+ InitData,
+ sizeof(DEVMODEW));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
}
/* FIXME - InitData can have some more bytes! */
}
-
+
if(Driver)
{
Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
return NULL;
}
}
-
+
if(Device)
{
Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
return NULL;
}
}
-
- Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData);
-
+
+ Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+ NULL == Device ? NULL : &SafeDevice, NULL,
+ NULL == InitData ? NULL : &SafeInitData, FALSE);
+
return Ret;
}
NtGdiCreateIC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
- CONST PDEVMODEW DevMode)
+ CONST PDEVMODEW InitData)
{
- /* FIXME: this should probably do something else... */
- return NtGdiCreateDC(Driver, Device, Output, DevMode);
+ UNICODE_STRING SafeDriver, SafeDevice;
+ DEVMODEW SafeInitData;
+ HDC Ret;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if(InitData)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(InitData,
+ sizeof(DEVMODEW),
+ 1);
+ RtlCopyMemory(&SafeInitData,
+ InitData,
+ sizeof(DEVMODEW));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+ /* FIXME - InitData can have some more bytes! */
+ }
+
+ if(Driver)
+ {
+ Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+ }
+
+ if(Device)
+ {
+ Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
+ if(!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&SafeDriver);
+ SetLastNtError(Status);
+ return NULL;
+ }
+ }
+
+ Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+ NULL == Device ? NULL : &SafeDevice, NULL,
+ NULL == InitData ? NULL : &SafeInitData, TRUE);
+
+ return Ret;
}
BOOL STDCALL
{
PDC DCToDelete;
+ if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
DCToDelete = DC_LockDc(DCHandle);
if (DCToDelete == NULL)
{
- return FALSE;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
}
- DPRINT( "Deleting DC\n" );
- CHECKPOINT;
+
/* First delete all saved DCs */
while (DCToDelete->saveLevel)
{
}
DC_SetNextDC (DCToDelete, DC_GetNextDC (savedDC));
DCToDelete->saveLevel--;
- DC_UnlockDc( savedHDC );
+ DC_UnlockDc( savedDC );
NtGdiDeleteDC (savedHDC);
}
DC_LockDC (DCHandle); NtGdiSelectObject does not recognize stock objects yet */
if (DCToDelete->w.flags & DC_MEMORY)
{
- EngDeleteSurface (DCToDelete->Surface);
NtGdiDeleteObject (DCToDelete->w.hFirstBitmap);
}
+ if (DCToDelete->XlateBrush != NULL)
+ EngDeleteXlate(DCToDelete->XlateBrush);
+ if (DCToDelete->XlatePen != NULL)
+ EngDeleteXlate(DCToDelete->XlatePen);
}
if (DCToDelete->w.hClipRgn)
{
#if 0 /* FIXME */
PATH_DestroyGdiPath (&DCToDelete->w.path);
#endif
- DC_UnlockDc( DCHandle );
+ DC_UnlockDc( DCToDelete );
DC_FreeDC ( DCHandle );
return TRUE;
LPCSTR lpszInData)
{
UNIMPLEMENTED;
+ return 0;
}
INT STDCALL
LPARAM lParam)
{
UNIMPLEMENTED;
+ return 0;
}
DC_GET_VAL( COLORREF, NtGdiGetBkColor, w.backgroundColor )
DC_GET_VAL( INT, NtGdiGetBkMode, w.backgroundMode )
-DC_GET_VAL_EX( NtGdiGetBrushOrgEx, IntGetBrushOrgEx, w.brushOrgX, w.brushOrgY, POINT )
+DC_GET_VAL_EX( GetBrushOrgEx, w.brushOrgX, w.brushOrgY, POINT, x, y )
DC_GET_VAL( HRGN, NtGdiGetClipRgn, w.hClipRgn )
HGDIOBJ STDCALL
NtGdiGetCurrentObject(HDC hDC, UINT ObjectType)
{
- UNIMPLEMENTED;
+ HGDIOBJ SelObject;
+ DC *dc;
+
+ if(!(dc = DC_LockDc(hDC)))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+
+ switch(ObjectType)
+ {
+ case OBJ_PEN:
+ SelObject = dc->w.hPen;
+ break;
+ case OBJ_BRUSH:
+ SelObject = dc->w.hBrush;
+ break;
+ case OBJ_PAL:
+ DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_PAL not supported yet!\n");
+ SelObject = NULL;
+ break;
+ case OBJ_FONT:
+ SelObject = dc->w.hFont;
+ break;
+ case OBJ_BITMAP:
+ SelObject = dc->w.hBitmap;
+ break;
+ case OBJ_COLORSPACE:
+ DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
+ SelObject = NULL;
+ break;
+ default:
+ SelObject = NULL;
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ break;
+ }
+
+ DC_UnlockDc(dc);
+ return SelObject;
}
-DC_GET_VAL_EX ( NtGdiGetCurrentPositionEx, IntGetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT )
+DC_GET_VAL_EX ( GetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT, x, y )
BOOL FASTCALL
IntGdiGetDCOrgEx(DC *dc, LPPOINT Point)
{
Point->x = dc->w.DCOrgX;
Point->y = dc->w.DCOrgY;
-
+
return TRUE;
}
BOOL Ret;
DC *dc;
POINT SafePoint;
- NTSTATUS Status;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
if(!Point)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
-
+
dc = DC_LockDc(hDC);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
-
+
Ret = IntGdiGetDCOrgEx(dc, &SafePoint);
-
- Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
+
+ _SEH_TRY
+ {
+ ProbeForWrite(Point,
+ sizeof(POINT),
+ 1);
+ *Point = SafePoint;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return FALSE;
}
-
- DC_UnlockDc(hDC);
+
+ DC_UnlockDc(dc);
return Ret;
}
NtGdiSetBkColor(HDC hDC, COLORREF color)
{
COLORREF oldColor;
- PDC dc = DC_LockDc(hDC);
+ PDC dc;
+ HBRUSH hBrush;
- if ( !dc )
- return 0x80000000;
+ if (!(dc = DC_LockDc(hDC)))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return CLR_INVALID;
+ }
oldColor = dc->w.backgroundColor;
dc->w.backgroundColor = color;
- DC_UnlockDc ( hDC );
+ hBrush = dc->w.hBrush;
+ DC_UnlockDc(dc);
+ NtGdiSelectObject(hDC, hBrush);
return oldColor;
}
dc = DC_LockDc(hDC);
if (dc == NULL)
{
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
- DC_UnlockDc( hDC );
+ DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
+ /* FIXME - newdc can be NULL!!!! Don't assert here!!! */
ASSERT( newdc );
newdc->w.flags = dc->w.flags | DC_SAVED;
newdc->w.hFirstBitmap = dc->w.hFirstBitmap;
#if 0
newdc->w.hDevice = dc->w.hDevice;
- newdc->w.hPalette = dc->w.hPalette;
#endif
+ newdc->w.hPalette = dc->w.hPalette;
newdc->w.totalExtent = dc->w.totalExtent;
newdc->w.bitsPerPixel = dc->w.bitsPerPixel;
newdc->w.ROPmode = dc->w.ROPmode;
newdc->w.CursPosX = dc->w.CursPosX;
newdc->w.CursPosY = dc->w.CursPosY;
newdc->w.ArcDirection = dc->w.ArcDirection;
-#if 0
newdc->w.xformWorld2Wnd = dc->w.xformWorld2Wnd;
newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
newdc->w.xformVport2World = dc->w.xformVport2World;
newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
-#endif
newdc->wndOrgX = dc->wndOrgX;
newdc->wndOrgY = dc->wndOrgY;
newdc->wndExtX = dc->wndExtX;
newdc->hSelf = hnewdc;
newdc->saveLevel = 0;
+ newdc->IsIC = dc->IsIC;
#if 0
PATH_InitGdiPath( &newdc->w.path );
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
-#if 0
newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
-#endif
if (dc->w.hClipRgn)
{
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
- else
- {
- newdc->w.hClipRgn = 0;
- }
- DC_UnlockDc( hnewdc );
- DC_UnlockDc( hDC );
+ DC_UnlockDc( newdc );
+ DC_UnlockDc( dc );
return hnewdc;
}
dc->w.CursPosY = dcs->w.CursPosY;
dc->w.ArcDirection = dcs->w.ArcDirection;
-#if 0
dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
dc->w.xformVport2World = dcs->w.xformVport2World;
dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
-#endif
dc->wndOrgX = dcs->wndOrgX;
dc->wndOrgY = dcs->wndOrgY;
dc->w.hClipRgn = 0;
}
- CLIPPING_UpdateGCRegion( dc );
- DC_UnlockDc ( hDC );
+ {
+ int res;
+ res = CLIPPING_UpdateGCRegion( dc );
+ ASSERT ( res != ERROR );
+ }
+ DC_UnlockDc ( dc );
#else
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
NtGdiSelectClipRgn(hDC, dcs->w.hClipRgn);
#endif
NtGdiSetBkColor( hDC, dcs->w.backgroundColor);
NtGdiSetTextColor( hDC, dcs->w.textColor);
+ NtGdiSelectPalette( hDC, dcs->w.hPalette, FALSE );
+
#if 0
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
#endif
} else {
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
}
- DC_UnlockDc ( hDCSave );
+ DC_UnlockDc ( dcs );
} else {
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
}
}
+ else
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
}
-INT STDCALL
-NtGdiGetDeviceCaps(HDC hDC,
- INT Index)
+INT FASTCALL
+IntGdiGetDeviceCaps(PDC dc, INT Index)
{
- PDC dc;
- INT ret;
+ INT ret = 0;
POINT pt;
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- return 0;
- }
-
/* Retrieve capability */
switch (Index)
{
break;
case PHYSICALWIDTH:
- if(NtGdiEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case PHYSICALHEIGHT:
- if(NtGdiEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
case PHYSICALOFFSETX:
- if(NtGdiEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case PHYSICALOFFSETY:
- if(NtGdiEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
case SCALINGFACTORX:
- if(NtGdiEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case SCALINGFACTORY:
- if(NtGdiEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
}
+ return ret;
+}
+
+INT STDCALL
+NtGdiGetDeviceCaps(HDC hDC,
+ INT Index)
+{
+ PDC dc;
+ INT ret;
+
+ dc = DC_LockDc(hDC);
+ if (dc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ ret = IntGdiGetDeviceCaps(dc, Index);
+
DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret);
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return ret;
}
DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode )
INT FASTCALL
-IntGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
+IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer)
{
- PGDIOBJHDR gdiObject;
- INT result = 0;
- DWORD objectType;
+ PVOID GdiObject;
+ INT Result = 0;
+ DWORD ObjectType;
- gdiObject = GDIOBJ_LockObj(handle, GDI_OBJECT_TYPE_DONTCARE);
- if (gdiObject == 0)
- return 0;
-
- objectType = GDIOBJ_GetObjectType(handle);
- switch(objectType)
- {
-/* case GDI_OBJECT_TYPE_PEN:
- result = PEN_GetObject((PENOBJ *)gdiObject, count, buffer);
- break;
- case GDI_OBJECT_TYPE_BRUSH:
- result = BRUSH_GetObject((BRUSHOBJ *)gdiObject, count, buffer);
- break; */
- case GDI_OBJECT_TYPE_BITMAP:
- result = BITMAP_GetObject((BITMAPOBJ *)gdiObject, count, buffer);
- break;
-/* case GDI_OBJECT_TYPE_FONT:
- result = FONT_GetObjectW((FONTOBJ *)gdiObject, count, buffer);
-
- // Fix the LOGFONT structure for the stock fonts
+ GdiObject = GDIOBJ_LockObj(Handle, GDI_OBJECT_TYPE_DONTCARE);
+ if (NULL == GdiObject)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
- if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
- FixStockFontSizeW(handle, count, buffer);
- break;
- case GDI_OBJECT_TYPE_PALETTE:
- result = PALETTE_GetObject((PALETTEOBJ *)gdiObject, count, buffer);
- break; */
- default:
- DPRINT1("GDI object type 0x%08x not implemented\n", objectType);
- break;
- }
+ ObjectType = GDIOBJ_GetObjectType(Handle);
+ switch (ObjectType)
+ {
+#if 0
+ case GDI_OBJECT_TYPE_PEN:
+ Result = PEN_GetObject((PENOBJ *) GdiObject, Count, Buffer);
+ break;
+ case GDI_OBJECT_TYPE_BRUSH:
+ Result = BRUSH_GetObject((BRUSHOBJ *) GdiObject, Count, Buffer);
+ break;
+#endif
+ case GDI_OBJECT_TYPE_BITMAP:
+ Result = BITMAP_GetObject((BITMAPOBJ *) GdiObject, Count, Buffer);
+ break;
+ case GDI_OBJECT_TYPE_FONT:
+ Result = FontGetObject((PTEXTOBJ) GdiObject, Count, Buffer);
+#if 0
+ // Fix the LOGFONT structure for the stock fonts
+ if (FIRST_STOCK_HANDLE <= Handle && Handle <= LAST_STOCK_HANDLE)
+ {
+ FixStockFontSizeW(Handle, Count, Buffer);
+ }
+#endif
+ break;
+#if 0
+ case GDI_OBJECT_TYPE_PALETTE:
+ Result = PALETTE_GetObject((PALETTEOBJ *) GdiObject, Count, Buffer);
+ break;
+#endif
+ default:
+ DPRINT1("GDI object type 0x%08x not implemented\n", ObjectType);
+ break;
+ }
- GDIOBJ_UnlockObj(handle, GDI_OBJECT_TYPE_DONTCARE);
+ GDIOBJ_UnlockObjByPtr(GdiObject);
- return result;
+ return Result;
}
INT STDCALL
{
INT Ret;
LPVOID SafeBuf;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
if (count <= 0)
{
return 0;
}
- SafeBuf = ExAllocatePool(NonPagedPool, count);
+ _SEH_TRY
+ {
+ ProbeForWrite(buffer,
+ count,
+ 1);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return 0;
+ }
+
+ SafeBuf = ExAllocatePoolWithTag(PagedPool, count, TAG_GDIOBJ);
if(!SafeBuf)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
-
+
Ret = IntGdiGetObject(handle, count, SafeBuf);
-
- Status = MmCopyToCaller(buffer, SafeBuf, count);
+
+ _SEH_TRY
+ {
+ /* pointer already probed! */
+ RtlCopyMemory(buffer,
+ SafeBuf,
+ count);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
ExFreePool(SafeBuf);
if(!NT_SUCCESS(Status))
{
NtGdiGetObjectType(HANDLE handle)
{
GDIOBJHDR * ptr;
- INT result = 0;
+ INT result;
DWORD objectType;
ptr = GDIOBJ_LockObj(handle, GDI_OBJECT_TYPE_DONTCARE);
if (ptr == 0)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
+ }
objectType = GDIOBJ_GetObjectType(handle);
switch(objectType)
case GDI_OBJECT_TYPE_MEMDC:
result = OBJ_MEMDC;
break;
+
default:
DPRINT1("Magic 0x%08x not implemented\n", objectType);
+ result = 0;
break;
}
- GDIOBJ_UnlockObj(handle, GDI_OBJECT_TYPE_DONTCARE);
+ GDIOBJ_UnlockObjByPtr(ptr);
return result;
}
DC_GET_VAL( INT, NtGdiGetStretchBltMode, w.stretchBltMode )
DC_GET_VAL( UINT, NtGdiGetTextAlign, w.textAlign )
DC_GET_VAL( COLORREF, NtGdiGetTextColor, w.textColor )
-DC_GET_VAL_EX( NtGdiGetViewportExtEx, IntGetViewportExtEx, vportExtX, vportExtY, SIZE )
-DC_GET_VAL_EX( NtGdiGetViewportOrgEx, IntGetViewportOrgEx, vportOrgX, vportOrgY, POINT )
-DC_GET_VAL_EX( NtGdiGetWindowExtEx, IntGetWindowExtEx, wndExtX, wndExtY, SIZE )
-DC_GET_VAL_EX( NtGdiGetWindowOrgEx, IntGetWindowOrgEx, wndOrgX, wndOrgY, POINT )
+DC_GET_VAL_EX( GetViewportExtEx, vportExtX, vportExtY, SIZE, cx, cy )
+DC_GET_VAL_EX( GetViewportOrgEx, vportOrgX, vportOrgY, POINT, x, y )
+DC_GET_VAL_EX( GetWindowExtEx, wndExtX, wndExtY, SIZE, cx, cy )
+DC_GET_VAL_EX( GetWindowOrgEx, wndOrgX, wndOrgY, POINT, x, y )
HDC STDCALL
NtGdiResetDC(HDC hDC, CONST DEVMODEW *InitData)
{
UNIMPLEMENTED;
+ return 0;
}
BOOL STDCALL
NtGdiRestoreDC(HDC hDC, INT SaveLevel)
{
- PDC dc, dcs;
- BOOL success;
+ PDC dc, dcs;
+ BOOL success;
+
+ DPRINT("NtGdiRestoreDC(%lx, %d)\n", hDC, SaveLevel);
dc = DC_LockDc(hDC);
- if(!dc)
+ if (!dc)
{
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (SaveLevel == -1)
- {
SaveLevel = dc->saveLevel;
- }
if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
{
+ DC_UnlockDc(dc);
return FALSE;
}
dcs = DC_LockDc (hdcs);
if (dcs == NULL)
{
+ DC_UnlockDc(dc);
return FALSE;
}
DC_SetNextDC (dcs, DC_GetNextDC (dcs));
if (--dc->saveLevel < SaveLevel)
{
- DC_UnlockDc( hDC );
- DC_UnlockDc( hdcs );
+ DC_UnlockDc( dc );
+ DC_UnlockDc( dcs );
NtGdiSetDCState(hDC, hdcs);
#if 0
if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
}
else
{
- DC_UnlockDc( hdcs );
+ DC_UnlockDc( dcs );
}
NtGdiDeleteDC (hdcs);
}
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return success;
}
PDC dc, dcs;
INT ret;
+ DPRINT("NtGdiSaveDC(%lx)\n", hDC);
+
if (!(hdcs = NtGdiGetDCState(hDC)))
{
return 0;
dcs = DC_LockDc (hdcs);
if (dcs == NULL)
{
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
dc = DC_LockDc (hDC);
if (dc == NULL)
{
- DC_UnlockDc(dc);
+ DC_UnlockDc(dcs);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
DC_SetNextDC (dcs, DC_GetNextDC (dc));
DC_SetNextDC (dc, hdcs);
ret = ++dc->saveLevel;
- DC_UnlockDc( hdcs );
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dcs );
+ DC_UnlockDc( dc );
return ret;
}
HGDIOBJ objOrg = NULL; // default to failure
BITMAPOBJ *pb;
PDC dc;
- PPENOBJ pen;
- PBRUSHOBJ brush;
- PXLATEOBJ XlateObj;
- PPALGDI PalGDI;
+ PGDIBRUSHOBJ pen;
+ PGDIBRUSHOBJ brush;
+ XLATEOBJ *XlateObj;
DWORD objectType;
- COLORREF *ColorMap;
- COLORREF MonoColorMap[2];
- ULONG NumColors, Index;
HRGN hVisRgn;
- USHORT Mode;
+ BOOLEAN Failed;
if(!hDC || !hGDIObj) return NULL;
switch (objectType)
{
case GDI_OBJECT_TYPE_PEN:
- objOrg = NULL;
- /* Convert the color of the pen to the format of the DC */
- PalGDI = PALETTE_LockPalette(dc->w.hPalette);
- if (NULL != PalGDI)
- {
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
- if (NULL != XlateObj)
- {
- pen = PENOBJ_LockPen((HPEN) hGDIObj);
- if (NULL != pen)
- {
- pen->iSolidColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor);
- PENOBJ_UnlockPen((HPEN) hGDIObj);
- objOrg = (HGDIOBJ)dc->w.hPen;
- dc->w.hPen = hGDIObj;
- }
- else
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- }
- EngDeleteXlate(XlateObj);
- }
- else
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- }
- }
- else
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- }
+ pen = PENOBJ_LockPen((HPEN) hGDIObj);
+ if (pen == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed);
+ PENOBJ_UnlockPen(pen);
+ if (Failed)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ break;
+ }
+
+ objOrg = (HGDIOBJ)dc->w.hPen;
+ dc->w.hPen = hGDIObj;
+ if (dc->XlatePen != NULL)
+ EngDeleteXlate(dc->XlatePen);
+ dc->XlatePen = XlateObj;
break;
case GDI_OBJECT_TYPE_BRUSH:
- objOrg = NULL;
- /* Convert the color of the brush to the format of the DC */
- PalGDI = PALETTE_LockPalette(dc->w.hPalette);
- if (NULL != PalGDI)
- {
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
- if (NULL != XlateObj)
- {
- brush = BRUSHOBJ_LockBrush((HBRUSH) hGDIObj);
- if (NULL != brush)
- {
- brush->iSolidColor = XLATEOBJ_iXlate(XlateObj, brush->logbrush.lbColor);
- BRUSHOBJ_UnlockBrush((HBRUSH) hGDIObj);
- objOrg = (HGDIOBJ)dc->w.hBrush;
- dc->w.hBrush = (HBRUSH) hGDIObj;
- }
- else
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- }
- EngDeleteXlate(XlateObj);
- }
- else
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- }
- }
- else
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- }
+ brush = BRUSHOBJ_LockBrush((HPEN) hGDIObj);
+ if (brush == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed);
+ BRUSHOBJ_UnlockBrush(brush);
+ if (Failed)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ break;
+ }
+
+ objOrg = (HGDIOBJ)dc->w.hBrush;
+ dc->w.hBrush = hGDIObj;
+ if (dc->XlateBrush != NULL)
+ EngDeleteXlate(dc->XlateBrush);
+ dc->XlateBrush = XlateObj;
break;
case GDI_OBJECT_TYPE_FONT:
- objOrg = (HGDIOBJ)dc->w.hFont;
- dc->w.hFont = (HFONT) hGDIObj;
- TextIntRealizeFont(dc->w.hFont);
+ if(NT_SUCCESS(TextIntRealizeFont((HFONT)hGDIObj)))
+ {
+ objOrg = (HGDIOBJ)dc->w.hFont;
+ dc->w.hFont = (HFONT) hGDIObj;
+ }
break;
case GDI_OBJECT_TYPE_BITMAP:
// must be memory dc to select bitmap
if (!(dc->w.flags & DC_MEMORY))
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return NULL;
}
pb = BITMAPOBJ_LockBitmap(hGDIObj);
if (NULL == pb)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return NULL;
}
objOrg = (HGDIOBJ)dc->w.hBitmap;
/* Release the old bitmap, lock the new one and convert it to a SURF */
- EngDeleteSurface(dc->Surface);
dc->w.hBitmap = hGDIObj;
- dc->Surface = BitmapToSurf(pb);
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)
{
dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
-
- if(pb->dib->dsBmih.biBitCount <= 8)
- {
- if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else
- if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else
- if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
-
- ColorMap = ExAllocatePoolWithTag(PagedPool, sizeof(COLORREF) * NumColors, TAG_DC);
- ASSERT(ColorMap);
- for (Index = 0; Index < NumColors; Index++)
- {
- ColorMap[Index] = RGB(pb->ColorMap[Index].rgbRed,
- pb->ColorMap[Index].rgbGreen,
- pb->ColorMap[Index].rgbBlue);
- }
- dc->w.hPalette = PALETTE_AllocPalette(PAL_INDEXED, NumColors, (ULONG *) ColorMap, 0, 0, 0);
- ExFreePool(ColorMap);
- }
- else if ( 16 == pb->dib->dsBmih.biBitCount )
- {
- dc->w.hPalette = PALETTE_AllocPalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0x7c00, 0x03e0, 0x001f);
- }
- else if(pb->dib->dsBmih.biBitCount >= 24)
- {
- dc->w.hPalette = PALETTE_AllocPalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
- }
+ dc->w.hPalette = pb->hDIBPalette;
}
else
{
- dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel;
- if (1 == dc->w.bitsPerPixel)
- {
- MonoColorMap[0] = RGB(0, 0, 0);
- MonoColorMap[1] = RGB(255, 255, 255);
- dc->w.hPalette = PALETTE_AllocPalette(PAL_INDEXED, 2, MonoColorMap, 0, 0, 0);
- }
- else
- {
- dc->w.hPalette = dc->DevInfo->hpalDefault;
- }
+ dc->w.bitsPerPixel = BitsPerFormat(pb->SurfObj.iBitmapFormat);
+ dc->w.hPalette = dc->DevInfo->hpalDefault;
}
- DC_UnlockDc ( hDC );
- hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->size.cx, pb->size.cy );
+ /* Reselect brush and pen to regenerate the XLATEOBJs. */
+ NtGdiSelectObject ( hDC, dc->w.hBrush );
+ NtGdiSelectObject ( hDC, dc->w.hPen );
+
+ DC_UnlockDc ( dc );
+ hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy );
+ BITMAPOBJ_UnlockBitmap( pb );
NtGdiSelectVisRgn ( hDC, hVisRgn );
NtGdiDeleteObject ( hVisRgn );
- BITMAPOBJ_UnlockBitmap(hGDIObj);
return objOrg;
-#if UPDATEREGIONS
case GDI_OBJECT_TYPE_REGION:
- DC_UnlockDc ( hDC );
- SelectClipRgn(hDC, (HRGN)hGDIObj);
- return NULL;
-#endif
+ DC_UnlockDc (dc);
+ /*
+ * The return value is one of the following values:
+ * SIMPLEREGION
+ * COMPLEXREGION
+ * NULLREGION
+ */
+ return (HGDIOBJ) NtGdiSelectClipRgn(hDC, (HRGN) hGDIObj);
+
default:
break;
}
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return objOrg;
}
if (NULL == dc)
{
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
dc->w.flags &= ~DC_DIRTY;
}
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return wRet;
}
PDC NewDC;
HDC hDC;
PWSTR Buf = NULL;
-
+
if (Driver != NULL)
{
Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
}
- hDC = (HDC) GDIOBJ_AllocObj(sizeof(DC), GDI_OBJECT_TYPE_DC, (GDICLEANUPPROC) DC_InternalDeleteDC);
+ hDC = (HDC) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_DC);
if (hDC == NULL)
{
if(Buf)
}
NewDC = DC_LockDc(hDC);
-
+ /* FIXME - Handle NewDC == NULL! */
+
if (Driver != NULL)
{
RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
NewDC->w.vport2WorldValid = TRUE;
+ NewDC->w.MapMode = MM_TEXT;
+ NewDC->wndExtX = 1.0f;
+ NewDC->wndExtY = 1.0f;
+ NewDC->vportExtX = 1.0f;
+ NewDC->vportExtY = 1.0f;
+ NewDC->w.textColor = 0;
+ NewDC->w.backgroundColor = 0xffffff;
NewDC->w.hFont = NtGdiGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(NewDC->w.hFont);
- DC_UnlockDc(hDC);
+ NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
+
+ DC_UnlockDc(NewDC);
return hDC;
}
NtGdiSelectObject(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
//NtGdiSelectObject(DCHandle, hFont);
-// CLIPPING_UpdateGCRegion(DCToInit);
-
+/*
+ {
+ int res;
+ res = CLIPPING_UpdateGCRegion(DCToInit);
+ ASSERT ( res != ERROR );
+ }
+*/
}
VOID FASTCALL
DC_FreeDC(HDC DCToFree)
{
- if (!GDIOBJ_FreeObj(DCToFree, GDI_OBJECT_TYPE_DC, GDIOBJFLAG_DEFAULT))
+ if (!GDIOBJ_FreeObj(DCToFree, GDI_OBJECT_TYPE_DC))
{
DPRINT("DC_FreeDC failed\n");
}
}
-BOOL FASTCALL
-DC_InternalDeleteDC( PDC DCToDelete )
+BOOL INTERNAL_CALL
+DC_Cleanup(PVOID ObjectBody)
{
-
- RtlFreeUnicodeString(&DCToDelete->DriverName);
+ PDC pDC = (PDC)ObjectBody;
+ RtlFreeUnicodeString(&pDC->DriverName);
return TRUE;
}
FLOAT scaleX, scaleY;
/* Construct a transformation to do the window-to-viewport conversion */
- scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
- scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
+ scaleX = (dc->wndExtX ? (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX : 0.0f);
+ scaleY = (dc->wndExtY ? (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY : 0.0f);
xformWnd2Vport.eM11 = scaleX;
xformWnd2Vport.eM12 = 0.0;
xformWnd2Vport.eM21 = 0.0;
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
/* Combine with the world transformation */
- NtGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
+ IntGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
/* Create inverse of world-to-viewport transformation */
dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);
{
GDIOBJ_CopyOwnership(hDC, DC->w.hGCClipRgn);
}
- DC_UnlockDc(hDC);
+ DC_UnlockDc(DC);
}
}
+BOOL FASTCALL
+IntIsPrimarySurface(SURFOBJ *SurfObj)
+{
+ if (PrimarySurface.Handle == NULL)
+ {
+ return FALSE;
+ }
+ return SurfObj->hsurf == PrimarySurface.Handle;
+}
+
+/*
+ * Returns the color of the brush or pen that is currently selected into the DC.
+ * This function is called from GetDCBrushColor() and GetDCPenColor()
+ */
+COLORREF FASTCALL
+IntGetDCColor(HDC hDC, ULONG Object)
+{
+ /*
+ * The previous implementation was completly incorrect. It modified the
+ * brush that was currently selected into the device context, but in fact
+ * the DC pen/brush color should be stored directly in the device context
+ * (at address 0x2C of the user mode DC object memory on Windows 2K/XP).
+ * The actual color is then used when DC_BRUSH/DC_PEN object is selected
+ * into the device context and BRUSHOBJ for drawing is composed (belongs
+ * to IntGdiInitBrushInstance in the current ReactOS implementation). Also
+ * the implementation should be moved to user mode GDI32.dll when UM
+ * mapped GDI objects will be implemented.
+ */
+
+ DPRINT("WIN32K:IntGetDCColor is unimplemented\n");
+ return 0xFFFFFF; /* The default DC color. */
+}
+
+/*
+ * Changes the color of the brush or pen that is currently selected into the DC.
+ * This function is called from SetDCBrushColor() and SetDCPenColor()
+ */
+COLORREF FASTCALL
+IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
+{
+ /* See the comment in IntGetDCColor. */
+
+ DPRINT("WIN32K:IntSetDCColor is unimplemented\n");
+ return CLR_INVALID;
+}
+
+#define SIZEOF_DEVMODEW_300 188
+#define SIZEOF_DEVMODEW_400 212
+#define SIZEOF_DEVMODEW_500 220
+
+/*! \brief Enumerate possible display settings for the given display...
+ *
+ * \todo Make thread safe!?
+ * \todo Don't ignore pDeviceName
+ * \todo Implement non-raw mode (only return settings valid for driver and monitor)
+ */
+BOOL FASTCALL
+IntEnumDisplaySettings(
+ IN PUNICODE_STRING pDeviceName OPTIONAL,
+ IN DWORD iModeNum,
+ IN OUT LPDEVMODEW pDevMode,
+ IN DWORD dwFlags)
+{
+ static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
+ static DWORD SizeOfCachedDevModes = 0;
+ PDEVMODEW CachedMode = NULL;
+ DEVMODEW DevMode;
+ INT Size, OldSize;
+ ULONG DisplayNumber = 0; /* only default display supported */
+
+ DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
+ DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
+ if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
+ pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
+ pDevMode->dmSize != SIZEOF_DEVMODEW_500)
+ {
+ SetLastWin32Error(STATUS_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (iModeNum == ENUM_CURRENT_SETTINGS)
+ {
+ CachedMode = &PrimarySurface.DMW;
+ ASSERT(CachedMode->dmSize > 0);
+ }
+ else if (iModeNum == ENUM_REGISTRY_SETTINGS)
+ {
+ RtlZeroMemory(&DevMode, sizeof (DevMode));
+ DevMode.dmSize = sizeof (DevMode);
+ DevMode.dmDriverExtra = 0;
+ if (SetupDevMode(&DevMode, DisplayNumber))
+ CachedMode = &DevMode;
+ else
+ {
+ SetLastWin32Error(0); /* FIXME: use error code */
+ return FALSE;
+ }
+ /* FIXME: Maybe look for the matching devmode supplied by the
+ * driver so we can provide driver private/extra data?
+ */
+ }
+ else
+ {
+ if (iModeNum == 0 || CachedDevModes == NULL) /* query modes from drivers */
+ {
+ BOOL PrimarySurfaceCreated = FALSE;
+ UNICODE_STRING DriverFileNames;
+ LPWSTR CurrentName;
+ DRVENABLEDATA DrvEnableData;
+
+ /* Retrieve DDI driver names from registry */
+ RtlInitUnicodeString(&DriverFileNames, NULL);
+ if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
+ {
+ DPRINT1("FindDriverFileNames failed\n");
+ return FALSE;
+ }
+
+ if (!HalQueryDisplayOwnership())
+ {
+ IntCreatePrimarySurface();
+ PrimarySurfaceCreated = TRUE;
+ }
+
+ /*
+ * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
+ * scan all of them until a good one found.
+ */
+ CurrentName = DriverFileNames.Buffer;
+ for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR));
+ CurrentName += wcslen(CurrentName) + 1)
+ {
+ INT i;
+ PGD_ENABLEDRIVER GDEnableDriver;
+
+ /* Get the DDI driver's entry point */
+ GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
+ if (NULL == GDEnableDriver)
+ {
+ DPRINT("FindDDIDriver failed for %S\n", CurrentName);
+ continue;
+ }
+
+ /* Call DDI driver's EnableDriver function */
+ RtlZeroMemory(&DrvEnableData, sizeof (DrvEnableData));
+
+ if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
+ {
+ DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
+ continue;
+ }
+
+ CachedDevModesEnd = CachedDevModes;
+
+ /* find DrvGetModes function */
+ for (i = 0; i < DrvEnableData.c; i++)
+ {
+ PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
+ PGD_GETMODES GetModes;
+ INT SizeNeeded, SizeUsed;
+
+ if (DrvFn->iFunc != INDEX_DrvGetModes)
+ continue;
+
+ GetModes = (PGD_GETMODES)DrvFn->pfn;
+
+ /* make sure we have enough memory to hold the modes */
+ SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
+ if (SizeNeeded <= 0)
+ {
+ DPRINT("DrvGetModes failed for %S\n", CurrentName);
+ break;
+ }
+
+ SizeUsed = CachedDevModesEnd - CachedDevModes;
+ if (SizeOfCachedDevModes - SizeUsed < SizeNeeded)
+ {
+ PVOID NewBuffer;
+
+ SizeOfCachedDevModes += SizeNeeded;
+ NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
+ if (NewBuffer == NULL)
+ {
+ /* clean up */
+ ExFreePool(CachedDevModes);
+ SizeOfCachedDevModes = 0;
+ CachedDevModes = NULL;
+ CachedDevModesEnd = NULL;
+ if (PrimarySurfaceCreated)
+ {
+ IntDestroyPrimarySurface();
+ }
+ SetLastWin32Error(STATUS_NO_MEMORY);
+ return FALSE;
+ }
+ if (CachedDevModes != NULL)
+ {
+ RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
+ ExFreePool(CachedDevModes);
+ }
+ CachedDevModes = NewBuffer;
+ CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
+ }
+
+ /* query modes */
+ SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
+ SizeOfCachedDevModes - SizeUsed,
+ CachedDevModesEnd);
+ if (SizeNeeded <= 0)
+ {
+ DPRINT("DrvGetModes failed for %S\n", CurrentName);
+ }
+ else
+ {
+ CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
+ }
+ break;
+ }
+ }
+
+ if (PrimarySurfaceCreated)
+ {
+ IntDestroyPrimarySurface();
+ }
+
+ RtlFreeUnicodeString(&DriverFileNames);
+ }
+
+ /* return cached info */
+ CachedMode = CachedDevModes;
+ if (CachedMode >= CachedDevModesEnd)
+ {
+ SetLastWin32Error(STATUS_NO_MORE_ENTRIES);
+ return FALSE;
+ }
+ while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd)
+ {
+ assert(CachedMode->dmSize > 0);
+ CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra);
+ }
+ if (CachedMode >= CachedDevModesEnd)
+ {
+ SetLastWin32Error(STATUS_NO_MORE_ENTRIES);
+ return FALSE;
+ }
+ }
+
+ ASSERT(CachedMode != NULL);
+
+ Size = OldSize = pDevMode->dmSize;
+ if (Size > CachedMode->dmSize)
+ Size = CachedMode->dmSize;
+ RtlCopyMemory(pDevMode, CachedMode, Size);
+ RtlZeroMemory((PCHAR)pDevMode + Size, OldSize - Size);
+ pDevMode->dmSize = OldSize;
+
+ Size = OldSize = pDevMode->dmDriverExtra;
+ if (Size > CachedMode->dmDriverExtra)
+ Size = CachedMode->dmDriverExtra;
+ RtlCopyMemory((PCHAR)pDevMode + pDevMode->dmSize,
+ (PCHAR)CachedMode + CachedMode->dmSize, Size);
+ RtlZeroMemory((PCHAR)pDevMode + pDevMode->dmSize + Size, OldSize - Size);
+ pDevMode->dmDriverExtra = OldSize;
+
+ return TRUE;
+}
+LONG
+FASTCALL
+IntChangeDisplaySettings(
+ IN PUNICODE_STRING pDeviceName OPTIONAL,
+ IN LPDEVMODEW DevMode,
+ IN DWORD dwflags,
+ IN PVOID lParam OPTIONAL)
+{
+ BOOLEAN Global = FALSE;
+ BOOLEAN NoReset = FALSE;
+ BOOLEAN Reset = FALSE;
+ BOOLEAN SetPrimary = FALSE;
+ LONG Ret=0;
+ NTSTATUS Status ;
+
+ DPRINT1("display flag : %x\n",dwflags);
+
+ if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
+ {
+ /* Check global, reset and noreset flags */
+ if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
+ Global = TRUE;
+ if ((dwflags & CDS_NORESET) == CDS_NORESET)
+ NoReset = TRUE;
+ dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
+ }
+ if ((dwflags & CDS_RESET) == CDS_RESET)
+ Reset = TRUE;
+ if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
+ SetPrimary = TRUE;
+ dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
+
+ if (Reset && NoReset)
+ return DISP_CHANGE_BADFLAGS;
+
+ if (dwflags == 0)
+ {
+ /* Dynamically change graphics mode */
+ DPRINT1("flag 0 UNIMPLEMENT \n");
+ return DISP_CHANGE_FAILED;
+ }
+
+ if ((dwflags & CDS_TEST) == CDS_TEST)
+ {
+ /* Test reslution */
+ dwflags &= ~CDS_TEST;
+ DPRINT1("flag CDS_TEST UNIMPLEMENT");
+ Ret = DISP_CHANGE_FAILED;
+ }
+
+ if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
+ {
+ DEVMODE lpDevMode;
+ /* Full Screen */
+ dwflags &= ~CDS_FULLSCREEN;
+ DPRINT1("flag CDS_FULLSCREEN partially implemented");
+ Ret = DISP_CHANGE_FAILED;
+
+ lpDevMode.dmBitsPerPel =0;
+ lpDevMode.dmPelsWidth =0;
+ lpDevMode.dmPelsHeight =0;
+ lpDevMode.dmDriverExtra =0;
+
+ lpDevMode.dmSize = sizeof(DEVMODE);
+ Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0);
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+
+ DPRINT1("Req Mode : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel);
+ DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel);
+
+
+ if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) &&
+ (lpDevMode.dmPelsWidth == DevMode->dmPelsWidth) &&
+ (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight))
+ Ret = DISP_CHANGE_SUCCESSFUL;
+ }
+
+ if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS)
+ {
+ dwflags &= ~CDS_VIDEOPARAMETERS;
+ if (lParam == NULL) Ret=DISP_CHANGE_BADPARAM;
+ else
+ {
+ DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENT");
+ Ret = DISP_CHANGE_FAILED;
+ }
+
+ }
+
+ if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
+ {
+
+ UNICODE_STRING ObjectName;
+ UNICODE_STRING KernelModeName;
+ WCHAR KernelModeNameBuffer[256];
+ UNICODE_STRING RegistryKey;
+ WCHAR RegistryKeyBuffer[512];
+ PDEVICE_OBJECT DeviceObject;
+ ULONG LastSlash;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE DevInstRegKey;
+ ULONG NewValue;
+
+
+ DPRINT1("set CDS_UPDATEREGISTRY \n");
+
+ dwflags &= ~CDS_UPDATEREGISTRY;
+
+ /* Get device name (pDeviceName is "\.\xxx") */
+ for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+ {
+ if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
+ break;
+ }
+
+ if (LastSlash == 0) return DISP_CHANGE_RESTART;
+ ObjectName = *pDeviceName;
+ ObjectName.Length -= LastSlash * sizeof(WCHAR);
+ ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+ ObjectName.Buffer += LastSlash;
+
+ KernelModeName.Length = 0;
+ KernelModeName.MaximumLength = sizeof(KernelModeNameBuffer);
+ KernelModeName.Buffer = KernelModeNameBuffer;
+
+ /* Open \??\xxx (ex: "\??\DISPLAY1") */
+ Status = RtlAppendUnicodeToString(&KernelModeName, L"\\??\\");
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ Status = ObReferenceObjectByName(
+ &KernelModeName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ 0,
+ IoDeviceObjectType,
+ KernelMode,
+ NULL,
+ (PVOID*)&DeviceObject);
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ /* Get associated driver name (ex: "VBE") */
+ for (LastSlash = DeviceObject->DriverObject->DriverName.Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+ {
+ if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
+ break;
+ }
+
+ if (LastSlash == 0) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ ObjectName = DeviceObject->DriverObject->DriverName;
+ ObjectName.Length -= LastSlash * sizeof(WCHAR);
+ ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+ ObjectName.Buffer += LastSlash;
+
+ RegistryKey.Length = 0;
+ RegistryKey.MaximumLength = sizeof(RegistryKeyBuffer);
+ RegistryKey.Buffer = RegistryKeyBuffer;
+
+ /* Open registry key */
+ Status = RtlAppendUnicodeToString(&RegistryKey,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\");
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ Status = RtlAppendUnicodeStringToString(&RegistryKey, &ObjectName);
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ Status = RtlAppendUnicodeToString(&RegistryKey,
+ L"\\Device0");
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+
+ InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
+ OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = ZwOpenKey(&DevInstRegKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes);
+ ObDereferenceObject(DeviceObject);
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+
+ /* Update needed fields */
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
+ NewValue = DevMode->dmBitsPerPel;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
+ NewValue = DevMode->dmPelsWidth;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
+ NewValue = DevMode->dmPelsHeight;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ ZwClose(DevInstRegKey);
+ if (NT_SUCCESS(Status))
+ Ret = DISP_CHANGE_RESTART;
+ else
+ /* return DISP_CHANGE_NOTUPDATED when we can save to reg only vaild for NT */
+ Ret = DISP_CHANGE_NOTUPDATED;
+
+ }
+
+ if (dwflags != 0)
+ Ret = DISP_CHANGE_BADFLAGS;
+
+ return Ret;
+}
+
/* EOF */