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
This commit is contained in:
James Tabor 2008-05-30 04:56:10 +00:00
parent a8585cf880
commit 87b264fba8
8 changed files with 336 additions and 39 deletions

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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 <debug.h>
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 */

View file

@ -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;
}

View file

@ -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;
}
//

View file

@ -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

View file

@ -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 */