* 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.135 2004/05/14 16:55:18 navaraf Exp $
+/* $Id$
*
* DC.C - Device context functions
*
*/
+
#include <w32k.h>
+#define NDEBUG
+#include <debug.h>
+
#ifndef OBJ_COLORSPACE
#define OBJ_COLORSPACE (14)
#endif
return 0; \
} \
ft = dc->dc_field; \
- DC_UnlockDc( hdc ); \
+ DC_UnlockDc(dc); \
return ft; \
}
} \
BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \
{ \
- NTSTATUS Status; \
+ NTSTATUS Status = STATUS_SUCCESS; \
type Safept; \
PDC dc; \
if(!pt) \
return FALSE; \
} \
Int##FuncName( dc, &Safept); \
- DC_UnlockDc(hdc); \
- Status = MmCopyToCaller(pt, &Safept, sizeof( type )); \
+ 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); \
} \
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);
/* Copy information from original DC to new DC */
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.hBitmap = hBitmap;
NewDC->w.hFirstBitmap = hBitmap;
NewDC->GDIDevice = OrigDC->GDIDevice;
- pb = BITMAPOBJ_LockBitmap(hBitmap);
- NewDC->Surface = (HSURF)BitmapToSurf(pb, NewDC->GDIDevice);
- BITMAPOBJ_UnlockBitmap(hBitmap);
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);
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;
- SURFOBJ *SurfObj;
- PSURFGDI SurfGDI;
UNICODE_STRING DriverFileNames;
PWSTR CurrentName;
BOOL GotDriver;
DPRINT("Trying to load display driver no. %d\n", DisplayNumber);
RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface));
- ExInitializeFastMutex(&PrimarySurface.DriverLock);
PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber);
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
{
DPRINT1("FindDriverFileNames failed\n");
- /* return FALSE; */
continue;
}
CurrentName = DriverFileNames.Buffer;
GotDriver = FALSE;
while (!GotDriver &&
- CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
+ CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
/* Get the DDI driver's entry point */
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
{
/* Skip to the next name but never get past the Unicode string */
while (L'\0' != *CurrentName &&
- CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
+ CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
CurrentName++;
}
- if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
+ if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
CurrentName++;
}
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("No suitable DDI driver found\n");
- /* return FALSE; */
continue;
}
}
/* 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.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
&PrimarySurface.DMW,
L"",
HS_DDI_MAX,
if (DoDefault)
{
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
- PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDev(
+ PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
+ PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
&PrimarySurface.DMW,
L"",
HS_DDI_MAX,
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("DrvEnablePDEV with default parameters failed\n");
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
- /* return FALSE; */
continue;
}
}
PrimarySurface.GDIInfo.ulLogPixelsY = 96;
}
+ PrimarySurface.Pointer.Exclude.right = -1;
+
DPRINT("calling completePDev\n");
/* Complete initialization of the physical device */
- PrimarySurface.DriverFunctions.CompletePDev(
+ PrimarySurface.DriverFunctions.CompletePDEV(
PrimarySurface.PDev,
(HDEV)&PrimarySurface);
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)
- {
-/* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
- PrimarySurface.DriverFunctions.DisablePDev(PrimarySurface.PDev);
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnableSurface failed\n");
- /* return FALSE; */
- continue;
- }
+ return TRUE;
+ }
- SurfObj = (SURFOBJ*)AccessUserObject((ULONG) PrimarySurface.Handle);
- SurfObj->dhpdev = PrimarySurface.PDev;
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle);
- IntShowDesktop(
- IntGetActiveDesktop(),
- SurfGDI->SurfObj.sizlBitmap.cx,
- SurfGDI->SurfObj.sizlBitmap.cy);
- break;
+ 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;
+ }
+
+ PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, 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()
{
-#if 0
- SURFOBJ *SurfObj;
- PSURFGDI SurfGDI;
-#endif
-
+ BOOL calledFromUser;
+
DRIVER_UnreferenceDriver(L"DISPLAY");
-#if 0
- DPRINT("Hiding mouse pointer\n" );
- SurfObj = (SURFOBJ*)AccessUserObject((ULONG) PrimarySurface.Handle);
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle);
- SurfGDI->SetPointerShape(SurfObj, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0);
-#endif
+ 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);
}
if (Driver != NULL && Driver->Buffer != NULL)
{
- DPRINT("NAME: %S\n", Driver->Buffer); // FIXME: Should not crash if NULL
+ DPRINT("NAME: %wZ\n", Driver); // FIXME: Should not crash if NULL
}
/* Allocate a DC object */
}
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 )
{
HGDIOBJ SelObject;
DC *dc;
-
+
if(!(dc = DC_LockDc(hDC)))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
-
+
switch(ObjectType)
{
case OBJ_PEN:
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_COLORSPACE:
DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
+ SelObject = NULL;
break;
default:
SelObject = NULL;
SetLastWin32Error(ERROR_INVALID_PARAMETER);
break;
}
-
- DC_UnlockDc(hDC);
+
+ DC_UnlockDc(dc);
return SelObject;
}
{
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;
}
oldColor = dc->w.backgroundColor;
dc->w.backgroundColor = color;
hBrush = dc->w.hBrush;
- DC_UnlockDc ( hDC );
+ DC_UnlockDc(dc);
NtGdiSelectObject(hDC, hBrush);
return oldColor;
}
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->hSelf = hnewdc;
newdc->saveLevel = 0;
+ newdc->IsIC = dc->IsIC;
#if 0
PATH_InitGdiPath( &newdc->w.path );
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
- DC_UnlockDc( hnewdc );
- DC_UnlockDc( hDC );
+ DC_UnlockDc( newdc );
+ DC_UnlockDc( dc );
return hnewdc;
}
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
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);
}
}
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)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- 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;
}
INT FASTCALL
IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer)
{
- PGDIOBJHDR GdiObject;
+ PVOID GdiObject;
INT Result = 0;
DWORD ObjectType;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
-
+
ObjectType = GDIOBJ_GetObjectType(Handle);
switch (ObjectType)
{
break;
}
- GDIOBJ_UnlockObj(Handle, GDI_OBJECT_TYPE_DONTCARE);
+ GDIOBJ_UnlockObjByPtr(GdiObject);
return Result;
}
{
INT Ret;
LPVOID SafeBuf;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
if (count <= 0)
{
return 0;
}
- SafeBuf = ExAllocatePoolWithTag(NonPagedPool, count, TAG_GDIOBJ);
+ _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);
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;
}
NtGdiResetDC(HDC hDC, CONST DEVMODEW *InitData)
{
UNIMPLEMENTED;
+ return 0;
}
BOOL STDCALL
SaveLevel = dc->saveLevel;
if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
+ {
+ DC_UnlockDc(dc);
return FALSE;
+ }
success = TRUE;
while (dc->saveLevel >= SaveLevel)
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;
}
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;
}
PGDIBRUSHOBJ pen;
PGDIBRUSHOBJ brush;
XLATEOBJ *XlateObj;
- PPALGDI PalGDI;
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 = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
- if (NULL != XlateObj)
- {
- pen = PENOBJ_LockPen((HPEN) hGDIObj);
- if (NULL != pen)
- {
- if (pen->flAttrs & GDIBRUSH_IS_SOLID)
- {
- pen->BrushObject.iSolidColor =
- XLATEOBJ_iXlate(XlateObj, pen->BrushAttr.lbColor);
- }
- else
- {
- pen->BrushObject.iSolidColor = 0xFFFFFFFF;
- }
- pen->crBack = XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor);
- pen->crFore = XLATEOBJ_iXlate(XlateObj, dc->w.textColor);
- 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 = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
- if (NULL != XlateObj)
- {
- brush = BRUSHOBJ_LockBrush((HBRUSH) hGDIObj);
- if (NULL != brush)
- {
- if (brush->flAttrs & GDIBRUSH_IS_SOLID)
- {
- brush->BrushObject.iSolidColor =
- XLATEOBJ_iXlate(XlateObj, brush->BrushAttr.lbColor);
- }
- else
- {
- brush->BrushObject.iSolidColor = 0xFFFFFFFF;
- }
- brush->crBack = XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor);
- brush->crFore = XLATEOBJ_iXlate(XlateObj, ((brush->flAttrs & GDIBRUSH_IS_HATCH) ?
- brush->BrushAttr.lbColor : dc->w.textColor));
- /* according to the documentation of SetBrushOrgEx(), the origin is assigned to the
- next brush selected into the DC, so we should set it here */
- brush->ptOrigin.x = dc->w.brushOrgX;
- brush->ptOrigin.y = dc->w.brushOrgY;
-
- 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 = (HSURF)BitmapToSurf(pb, dc->GDIDevice);
// 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->bitmap.bmWidth, pb->bitmap.bmHeight );
+ /* 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;
case GDI_OBJECT_TYPE_REGION:
- DC_UnlockDc (hDC);
+ 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;
}
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.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);
NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
- DC_UnlockDc(hDC);
+ 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 = (dc->wndExtX ? (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX : 0.0);
- scaleY = (dc->wndExtY ? (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY : 0.0);
+ 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;
{
GDIOBJ_CopyOwnership(hDC, DC->w.hGCClipRgn);
}
- DC_UnlockDc(hDC);
+ DC_UnlockDc(DC);
}
}
BOOL FASTCALL
-IntIsPrimarySurface(PSURFGDI SurfGDI)
+IntIsPrimarySurface(SURFOBJ *SurfObj)
{
if (PrimarySurface.Handle == NULL)
{
return FALSE;
}
- return SurfGDI == (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle) ? TRUE : FALSE;
+ return SurfObj->hsurf == PrimarySurface.Handle;
}
/*
COLORREF FASTCALL
IntGetDCColor(HDC hDC, ULONG Object)
{
- COLORREF Result;
- DC *dc;
- PPALGDI PalGDI;
- PGDIBRUSHOBJ pen;
- PGDIBRUSHOBJ brush;
- XLATEOBJ *XlateObj;
- HPALETTE Pal;
- USHORT Mode;
- ULONG iColor;
-
- if(!(dc = DC_LockDc(hDC)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return CLR_INVALID;
- }
-
- switch(Object)
- {
- case OBJ_PEN:
- {
- if(!(pen = PENOBJ_LockPen(dc->w.hPen)))
- {
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- if(!(pen->flAttrs & GDIBRUSH_IS_SOLID))
- {
- /* FIXME - just bail here? */
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- iColor = pen->BrushObject.iSolidColor;
- PENOBJ_UnlockPen(dc->w.hPen);
- break;
- }
- case OBJ_BRUSH:
- {
- if(!(brush = BRUSHOBJ_LockBrush(dc->w.hBrush)))
- {
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- if(!(brush->flAttrs & GDIBRUSH_IS_SOLID))
- {
- /* FIXME - just bail here? */
- BRUSHOBJ_UnlockBrush(dc->w.hBrush);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- iColor = brush->BrushObject.iSolidColor;
- BRUSHOBJ_UnlockBrush(dc->w.hBrush);
- break;
- }
- default:
- {
- DC_UnlockDc(hDC);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return CLR_INVALID;
- }
- }
-
- /* translate the color into RGB */
-
- if(dc->w.hPalette)
- Pal = dc->w.hPalette;
-
- Result = CLR_INVALID;
-
- if((PalGDI = PALETTE_LockPalette(dc->w.hPalette)))
- {
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, Mode, NULL, Pal);
- if(XlateObj)
- {
- Result = XLATEOBJ_iXlate(XlateObj, iColor);
- EngDeleteXlate(XlateObj);
- }
- }
-
- DC_UnlockDc(hDC);
- return Result;
+ /*
+ * 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. */
}
/*
COLORREF FASTCALL
IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
{
- COLORREF Result;
- DC *dc;
- PPALGDI PalGDI;
- PGDIBRUSHOBJ pen;
- PGDIBRUSHOBJ brush;
- XLATEOBJ *XlateObj;
- HPALETTE Pal;
- USHORT Mode;
- ULONG iColor;
-
- if(Color == CLR_INVALID)
+ /* 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(ERROR_INVALID_PARAMETER);
- return CLR_INVALID;
+ SetLastWin32Error(STATUS_INVALID_PARAMETER);
+ return FALSE;
}
-
- if(!(dc = DC_LockDc(hDC)))
+
+ if (iModeNum == ENUM_CURRENT_SETTINGS)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return CLR_INVALID;
+ CachedMode = &PrimarySurface.DMW;
+ ASSERT(CachedMode->dmSize > 0);
}
-
- switch(Object)
+ else if (iModeNum == ENUM_REGISTRY_SETTINGS)
{
- case OBJ_PEN:
+ RtlZeroMemory(&DevMode, sizeof (DevMode));
+ DevMode.dmSize = sizeof (DevMode);
+ DevMode.dmDriverExtra = 0;
+ if (SetupDevMode(&DevMode, DisplayNumber))
+ CachedMode = &DevMode;
+ else
{
- if(!(pen = PENOBJ_LockPen(dc->w.hPen)))
- {
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- if(!(pen->flAttrs & GDIBRUSH_IS_SOLID))
- {
- /* FIXME - just bail here? */
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
-
- /* save old color index, translate it to RGB later */
- iColor = pen->BrushObject.iSolidColor;
-
- if(!(PalGDI = PALETTE_LockPalette(dc->w.hPalette)))
- {
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- if(!(XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL)))
- {
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
- }
- pen->BrushObject.iSolidColor = XLATEOBJ_iXlate(XlateObj, (ULONG)Color);
- EngDeleteXlate(XlateObj);
- PENOBJ_UnlockPen(dc->w.hPen);
- break;
+ SetLastWin32Error(0); /* FIXME: use error code */
+ return FALSE;
}
- case OBJ_BRUSH:
+ /* 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 */
{
- if(!(brush = BRUSHOBJ_LockBrush(dc->w.hBrush)))
+ BOOL PrimarySurfaceCreated = FALSE;
+ UNICODE_STRING DriverFileNames;
+ LPWSTR CurrentName;
+ DRVENABLEDATA DrvEnableData;
+
+ /* Retrieve DDI driver names from registry */
+ RtlInitUnicodeString(&DriverFileNames, NULL);
+ if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
{
- DC_UnlockDc(hDC);
- return CLR_INVALID;
+ DPRINT1("FindDriverFileNames failed\n");
+ return FALSE;
}
- if(!(brush->flAttrs & GDIBRUSH_IS_SOLID))
+
+ if (!HalQueryDisplayOwnership())
{
- /* FIXME - just bail here? */
- BRUSHOBJ_UnlockBrush(dc->w.hBrush);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
+ IntCreatePrimarySurface();
+ PrimarySurfaceCreated = TRUE;
}
-
- /* save old color index, translate it to RGB later */
- iColor = brush->BrushObject.iSolidColor;
-
- if(!(PalGDI = PALETTE_LockPalette(dc->w.hPalette)))
+
+ /*
+ * 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)
{
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
+ 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;
+ }
}
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- if(!(XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL)))
+
+ if (PrimarySurfaceCreated)
{
- PENOBJ_UnlockPen(dc->w.hPen);
- DC_UnlockDc(hDC);
- return CLR_INVALID;
+ IntDestroyPrimarySurface();
}
- brush->BrushObject.iSolidColor = XLATEOBJ_iXlate(XlateObj, (ULONG)Color);
- EngDeleteXlate(XlateObj);
- BRUSHOBJ_UnlockBrush(dc->w.hBrush);
- break;
+
+ RtlFreeUnicodeString(&DriverFileNames);
}
- default:
+
+ /* return cached info */
+ CachedMode = CachedDevModes;
+ if (CachedMode >= CachedDevModesEnd)
{
- DC_UnlockDc(hDC);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return CLR_INVALID;
+ 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;
+ }
- /* translate the old color into RGB */
-
- if(dc->w.hPalette)
- Pal = dc->w.hPalette;
-
- Result = CLR_INVALID;
-
- if((PalGDI = PALETTE_LockPalette(dc->w.hPalette)))
+ if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
{
- Mode = PalGDI->Mode;
- PALETTE_UnlockPalette(dc->w.hPalette);
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, Mode, NULL, Pal);
- if(XlateObj)
- {
- Result = XLATEOBJ_iXlate(XlateObj, iColor);
- EngDeleteXlate(XlateObj);
- }
+ 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)
+ {
- DC_UnlockDc(hDC);
- return Result;
+ 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 */