From 87b264fba812958ab7f1621d6c162d18db62d1ea Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 30 May 2008 04:56:10 +0000 Subject: [PATCH] Modified GDIOBJ_Copy and Set owner to return bool. Start the use of server info for metrics data. Tested with Qemu on Linux. svn path=/trunk/; revision=33765 --- reactos/include/reactos/win32k/ntuser.h | 6 +- reactos/subsystems/win32/win32k/include/dc.h | 2 +- .../subsystems/win32/win32k/include/gdiobj.h | 6 +- .../subsystems/win32/win32k/ntuser/metric.c | 250 +++++++++++++++++- .../subsystems/win32/win32k/ntuser/winsta.c | 10 +- reactos/subsystems/win32/win32k/objects/dc.c | 12 +- .../subsystems/win32/win32k/objects/gdiobj.c | 81 ++++-- .../win32/win32k/objects/stockobj.c | 8 +- 8 files changed, 336 insertions(+), 39 deletions(-) diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index ceacc1e2ba9..e0efc618e9c 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -169,10 +169,12 @@ typedef struct _WINDOW UINT HideAccel : 1; } WINDOW, *PWINDOW; +#define SRVINFO_METRICS 0x0020 + typedef struct _SERVERINFO { -// DWORD SystemMetrics[SM_CMETRICS]; // System Metrics -// COLORREF SystemColorCopy[COLOR_MENUBAR+1]; // Backup Copy of system colors. + DWORD SRVINFO_Flags; + DWORD SystemMetrics[SM_CMETRICS]; // System Metrics COLORREF SysColors[COLOR_MENUBAR+1]; // GetSysColor HBRUSH SysColorBrushes[COLOR_MENUBAR+1]; // GetSysColorBrush HPEN SysColorPens[COLOR_MENUBAR+1]; // ReactOS exclusive diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 0a41b50a077..863f41d8902 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -277,7 +277,7 @@ VOID FASTCALL DC_FreeDcAttr(HDC); BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody); HDC FASTCALL DC_GetNextDC (PDC pDC); VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC); -VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); +BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); VOID FASTCALL DC_LockDisplay(HDC); VOID FASTCALL DC_UnlockDisplay(HDC); VOID FASTCALL IntGdiCopyFromSaveState(PDC, PDC, HDC); diff --git a/reactos/subsystems/win32/win32k/include/gdiobj.h b/reactos/subsystems/win32/win32k/include/gdiobj.h index 543f28760e6..a31df8f2cbe 100644 --- a/reactos/subsystems/win32/win32k/include/gdiobj.h +++ b/reactos/subsystems/win32/win32k/include/gdiobj.h @@ -58,8 +58,8 @@ enum BASEFLAGS }; BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle); -VOID INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner); -VOID INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo); +BOOL INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner); +BOOL INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo); BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj); VOID INTERNAL_CALL GDIOBJ_UnlockObjByPtr(POBJ Object); VOID INTERNAL_CALL GDIOBJ_ShareUnlockObjByPtr(POBJ Object); @@ -82,6 +82,6 @@ PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCES BOOL FASTCALL NtGdiDeleteObject(HGDIOBJ hObject); BOOL FASTCALL IsObjectDead(HGDIOBJ); -BOOL FASTCALL IntGdiSetDCOwnerEx( HGDIOBJ, DWORD, BOOL); +BOOL FASTCALL IntGdiSetDCOwnerEx( HDC, DWORD, BOOL); #endif diff --git a/reactos/subsystems/win32/win32k/ntuser/metric.c b/reactos/subsystems/win32/win32k/ntuser/metric.c index ccabc1fd174..ce9cc4fbc05 100644 --- a/reactos/subsystems/win32/win32k/ntuser/metric.c +++ b/reactos/subsystems/win32/win32k/ntuser/metric.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ +/* * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -34,9 +34,243 @@ #define NDEBUG #include +extern PSERVERINFO gpsi; + +static BOOL Setup = FALSE; + /* FUNCTIONS *****************************************************************/ -/* FIXME: Alot of thse values should NOT be hardcoded but they are */ +BOOL +FASTCALL +InitMetrics(VOID) +{ + INT Index; + NTSTATUS Status; + PWINSTATION_OBJECT WinStaObject; + ULONG Width = 640, Height = 480; + + for (Index = 0; Index < SM_CMETRICS; Index++) + { + switch (Index) + { + case SM_CXSCREEN: + { + HDC ScreenDCHandle; + PDC ScreenDC; + + ScreenDCHandle = IntGdiCreateDC(NULL, NULL, NULL, NULL, TRUE); + if (NULL != ScreenDCHandle) + { + ScreenDC = DC_LockDc(ScreenDCHandle); + if (NULL != ScreenDC) + { + Width = ((PGDIDEVICE)ScreenDC->pPDev)->GDIInfo.ulHorzRes; + Height = ((PGDIDEVICE)ScreenDC->pPDev)->GDIInfo.ulVertRes; + DC_UnlockDc(ScreenDC); + } + NtGdiDeleteObjectApp(ScreenDCHandle); + } + gpsi->SystemMetrics[Index] = Width; + break; + } + case SM_CYSCREEN: + gpsi->SystemMetrics[Index] = Height; + break; + case SM_ARRANGE: + gpsi->SystemMetrics[Index] = 8; + break; + case SM_CLEANBOOT: + gpsi->SystemMetrics[Index] = 0; + break; + case SM_CMOUSEBUTTONS: + gpsi->SystemMetrics[Index] = 2; + break; + case SM_CXBORDER: + case SM_CYBORDER: + gpsi->SystemMetrics[Index] = 1; + break; + case SM_CXCURSOR: + case SM_CYCURSOR: + gpsi->SystemMetrics[Index] = 32; + break; + case SM_CXDLGFRAME: + case SM_CYDLGFRAME: + gpsi->SystemMetrics[Index] = 3; + break; + case SM_CXDOUBLECLK: + case SM_CYDOUBLECLK: + case SM_SWAPBUTTON: + { + PSYSTEM_CURSORINFO CurInfo; + Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, + KernelMode, + 0, + &WinStaObject); + if (!NT_SUCCESS(Status)) + gpsi->SystemMetrics[Index] = 0xFFFFFFFF; + break; + + CurInfo = IntGetSysCursorInfo(WinStaObject); + switch(Index) + { + case SM_CXDOUBLECLK: + gpsi->SystemMetrics[Index] = CurInfo->DblClickWidth; + break; + case SM_CYDOUBLECLK: + gpsi->SystemMetrics[Index] = CurInfo->DblClickWidth; + break; + case SM_SWAPBUTTON: + gpsi->SystemMetrics[Index] = CurInfo->SwapButtons; + break; + } + + ObDereferenceObject(WinStaObject); + break; + } + case SM_CXDRAG: + case SM_CYDRAG: + gpsi->SystemMetrics[Index] = 2; + break; + case SM_CXEDGE: + case SM_CYEDGE: + gpsi->SystemMetrics[Index] = 2; + break; + case SM_CXFRAME: + case SM_CYFRAME: + gpsi->SystemMetrics[Index] = 4; + break; + case SM_CXFULLSCREEN: + /* FIXME: shouldn't we take borders etc into account??? */ + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CXSCREEN]; + break; + case SM_CYFULLSCREEN: + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CYSCREEN]; + break; + case SM_CXHSCROLL: + case SM_CYHSCROLL: + gpsi->SystemMetrics[Index] = 16; + break; + case SM_CYVTHUMB: + case SM_CXHTHUMB: + gpsi->SystemMetrics[Index] = 16; + break; + case SM_CXICON: + case SM_CYICON: + gpsi->SystemMetrics[Index] = 32; + break; + case SM_CXICONSPACING: + case SM_CYICONSPACING: + gpsi->SystemMetrics[Index] = 64; + break; + case SM_CXMAXIMIZED: + /* This seems to be 8 pixels greater than the screen width */ + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CXSCREEN] + 8; + break; + case SM_CYMAXIMIZED: + /* This seems to be 20 pixels less than the screen height, taskbar maybe? */ + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CYSCREEN] - 20; + break; + case SM_CXMAXTRACK: + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CYSCREEN] + 12; + break; + case SM_CYMAXTRACK: + gpsi->SystemMetrics[Index] = gpsi->SystemMetrics[SM_CYSCREEN] + 12; + break; + case SM_CXMENUCHECK: + case SM_CYMENUCHECK: + gpsi->SystemMetrics[Index] = 13; + break; + case SM_CXMENUSIZE: + case SM_CYMENUSIZE: + gpsi->SystemMetrics[Index] = 18; + break; + case SM_CXMIN: + gpsi->SystemMetrics[Index] = 112; + break; + case SM_CYMIN: + gpsi->SystemMetrics[Index] = 27; + break; + case SM_CXMINIMIZED: + gpsi->SystemMetrics[Index] = 160; + break; + case SM_CYMINIMIZED: + gpsi->SystemMetrics[Index] = 24; + break; + case SM_CXMINSPACING: + gpsi->SystemMetrics[Index] = 160; + break; + case SM_CYMINSPACING: + gpsi->SystemMetrics[Index] = 24; + break; + case SM_CXMINTRACK: + gpsi->SystemMetrics[Index] = 112; + break; + case SM_CYMINTRACK: + gpsi->SystemMetrics[Index] = 27; + break; + case SM_CXSIZE: + case SM_CYSIZE: + gpsi->SystemMetrics[Index] = 18; + break; + case SM_CXSMICON: + case SM_CYSMICON: + gpsi->SystemMetrics[Index] = 16; + break; + case SM_CXSMSIZE: + gpsi->SystemMetrics[Index] = 12; + break; + case SM_CYSMSIZE: + gpsi->SystemMetrics[Index] = 14; + break; + case SM_CXVSCROLL: + case SM_CYVSCROLL: + gpsi->SystemMetrics[Index] = 16; + break; + case SM_CYCAPTION: + gpsi->SystemMetrics[Index] = 19; + break; + case SM_CYKANJIWINDOW: + gpsi->SystemMetrics[Index] = 0; + break; + case SM_CYMENU: + gpsi->SystemMetrics[Index] = 19; + break; + case SM_CYSMCAPTION: + gpsi->SystemMetrics[Index] = 15; + break; + case SM_DBCSENABLED: + case SM_DEBUG: + case SM_MENUDROPALIGNMENT: + case SM_MIDEASTENABLED: + gpsi->SystemMetrics[Index] = 0; + break; + case SM_MOUSEPRESENT: + gpsi->SystemMetrics[Index] = 1; + break; + case SM_NETWORK: + gpsi->SystemMetrics[Index] = 3; + break; + case SM_PENWINDOWS: + case SM_SECURE: + case SM_SHOWSOUNDS: + case SM_SLOWMACHINE: + gpsi->SystemMetrics[Index] = 0; + break; + case SM_CMONITORS: + gpsi->SystemMetrics[Index] = 1; + break; + case SM_REMOTESESSION: + gpsi->SystemMetrics[Index] = 0; + break; + default: + gpsi->SystemMetrics[Index] = 0xFFFFFFFF; + } + } + gpsi->SRVINFO_Flags |= SRVINFO_METRICS; + Setup = TRUE; + return TRUE; +} + ULONG FASTCALL UserGetSystemMetrics(ULONG Index) { @@ -44,6 +278,11 @@ UserGetSystemMetrics(ULONG Index) PWINSTATION_OBJECT WinStaObject; ULONG Width, Height, Result; +// DPRINT1("UserGetSystemMetrics -> %d\n",Index); + if (gpsi && Setup) + return gpsi->SystemMetrics[Index]; + else + { Result = 0; switch (Index) { @@ -176,6 +415,7 @@ UserGetSystemMetrics(ULONG Index) return SM_CXSCREEN == Index ? Width : Height; } case SM_CXSIZE: + InitMetrics(); case SM_CYSIZE: return(18); case SM_CXSMICON: @@ -218,11 +458,9 @@ UserGetSystemMetrics(ULONG Index) default: return(0xFFFFFFFF); } + } } - - -/* FIXME: Alot of thse values should NOT be hardcoded but they are */ ULONG STDCALL NtUserGetSystemMetrics(ULONG Index) { @@ -238,4 +476,6 @@ CLEANUP: UserLeave(); END_CLEANUP; } + + /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/winsta.c b/reactos/subsystems/win32/win32k/ntuser/winsta.c index f8169155aa8..57a4522cdec 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winsta.c +++ b/reactos/subsystems/win32/win32k/ntuser/winsta.c @@ -290,6 +290,8 @@ IntGetWindowStationObject(PWINSTATION_OBJECT Object) return NT_SUCCESS(Status); } +extern HDC hSystemBM; + BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID) { @@ -304,12 +306,16 @@ co_IntInitializeDesktopGraphics(VOID) IntDestroyPrimarySurface(); return FALSE; } - DC_FreeDcAttr(ScreenDeviceContext); // Free the dcattr! - DC_SetOwnership(ScreenDeviceContext, NULL); // This hDC is inaccessible! + IntGdiSetDCOwnerEx(ScreenDeviceContext, GDI_OBJ_HMGR_PUBLIC, FALSE); /* Setup the cursor */ co_IntLoadDefaultCursors(); + hSystemBM = NtGdiCreateCompatibleDC(ScreenDeviceContext); + + NtGdiSelectFont( hSystemBM, NtGdiGetStockObject(SYSTEM_FONT)); + IntGdiSetDCOwnerEx( hSystemBM, GDI_OBJ_HMGR_PUBLIC, FALSE); + return TRUE; } diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index ad970b42fbc..b40806fa77f 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -2642,29 +2642,31 @@ DC_InvertXform(const XFORM *xformSrc, return TRUE; } -VOID FASTCALL +BOOL +FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner) { PDC pDC; - GDIOBJ_SetOwnership(hDC, Owner); + if(!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE; pDC = DC_LockDc(hDC); if (pDC) { if (pDC->w.hClipRgn) { - GDIOBJ_SetOwnership(pDC->w.hClipRgn, Owner); + if(!GDIOBJ_SetOwnership(pDC->w.hClipRgn, Owner)) return FALSE; } if (pDC->w.hVisRgn) { - GDIOBJ_SetOwnership(pDC->w.hVisRgn, Owner); + if(!GDIOBJ_SetOwnership(pDC->w.hVisRgn, Owner)) return FALSE; } if (pDC->w.hGCClipRgn) { - GDIOBJ_SetOwnership(pDC->w.hGCClipRgn, Owner); + if(!GDIOBJ_SetOwnership(pDC->w.hGCClipRgn, Owner)) return FALSE; } DC_UnlockDc(pDC); } + return TRUE; } // diff --git a/reactos/subsystems/win32/win32k/objects/gdiobj.c b/reactos/subsystems/win32/win32k/objects/gdiobj.c index f609e1e3f8c..ffeda8bcf2b 100644 --- a/reactos/subsystems/win32/win32k/objects/gdiobj.c +++ b/reactos/subsystems/win32/win32k/objects/gdiobj.c @@ -1151,12 +1151,13 @@ LockHandle: return FALSE; } -void INTERNAL_CALL +BOOL INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS NewOwner) { PGDI_TABLE_ENTRY Entry; HANDLE ProcessId, LockedProcessId, PrevProcId; PW32THREAD Thread; + BOOL Ret = TRUE; GDIDBG_INITLOOPTRACE(); @@ -1223,7 +1224,7 @@ LockHandle: (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, ProcessId); /* we're done! */ - return; + return Ret; } else { @@ -1245,6 +1246,7 @@ LockHandle: { DPRINT1("Attempted to change ownership of an object 0x%x currently being destroyed!!!\n", ObjectHandle); DPRINT1("Entry->Type = 0x%lx, Entry->KernelData = 0x%p\n", Entry->Type, Entry->KernelData); + Ret = FALSE; } } else if (PrevProcId == LockedProcessId) @@ -1267,20 +1269,24 @@ LockHandle: else if ((HANDLE)((ULONG_PTR)PrevProcId & ~0x1) != PsGetCurrentProcessId()) { DPRINT1("Attempted to change ownership of object 0x%x (pid: 0x%x) from pid 0x%x!!!\n", ObjectHandle, (ULONG_PTR)PrevProcId & ~0x1, PsGetCurrentProcessId()); + Ret = FALSE; } else { DPRINT1("Attempted to change owner of invalid handle: 0x%x\n", ObjectHandle); + Ret = FALSE; } } + return Ret; } -void INTERNAL_CALL +BOOL INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo) { PGDI_TABLE_ENTRY FromEntry; PW32THREAD Thread; HANDLE FromProcessId, FromLockedProcessId, FromPrevProcId; + BOOL Ret = TRUE; GDIDBG_INITLOOPTRACE(); @@ -1351,6 +1357,7 @@ LockHandleFrom: else { DPRINT1("Attempted to copy ownership from an object 0x%x currently being destroyed!!!\n", CopyFrom); + Ret = FALSE; } } else if (FromPrevProcId == FromLockedProcessId) @@ -1374,8 +1381,10 @@ LockHandleFrom: else { DPRINT1("Attempted to copy ownership from invalid handle: 0x%x\n", CopyFrom); + Ret = FALSE; } } + return Ret; } PVOID INTERNAL_CALL @@ -1410,6 +1419,60 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process) /** PUBLIC FUNCTIONS **********************************************************/ +BOOL +FASTCALL +IntGdiSetBrushOwner(PGDIBRUSHOBJ pbr, DWORD OwnerMask) +{ + // Inc/Dec share locks and process counts. + return TRUE; +} + + +BOOL +FASTCALL +IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush) +{ + PDC pDC; + BOOL Ret = FALSE; + + if (!hDC || (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)) return FALSE; + + if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE) + { + pDC = DC_LockDc ( hDC ); + MmCopyFromCaller(&pDC->Dc_Attr, pDC->pDc_Attr, sizeof(DC_ATTR)); + DC_UnlockDc( pDC ); + + DC_FreeDcAttr( hDC ); // Free the dcattr! + + if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible! + return Ret; + } + + if (OwnerMask == GDI_OBJ_HMGR_POWNED) + { + pDC = DC_LockDc ( hDC ); + if ( !pDC->pDc_Attr ) Ret = TRUE; // Must be zero. + DC_UnlockDc( pDC ); + if (!Ret) return Ret; + + if (!DC_SetOwnership( hDC, PsGetCurrentProcess() )) return Ret; + + DC_AllocateDcAttr( hDC ); // Allocate new dcattr + + DCU_SynchDcAttrtoUser( hDC ); // Copy data from dc to dcattr + } + + if ((OwnerMask != GDI_OBJ_HMGR_NONE) && !NoSetBrush) + { + pDC = DC_LockDc ( hDC ); + if (IntGdiSetBrushOwner((PGDIBRUSHOBJ)pDC->DcLevel.pbrFill, OwnerMask)) + IntGdiSetBrushOwner((PGDIBRUSHOBJ)pDC->DcLevel.pbrLine, OwnerMask); + DC_UnlockDc( pDC ); + } + return TRUE; +} + W32KAPI HANDLE APIENTRY @@ -1417,11 +1480,6 @@ NtGdiCreateClientObj( IN ULONG ulType ) { -// ATM we use DC object for KernelData. This is wrong. -// The real type consists of BASEOBJECT and a pointer. -// The UserData is set in user mode, so it is always NULL. -// HANDLE should be HGDIOBJ -// POBJ pObject; HANDLE handle; @@ -1521,13 +1579,6 @@ IntGdiGetObject(IN HANDLE Handle, } -BOOL -FASTCALL -IntGdiSetDCOwnerEx( HGDIOBJ hObject, DWORD OwnerMask, BOOL NoSetBrush) -{ - UNIMPLEMENTED; - return FALSE; -} W32KAPI INT diff --git a/reactos/subsystems/win32/win32k/objects/stockobj.c b/reactos/subsystems/win32/win32k/objects/stockobj.c index c2aa9a6311d..a0d3525b99a 100644 --- a/reactos/subsystems/win32/win32k/objects/stockobj.c +++ b/reactos/subsystems/win32/win32k/objects/stockobj.c @@ -19,7 +19,6 @@ /* * STOCKOBJ.C - GDI Stock Objects * - * $Id$ * */ @@ -66,11 +65,8 @@ static COLORREF SysColors[] = }; #define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0])) -//static HPEN SysColorPens[NUM_SYSCOLORS]; -//static HBRUSH SysColorBrushes[NUM_SYSCOLORS]; - -// System Bitmap DC and System Display DC... -HDC hSystemBM, hSystemDisplayDC; +// System Bitmap DC +HDC hSystemBM; /* GDI stock objects */