diff --git a/reactos/config b/reactos/config index 5baab0c73d4..9e68061c28e 100644 --- a/reactos/config +++ b/reactos/config @@ -25,7 +25,7 @@ KDBG := 0 # # Whether to compile for debugging # -DBG := 0 +DBG := 1 # # Whether to compile with optimizations diff --git a/reactos/include/napi/win32.h b/reactos/include/napi/win32.h index 729220f1477..3807f97b7af 100644 --- a/reactos/include/napi/win32.h +++ b/reactos/include/napi/win32.h @@ -32,8 +32,8 @@ typedef struct _W32PROCESS LIST_ENTRY CursorIconListHead; struct _KBDTABLES* KeyboardLayout; ULONG Flags; - WORD GDIObjects; - WORD UserObjects; + LONG GDIObjects; + LONG UserObjects; } W32PROCESS, *PW32PROCESS; PW32THREAD STDCALL diff --git a/reactos/include/win32k/bitmaps.h b/reactos/include/win32k/bitmaps.h index 084519ed94c..a438eba6cd8 100644 --- a/reactos/include/win32k/bitmaps.h +++ b/reactos/include/win32k/bitmaps.h @@ -26,11 +26,12 @@ typedef struct _BITMAPOBJ /* Internal interface */ #define BITMAPOBJ_AllocBitmap() \ - ((HBITMAP) GDIOBJ_AllocObj (sizeof (BITMAPOBJ), GDI_OBJECT_TYPE_BITMAP, (GDICLEANUPPROC) Bitmap_InternalDelete)) + ((HBITMAP) GDIOBJ_AllocObj (GDI_OBJECT_TYPE_BITMAP)) #define BITMAPOBJ_FreeBitmap(hBMObj) \ - GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP, GDIOBJFLAG_DEFAULT) + GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP) #define BITMAPOBJ_LockBitmap(hBMObj) GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP) -#define BITMAPOBJ_UnlockBitmap(hBMObj) GDIOBJ_UnlockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP) +#define BITMAPOBJ_UnlockBitmap(hBMObj) GDIOBJ_UnlockObj((HGDIOBJ) hBMObj) +BOOL INTERNAL_CALL BITMAP_Cleanup(PVOID ObjectBody); INT FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp); HBITMAP FASTCALL BITMAPOBJ_CopyBitmap (HBITMAP hBitmap); @@ -38,7 +39,6 @@ INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth); int STDCALL DIB_GetDIBImageBytes (INT width, INT height, INT depth); INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse); INT STDCALL BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer); -BOOL FASTCALL Bitmap_InternalDelete( PBITMAPOBJ pBmp ); HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj, HDEV GDIDevice); HBITMAP FASTCALL IntCreateCompatibleBitmap(PDC Dc, INT Width, INT Height); diff --git a/reactos/include/win32k/brush.h b/reactos/include/win32k/brush.h index e191ec63e21..3f39a5ffe46 100644 --- a/reactos/include/win32k/brush.h +++ b/reactos/include/win32k/brush.h @@ -68,10 +68,11 @@ typedef struct #define GDIBRUSH_IS_MASKING 0x8000 /* Pattern bitmap is used as transparent mask (?) */ #define GDIBRUSH_CACHED_IS_SOLID 0x80000000 -#define BRUSHOBJ_AllocBrush() ((HBRUSH) GDIOBJ_AllocObj (sizeof(GDIBRUSHOBJ), GDI_OBJECT_TYPE_BRUSH, (GDICLEANUPPROC) Brush_InternalDelete)) -#define BRUSHOBJ_FreeBrush(hBrush) GDIOBJ_FreeObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH, GDIOBJFLAG_DEFAULT) +#define BRUSHOBJ_AllocBrush() ((HBRUSH) GDIOBJ_AllocObj (GDI_OBJECT_TYPE_BRUSH)) +#define BRUSHOBJ_FreeBrush(hBrush) GDIOBJ_FreeObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH) #define BRUSHOBJ_LockBrush(hBrush) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH)) -#define BRUSHOBJ_UnlockBrush(hBrush) GDIOBJ_UnlockObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH) +#define BRUSHOBJ_UnlockBrush(hBrush) GDIOBJ_UnlockObj((HGDIOBJ)hBrush) +BOOL INTERNAL_CALL BRUSH_Cleanup(PVOID ObjectBody); #ifdef __USE_W32API typedef struct _PATRECT { diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index f0733848462..0d5aedd7096 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -108,6 +108,26 @@ typedef struct _DC WIN_DC_INFO w; } DC, *PDC; +typedef struct _GDIPOINTER +{ + BOOL Enabled; + POINTL Pos; + SIZEL Size; + POINTL HotSpot; + + PGD_MOVEPOINTER MovePointer; + + XLATEOBJ *XlateObject; + HSURF ColorSurface; + HSURF MaskSurface; + HSURF SaveSurface; + + ULONG Status; + + BOOL SafetySwitch; + UINT SafetyRemoveCount; +} GDIPOINTER, *PGDIPOINTER; + typedef struct { HANDLE Handle; @@ -119,21 +139,7 @@ typedef struct DRIVER_FUNCTIONS DriverFunctions; PFILE_OBJECT VideoFileObject; - PGD_MOVEPOINTER MovePointer; - - struct { - BOOL Enable; - LONG Column; - LONG Row; - LONG Width; - LONG Height; - } PointerAttributes; - XLATEOBJ *PointerXlateObject; - HSURF PointerColorSurface; - HSURF PointerMaskSurface; - HSURF PointerSaveSurface; - POINTL PointerHotSpot; - ULONG PointerStatus; + GDIPOINTER Pointer; } GDIDEVICE; /* Internal functions */ @@ -141,16 +147,16 @@ typedef struct #define DC_LockDc(hDC) \ ((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC)) #define DC_UnlockDc(hDC) \ - GDIOBJ_UnlockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC) + GDIOBJ_UnlockObj ((HGDIOBJ) hDC) HDC FASTCALL RetrieveDisplayHDC(VOID); HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver); VOID FASTCALL DC_InitDC(HDC DCToInit); HDC FASTCALL DC_FindOpenDC(PUNICODE_STRING Driver); VOID FASTCALL DC_FreeDC(HDC DCToFree); +BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody); HDC FASTCALL DC_GetNextDC (PDC pDC); VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC); -BOOL FASTCALL DC_InternalDeleteDC( PDC DCToDelete ); VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); VOID FASTCALL DC_UpdateXforms(PDC dc); diff --git a/reactos/include/win32k/gdiobj.h b/reactos/include/win32k/gdiobj.h index b29164e1ce9..be4e9eb5e66 100644 --- a/reactos/include/win32k/gdiobj.h +++ b/reactos/include/win32k/gdiobj.h @@ -8,6 +8,26 @@ #include +/* base address where the handle table is mapped to */ +#define GDI_HANDLE_TABLE_BASE_ADDRESS (0x400000) + +/* gdi handle table can hold 0x4000 handles */ +#define GDI_HANDLE_COUNT 0x4000 + +#define GDI_GLOBAL_PROCESS (0x0) + +#define GDI_HANDLE_INDEX_MASK (GDI_HANDLE_COUNT - 1) +#define GDI_HANDLE_TYPE_MASK 0x007f0000 +#define GDI_HANDLE_STOCK_MASK 0x00800000 + +#define GDI_HANDLE_CREATE(i, t) ((HANDLE)(((i) & GDI_HANDLE_INDEX_MASK) | ((t) & GDI_HANDLE_TYPE_MASK))) +#define GDI_HANDLE_GET_INDEX(h) (((DWORD)(h)) & GDI_HANDLE_INDEX_MASK) +#define GDI_HANDLE_GET_TYPE(h) (((DWORD)(h)) & GDI_HANDLE_TYPE_MASK) +#define GDI_HANDLE_IS_TYPE(h, t) ((t) == (((DWORD)(h)) & GDI_HANDLE_TYPE_MASK)) +#define GDI_HANDLE_IS_STOCKOBJ(h) (0 != (((DWORD)(h)) & GDI_HANDLE_STOCK_MASK)) +#define GDI_HANDLE_SET_STOCKOBJ(h) ((h) = (HANDLE)(((DWORD)(h)) | GDI_HANDLE_STOCK_MASK)) + + /*! \defgroup GDI object types * * GDI object types @@ -35,28 +55,18 @@ typedef PVOID PGDIOBJ; -typedef BOOL (FASTCALL *GDICLEANUPPROC)(PGDIOBJ Obj); - -#define GDIOBJ_USE_FASTMUTEX +typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody); /*! * GDI object header. This is a part of any GDI object */ typedef struct _GDIOBJHDR { - DWORD dwCount; /* reference count for the object */ - HANDLE hProcessId; - GDICLEANUPPROC CleanupProc; - WORD wTableIndex; - WORD Magic; + PETHREAD LockingThread; /* only assigned if a thread is holding the lock! */ + ULONG Locks; +#ifdef GDI_DEBUG const char* lockfile; int lockline; -#ifdef GDIOBJ_USE_FASTMUTEX - FAST_MUTEX Lock; - DWORD RecursiveLockCount; -#else - DWORD LockTid; - DWORD LockCount; #endif } GDIOBJHDR, *PGDIOBJHDR; @@ -67,32 +77,41 @@ typedef struct _GDIMULTILOCK DWORD ObjectType; } GDIMULTILOCK, *PGDIMULTILOCK; -HGDIOBJ FASTCALL GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProcPtr); -BOOL STDCALL GDIOBJ_FreeObj (HGDIOBJ Obj, DWORD ObjectType, DWORD Flag); -PGDIOBJ FASTCALL GDIOBJ_LockObj (HGDIOBJ Obj, DWORD ObjectType); -BOOL FASTCALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj); -BOOL FASTCALL GDIOBJ_UnlockObj (HGDIOBJ Obj, DWORD ObjectType); -BOOL FASTCALL GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj); -DWORD FASTCALL GDIOBJ_GetObjectType(HGDIOBJ ObjectHandle); -BOOL FASTCALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle); -void FASTCALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner); -void FASTCALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo); -BOOL FASTCALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj); +HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObj(ULONG ObjectType); +BOOL INTERNAL_CALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj); +BOOL INTERNAL_CALL GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj); +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_ConvertToStockObj(HGDIOBJ *hObj); +BOOL INTERNAL_CALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj); + +#define GDIOBJ_GetObjectType(Handle) \ + GDI_HANDLE_GET_TYPE(Handle) + +#ifdef GDI_DEBUG /* a couple macros for debugging GDIOBJ locking */ +#define GDIOBJ_FreeObj(obj,ty) GDIOBJ_FreeObjDbg(__FILE__,__LINE__,obj,ty) #define GDIOBJ_LockObj(obj,ty) GDIOBJ_LockObjDbg(__FILE__,__LINE__,obj,ty) -#define GDIOBJ_UnlockObj(obj,ty) GDIOBJ_UnlockObjDbg(__FILE__,__LINE__,obj,ty) +#define GDIOBJ_UnlockObj(obj) GDIOBJ_UnlockObjDbg(__FILE__,__LINE__,obj) -#ifdef GDIOBJ_LockObj -PGDIOBJ FASTCALL GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ Obj, DWORD ObjectType); -#endif /* GDIOBJ_LockObj */ +BOOL INTERNAL_CALL GDIOBJ_FreeObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType); +PGDIOBJ INTERNAL_CALL GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType); +BOOL INTERNAL_CALL GDIOBJ_UnlockObjDbg (const char* file, int line, HGDIOBJ hObj); -#ifdef GDIOBJ_UnlockObj -BOOL FASTCALL GDIOBJ_UnlockObjDbg (const char* file, int line, HGDIOBJ Obj, DWORD ObjectType); -#endif /* GDIOBJ_UnlockObj */ +#else /* !GDI_DEBUG */ + +BOOL INTERNAL_CALL GDIOBJ_FreeObj (HGDIOBJ hObj, DWORD ObjectType); +PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType); +BOOL INTERNAL_CALL GDIOBJ_UnlockObj (HGDIOBJ hObj); + +#endif /* GDI_DEBUG */ #define GDIOBJFLAG_DEFAULT (0x0) #define GDIOBJFLAG_IGNOREPID (0x1) #define GDIOBJFLAG_IGNORELOCK (0x2) +PVOID INTERNAL_CALL GDI_MapHandleTable(HANDLE hProcess); + #endif diff --git a/reactos/include/win32k/kapi.h b/reactos/include/win32k/kapi.h index 7e6c30f2cb3..a37437a7ab4 100644 --- a/reactos/include/win32k/kapi.h +++ b/reactos/include/win32k/kapi.h @@ -1,5 +1,10 @@ #ifndef _WIN32K_KAPI_H #define _WIN32K_KAPI_H + +#ifndef INTERNAL_CALL +#define INTERNAL_CALL STDCALL +#endif + #include #include #include diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index f8043e3f65c..23b7f5326cd 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -212,6 +212,10 @@ NtUserCallOneParam( #define TWOPARAM_ROUTINE_SETCARETPOS 0x60 #define TWOPARAM_ROUTINE_GETWINDOWINFO 0x61 #define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0x62 +#define TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES 0x63 +#define TWOPARAM_ROUTINE_GETSYSCOLORPENS 0x64 +#define TWOPARAM_ROUTINE_GETSYSCOLORS 0x65 +#define TWOPARAM_ROUTINE_SETSYSCOLORS 0x66 DWORD STDCALL NtUserCallTwoParam( @@ -1805,17 +1809,13 @@ typedef struct tagKMDDELPARAM } Value; } KMDDELPARAM, *PKMDDELPARAM; -#include typedef struct _GDI_TABLE_ENTRY { - PVOID KernelData; /* Points to the kernel mode structure */ - unsigned short ProcessId; /* process id that created the object, 0 for stock objects */ - unsigned short Count; /* we don't use this field, only NT4 uses it */ - unsigned short Upper; /* copy of the upper 16 bit of the handle, contains the object type */ - unsigned short nType; /* object type */ - PVOID UserData; /* Points to the user mode structure, usually NULL though */ + PVOID KernelData; /* Points to the kernel mode structure */ + LONG ProcessId; /* process id that created the object, 0 for stock objects */ + LONG Type; /* the first 16 bit is the object type including the stock obj flag, the last 16 bits is just the object type */ + PVOID UserData; /* Points to the user mode structure, usually NULL though */ } GDI_TABLE_ENTRY, *PGDI_TABLE_ENTRY; -#include #endif /* __WIN32K_NTUSER_H */ diff --git a/reactos/include/win32k/pen.h b/reactos/include/win32k/pen.h index b934be08b0d..aaee161fe8b 100644 --- a/reactos/include/win32k/pen.h +++ b/reactos/include/win32k/pen.h @@ -6,10 +6,10 @@ /* Internal interface */ -#define PENOBJ_AllocPen() ((HPEN)GDIOBJ_AllocObj(sizeof(GDIBRUSHOBJ), GDI_OBJECT_TYPE_PEN, NULL)) -#define PENOBJ_FreePen(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN, GDIOBJFLAG_DEFAULT) +#define PENOBJ_AllocPen() ((HPEN)GDIOBJ_AllocObj(GDI_OBJECT_TYPE_PEN)) +#define PENOBJ_FreePen(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN) #define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)) -#define PENOBJ_UnlockPen(hBMObj) GDIOBJ_UnlockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN) +#define PENOBJ_UnlockPen(hBMObj) GDIOBJ_UnlockObj((HGDIOBJ) hBMObj) HPEN STDCALL NtGdiCreatePen( diff --git a/reactos/include/win32k/region.h b/reactos/include/win32k/region.h index 1a96f5b0a71..c2812115e2a 100644 --- a/reactos/include/win32k/region.h +++ b/reactos/include/win32k/region.h @@ -11,12 +11,11 @@ typedef struct _ROSRGNDATA { } ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA; -#define RGNDATA_FreeRgn(hRgn) GDIOBJ_FreeObj((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION, GDIOBJFLAG_DEFAULT) +#define RGNDATA_FreeRgn(hRgn) GDIOBJ_FreeObj((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION) #define RGNDATA_LockRgn(hRgn) ((PROSRGNDATA)GDIOBJ_LockObj((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION)) -#define RGNDATA_UnlockRgn(hRgn) GDIOBJ_UnlockObj((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION) +#define RGNDATA_UnlockRgn(hRgn) GDIOBJ_UnlockObj((HGDIOBJ)hRgn) HRGN FASTCALL RGNDATA_AllocRgn(INT n); - -BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA Obj ); +BOOL INTERNAL_CALL RGNDATA_Cleanup(PVOID ObjectBody); /* User entry points */ HRGN STDCALL diff --git a/reactos/include/win32k/text.h b/reactos/include/win32k/text.h index c75715483b3..2f15da1c667 100644 --- a/reactos/include/win32k/text.h +++ b/reactos/include/win32k/text.h @@ -6,16 +6,16 @@ typedef struct { LOGFONTW logfont; - HFONT GDIFontHandle; + FONTOBJ *Font; } TEXTOBJ, *PTEXTOBJ; /* Internal interface */ #define TEXTOBJ_AllocText() \ - ((HFONT) GDIOBJ_AllocObj (sizeof (TEXTOBJ), GDI_OBJECT_TYPE_FONT, NULL)) -#define TEXTOBJ_FreeText(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT, GDIOBJFLAG_DEFAULT) + ((HFONT) GDIOBJ_AllocObj (GDI_OBJECT_TYPE_FONT)) +#define TEXTOBJ_FreeText(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT) #define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT)) -#define TEXTOBJ_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT) +#define TEXTOBJ_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj) NTSTATUS FASTCALL TextIntRealizeFont(HFONT FontHandle); NTSTATUS FASTCALL TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont); diff --git a/reactos/lib/user32/include/user32.h b/reactos/lib/user32/include/user32.h index 498856815db..a9aba8750a0 100644 --- a/reactos/lib/user32/include/user32.h +++ b/reactos/lib/user32/include/user32.h @@ -30,10 +30,21 @@ typedef struct _THRDCARETINFO BYTE Showing; } THRDCARETINFO, *PTHRDCARETINFO; +void InitStockObjects(void); VOID CreateFrameBrushes(VOID); VOID DeleteFrameBrushes(VOID); void DrawCaret(HWND hWnd, PTHRDCARETINFO CaretInfo); +LONG WINAPI RegCloseKey(HKEY); +LONG WINAPI RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); +LONG WINAPI RegQueryValueExW(HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); + +#ifdef __USE_W32API +NTSTATUS STDCALL ZwCallbackReturn(PVOID Result, + ULONG ResultLength, + NTSTATUS Status); +#endif + #define NtUserAnyPopup() \ (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ANYPOPUP) @@ -61,6 +72,18 @@ void DrawCaret(HWND hWnd, PTHRDCARETINFO CaretInfo); #define NtUserRegisterLogonProcess(hproc, x) \ (BOOL)NtUserCallTwoParam((DWORD)hproc, (DWORD)x, TWOPARAM_ROUTINE_REGISTERLOGONPROC) +#define NtUserGetSysColorBrushes(HBrushes, count) \ + (BOOL)NtUserCallTwoParam((DWORD)(HBrushes), (DWORD)(count), TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES) + +#define NtUserGetSysColorPens(HPens, count) \ + (BOOL)NtUserCallTwoParam((DWORD)(HPens), (DWORD)(count), TWOPARAM_ROUTINE_GETSYSCOLORPENS) + +#define NtUserGetSysColors(ColorRefs, count) \ + (BOOL)NtUserCallTwoParam((DWORD)(ColorRefs), (DWORD)(count), TWOPARAM_ROUTINE_GETSYSCOLORS) + +#define NtUserSetSysColors(ColorRefs, count) \ + (BOOL)NtUserCallTwoParam((DWORD)(ColorRefs), (DWORD)(count), TWOPARAM_ROUTINE_SETSYSCOLORS) + #define NtUserSetCaretBlinkTime(uMSeconds) \ (BOOL)NtUserCallOneParam((DWORD)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME) @@ -100,12 +123,3 @@ void DrawCaret(HWND hWnd, PTHRDCARETINFO CaretInfo); #define NtUserEnableProcessWindowGhosting(bEnable) \ NtUserCallOneParam((DWORD)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING) -LONG WINAPI RegCloseKey(HKEY); -LONG WINAPI RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); -LONG WINAPI RegQueryValueExW(HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); - -#ifdef __USE_W32API -NTSTATUS STDCALL ZwCallbackReturn(PVOID Result, - ULONG ResultLength, - NTSTATUS Status); -#endif diff --git a/reactos/lib/user32/include/window.h b/reactos/lib/user32/include/window.h index 5a2707702e3..20a59ad4469 100644 --- a/reactos/lib/user32/include/window.h +++ b/reactos/lib/user32/include/window.h @@ -7,14 +7,37 @@ #include #include +extern COLORREF SysColors[]; +extern HPEN SysPens[]; +extern HBRUSH SysBrushes[]; + +#define NUM_SYSCOLORS 31 + #define IS_ATOM(x) \ (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) +#define UserHasAnyFrameStyle(Style, ExStyle) \ + (((Style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \ + ((ExStyle) & WS_EX_DLGMODALFRAME) || \ + (!((Style) & (WS_CHILD | WS_POPUP)))) + +#define UserHasDlgFrameStyle(Style, ExStyle) \ + (((ExStyle) & WS_EX_DLGMODALFRAME) || \ + (((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME)))) + +#define UserHasThickFrameStyle(Style, ExStyle) \ + (((Style) & WS_THICKFRAME) && \ + (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))) + +#define UserHasThinFrameStyle(Style, ExStyle) \ + (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP)))) + +#define UserHasBigFrameStyle(Style, ExStyle) \ + (((Style) & (WS_THICKFRAME | WS_DLGFRAME)) || \ + ((ExStyle) & WS_EX_DLGMODALFRAME)) + + BOOL UserDrawSysMenuButton( HWND hWnd, HDC hDC, LPRECT, BOOL down ); -ULONG -UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle); -ULONG -UserHasThickFrameStyle(ULONG Style, ULONG ExStyle); void UserGetFrameSize(ULONG Style, ULONG ExStyle, SIZE *Size); void diff --git a/reactos/lib/user32/misc/dllmain.c b/reactos/lib/user32/misc/dllmain.c index 8dee1fce82b..a8b4b5e8cab 100644 --- a/reactos/lib/user32/misc/dllmain.c +++ b/reactos/lib/user32/misc/dllmain.c @@ -76,6 +76,7 @@ Init(VOID) InitializeCriticalSection(&gcsMPH); GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); + InitStockObjects(); } VOID diff --git a/reactos/lib/user32/misc/stubs.c b/reactos/lib/user32/misc/stubs.c index 5de5bb0e74a..35e5b265f1c 100644 --- a/reactos/lib/user32/misc/stubs.c +++ b/reactos/lib/user32/misc/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.68 2004/11/16 16:27:48 blight Exp $ +/* $Id: stubs.c,v 1.69 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -143,21 +143,6 @@ RealMsgWaitForMultipleObjectsEx( } -/* - * @unimplemented - */ -BOOL -STDCALL -SetSysColors( - int cElements, - CONST INT *lpaElements, - CONST COLORREF *lpaRgbValues) -{ - UNIMPLEMENTED; - return FALSE; -} - - /* * @unimplemented */ diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index e976552b7b3..e3d2231625d 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.147 2004/11/19 23:07:09 gvg Exp $ +/* $Id: defwnd.c,v 1.148 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -41,70 +41,46 @@ void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG /* GLOBALS *******************************************************************/ -/* TODO: widgets will be cached here. -static HBITMAP hbClose; -static HBITMAP hbCloseD; -static HBITMAP hbMinimize; -static HBITMAP hbMinimizeD; -static HBITMAP hbRestore; -static HBITMAP hbRestoreD; -static HBITMAP hbMaximize; -static HBITMAP hbScrUp; -static HBITMAP hbScrDwn; -static HBITMAP hbScrLeft; -static HBITMAP hbScrRight; -*/ - - -static COLORREF SysColors[] = -{ - RGB(212, 208, 200), /* COLOR_SCROLLBAR */ - RGB(58, 110, 165), /* COLOR_BACKGROUND */ - RGB(10, 36, 106), /* COLOR_ACTIVECAPTION */ - RGB(128, 128, 128), /* COLOR_INACTIVECAPTION */ - RGB(212, 208, 200), /* COLOR_MENU */ - RGB(255, 255, 255), /* COLOR_WINDOW */ - RGB(0, 0, 0), /* COLOR_WINDOWFRAME */ - RGB(0, 0, 0), /* COLOR_MENUTEXT */ - RGB(0, 0, 0), /* COLOR_WINDOWTEXT */ - RGB(255, 255, 255), /* COLOR_CAPTIONTEXT */ - RGB(212, 208, 200), /* COLOR_ACTIVEBORDER */ - RGB(212, 208, 200), /* COLOR_INACTIVEBORDER */ - RGB(128, 128, 128), /* COLOR_APPWORKSPACE */ - RGB(10, 36, 106), /* COLOR_HIGHLIGHT */ - RGB(255, 255, 255), /* COLOR_HIGHLIGHTTEXT */ - RGB(212, 208, 200), /* COLOR_BTNFACE */ - RGB(128, 128, 128), /* COLOR_BTNSHADOW */ - RGB(128, 128, 128), /* COLOR_GRAYTEXT */ - RGB(0, 0, 0), /* COLOR_BTNTEXT */ - RGB(212, 208, 200), /* COLOR_INACTIVECAPTIONTEXT */ - RGB(255, 255, 255), /* COLOR_BTNHIGHLIGHT */ - RGB(64, 64, 64), /* COLOR_3DDKSHADOW */ - RGB(212, 208, 200), /* COLOR_3DLIGHT */ - RGB(0, 0, 0), /* COLOR_INFOTEXT */ - RGB(255, 255, 225), /* COLOR_INFOBK */ - RGB(181, 181, 181), /* COLOR_UNKNOWN */ - RGB(0, 0, 128), /* COLOR_HOTLIGHT */ - RGB(166, 202, 240), /* COLOR_GRADIENTACTIVECAPTION */ - RGB(192, 192, 192), /* COLOR_GRADIENTINACTIVECAPTION */ - RGB(49, 106, 197), /* COLOR_MENUHILIGHT */ - RGB(236, 233, 216) /* COLOR_MENUBAR */ -}; - -#define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0])) +static COLORREF SysColors[NUM_SYSCOLORS] = {0}; +static HPEN SysPens[NUM_SYSCOLORS] = {0}; +static HBRUSH SysBrushes[NUM_SYSCOLORS] = {0}; /* Bits in the dwKeyData */ #define KEYDATA_ALT 0x2000 /* FUNCTIONS *****************************************************************/ +void +InitStockObjects(void) +{ + /* FIXME - Instead of copying the stuff to usermode we should map the tables to + userland. The current implementation has one big flaw: the system color + table doesn't get updated when another process changes them. That's why + we should rather map the table into usermode. But it only affects the + SysColors table - the pens, brushes and stock objects are not affected + as their handles never change. But it'd be faster to map them, too. */ + if(SysBrushes[0] == NULL) + { + /* only initialize once */ + NtUserGetSysColors(SysColors, NUM_SYSCOLORS); + NtUserGetSysColorPens(SysPens, NUM_SYSCOLORS); + NtUserGetSysColorBrushes(SysBrushes, NUM_SYSCOLORS); + } +} + /* * @implemented */ DWORD STDCALL GetSysColor(int nIndex) { + if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS) + { return SysColors[nIndex]; + } + + SetLastError(ERROR_INVALID_PARAMETER); + return 0; } /* @@ -113,22 +89,13 @@ GetSysColor(int nIndex) HPEN STDCALL GetSysColorPen(int nIndex) { - static HPEN SysPens[NUM_SYSCOLORS]; + if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS) + { + return SysPens[nIndex]; + } - if (nIndex < 0 || NUM_SYSCOLORS < nIndex) - { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - /* FIXME should register this object with DeleteObject() so it - can't be deleted */ - if (NULL == SysPens[nIndex]) - { - SysPens[nIndex] = CreatePen(PS_SOLID, 1, SysColors[nIndex]); - } - - return SysPens[nIndex]; + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; } /* @@ -137,89 +104,51 @@ GetSysColorPen(int nIndex) HBRUSH STDCALL GetSysColorBrush(int nIndex) { - static HBRUSH SysBrushes[NUM_SYSCOLORS]; + if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS) + { + return SysBrushes[nIndex]; + } - if (nIndex < 0 || NUM_SYSCOLORS < nIndex) - { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - /* FIXME should register this object with DeleteObject() so it - can't be deleted */ - if (NULL == SysBrushes[nIndex]) - { - SysBrushes[nIndex] = (HBRUSH) ((DWORD) CreateSolidBrush(SysColors[nIndex]) | 0x00800000); - } - - return SysBrushes[nIndex]; + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; } /* - * @unimplemented + * @implemented */ -/* -LRESULT STDCALL -DefFrameProcA( HWND hWnd, - HWND hWndMDIClient, - UINT uMsg, - WPARAM wParam, - LPARAM lParam ) +BOOL +STDCALL +SetSysColors( + int cElements, + CONST INT *lpaElements, + CONST COLORREF *lpaRgbValues) { - UNIMPLEMENTED; - return ((LRESULT)0); -} -*/ + BOOL Ret; + struct + { + INT *Elements; + COLORREF *Colors; + } ChangeSysColors; -/* - * @unimplemented - */ -/* -LRESULT STDCALL -DefFrameProcW(HWND hWnd, - HWND hWndMDIClient, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - UNIMPLEMENTED; - return ((LRESULT)0); -} -*/ - -ULONG -UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle) -{ - return ((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || - (ExStyle & WS_EX_DLGMODALFRAME) || - (!(Style & (WS_CHILD | WS_POPUP)))); -} - -ULONG -UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle) -{ - return ((ExStyle & WS_EX_DLGMODALFRAME) || - ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME)))); -} - -ULONG -UserHasThickFrameStyle(ULONG Style, ULONG ExStyle) -{ - return ((Style & WS_THICKFRAME) && - (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))); -} - -ULONG -UserHasThinFrameStyle(ULONG Style, ULONG ExStyle) -{ - return ((Style & WS_BORDER) || (!(Style & (WS_CHILD | WS_POPUP)))); -} - -ULONG -UserHasBigFrameStyle(ULONG Style, ULONG ExStyle) -{ - return ((Style & (WS_THICKFRAME | WS_DLGFRAME)) || - (ExStyle & WS_EX_DLGMODALFRAME)); + ChangeSysColors.Elements = (INT*)lpaElements; + ChangeSysColors.Colors = (COLORREF*)lpaRgbValues; + + if(cElements > 0) + { + Ret = NtUserSetSysColors(&ChangeSysColors, cElements); + if(Ret) + { + /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */ + NtUserGetSysColors(SysColors, NUM_SYSCOLORS); + } + } + else + { + SetLastError(ERROR_INVALID_PARAMETER); + Ret = FALSE; + } + + return Ret; } void diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index 30ce8fc26ab..ddc599f28d6 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.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: bitblt.c,v 1.58 2004/07/14 20:48:57 navaraf Exp $ +/* $Id: bitblt.c,v 1.59 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -89,8 +89,9 @@ BltMask(SURFOBJ* Dest, static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; /* Pattern brushes */ PGDIBRUSHINST GdiBrush = NULL; - HBITMAP PatternSurface = NULL; + HBITMAP PatternSurface; SURFOBJ *PatternObj = NULL; + PBITMAPOBJ PatternBitmap; ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0; if (Mask == NULL) @@ -103,8 +104,6 @@ BltMask(SURFOBJ* Dest, if (Brush->iSolidColor == 0xFFFFFFFF) { - PBITMAPOBJ PatternBitmap; - GdiBrush = CONTAINING_RECORD( Brush, GDIBRUSHINST, @@ -112,11 +111,15 @@ BltMask(SURFOBJ* Dest, PatternSurface = GdiBrush->GdiBrushObject->hbmPattern; PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern); - - PatternObj = &PatternBitmap->SurfObj; - PatternWidth = PatternObj->sizlBitmap.cx; - PatternHeight = PatternObj->sizlBitmap.cy; + if(PatternBitmap != NULL) + { + PatternObj = &PatternBitmap->SurfObj; + PatternWidth = PatternObj->sizlBitmap.cx; + PatternHeight = PatternObj->sizlBitmap.cy; + } } + else + PatternBitmap = NULL; tMask = Mask->pvScan0 + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3); for (j = 0; j < dy; j++) @@ -124,14 +127,14 @@ BltMask(SURFOBJ* Dest, lMask = tMask; c8 = SourcePoint->x & 0x07; - if(PatternSurface) + if(PatternBitmap != NULL) PatternY = (DestRect->top + j) % PatternHeight; for (i = 0; i < dx; i++) { if (0 != (*lMask & maskbit[c8])) { - if (PatternSurface == NULL) + if (PatternBitmap == NULL) { DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel( Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor); @@ -153,7 +156,7 @@ BltMask(SURFOBJ* Dest, tMask += Mask->lDelta; } - if (PatternSurface != NULL) + if (PatternBitmap != NULL) BITMAPOBJ_UnlockBitmap(PatternSurface); return TRUE; @@ -222,15 +225,25 @@ CallDibBitBlt(SURFOBJ* OutputObj, if (ROP_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF) { GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject); - bmPattern = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern); - BltInfo.PatternSurface = &bmPattern->SurfObj; + if((bmPattern = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern))) + { + BltInfo.PatternSurface = &bmPattern->SurfObj; + } + else + { + /* FIXME - What to do here? */ + } BltInfo.XlatePatternToDest = GdiBrush->XlateObject; } + else + { + bmPattern = NULL; + } Result = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBlt(&BltInfo); /* Pattern brush */ - if (ROP_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF) + if (bmPattern != NULL) { BITMAPOBJ_UnlockBitmap(BltInfo.PatternSurface->hsurf); } diff --git a/reactos/subsys/win32k/eng/clip.c b/reactos/subsys/win32k/eng/clip.c index a54700834dc..02cfff9c84a 100644 --- a/reactos/subsys/win32k/eng/clip.c +++ b/reactos/subsys/win32k/eng/clip.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: clip.c,v 1.22 2004/05/30 14:01:12 weiden Exp $ +/* $Id: clip.c,v 1.23 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -28,83 +28,7 @@ */ #include -VOID STDCALL IntEngDeleteClipRegion(CLIPOBJ *ClipObj) -{ - HCLIP HClip = AccessHandleFromUserObject(ClipObj); - FreeGDIHandle(HClip); -} - -CLIPOBJ* STDCALL -IntEngCreateClipRegion(ULONG count, PRECTL pRect, PRECTL rcBounds) -{ - HCLIP hClip; - CLIPGDI* clipInt; - CLIPOBJ* clipUser; - - DPRINT("IntEngCreateClipRegion count: %d\n", count); - if (1 < count) - { - hClip = (HCLIP) CreateGDIHandle(sizeof(CLIPGDI) + count * sizeof(RECTL), - sizeof(CLIPOBJ), (PVOID*)&clipInt, (PVOID*)&clipUser); - - if (hClip) - { - RtlCopyMemory(clipInt->EnumRects.arcl, pRect, count * sizeof(RECTL)); - clipInt->EnumRects.c = count; - clipInt->EnumOrder = CD_ANY; - - clipUser->iDComplexity = DC_COMPLEX; - clipUser->iFComplexity = (count <= 4) ? FC_RECT4: FC_COMPLEX; - clipUser->iMode = TC_RECTANGLES; - RtlCopyMemory(&(clipUser->rclBounds), rcBounds, sizeof(RECTL)); - - return clipUser; - } - } - else - { - hClip = (HCLIP) CreateGDIHandle(sizeof(CLIPGDI), - sizeof(CLIPOBJ), - (PVOID)&clipInt, (PVOID)&clipUser); - if (hClip) - { - RtlCopyMemory(clipInt->EnumRects.arcl, rcBounds, sizeof(RECTL)); - clipInt->EnumRects.c = 1; - clipInt->EnumOrder = CD_ANY; - - clipUser->iDComplexity = ((rcBounds->top==rcBounds->bottom) - && (rcBounds->left==rcBounds->right)) - ? DC_TRIVIAL : DC_RECT; - clipUser->iFComplexity = FC_RECT; - clipUser->iMode = TC_RECTANGLES; - DPRINT("IntEngCreateClipRegion: iDComplexity: %d\n", clipUser->iDComplexity); - RtlCopyMemory(&(clipUser->rclBounds), rcBounds, sizeof(RECTL)); - return clipUser; - } - } - - return NULL; -} - -/* - * @implemented - */ -CLIPOBJ * STDCALL -EngCreateClip(VOID) -{ - return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), 0); -} - -/* - * @implemented - */ -VOID STDCALL -EngDeleteClip(CLIPOBJ *ClipRegion) -{ - EngFreeMem(ClipRegion); -} - -static int +static inline int CompareRightDown(const PRECT r1, const PRECT r2) { int Cmp; @@ -117,7 +41,7 @@ CompareRightDown(const PRECT r1, const PRECT r2) { Cmp = +1; } - else + else { ASSERT(r1->bottom == r2->bottom); if (r1->left < r2->left) @@ -138,7 +62,7 @@ CompareRightDown(const PRECT r1, const PRECT r2) return Cmp; } -static int +static inline int CompareRightUp(const PRECT r1, const PRECT r2) { int Cmp; @@ -151,7 +75,7 @@ CompareRightUp(const PRECT r1, const PRECT r2) { Cmp = -1; } - else + else { ASSERT(r1->top == r2->top); if (r1->left < r2->left) @@ -172,7 +96,7 @@ CompareRightUp(const PRECT r1, const PRECT r2) return Cmp; } -static int +static inline int CompareLeftDown(const PRECT r1, const PRECT r2) { int Cmp; @@ -185,7 +109,7 @@ CompareLeftDown(const PRECT r1, const PRECT r2) { Cmp = +1; } - else + else { ASSERT(r1->bottom == r2->bottom); if (r1->right < r2->right) @@ -206,7 +130,7 @@ CompareLeftDown(const PRECT r1, const PRECT r2) return Cmp; } -static int +static inline int CompareLeftUp(const PRECT r1, const PRECT r2) { int Cmp; @@ -219,7 +143,7 @@ CompareLeftUp(const PRECT r1, const PRECT r2) { Cmp = -1; } - else + else { ASSERT(r1->top == r2->top); if (r1->right < r2->right) @@ -240,6 +164,122 @@ CompareLeftUp(const PRECT r1, const PRECT r2) return Cmp; } +static inline int +CompareSpans(const PSPAN Span1, const PSPAN Span2) +{ + int Cmp; + + if (Span1->Y < Span2->Y) + { + Cmp = -1; + } + else if (Span2->Y < Span1->Y) + { + Cmp = +1; + } + else + { + if (Span1->X < Span2->X) + { + Cmp = -1; + } + else if (Span2->X < Span1->X) + { + Cmp = +1; + } + else + { + Cmp = 0; + } + } + + return Cmp; +} + +VOID FASTCALL +IntEngDeleteClipRegion(CLIPOBJ *ClipObj) +{ + EngFreeMem(ObjToGDI(ClipObj, CLIP)); +} + +CLIPOBJ* FASTCALL +IntEngCreateClipRegion(ULONG count, PRECTL pRect, PRECTL rcBounds) +{ + CLIPGDI *Clip; + + if(count > 1) + { + RECTL *dest; + + Clip = EngAllocMem(0, sizeof(CLIPGDI) + ((count - 1) * sizeof(RECTL)), TAG_CLIPOBJ); + + if(Clip != NULL) + { + Clip->EnumRects.c = count; + Clip->EnumOrder = CD_ANY; + for(dest = Clip->EnumRects.arcl; + count > 0; + count--, dest++, pRect++) + { + *dest = *pRect; + } + + Clip->ClipObj.iDComplexity = DC_COMPLEX; + Clip->ClipObj.iFComplexity = ((Clip->EnumRects.c <= 4) ? FC_RECT4 : FC_COMPLEX); + Clip->ClipObj.iMode = TC_RECTANGLES; + Clip->ClipObj.rclBounds = *rcBounds; + + return GDIToObj(Clip, CLIP); + } + } + else + { + Clip = EngAllocMem(0, sizeof(CLIPGDI), TAG_CLIPOBJ); + + if(Clip != NULL) + { + Clip->EnumRects.c = 1; + Clip->EnumOrder = CD_ANY; + Clip->EnumRects.arcl[0] = *rcBounds; + + Clip->ClipObj.iDComplexity = (((rcBounds->top == rcBounds->bottom) && + (rcBounds->left == rcBounds->right)) + ? DC_TRIVIAL : DC_RECT); + Clip->ClipObj.iFComplexity = FC_RECT; + Clip->ClipObj.iMode = TC_RECTANGLES; + Clip->ClipObj.rclBounds = *rcBounds; + + return GDIToObj(Clip, CLIP); + } + } + + return NULL; +} + +/* + * @implemented + */ +CLIPOBJ * STDCALL +EngCreateClip(VOID) +{ + CLIPGDI *Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), TAG_CLIPOBJ); + if(Clip != NULL) + { + return GDIToObj(Clip, CLIP); + } + + return NULL; +} + +/* + * @implemented + */ +VOID STDCALL +EngDeleteClip(CLIPOBJ *ClipRegion) +{ + EngFreeMem(ObjToGDI(ClipRegion, CLIP)); +} + /* * @implemented */ @@ -250,7 +290,7 @@ CLIPOBJ_cEnumStart(IN CLIPOBJ* ClipObj, IN ULONG BuildOrder, IN ULONG MaxRects) { - CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj); + CLIPGDI *ClipGDI = ObjToGDI(ClipObj, CLIP); SORTCOMP CompareFunc; ClipGDI->EnumPos = 0; @@ -305,8 +345,9 @@ CLIPOBJ_bEnum(IN CLIPOBJ* ClipObj, IN ULONG ObjSize, OUT ULONG *EnumRects) { - CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj); - ULONG nCopy; + RECTL *dest, *src; + CLIPGDI *ClipGDI = ObjToGDI(ClipObj, CLIP); + ULONG nCopy, i; ENUMRECTS* pERects = (ENUMRECTS*)EnumRects; //calculate how many rectangles we should copy @@ -317,8 +358,16 @@ CLIPOBJ_bEnum(IN CLIPOBJ* ClipObj, { return FALSE; } - RtlCopyMemory( pERects->arcl, ClipGDI->EnumRects.arcl + ClipGDI->EnumPos, - nCopy * sizeof(RECTL) ); + + /* copy rectangles */ + src = ClipGDI->EnumRects.arcl + ClipGDI->EnumPos; + for(i = 0, dest = pERects->arcl; + i < nCopy; + i++, dest++, src++) + { + *dest = *src; + } + pERects->c = nCopy; ClipGDI->EnumPos+=nCopy; @@ -326,38 +375,6 @@ CLIPOBJ_bEnum(IN CLIPOBJ* ClipObj, return ClipGDI->EnumPos < ClipGDI->EnumRects.c; } -static int -CompareSpans(const PSPAN Span1, const PSPAN Span2) -{ - int Cmp; - - if (Span1->Y < Span2->Y) - { - Cmp = -1; - } - else if (Span2->Y < Span1->Y) - { - Cmp = +1; - } - else - { - if (Span1->X < Span2->X) - { - Cmp = -1; - } - else if (Span2->X < Span1->X) - { - Cmp = +1; - } - else - { - Cmp = 0; - } - } - - return Cmp; -} - BOOLEAN FASTCALL ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary) { @@ -418,7 +435,14 @@ ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary) } if (0 != *Count) { - RtlCopyMemory(NewSpans, *Spans, *Count * sizeof(SPAN)); + PSPAN dest, src; + UINT i = *Count; + for(dest = NewSpans, src = *Spans; + i > 0; + i--) + { + *dest++ = *src++; + } ExFreePool(*Spans); } *Spans = NewSpans; diff --git a/reactos/subsys/win32k/eng/clip.h b/reactos/subsys/win32k/eng/clip.h deleted file mode 100644 index dc0d079c9fe..00000000000 --- a/reactos/subsys/win32k/eng/clip.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __WIN32K_CLIP_H -#define __WIN32K_CLIP_H - -typedef ULONG HCLIP; -CLIPOBJ* STDCALL IntEngCreateClipRegion( ULONG count, PRECTL pRect, PRECTL rcBounds ); -VOID STDCALL IntEngDeleteClipRegion(CLIPOBJ *ClipObj); - - -#define ENUM_RECT_LIMIT 50 - -typedef struct _RECT_ENUM -{ - ULONG c; - RECTL arcl[ENUM_RECT_LIMIT]; -} RECT_ENUM; - -typedef struct tagSPAN -{ - LONG Y; - LONG X; - ULONG Width; -} SPAN, *PSPAN; - -BOOLEAN FASTCALL ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary); - -#endif diff --git a/reactos/subsys/win32k/eng/handle.c b/reactos/subsys/win32k/eng/handle.c deleted file mode 100644 index 825a45cb378..00000000000 --- a/reactos/subsys/win32k/eng/handle.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id: handle.c,v 1.16 2004/05/30 14:01:12 weiden Exp $ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Manage GDI Handles - * FILE: subsys/win32k/eng/handle.c - * PROGRAMER: Jason Filby - * REVISION HISTORY: - * 29/8/1999: Created - */ -#include - -static int LastHandle = MAX_GDI_HANDLES; -static GDI_HANDLE GDIHandles[MAX_GDI_HANDLES]; - -ULONG FASTCALL CreateGDIHandle(ULONG InternalSize, ULONG UserSize, PVOID *InternalObject, PVOID *UserObject) -{ - PENGOBJ pObj; - int i; - - /* internal size includes header and user portions */ - pObj = EngAllocMem( FL_ZERO_MEMORY, InternalSize, 0 ); - - if( !pObj ) - return 0; - - #if 0 - /* not used at the moment */ - pObj->InternalSize = InternalSize; - pObj->UserSize = UserSize; - #endif - - for( i = (MAX_GDI_HANDLES - 1 <= LastHandle ? 1 : LastHandle + 1); i != LastHandle; - i = (MAX_GDI_HANDLES - 1 <= i ? 1 : i + 1) ){ - if( GDIHandles[ i ].pEngObj == NULL ){ - pObj->hObj = i; - GDIHandles[ i ].pEngObj = pObj; - - *InternalObject = pObj; - *UserObject = (PVOID)( (PCHAR)pObj + sizeof( ENGOBJ ) ); - - DPRINT("CreateGDIHandle: obj: %x, handle: %d, usersize: %d\n", pObj, i, UserSize ); - LastHandle = i; - return i; - } - } - DPRINT1("CreateGDIHandle: Out of available handles!!!\n"); - EngFreeMem( pObj ); - return 0; -} - -VOID FASTCALL FreeGDIHandle(ULONG Handle) -{ - if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT1("FreeGDIHandle: invalid handle!!!!\n"); - return; - } - DPRINT("FreeGDIHandle: handle: %d\n", Handle); - EngFreeMem( GDIHandles[Handle].pEngObj ); - GDIHandles[Handle].pEngObj = NULL; -} - -PVOID FASTCALL AccessInternalObject(ULONG Handle) -{ - PENGOBJ pEngObj; - - if (Handle == 0 || Handle >= MAX_GDI_HANDLES - || !(pEngObj = GDIHandles[Handle].pEngObj)) - { - DPRINT1("AccessInternalObject: invalid handle: %d!!!!\n", Handle); - return NULL; - } - - return (PVOID)pEngObj; -} - -PVOID FASTCALL AccessUserObject(ULONG Handle) -{ - PENGOBJ pEngObj; - - if (Handle == 0 || Handle >= MAX_GDI_HANDLES - || !(pEngObj = GDIHandles[Handle].pEngObj)) - { - DPRINT1("AccessUserObject: invalid handle: %d!!!!\n", Handle); - return NULL; - } - - return (PVOID)( (PCHAR)pEngObj + sizeof( ENGOBJ ) ); -} - -ULONG FASTCALL AccessHandleFromUserObject(PVOID UserObject) -{ - PENGOBJ pEngObj; - ULONG Handle; - - if( !UserObject ) - return INVALID_HANDLE; - - pEngObj = (PENGOBJ)((PCHAR) UserObject - sizeof( ENGOBJ )); - Handle = pEngObj->hObj; - - if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT1("AccessHandleFromUserObject: inv handle: %d, obj: %x!!!!\n", Handle, pEngObj); - return INVALID_HANDLE; - } - return Handle; -} - -VOID FASTCALL InitEngHandleTable( void ) -{ - ULONG i; - for( i=1; i < MAX_GDI_HANDLES; i++ ){ - GDIHandles[ i ].pEngObj = NULL; - } -} -/* EOF */ diff --git a/reactos/subsys/win32k/eng/handle.h b/reactos/subsys/win32k/eng/handle.h deleted file mode 100644 index 6d790cfd17b..00000000000 --- a/reactos/subsys/win32k/eng/handle.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id: handle.h,v 1.6 2004/05/30 14:01:12 weiden Exp $ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Manage GDI Handle definitions - * FILE: subsys/win32k/eng/handle.h - * PROGRAMER: Jason Filby - * REVISION HISTORY: - * 29/8/1999: Created - */ -#ifndef __ENG_HANDLE_H -#define __ENG_HANDLE_H - -#include "objects.h" -#include - -typedef struct _GDI_HANDLE { - PENGOBJ pEngObj; -} GDI_HANDLE, *PGDI_HANDLE; - -#define INVALID_HANDLE 0 -#define MAX_GDI_HANDLES 4096 - -#define ValidEngHandle( x ) (!( (x) == INVALID_HANDLE )) - -#endif diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index d97947ebf5d..99ffdeba280 100644 --- a/reactos/subsys/win32k/eng/mouse.c +++ b/reactos/subsys/win32k/eng/mouse.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: mouse.c,v 1.77 2004/07/30 09:42:11 weiden Exp $ +/* $Id: mouse.c,v 1.78 2004/12/12 01:40:36 weiden Exp $ * * PROJECT: ReactOS kernel * PURPOSE: Mouse @@ -30,64 +30,7 @@ /* FUNCTIONS *****************************************************************/ -BOOL FASTCALL -IntIsPrimarySurface(SURFOBJ *SurfObj); - -VOID FASTCALL -EnableMouse(HDC hDisplayDC) -{ - PDC dc; - BITMAPOBJ *BitmapObj; - GDIDEVICE *GdiDev; - PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo(InputWindowStation); - - if( hDisplayDC && InputWindowStation) - { - if(!IntGetWindowStationObject(InputWindowStation)) - { - CurInfo->Enabled = FALSE; - return; - } - - dc = DC_LockDc(hDisplayDC); - ASSERT(dc); - BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); - ASSERT(BitmapObj); - - /* Move the cursor to the screen center */ - DPRINT("Setting Cursor up at 0x%x, 0x%x\n", SurfObj->sizlBitmap.cx / 2, SurfObj->sizlBitmap.cy / 2); - ExAcquireFastMutex(&CurInfo->CursorMutex); - CurInfo->x = BitmapObj->SurfObj.sizlBitmap.cx / 2; - CurInfo->y = BitmapObj->SurfObj.sizlBitmap.cy / 2; - ExReleaseFastMutex(&CurInfo->CursorMutex); - - GdiDev = GDIDEV(&BitmapObj->SurfObj); - BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); - DC_UnlockDc( hDisplayDC ); - - IntSetCursor(InputWindowStation, NULL, TRUE); - - CurInfo->Enabled = (SPS_ACCEPT_EXCLUDE == GdiDev->PointerStatus || - SPS_ACCEPT_NOEXCLUDE == GdiDev->PointerStatus); - - IntLoadDefaultCursors(); - - ObDereferenceObject(InputWindowStation); - } - else - { - if(IntGetWindowStationObject(InputWindowStation)) - { - IntSetCursor(InputWindowStation, NULL, TRUE); - CurInfo->Enabled = FALSE; - CurInfo->CursorClipInfo.IsClipped = FALSE; - ObDereferenceObject(InputWindowStation); - return; - } - } -} - -INT FASTCALL +INT INTERNAL_CALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2) /* @@ -96,45 +39,25 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, */ { LONG tmp; - PSYSTEM_CURSORINFO CurInfo; - BOOL MouseEnabled = FALSE; - PCURICON_OBJECT Cursor; + GDIDEVICE *ppdev; + GDIPOINTER *pgp; + POINTL pt; + ASSERT(SurfObj != NULL); - /* Mouse is not allowed to move if GDI is busy drawing */ - - if(IntGetWindowStationObject(InputWindowStation)) - { - CurInfo = IntGetSysCursorInfo(InputWindowStation); - - MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor; - } - else - return FALSE; - - if (SurfObj == NULL) + ppdev = GDIDEV(SurfObj); + + if(ppdev == NULL) { - ObDereferenceObject(InputWindowStation); - return(FALSE); - } - if (!IntIsPrimarySurface(SurfObj) || MouseEnabled == FALSE) - { - ObDereferenceObject(InputWindowStation); - return(FALSE); - } - - if (SPS_ACCEPT_NOEXCLUDE == GDIDEV(SurfObj)->PointerStatus) - { - /* Hardware cursor, no need to remove it */ - ObDereferenceObject(InputWindowStation); return(FALSE); } - if(!(Cursor = CurInfo->CurrentCursorObject)) - { - ObDereferenceObject(InputWindowStation); - return(FALSE); - } + pgp = &ppdev->Pointer; + + if (SPS_ACCEPT_NOEXCLUDE == pgp->Status) + { + return(FALSE); + } if (HazardX1 > HazardX2) { @@ -145,182 +68,174 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; } - if (CurInfo->PointerRectRight >= HazardX1 - && CurInfo->PointerRectLeft <= HazardX2 - && CurInfo->PointerRectBottom >= HazardY1 - && CurInfo->PointerRectTop <= HazardY2) + pt.x = pgp->Pos.x - pgp->HotSpot.x; + pt.y = pgp->Pos.y - pgp->HotSpot.y; + + if (pt.x + pgp->Size.cx >= HazardX1 + && pt.x <= HazardX2 + && pt.y + pgp->Size.cy >= HazardY1 + && pt.y <= HazardY2) { - /* Mouse is not allowed to move if GDI is busy drawing */ - ExAcquireFastMutex(&CurInfo->CursorMutex); - if (0 != CurInfo->SafetyRemoveCount++) + if (0 != pgp->SafetyRemoveCount++) { - /* Was already removed */ - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); return FALSE; } - CurInfo->SafetySwitch = TRUE; - if (GDIDEVFUNCS(SurfObj).MovePointer) - GDIDEVFUNCS(SurfObj).MovePointer(SurfObj, -1, -1, NULL); + pgp->SafetySwitch = TRUE; + if (pgp->MovePointer) + pgp->MovePointer(SurfObj, -1, -1, NULL); else - EngMovePointer(SurfObj, -1, -1, NULL); - ExReleaseFastMutex(&CurInfo->CursorMutex); + EngMovePointer(SurfObj, -1, -1, NULL); } - - ObDereferenceObject(InputWindowStation); + return(TRUE); } -VOID FASTCALL -SetPointerRect(PSYSTEM_CURSORINFO CurInfo, PRECTL PointerRect) -{ - CurInfo->PointerRectLeft = PointerRect->left; - CurInfo->PointerRectRight = PointerRect->right; - CurInfo->PointerRectTop = PointerRect->top; - CurInfo->PointerRectBottom = PointerRect->bottom; -} - -INT FASTCALL +INT INTERNAL_CALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj) /* * FUNCTION: Notify the mouse driver that drawing has finished on a surface. */ { - PSYSTEM_CURSORINFO CurInfo; - BOOL MouseEnabled = FALSE; - RECTL PointerRect; - - if(IntGetWindowStationObject(InputWindowStation)) - { - CurInfo = IntGetSysCursorInfo(InputWindowStation); - } - else - return FALSE; - - ExAcquireFastMutex(&CurInfo->CursorMutex); - if(SurfObj == NULL) - { - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); - return FALSE; - } + GDIDEVICE *ppdev; + GDIPOINTER *pgp; + + ASSERT(SurfObj != NULL); + + ppdev = GDIDEV(SurfObj); - MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor; - if (!IntIsPrimarySurface(SurfObj) || MouseEnabled == FALSE) + if(ppdev == NULL) { - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); return(FALSE); } - if (SPS_ACCEPT_NOEXCLUDE == GDIDEV(SurfObj)->PointerStatus) + pgp = &ppdev->Pointer; + + if(SPS_ACCEPT_NOEXCLUDE == pgp->Status) + { + return FALSE; + } + + if (pgp->SafetySwitch) { - /* Hardware cursor, it wasn't removed so need to restore it */ - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); - return(FALSE); - } - - if (CurInfo->SafetySwitch) - { - if (1 < CurInfo->SafetyRemoveCount--) + if (1 < pgp->SafetyRemoveCount--) { /* Someone else removed it too, let them restore it */ - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); return FALSE; } - if (GDIDEVFUNCS(SurfObj).MovePointer) - GDIDEVFUNCS(SurfObj).MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect); + if (pgp->MovePointer) + pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL); else - EngMovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect); - SetPointerRect(CurInfo, &PointerRect); - CurInfo->SafetySwitch = FALSE; + EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL); + pgp->SafetySwitch = FALSE; } - ExReleaseFastMutex(&CurInfo->CursorMutex); - ObDereferenceObject(InputWindowStation); return(TRUE); } /* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/ -VOID FASTCALL +VOID INTERNAL_CALL IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface) { - if (ppdev->PointerAttributes.Enable == FALSE) + GDIPOINTER *pgp; + POINTL pt; + + ASSERT(ppdev); + ASSERT(DestSurface); + + pgp = &ppdev->Pointer; + + if (!pgp->Enabled) { return; } - ppdev->PointerAttributes.Enable = FALSE; - - if (ppdev->PointerAttributes.Column + ppdev->PointerHotSpot.x == -1) + pgp->Enabled = FALSE; + + if(pgp->Pos.x == -1) { return; } + + pt.x = pgp->Pos.x - pgp->HotSpot.x; + pt.y = pgp->Pos.y - pgp->HotSpot.y; - if (ppdev->PointerSaveSurface != NULL) + if (pgp->SaveSurface != NULL) { RECTL DestRect; POINTL SrcPoint; SURFOBJ *SaveSurface; SURFOBJ *MaskSurface; - DestRect.left = max(ppdev->PointerAttributes.Column, 0); - DestRect.top = max(ppdev->PointerAttributes.Row, 0); + DestRect.left = max(pt.x, 0); + DestRect.top = max(pt.y, 0); DestRect.right = min( - ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, + pt.x + pgp->Size.cx, DestSurface->sizlBitmap.cx); DestRect.bottom = min( - ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, + pt.y + pgp->Size.cy, DestSurface->sizlBitmap.cy); - SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); - SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); + SrcPoint.x = max(-pt.x, 0); + SrcPoint.y = max(-pt.y, 0); - SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); - MaskSurface = EngLockSurface(ppdev->PointerMaskSurface); - EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL, - &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY); - EngUnlockSurface(MaskSurface); - EngUnlockSurface(SaveSurface); + if((SaveSurface = EngLockSurface(pgp->SaveSurface))) + { + if((MaskSurface = EngLockSurface(pgp->MaskSurface))) + { + EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL, + &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY); + EngUnlockSurface(MaskSurface); + } + EngUnlockSurface(SaveSurface); + } } } -VOID FASTCALL +VOID INTERNAL_CALL IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface) { - if (ppdev->PointerAttributes.Enable == TRUE) + GDIPOINTER *pgp; + SURFOBJ *SaveSurface; + POINTL pt; + + ASSERT(ppdev); + ASSERT(DestSurface); + + pgp = &ppdev->Pointer; + + if (pgp->Enabled) { return; } - ppdev->PointerAttributes.Enable = TRUE; + pgp->Enabled = TRUE; + + pt.x = pgp->Pos.x - pgp->HotSpot.x; + pt.y = pgp->Pos.y - pgp->HotSpot.y; /* * Copy the pixels under the cursor to temporary surface. */ - - if (ppdev->PointerSaveSurface != NULL) + + if (pgp->SaveSurface != NULL && + (SaveSurface = EngLockSurface(pgp->SaveSurface))) { RECTL DestRect; POINTL SrcPoint; - SURFOBJ *SaveSurface; - SrcPoint.x = max(ppdev->PointerAttributes.Column, 0); - SrcPoint.y = max(ppdev->PointerAttributes.Row, 0); + SrcPoint.x = max(pt.x, 0); + SrcPoint.y = max(pt.y, 0); - DestRect.left = SrcPoint.x - ppdev->PointerAttributes.Column; - DestRect.top = SrcPoint.y - ppdev->PointerAttributes.Row; + DestRect.left = SrcPoint.x - pt.x; + DestRect.top = SrcPoint.y - pt.y; DestRect.right = min( - ppdev->PointerAttributes.Width, - DestSurface->sizlBitmap.cx - ppdev->PointerAttributes.Column); + pgp->Size.cx, + DestSurface->sizlBitmap.cx - pt.x); DestRect.bottom = min( - ppdev->PointerAttributes.Height, - DestSurface->sizlBitmap.cy - ppdev->PointerAttributes.Row); + pgp->Size.cy, + DestSurface->sizlBitmap.cy - pt.y); - SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL, &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY); EngUnlockSurface(SaveSurface); @@ -336,35 +251,40 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface) SURFOBJ *ColorSurf; SURFOBJ *MaskSurf; - DestRect.left = max(ppdev->PointerAttributes.Column, 0); - DestRect.top = max(ppdev->PointerAttributes.Row, 0); + DestRect.left = max(pt.x, 0); + DestRect.top = max(pt.y, 0); DestRect.right = min( - ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, + pt.x + pgp->Size.cx, DestSurface->sizlBitmap.cx); DestRect.bottom = min( - ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, + pt.y + pgp->Size.cy, DestSurface->sizlBitmap.cy); - SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); - SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); + SrcPoint.x = max(-pt.x, 0); + SrcPoint.y = max(-pt.y, 0); - MaskSurf = EngLockSurface(ppdev->PointerMaskSurface); - if (ppdev->PointerColorSurface != NULL) + MaskSurf = EngLockSurface(pgp->MaskSurface); + if (MaskSurf != NULL) { - ColorSurf = EngLockSurface(ppdev->PointerColorSurface); - EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, ppdev->PointerXlateObject, - &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC); - EngUnlockSurface(ColorSurf); + if (pgp->ColorSurface != NULL) + { + if((ColorSurf = EngLockSurface(pgp->ColorSurface))) + { + EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, pgp->XlateObject, + &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC); + EngUnlockSurface(ColorSurf); + } + } + else + { + EngBitBlt(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject, + &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND); + SrcPoint.y += pgp->Size.cy; + EngBitBlt(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject, + &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT); + } + EngUnlockSurface(MaskSurf); } - else - { - EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, - &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND); - SrcPoint.y += ppdev->PointerAttributes.Height; - EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, - &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT); - } - EngUnlockSurface(MaskSurf); } } @@ -385,45 +305,55 @@ EngSetPointerShape( IN RECTL *prcl, IN FLONG fl) { - GDIDEVICE *ppdev = (GDIDEVICE *)pso->hdev; + GDIDEVICE *ppdev; SURFOBJ *TempSurfObj; - + GDIPOINTER *pgp; + + ASSERT(pso); + + ppdev = GDIDEV(pso); + pgp = &ppdev->Pointer; + IntHideMousePointer(ppdev, pso); - if (ppdev->PointerColorSurface != NULL) + if (pgp->ColorSurface != NULL) { /* FIXME: Is this really needed? */ - TempSurfObj = EngLockSurface(ppdev->PointerColorSurface); - EngFreeMem(TempSurfObj->pvBits); - TempSurfObj->pvBits = 0; - EngUnlockSurface(TempSurfObj); + if((TempSurfObj = EngLockSurface(pgp->ColorSurface))) + { + EngFreeMem(TempSurfObj->pvBits); + TempSurfObj->pvBits = 0; + EngUnlockSurface(TempSurfObj); + } - EngDeleteSurface(ppdev->PointerColorSurface); - ppdev->PointerMaskSurface = NULL; + EngDeleteSurface(pgp->ColorSurface); + pgp->MaskSurface = NULL; } - if (ppdev->PointerMaskSurface != NULL) + if (pgp->MaskSurface != NULL) { /* FIXME: Is this really needed? */ - TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface); - EngFreeMem(TempSurfObj->pvBits); - TempSurfObj->pvBits = 0; - EngUnlockSurface(TempSurfObj); + if((TempSurfObj = EngLockSurface(pgp->MaskSurface))) + { + EngFreeMem(TempSurfObj->pvBits); + TempSurfObj->pvBits = 0; + EngUnlockSurface(TempSurfObj); + } - EngDeleteSurface(ppdev->PointerMaskSurface); - ppdev->PointerMaskSurface = NULL; + EngDeleteSurface(pgp->MaskSurface); + pgp->MaskSurface = NULL; } - if (ppdev->PointerSaveSurface != NULL) + if (pgp->SaveSurface != NULL) { - EngDeleteSurface(ppdev->PointerSaveSurface); - ppdev->PointerSaveSurface = NULL; + EngDeleteSurface(pgp->SaveSurface); + pgp->SaveSurface = NULL; } - if (ppdev->PointerXlateObject != NULL) + if (pgp->XlateObject != NULL) { - EngDeleteXlate(ppdev->PointerXlateObject); - ppdev->PointerXlateObject = NULL; + EngDeleteXlate(pgp->XlateObject); + pgp->XlateObject = NULL; } /* @@ -435,51 +365,49 @@ EngSetPointerShape( return SPS_ACCEPT_NOEXCLUDE; } - ppdev->PointerHotSpot.x = xHot; - ppdev->PointerHotSpot.y = yHot; + pgp->HotSpot.x = xHot; + pgp->HotSpot.y = yHot; - ppdev->PointerAttributes.Column = x - xHot; - ppdev->PointerAttributes.Row = y - yHot; - ppdev->PointerAttributes.Width = abs(psoMask->lDelta) << 3; - ppdev->PointerAttributes.Height = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1; + pgp->Pos.x = x; + pgp->Pos.y = y; + pgp->Size.cx = abs(psoMask->lDelta) << 3; + pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1; if (prcl != NULL) { - prcl->left = ppdev->PointerAttributes.Column; - prcl->top = ppdev->PointerAttributes.Row; - prcl->right = prcl->left + ppdev->PointerAttributes.Width; - prcl->bottom = prcl->top + ppdev->PointerAttributes.Height; + /* FIXME - right rectangle when x == -1? */ + prcl->left = pgp->Pos.x - pgp->HotSpot.x; + prcl->top = pgp->Pos.y - pgp->HotSpot.x; + prcl->right = prcl->left + pgp->Size.cx; + prcl->bottom = prcl->top + pgp->Size.cy; } if (psoColor != NULL) { - SIZEL Size; PBYTE Bits; - Size.cx = ppdev->PointerAttributes.Width; - Size.cy = ppdev->PointerAttributes.Height; Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE); memcpy(Bits, psoColor->pvBits, psoColor->cjBits); - ppdev->PointerColorSurface = (HSURF)EngCreateBitmap(Size, + pgp->ColorSurface = (HSURF)EngCreateBitmap(pgp->Size, psoColor->lDelta, psoColor->iBitmapFormat, psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits); } else { - ppdev->PointerColorSurface = NULL; + pgp->ColorSurface = NULL; } { SIZEL Size; PBYTE Bits; - Size.cx = ppdev->PointerAttributes.Width; - Size.cy = ppdev->PointerAttributes.Height << 1; + Size.cx = pgp->Size.cx; + Size.cy = pgp->Size.cy << 1; Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE); memcpy(Bits, psoMask->pvBits, psoMask->cjBits); - ppdev->PointerMaskSurface = (HSURF)EngCreateBitmap(Size, + pgp->MaskSurface = (HSURF)EngCreateBitmap(Size, psoMask->lDelta, psoMask->iBitmapFormat, psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits); } @@ -493,20 +421,18 @@ EngSetPointerShape( { HPALETTE BWPalette, DestPalette; ULONG BWColors[] = {0, 0xFFFFFF}; - PDC Dc; BWPalette = EngCreatePalette(PAL_INDEXED, sizeof(BWColors) / sizeof(ULONG), BWColors, 0, 0, 0); - Dc = DC_LockDc(IntGetScreenDC()); - DestPalette = Dc->w.hPalette; - DC_UnlockDc(IntGetScreenDC()); - ppdev->PointerXlateObject = IntEngCreateXlate(0, PAL_INDEXED, + + DestPalette = ppdev->DevInfo.hpalDefault; + pgp->XlateObject = IntEngCreateXlate(0, PAL_INDEXED, DestPalette, BWPalette); EngDeletePalette(BWPalette); } else { - ppdev->PointerXlateObject = pxlo; + pgp->XlateObject = pxlo; } /* @@ -514,28 +440,41 @@ EngSetPointerShape( */ { - SIZEL Size; LONG lDelta; - Size.cx = ppdev->PointerAttributes.Width; - Size.cy = ppdev->PointerAttributes.Height; - switch (pso->iBitmapFormat) { - case BMF_1BPP: lDelta = Size.cx >> 3; break; - case BMF_4BPP: lDelta = Size.cx >> 1; break; - case BMF_8BPP: lDelta = Size.cx; break; - case BMF_16BPP: lDelta = Size.cx << 1; break; - case BMF_24BPP: lDelta = Size.cx * 3; break; - case BMF_32BPP: lDelta = Size.cx << 2; break; - default: lDelta = 0; break; + case BMF_1BPP: + lDelta = pgp->Size.cx >> 3; + break; + case BMF_4BPP: + lDelta = pgp->Size.cx >> 1; + break; + case BMF_8BPP: + lDelta = pgp->Size.cx; + break; + case BMF_16BPP: + lDelta = pgp->Size.cx << 1; + break; + case BMF_24BPP: + lDelta = pgp->Size.cx * 3; + break; + case BMF_32BPP: + lDelta = pgp->Size.cx << 2; + break; + default: + lDelta = 0; + break; } - ppdev->PointerSaveSurface = (HSURF)EngCreateBitmap( - Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); + pgp->SaveSurface = (HSURF)EngCreateBitmap( + pgp->Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); } - IntShowMousePointer(ppdev, pso); + if(x != -1) + { + IntShowMousePointer(ppdev, pso); + } return SPS_ACCEPT_EXCLUDE; } @@ -551,22 +490,33 @@ EngMovePointer( IN LONG y, IN RECTL *prcl) { - GDIDEVICE *ppdev = (GDIDEVICE *)pso->hdev; + GDIDEVICE *ppdev; + GDIPOINTER *pgp; + ASSERT(pso); + + ppdev = GDIDEV(pso); + + ASSERT(ppdev); + + pgp = &ppdev->Pointer; + + IntHideMousePointer(ppdev, pso); - ppdev->PointerAttributes.Column = x - ppdev->PointerHotSpot.x; - ppdev->PointerAttributes.Row = y - ppdev->PointerHotSpot.y; if (x != -1) { - IntShowMousePointer(ppdev, pso); + pgp->Pos.x = x; + pgp->Pos.y = y; + IntShowMousePointer(ppdev, pso); } if (prcl != NULL) { - prcl->left = ppdev->PointerAttributes.Column; - prcl->top = ppdev->PointerAttributes.Row; - prcl->right = prcl->left + ppdev->PointerAttributes.Width; - prcl->bottom = prcl->top + ppdev->PointerAttributes.Height; + /* FIXME - right rectangle when x == -1? */ + prcl->left = pgp->Pos.x - pgp->HotSpot.x; + prcl->top = pgp->Pos.y - pgp->HotSpot.x; + prcl->right = prcl->left + pgp->Size.cx; + prcl->bottom = prcl->top + pgp->Size.cy; } } diff --git a/reactos/subsys/win32k/eng/objects.h b/reactos/subsys/win32k/eng/objects.h index a169f72f8d9..d825487b633 100644 --- a/reactos/subsys/win32k/eng/objects.h +++ b/reactos/subsys/win32k/eng/objects.h @@ -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: objects.h,v 1.32 2004/07/03 13:55:35 navaraf Exp $ +/* $Id: objects.h,v 1.33 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,8 +33,6 @@ #include /* Structure of internal gdi objects that win32k manages for ddi engine: - |---------------------------------| - | EngObj | |---------------------------------| | Public part | | accessed from engine | @@ -45,21 +43,8 @@ ---------------------------------------------------------------------------*/ -typedef struct _ENGOBJ { - ULONG hObj; - ULONG InternalSize; - ULONG UserSize; -} ENGOBJ, *PENGOBJ; - typedef struct _CLIPGDI { - ENGOBJ Header; - CLIPOBJ ClipObj; - /* ei what were these for? - ULONG NumRegionRects; - ULONG NumIntersectRects; - RECTL *RegionRects; - RECTL *IntersectRects; - */ + CLIPOBJ ClipObj; ULONG EnumPos; ULONG EnumOrder; ULONG EnumMax; @@ -73,12 +58,11 @@ typedef struct _DRVFUNCTIONSGDI { } DRVFUNCTIONSGDI; typedef struct _FLOATGDI { - + ULONG Dummy; } FLOATGDI; typedef struct _FONTGDI { - ENGOBJ Header; - FONTOBJ FontObj; + FONTOBJ FontObj; LPCWSTR Filename; FT_Face face; @@ -86,13 +70,11 @@ typedef struct _FONTGDI { } FONTGDI, *PFONTGDI; typedef struct _PATHGDI { - ENGOBJ Header; - PATHOBJ PathObj; + PATHOBJ PathObj; } PATHGDI; typedef struct _STRGDI { - ENGOBJ Header; - STROBJ StrObj; + STROBJ StrObj; } STRGDI; typedef BOOL STDCALL (*PFN_BitBlt)(SURFOBJ *, SURFOBJ *, SURFOBJ *, CLIPOBJ *, @@ -141,12 +123,11 @@ typedef BOOL STDCALL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG); typedef BOOL STDCALL (*PFN_GradientFill)(SURFOBJ*, CLIPOBJ*, XLATEOBJ*, TRIVERTEX*, ULONG, PVOID, ULONG, RECTL*, POINTL*, ULONG); typedef struct _XFORMGDI { - ENGOBJ Header; + ULONG Dummy; /* XFORMOBJ has no public members */ } XFORMGDI; typedef struct _XLATEGDI { - ENGOBJ Header; XLATEOBJ XlateObj; HPALETTE DestPal; HPALETTE SourcePal; @@ -170,4 +151,10 @@ typedef struct _XLATEGDI { // }; } XLATEGDI; +/* as the *OBJ structures are located at the beginning of the *GDI structures + we can simply typecast the pointer */ +#define ObjToGDI(ClipObj, Type) (Type##GDI *)(ClipObj) +#define GDIToObj(ClipGDI, Type) (Type##OBJ *)(ClipGDI) + + #endif //__ENG_OBJECTS_H diff --git a/reactos/subsys/win32k/eng/surface.c b/reactos/subsys/win32k/eng/surface.c index 40b4a82ace0..7b6d003cd7d 100644 --- a/reactos/subsys/win32k/eng/surface.c +++ b/reactos/subsys/win32k/eng/surface.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: surface.c,v 1.44 2004/07/07 16:33:44 navaraf Exp $ +/* $Id: surface.c,v 1.45 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -481,7 +481,13 @@ EngEraseSurface(SURFOBJ *Surface, SURFOBJ * STDCALL EngLockSurface(IN HSURF Surface) { - return &((BITMAPOBJ*)BITMAPOBJ_LockBitmap(Surface))->SurfObj; + BITMAPOBJ *bmp = (BITMAPOBJ*)BITMAPOBJ_LockBitmap(Surface); + if(bmp != NULL) + { + return &bmp->SurfObj; + } + + return NULL; } /* @@ -490,6 +496,7 @@ EngLockSurface(IN HSURF Surface) VOID STDCALL EngUnlockSurface(IN SURFOBJ *Surface) { - BITMAPOBJ_UnlockBitmap ( Surface->hsurf ); + ASSERT (Surface); + BITMAPOBJ_UnlockBitmap (Surface->hsurf); } /* EOF */ diff --git a/reactos/subsys/win32k/eng/xlate.c b/reactos/subsys/win32k/eng/xlate.c index 5824aded274..6b955c6aeb5 100644 --- a/reactos/subsys/win32k/eng/xlate.c +++ b/reactos/subsys/win32k/eng/xlate.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: xlate.c,v 1.42 2004/07/15 21:14:51 navaraf Exp $ +/* $Id: xlate.c,v 1.43 2004/12/12 01:40:36 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -29,7 +29,8 @@ #include -static ULONG FASTCALL ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color) +static inline ULONG +ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color) { ULONG TranslatedColor; @@ -50,62 +51,65 @@ static ULONG FASTCALL ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color) } -ULONG STDCALL +static inline ULONG ClosestColorMatch(XLATEGDI *XlateGDI, LPPALETTEENTRY SourceColor, PALETTEENTRY *DestColors, ULONG NumColors) { ULONG SourceRed, SourceGreen, SourceBlue; - ULONG cxRed, cxGreen, cxBlue, Rating, BestMatch = 16777215; + ULONG cxRed, cxGreen, cxBlue, Rating, BestMatch = 0xFFFFFF; ULONG CurrentIndex, BestIndex = 0; SourceRed = SourceColor->peRed; SourceGreen = SourceColor->peGreen; SourceBlue = SourceColor->peBlue; - for (CurrentIndex = 0; CurrentIndex < NumColors; CurrentIndex++) + for (CurrentIndex = 0; CurrentIndex < NumColors; CurrentIndex++, DestColors++) { - cxRed = abs((SHORT)SourceRed - (SHORT)DestColors[CurrentIndex].peRed); + cxRed = abs((SHORT)SourceRed - (SHORT)DestColors->peRed); cxRed *= cxRed; - cxGreen = abs((SHORT)SourceGreen - (SHORT)DestColors[CurrentIndex].peGreen); + cxGreen = abs((SHORT)SourceGreen - (SHORT)DestColors->peGreen); cxGreen *= cxGreen; - cxBlue = abs((SHORT)SourceBlue - (SHORT)DestColors[CurrentIndex].peBlue); + cxBlue = abs((SHORT)SourceBlue - (SHORT)DestColors->peBlue); cxBlue *= cxBlue; Rating = cxRed + cxGreen + cxBlue; + + if (Rating == 0) + { + /* Exact match */ + BestIndex = CurrentIndex; + break; + } if (Rating < BestMatch) { BestIndex = CurrentIndex; BestMatch = Rating; } - - /* Exact match */ - if (Rating == 0) - break; } return BestIndex; } -static VOID STDCALL +static inline VOID BitMasksFromPal(USHORT PalType, PPALGDI Palette, PULONG RedMask, PULONG BlueMask, PULONG GreenMask) { - static const union { PALETTEENTRY Color; ULONG Mask; } Red = {{255, 0, 0}}; - static const union { PALETTEENTRY Color; ULONG Mask; } Green = {{0, 255, 0}}; - static const union { PALETTEENTRY Color; ULONG Mask; } Blue = {{0, 0, 255}}; + static const union { PALETTEENTRY Color; ULONG Mask; } Red = {{0xFF, 0x00, 0x00}}; + static const union { PALETTEENTRY Color; ULONG Mask; } Green = {{0x00, 0xFF, 0x00}}; + static const union { PALETTEENTRY Color; ULONG Mask; } Blue = {{0x00, 0x00, 0xFF}}; switch (PalType) { case PAL_RGB: - *RedMask = RGB(255, 0, 0); - *GreenMask = RGB(0, 255, 0); - *BlueMask = RGB(0, 0, 255); + *RedMask = RGB(0xFF, 0x00, 0x00); + *GreenMask = RGB(0x00, 0xFF, 0x00); + *BlueMask = RGB(0x00, 0x00, 0xFF); break; case PAL_BGR: - *RedMask = RGB(0, 0, 255); - *GreenMask = RGB(0, 255, 0); - *BlueMask = RGB(255, 0, 0); + *RedMask = RGB(0x00, 0x00, 0xFF); + *GreenMask = RGB(0x00, 0xFF, 0x00); + *BlueMask = RGB(0xFF, 0x00, 0x00); break; case PAL_BITFIELDS: *RedMask = Palette->RedMask; @@ -124,7 +128,8 @@ BitMasksFromPal(USHORT PalType, PPALGDI Palette, * Calculate the number of bits Mask must be shift to the left to get a * 1 in the most significant bit position */ -static INT FASTCALL CalculateShift(ULONG Mask) +static inline INT +CalculateShift(ULONG Mask) { ULONG Shift = 0; ULONG LeftmostBit = 1 << (8 * sizeof(ULONG) - 1); @@ -138,11 +143,10 @@ static INT FASTCALL CalculateShift(ULONG Mask) return Shift; } -XLATEOBJ* STDCALL +XLATEOBJ* FASTCALL IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, HPALETTE PaletteDest, HPALETTE PaletteSource) { - ULONG NewXlate; XLATEOBJ *XlateObj; XLATEGDI *XlateGDI; PALGDI *SourcePalGDI = 0; @@ -151,9 +155,13 @@ IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, ULONG DestRedMask, DestGreenMask, DestBlueMask; ULONG i; - NewXlate = CreateGDIHandle(sizeof(XLATEGDI), sizeof(XLATEOBJ), (PVOID*)&XlateGDI, (PVOID*)&XlateObj); - if (!ValidEngHandle(NewXlate)) + XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); + if (XlateGDI == NULL) + { + DPRINT1("Failed to allocate memory for a XLATE structure!\n"); return NULL; + } + XlateObj = GDIToObj(XlateGDI, XLATE); if (PaletteSource != NULL) SourcePalGDI = PALETTE_LockPalette(PaletteSource); @@ -270,20 +278,25 @@ end: return XlateObj; } -XLATEOBJ * STDCALL IntEngCreateMonoXlate( +XLATEOBJ* FASTCALL +IntEngCreateMonoXlate( USHORT SourcePalType, HPALETTE PaletteDest, HPALETTE PaletteSource, ULONG BackgroundColor) { - ULONG NewXlate; XLATEOBJ *XlateObj; XLATEGDI *XlateGDI; PALGDI *SourcePalGDI; - NewXlate = CreateGDIHandle(sizeof(XLATEGDI), sizeof(XLATEOBJ), (PVOID*)&XlateGDI, (PVOID*)&XlateObj); - if (!ValidEngHandle(NewXlate)) + XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); + if (XlateGDI == NULL) + { + DPRINT1("Failed to allocate memory for a XLATE structure!\n"); return NULL; + } + XlateObj = GDIToObj(XlateGDI, XLATE); SourcePalGDI = PALETTE_LockPalette(PaletteSource); + /* FIXME - SourcePalGDI can be NULL!!! Handle this case instead of ASSERT! */ ASSERT(SourcePalGDI); if (SourcePalType == 0) @@ -329,12 +342,11 @@ XLATEOBJ * STDCALL IntEngCreateMonoXlate( return XlateObj; } -XLATEOBJ * STDCALL +XLATEOBJ* FASTCALL IntEngCreateSrcMonoXlate(HPALETTE PaletteDest, ULONG ForegroundColor, ULONG BackgroundColor) { - ULONG NewXlate; XLATEOBJ *XlateObj; XLATEGDI *XlateGDI; PALGDI *DestPalGDI; @@ -343,14 +355,20 @@ IntEngCreateSrcMonoXlate(HPALETTE PaletteDest, if (DestPalGDI == NULL) return NULL; - NewXlate = CreateGDIHandle(sizeof(XLATEGDI), sizeof(XLATEOBJ), (PVOID*)&XlateGDI, (PVOID*)&XlateObj); - if (!ValidEngHandle(NewXlate)) + XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); + if (XlateGDI == NULL) + { + PALETTE_UnlockPalette(PaletteDest); + DPRINT1("Failed to allocate memory for a XLATE structure!\n"); return NULL; + } + XlateObj = GDIToObj(XlateGDI, XLATE); XlateGDI->translationTable = EngAllocMem(0, sizeof(ULONG) * 2, 0); if (XlateGDI->translationTable == NULL) { - FreeGDIHandle(NewXlate); + PALETTE_UnlockPalette(PaletteDest); + EngFreeMem(XlateGDI); return NULL; } @@ -368,9 +386,9 @@ IntEngCreateSrcMonoXlate(HPALETTE PaletteDest, BitMasksFromPal(DestPalGDI->Mode, DestPalGDI, &XlateGDI->RedMask, &XlateGDI->BlueMask, &XlateGDI->GreenMask); - XlateGDI->RedShift = CalculateShift(RGB(255, 0, 0)) - CalculateShift(XlateGDI->RedMask); - XlateGDI->GreenShift = CalculateShift(RGB(0, 255, 0)) - CalculateShift(XlateGDI->GreenMask); - XlateGDI->BlueShift = CalculateShift(RGB(0, 0, 255)) - CalculateShift(XlateGDI->BlueMask); + XlateGDI->RedShift = CalculateShift(RGB(0xFF, 0x00, 0x00)) - CalculateShift(XlateGDI->RedMask); + XlateGDI->GreenShift = CalculateShift(RGB(0x00, 0xFF, 0x00)) - CalculateShift(XlateGDI->GreenMask); + XlateGDI->BlueShift = CalculateShift(RGB(0x00, 0x00, 0xFF)) - CalculateShift(XlateGDI->BlueMask); XlateGDI->translationTable[0] = ShiftAndMask(XlateGDI, BackgroundColor); XlateGDI->translationTable[1] = ShiftAndMask(XlateGDI, ForegroundColor); @@ -403,7 +421,6 @@ VOID FASTCALL EngDeleteXlate(XLATEOBJ *XlateObj) { XLATEGDI *XlateGDI; - HANDLE HXlate; if (XlateObj == NULL) { @@ -411,8 +428,7 @@ EngDeleteXlate(XLATEOBJ *XlateObj) return; } - XlateGDI = (XLATEGDI *)AccessInternalObjectFromUserObject(XlateObj); - HXlate = (HANDLE)AccessHandleFromUserObject(XlateObj); + XlateGDI = ObjToGDI(XlateObj, XLATE); if ((XlateObj->flXlate & XO_TABLE) && XlateGDI->translationTable != NULL) @@ -420,7 +436,7 @@ EngDeleteXlate(XLATEOBJ *XlateObj) EngFreeMem(XlateGDI->translationTable); } - FreeGDIHandle((ULONG)HXlate); + EngFreeMem(XlateGDI); } /* @@ -429,7 +445,7 @@ EngDeleteXlate(XLATEOBJ *XlateObj) PULONG STDCALL XLATEOBJ_piVector(XLATEOBJ *XlateObj) { - XLATEGDI *XlateGDI = (XLATEGDI*)AccessInternalObjectFromUserObject(XlateObj); + XLATEGDI *XlateGDI = ObjToGDI(XlateObj, XLATE); if (XlateObj->iSrcType == PAL_INDEXED) { @@ -459,7 +475,7 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color) if (XlateObj->flXlate & XO_TABLE) return XlateObj->pulXlate[Color]; - XlateGDI = (XLATEGDI *)AccessInternalObjectFromUserObject(XlateObj); + XlateGDI = ObjToGDI(XlateObj, XLATE); if (XlateObj->flXlate & XO_TO_MONO) return Color == XlateGDI->BackgroundColor; @@ -472,17 +488,19 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color) { /* FIXME: should we cache colors used often? */ /* FIXME: won't work if destination isn't indexed */ - - /* Extract the destination palette. */ - PalGDI = PALETTE_LockPalette(XlateGDI->DestPal); - + /* Convert the source color to the palette RGB format. */ Color = ShiftAndMask(XlateGDI, Color); - /* Return closest match for the given color. */ - Closest = ClosestColorMatch(XlateGDI, (LPPALETTEENTRY)&Color, PalGDI->IndexedColors, PalGDI->NumColors); - PALETTE_UnlockPalette(XlateGDI->DestPal); - return Closest; + /* Extract the destination palette. */ + PalGDI = PALETTE_LockPalette(XlateGDI->DestPal); + if(PalGDI != NULL) + { + /* Return closest match for the given color. */ + Closest = ClosestColorMatch(XlateGDI, (LPPALETTEENTRY)&Color, PalGDI->IndexedColors, PalGDI->NumColors); + PALETTE_UnlockPalette(XlateGDI->DestPal); + return Closest; + } } return 0; @@ -498,8 +516,9 @@ XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj, ULONG PalOutType, ULONG cPal, HPALETTE hPalette; XLATEGDI *XlateGDI; PALGDI *PalGDI; + ULONG *InPal; - XlateGDI = (XLATEGDI*)AccessInternalObjectFromUserObject(XlateObj); + XlateGDI = ObjToGDI(XlateObj, XLATE); if (PalOutType == XO_SRCPALETTE) hPalette = XlateGDI->SourcePal; else if (PalOutType == XO_DESTPALETTE) @@ -508,10 +527,23 @@ XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj, ULONG PalOutType, ULONG cPal, UNIMPLEMENTED; PalGDI = PALETTE_LockPalette(hPalette); - RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG) * cPal); - PALETTE_UnlockPalette(hPalette); + if(PalGDI != NULL) + { + /* copy the indexed colors into the buffer */ - return cPal; + for(InPal = (ULONG*)PalGDI->IndexedColors; + cPal > 0; + cPal--, InPal++, OutPal++) + { + *OutPal = *InPal; + } + + PALETTE_UnlockPalette(hPalette); + + return cPal; + } + + return 0; } /* EOF */ diff --git a/reactos/subsys/win32k/include/cursoricon.h b/reactos/subsys/win32k/include/cursoricon.h index 52121543015..620799c4cbd 100644 --- a/reactos/subsys/win32k/include/cursoricon.h +++ b/reactos/subsys/win32k/include/cursoricon.h @@ -31,12 +31,6 @@ typedef struct _SYSTEM_CURSORINFO BOOL SwapButtons; UINT ButtonsDown; LONG x, y; - BOOL SafetySwitch; - UINT SafetyRemoveCount; - LONG PointerRectLeft; - LONG PointerRectTop; - LONG PointerRectRight; - LONG PointerRectBottom; FAST_MUTEX CursorMutex; CURSORCLIP_INFO CursorClipInfo; PCURICON_OBJECT CurrentCursorObject; diff --git a/reactos/subsys/win32k/include/dce.h b/reactos/subsys/win32k/include/dce.h index 25a79845d35..9fd0f4efd22 100644 --- a/reactos/subsys/win32k/include/dce.h +++ b/reactos/subsys/win32k/include/dce.h @@ -37,10 +37,11 @@ typedef struct tagDCE } DCE; /* PDCE already declared at top of file */ #define DCEOBJ_AllocDCE() \ - ((HDCE) GDIOBJ_AllocObj (sizeof (DCE), GDI_OBJECT_TYPE_DCE, (GDICLEANUPPROC) DCE_InternalDelete)) -#define DCEOBJ_FreeDCE(hDCE) GDIOBJ_FreeObj((HGDIOBJ)hDCE, GDI_OBJECT_TYPE_DCE, GDIOBJFLAG_DEFAULT) + ((HDCE) GDIOBJ_AllocObj (GDI_OBJECT_TYPE_DCE)) +#define DCEOBJ_FreeDCE(hDCE) GDIOBJ_FreeObj((HGDIOBJ)hDCE, GDI_OBJECT_TYPE_DCE) #define DCEOBJ_LockDCE(hDCE) ((PDCE)GDIOBJ_LockObj((HGDIOBJ)hDCE, GDI_OBJECT_TYPE_DCE)) -#define DCEOBJ_UnlockDCE(hDCE) GDIOBJ_UnlockObj((HGDIOBJ)hDCE, GDI_OBJECT_TYPE_DCE) +#define DCEOBJ_UnlockDCE(hDCE) GDIOBJ_UnlockObj((HGDIOBJ)hDCE) +BOOL INTERNAL_CALL DCE_Cleanup(PVOID ObjectBody); PDCE FASTCALL DceAllocDCE(HWND hWnd, DCE_TYPE Type); PDCE FASTCALL DCE_FreeDCE(PDCE dce); @@ -48,9 +49,8 @@ VOID FASTCALL DCE_FreeWindowDCE(HWND); HRGN STDCALL DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags); INT FASTCALL DCE_ExcludeRgn(HDC, HWND, HRGN); BOOL FASTCALL DCE_InvalidateDCE(HWND, const PRECTL); -BOOL FASTCALL DCE_InternalDelete(PDCE dce); HWND FASTCALL IntWindowFromDC(HDC hDc); -PDCE FASTCALL DceFreeDCE(PDCE dce); +PDCE FASTCALL DceFreeDCE(PDCE dce, BOOLEAN Force); void FASTCALL DceFreeWindowDCE(PWINDOW_OBJECT Window); void FASTCALL DceEmptyCache(void); VOID FASTCALL DceResetActiveDCEs(PWINDOW_OBJECT Window, int DeltaX, int DeltaY); diff --git a/reactos/subsys/win32k/include/intddraw.h b/reactos/subsys/win32k/include/intddraw.h new file mode 100644 index 00000000000..8264de4e301 --- /dev/null +++ b/reactos/subsys/win32k/include/intddraw.h @@ -0,0 +1,67 @@ +#ifndef _INT_W32k_DDRAW +#define _INT_W32k_DDRAW + +#define GDI_OBJECT_TYPE_DIRECTDRAW 0x00600000 +#define GDI_OBJECT_TYPE_DD_SURFACE 0x00610000 +#define GDI_OBJECT_TYPE_DD_VIDEOPORT 0x00620000 +#define GDI_OBJECT_TYPE_DD_PALETTE 0x00630000 +#define GDI_OBJECT_TYPE_DD_CLIPPER 0x00640000 +#define GDI_OBJECT_TYPE_DD_MOTIONCOMP 0x00650000 + +typedef struct +{ + DD_SURFACE_LOCAL Local; + DD_SURFACE_MORE More; + DD_SURFACE_GLOBAL Global; + DD_ATTACHLIST AttachList; + DD_ATTACHLIST AttachListFrom; + BOOL bComplete; +} DD_SURFACE, *PDD_SURFACE; + +typedef struct +{ + DD_DIRECTDRAW_LOCAL Local; + DD_DIRECTDRAW_GLOBAL Global; + // Drv callbacks + PGD_GETDIRECTDRAWINFO DrvGetDirectDrawInfo; + PGD_DISABLEDIRECTDRAW DrvDisableDirectDraw; + // DD callbacks + PDD_CREATESURFACE DdCreateSurface; + PDD_SETCOLORKEY DdDrvSetColorKey; // ????? + PDD_WAITFORVERTICALBLANK DdWaitForVerticalBlank; + PDD_CANCREATESURFACE DdCanCreateSurface; + PDD_CREATEPALETTE DdCreatePalette; + PDD_GETSCANLINE DdGetScanLine; + PDD_MAPMEMORY DdMapMemory; + // Surface callbacks + PDD_SURFCB_DESTROYSURFACE DdDestroySurface; + PDD_SURFCB_FLIP DdFlip; + PDD_SURFCB_SETCLIPLIST DdSetClipList; + PDD_SURFCB_LOCK DdLock; + PDD_SURFCB_UNLOCK DdUnlock; + PDD_SURFCB_BLT DdBlt; + PDD_SURFCB_SETCOLORKEY DdSetColorKey; + PDD_SURFCB_ADDATTACHEDSURFACE DdAddAttachedSurface; + PDD_SURFCB_GETBLTSTATUS DdGetBltStatus; + PDD_SURFCB_GETFLIPSTATUS DdGetFlipStatus; + PDD_SURFCB_UPDATEOVERLAY DdUpdateOverlay; + PDD_SURFCB_SETOVERLAYPOSITION DdSetOverlayPosition; + PDD_SURFCB_SETPALETTE DdSetPalette; + // Palette callbacks + PDD_PALCB_DESTROYPALETTE DdDestroyPalette; + PDD_PALCB_SETENTRIES DdSetEntries; + // D3D Device context callbacks + PD3DNTHAL_CONTEXTCREATECB D3dContextCreate; + PD3DNTHAL_CONTEXTDESTROYCB D3dContextDestroy; + // D3D Buffer callbacks + PDD_CANCREATESURFACE DdCanCreateD3DBuffer; + PDD_CREATESURFACE DdCreateD3DBuffer; + PDD_SURFCB_DESTROYSURFACE DdDestroyD3DBuffer; + PDD_SURFCB_LOCK DdLockD3DBuffer; + PDD_SURFCB_UNLOCK DdUnlockD3DBuffer; +} DD_DIRECTDRAW, *PDD_DIRECTDRAW; + +BOOL FASTCALL DD_Cleanup(PDD_DIRECTDRAW pDD); +BOOL FASTCALL DDSURF_Cleanup(PDD_SURFACE pDDSurf); + +#endif /* _INT_W32k_DDRAW */ diff --git a/reactos/subsys/win32k/include/inteng.h b/reactos/subsys/win32k/include/inteng.h index b6d2744f865..8272371ac21 100644 --- a/reactos/subsys/win32k/include/inteng.h +++ b/reactos/subsys/win32k/include/inteng.h @@ -1,6 +1,23 @@ #ifndef _WIN32K_INTENG_H #define _WIN32K_INTENG_H +typedef ULONG HCLIP; + +#define ENUM_RECT_LIMIT 50 + +typedef struct _RECT_ENUM +{ + ULONG c; + RECTL arcl[ENUM_RECT_LIMIT]; +} RECT_ENUM; + +typedef struct tagSPAN +{ + LONG Y; + LONG X; + ULONG Width; +} SPAN, *PSPAN; + #define ROP_NOOP 0x00AA0029 /* Definitions of IntEngXxx functions */ @@ -54,19 +71,19 @@ IntEngGradientFill(BITMAPOBJ *psoDest, POINTL *pptlDitherOrg, ULONG ulMode); -XLATEOBJ * STDCALL +XLATEOBJ* FASTCALL IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, HPALETTE PaletteDest, HPALETTE PaletteSource); -XLATEOBJ * STDCALL +XLATEOBJ* FASTCALL IntEngCreateMonoXlate(USHORT SourcePalType, HPALETTE PaletteDest, HPALETTE PaletteSource, ULONG BackgroundColor); -XLATEOBJ * STDCALL +XLATEOBJ* FASTCALL IntEngCreateSrcMonoXlate(HPALETTE PaletteDest, ULONG ForegroundColor, ULONG BackgroundColor); @@ -79,11 +96,20 @@ IntEngPolyline(BITMAPOBJ *DestSurf, LONG dCount, MIX mix); -CLIPOBJ* STDCALL +CLIPOBJ* FASTCALL IntEngCreateClipRegion(ULONG count, PRECTL pRect, PRECTL rcBounds); +VOID FASTCALL +IntEngDeleteClipRegion(CLIPOBJ *ClipObj); + +BOOLEAN FASTCALL +ClipobjToSpans(PSPAN *Spans, + UINT *Count, + CLIPOBJ *ClipRegion, + PRECTL Boundary); + BOOL FASTCALL IntEngTransparentBlt(BITMAPOBJ *Dest, BITMAPOBJ *Source, diff --git a/reactos/subsys/win32k/include/intgdi.h b/reactos/subsys/win32k/include/intgdi.h index 1eb7b922cbc..c04c74f834b 100644 --- a/reactos/subsys/win32k/include/intgdi.h +++ b/reactos/subsys/win32k/include/intgdi.h @@ -165,5 +165,19 @@ IntGdiUnionRect(PRECT Dest, const RECT* Src1, const RECT* Src2); BOOL FASTCALL IntGdiIntersectRect(PRECT Dest, const RECT* Src1, const RECT* Src2); +/* Stock objects */ + +BOOL FASTCALL +IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors); + +BOOL FASTCALL +IntGetSysColorBrushes(HBRUSH *Brushes, UINT nBrushes); + +BOOL FASTCALL +IntGetSysColorPens(HPEN *Pens, UINT nPens); + +BOOL FASTCALL +IntGetSysColors(COLORREF *Colors, UINT nColors); + #endif /* _WIN32K_INTGDI_H */ diff --git a/reactos/subsys/win32k/include/mouse.h b/reactos/subsys/win32k/include/mouse.h index d114c682583..5bd050a8cf0 100644 --- a/reactos/subsys/win32k/include/mouse.h +++ b/reactos/subsys/win32k/include/mouse.h @@ -5,14 +5,8 @@ #include //#include -BOOL FASTCALL IntCheckClipCursor(LONG *x, LONG *y, PSYSTEM_CURSORINFO CurInfo); -BOOL FASTCALL IntSwapMouseButton(PWINSTATION_OBJECT WinStaObject, BOOL Swap); -INT FASTCALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2); -INT FASTCALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj); -BOOL FASTCALL MouseMoveCursor(LONG X, LONG Y); -VOID FASTCALL EnableMouse(HDC hDisplayDC); -VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount); -VOID FASTCALL SetPointerRect(PSYSTEM_CURSORINFO CurInfo, PRECTL PointerRect); +INT INTERNAL_CALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2); +INT INTERNAL_CALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj); #ifndef XBUTTON1 #define XBUTTON1 (0x01) diff --git a/reactos/subsys/win32k/include/object.h b/reactos/subsys/win32k/include/object.h index ad1565ac12a..54e73794936 100644 --- a/reactos/subsys/win32k/include/object.h +++ b/reactos/subsys/win32k/include/object.h @@ -113,23 +113,10 @@ ObmCreateHandleTable(VOID); VOID FASTCALL ObmDestroyHandleTable (PUSER_HANDLE_TABLE HandleTable); -ULONG FASTCALL CreateGDIHandle (ULONG InternalSize, ULONG UserSize, PVOID *InternalObject, PVOID *UserObject); -VOID FASTCALL FreeGDIHandle (ULONG Handle); - -PVOID FASTCALL AccessUserObject (ULONG Handle); -PVOID FASTCALL AccessInternalObject (ULONG Handle); - -ULONG FASTCALL AccessHandleFromUserObject (PVOID UserObject); - -#define AccessInternalObjectFromUserObject(UserObj) \ - ((PVOID)( (PCHAR)(UserObj) - sizeof( ENGOBJ ) ) ) - -VOID FASTCALL InitEngHandleTable (VOID); -VOID FASTCALL InitGdiObjectHandleTable (VOID); +VOID INTERNAL_CALL InitGdiObjectHandleTable (VOID); VOID FASTCALL CreateStockObjects (VOID); - -BOOL FASTCALL CleanupForProcess (struct _EPROCESS *Process, INT Pid); +VOID FASTCALL CreateSysColorObjects (VOID); PPOINT FASTCALL GDI_Bezier (const POINT *Points, INT count, PINT nPtsOut); diff --git a/reactos/subsys/win32k/include/palette.h b/reactos/subsys/win32k/include/palette.h index 073022a7920..5e6238e149a 100644 --- a/reactos/subsys/win32k/include/palette.h +++ b/reactos/subsys/win32k/include/palette.h @@ -35,9 +35,10 @@ HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, ULONG Blue); HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, CONST RGBQUAD *Colors); -#define PALETTE_FreePalette(hPalette) GDIOBJ_FreeObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE, GDIOBJFLAG_DEFAULT) +#define PALETTE_FreePalette(hPalette) GDIOBJ_FreeObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE) #define PALETTE_LockPalette(hPalette) ((PPALGDI)GDIOBJ_LockObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE)) -#define PALETTE_UnlockPalette(hPalette) GDIOBJ_UnlockObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE) +#define PALETTE_UnlockPalette(hPalette) GDIOBJ_UnlockObj((HGDIOBJ)hPalette) +BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); HPALETTE FASTCALL PALETTE_Init (VOID); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); diff --git a/reactos/subsys/win32k/include/tags.h b/reactos/subsys/win32k/include/tags.h index e9054445944..bd5eb541d75 100644 --- a/reactos/subsys/win32k/include/tags.h +++ b/reactos/subsys/win32k/include/tags.h @@ -42,9 +42,15 @@ #define TAG_PRINT TAG('P', 'R', 'N', 'T') /* print */ #define TAG_REGION TAG('R', 'G', 'N', 'O') /* region */ #define TAG_GDITEXT TAG('T', 'X', 'T', 'O') /* text */ -#define TAG_FONT TAG('F', 'N', 'T', 'O') /* font entry */ + +/* Eng objects */ +#define TAG_CLIPOBJ TAG('C', 'L', 'P', 'O') /* clip object */ +#define TAG_XLATEOBJ TAG('X', 'L', 'A', 'O') /* xlate object */ +#define TAG_FONT TAG('F', 'N', 'T', 'E') /* font entry */ +#define TAG_FONTOBJ TAG('F', 'N', 'T', 'O') /* font object */ /* misc */ -#define TAG_DRIVER TAG('G', 'D', 'R', 'V') /* video drivers */ +#define TAG_DRIVER TAG('G', 'D', 'R', 'V') /* video drivers */ +#define TAG_FNTFILE TAG('F', 'N', 'T', 'F') /* font file */ #endif /* _WIN32K_TAGS_H */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 55dda051ad5..63eac2351f4 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.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: dllmain.c,v 1.82 2004/11/20 16:46:05 weiden Exp $ +/* $Id: dllmain.c,v 1.83 2004/12/12 01:40:37 weiden Exp $ * * Entry Point for win32k.sys */ @@ -45,6 +45,8 @@ PsEstablishWin32Callouts( ULONG W32ProcessSize); #endif +BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process); + extern SSDT Win32kSSDT[]; extern SSPT Win32kSSPT[]; extern ULONG Win32kNumberOfSysCalls; @@ -85,7 +87,7 @@ Win32kProcessCallback (struct _EPROCESS *Process, IntCleanupCurIcons(Process, Win32Process); CleanupMonitorImpl(); - CleanupForProcess(Process, Process->UniqueProcessId); + GDI_CleanupForProcess(Process); IntGraphicsCheck(FALSE); @@ -331,6 +333,7 @@ DllMain ( /* Create stock objects, ie. precreated objects commonly used by win32 applications */ CreateStockObjects(); + CreateSysColorObjects(); PREPARE_TESTS diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 622dc572e8e..a622d54a536 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.106 2004/12/03 23:37:43 blight Exp $ +# $Id: makefile,v 1.107 2004/12/12 01:40:37 weiden Exp $ PATH_TO_TOP = ../.. @@ -40,6 +40,7 @@ TARGET_CFLAGS =\ -DUNICODE \ -Wall -Werror \ -D__USE_W32API -D_WIN32_WINNT=0x0501 \ + -DGDI_DEBUG \ -DWINVER=0x600 -D_WIN32K_ \ $(CFLAGS_OPT) @@ -49,7 +50,7 @@ TARGET_LFLAGS =\ --disable-stdcall-fixup ENG_OBJECTS= eng/debug.o eng/error.o eng/mem.o eng/brush.o eng/bitblt.o \ - eng/clip.o eng/copybits.o eng/device.o eng/handle.o eng/lineto.o \ + eng/clip.o eng/copybits.o eng/device.o eng/lineto.o \ eng/paint.o eng/palette.o eng/perfcnt.o eng/semaphor.o eng/surface.o \ eng/xlate.o eng/transblt.o eng/mouse.o eng/misc.o eng/sort.o \ eng/gradient.o eng/event.o eng/float.o @@ -61,7 +62,7 @@ MISC_OBJECTS = misc/driver.o misc/error.o misc/math.o misc/object.o LDR_OBJECTS = ldr/loader.o NTUSER_OBJECTS = ntuser/accelerator.o ntuser/callback.o ntuser/caret.o ntuser/class.o \ - ntuser/clipboard.o ntuser/csr.o ntuser/focus.o ntuser/desktop.o \ + ntuser/clipboard.o ntuser/csr.o ntuser/cursoricon.o ntuser/focus.o ntuser/desktop.o \ ntuser/guicheck.o ntuser/hook.o ntuser/hotkey.o ntuser/input.o \ ntuser/keyboard.o ntuser/menu.o ntuser/message.o ntuser/metric.o \ ntuser/misc.o ntuser/monitor.o ntuser/msgqueue.o ntuser/painting.o \ @@ -70,13 +71,13 @@ NTUSER_OBJECTS = ntuser/accelerator.o ntuser/callback.o ntuser/caret.o ntuser/cl ntuser/winpos.o ntuser/winsta.o OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ - objects/color.o objects/coord.o objects/dc.o \ - objects/fillshap.o objects/gdiobj.o objects/icm.o \ - objects/line.o objects/metafile.o objects/paint.o \ + objects/color.o objects/coord.o \ + objects/dc.o objects/fillshap.o objects/gdiobj.o \ + objects/icm.o objects/line.o objects/metafile.o objects/paint.o \ objects/path.o objects/pen.o objects/print.o \ objects/region.o objects/text.o objects/wingl.o \ objects/bezier.o objects/dib.o objects/palette.o \ - objects/rect.o objects/polyfill.o objects/cursoricon.o + objects/rect.o objects/polyfill.o objects/stockobj.o DIB_OBJECTS = dib/dib.o dib/dib1bpp.o dib/dib4bpp.o dib/dib8bpp.o dib/dib16bpp.o \ dib/dib24bpp.o dib/dib32bpp.o diff --git a/reactos/subsys/win32k/misc/object.c b/reactos/subsys/win32k/misc/object.c index 9105fb1353d..86c7239ffc9 100644 --- a/reactos/subsys/win32k/misc/object.c +++ b/reactos/subsys/win32k/misc/object.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: object.c,v 1.12 2004/06/20 00:45:36 navaraf Exp $ +/* $Id: object.c,v 1.13 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -29,8 +29,7 @@ */ /* INCLUDES ******************************************************************/ -#include -#include +#include #define NDEBUG #include diff --git a/reactos/subsys/win32k/ntddraw/ddraw.c b/reactos/subsys/win32k/ntddraw/ddraw.c index 6447a029e2a..943dfb1618b 100644 --- a/reactos/subsys/win32k/ntddraw/ddraw.c +++ b/reactos/subsys/win32k/ntddraw/ddraw.c @@ -8,71 +8,24 @@ * REVISION HISTORY: * 25-10-2003 PB Created */ + #include #include #include +#include #include #define NDEBUG #include -#define GDI_OBJECT_TYPE_DIRECTDRAW 0x00600000 -#define GDI_OBJECT_TYPE_DD_SURFACE 0x00610000 -#define GDI_OBJECT_TYPE_DD_VIDEOPORT 0x00620000 -#define GDI_OBJECT_TYPE_DD_PALETTE 0x00630000 -#define GDI_OBJECT_TYPE_DD_CLIPPER 0x00640000 -#define GDI_OBJECT_TYPE_DD_MOTIONCOMP 0x00650000 - /************************************************************************/ /* DIRECT DRAW OBJECT */ /************************************************************************/ -typedef struct +BOOL FASTCALL +DD_Cleanup(PDD_DIRECTDRAW pDD) { - DD_DIRECTDRAW_LOCAL Local; - DD_DIRECTDRAW_GLOBAL Global; - // Drv callbacks - PGD_GETDIRECTDRAWINFO DrvGetDirectDrawInfo; - PGD_DISABLEDIRECTDRAW DrvDisableDirectDraw; - // DD callbacks - PDD_CREATESURFACE DdCreateSurface; - PDD_SETCOLORKEY DdDrvSetColorKey; // ????? - PDD_WAITFORVERTICALBLANK DdWaitForVerticalBlank; - PDD_CANCREATESURFACE DdCanCreateSurface; - PDD_CREATEPALETTE DdCreatePalette; - PDD_GETSCANLINE DdGetScanLine; - PDD_MAPMEMORY DdMapMemory; - // Surface callbacks - PDD_SURFCB_DESTROYSURFACE DdDestroySurface; - PDD_SURFCB_FLIP DdFlip; - PDD_SURFCB_SETCLIPLIST DdSetClipList; - PDD_SURFCB_LOCK DdLock; - PDD_SURFCB_UNLOCK DdUnlock; - PDD_SURFCB_BLT DdBlt; - PDD_SURFCB_SETCOLORKEY DdSetColorKey; - PDD_SURFCB_ADDATTACHEDSURFACE DdAddAttachedSurface; - PDD_SURFCB_GETBLTSTATUS DdGetBltStatus; - PDD_SURFCB_GETFLIPSTATUS DdGetFlipStatus; - PDD_SURFCB_UPDATEOVERLAY DdUpdateOverlay; - PDD_SURFCB_SETOVERLAYPOSITION DdSetOverlayPosition; - PDD_SURFCB_SETPALETTE DdSetPalette; - // Palette callbacks - PDD_PALCB_DESTROYPALETTE DdDestroyPalette; - PDD_PALCB_SETENTRIES DdSetEntries; - // D3D Device context callbacks - PD3DNTHAL_CONTEXTCREATECB D3dContextCreate; - PD3DNTHAL_CONTEXTDESTROYCB D3dContextDestroy; - // D3D Buffer callbacks - PDD_CANCREATESURFACE DdCanCreateD3DBuffer; - PDD_CREATESURFACE DdCreateD3DBuffer; - PDD_SURFCB_DESTROYSURFACE DdDestroyD3DBuffer; - PDD_SURFCB_LOCK DdLockD3DBuffer; - PDD_SURFCB_UNLOCK DdUnlockD3DBuffer; -} DD_DIRECTDRAW, *PDD_DIRECTDRAW; - -static BOOL FASTCALL DirectDrawCleanup(PDD_DIRECTDRAW pDirectDraw) -{ - pDirectDraw->DrvDisableDirectDraw(pDirectDraw->Global.dhpdev); + pDD->DrvDisableDirectDraw(pDD->Global.dhpdev); return TRUE; } @@ -112,7 +65,7 @@ HANDLE STDCALL NtGdiDdCreateDirectDrawObject( return NULL; } - HANDLE hDirectDraw = GDIOBJ_AllocObj(sizeof(DD_DIRECTDRAW), GDI_OBJECT_TYPE_DIRECTDRAW, (GDICLEANUPPROC)DirectDrawCleanup); + HANDLE hDirectDraw = GDIOBJ_AllocObj(GDI_OBJECT_TYPE_DIRECTDRAW); PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW); pDirectDraw->Global.dhpdev = pDC->PDev; @@ -121,54 +74,54 @@ HANDLE STDCALL NtGdiDdCreateDirectDrawObject( pDirectDraw->DrvGetDirectDrawInfo = pDC->DriverFunctions.GetDirectDrawInfo; pDirectDraw->DrvDisableDirectDraw = pDC->DriverFunctions.DisableDirectDraw; - if (callbacks.dwFlags && DDHAL_CB32_CREATESURFACE) + if (callbacks.dwFlags & DDHAL_CB32_CREATESURFACE) pDirectDraw->DdCreateSurface = callbacks.CreateSurface; - if (callbacks.dwFlags && DDHAL_CB32_SETCOLORKEY) + if (callbacks.dwFlags & DDHAL_CB32_SETCOLORKEY) pDirectDraw->DdDrvSetColorKey = callbacks.SetColorKey; - if (callbacks.dwFlags && DDHAL_CB32_WAITFORVERTICALBLANK) + if (callbacks.dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK) pDirectDraw->DdWaitForVerticalBlank = callbacks.WaitForVerticalBlank; - if (callbacks.dwFlags && DDHAL_CB32_CANCREATESURFACE) + if (callbacks.dwFlags & DDHAL_CB32_CANCREATESURFACE) pDirectDraw->DdCanCreateSurface = callbacks.CanCreateSurface; - if (callbacks.dwFlags && DDHAL_CB32_CREATEPALETTE) + if (callbacks.dwFlags & DDHAL_CB32_CREATEPALETTE) pDirectDraw->DdCreatePalette = callbacks.CreatePalette; - if (callbacks.dwFlags && DDHAL_CB32_GETSCANLINE) + if (callbacks.dwFlags & DDHAL_CB32_GETSCANLINE) pDirectDraw->DdGetScanLine = callbacks.GetScanLine; - if (callbacks.dwFlags && DDHAL_CB32_MAPMEMORY) + if (callbacks.dwFlags & DDHAL_CB32_MAPMEMORY) pDirectDraw->DdMapMemory = callbacks.MapMemory; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_DESTROYSURFACE) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_DESTROYSURFACE) pDirectDraw->DdDestroySurface = surface_callbacks.DestroySurface; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_FLIP) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_FLIP) pDirectDraw->DdFlip = surface_callbacks.Flip; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETCLIPLIST) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_SETCLIPLIST) pDirectDraw->DdSetClipList = surface_callbacks.SetClipList; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_LOCK) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_LOCK) pDirectDraw->DdLock = surface_callbacks.Lock; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_UNLOCK) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_UNLOCK) pDirectDraw->DdUnlock = surface_callbacks.Unlock; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_BLT) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_BLT) pDirectDraw->DdBlt = surface_callbacks.Blt; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETCOLORKEY) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_SETCOLORKEY) pDirectDraw->DdSetColorKey = surface_callbacks.SetColorKey; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_ADDATTACHEDSURFACE) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_ADDATTACHEDSURFACE) pDirectDraw->DdAddAttachedSurface = surface_callbacks.AddAttachedSurface; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_GETBLTSTATUS) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_GETBLTSTATUS) pDirectDraw->DdGetBltStatus = surface_callbacks.GetBltStatus; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_GETFLIPSTATUS) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_GETFLIPSTATUS) pDirectDraw->DdGetFlipStatus = surface_callbacks.GetFlipStatus; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_UPDATEOVERLAY) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_UPDATEOVERLAY) pDirectDraw->DdUpdateOverlay = surface_callbacks.UpdateOverlay; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETOVERLAYPOSITION) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_SETOVERLAYPOSITION) pDirectDraw->DdSetOverlayPosition = surface_callbacks.SetOverlayPosition; - if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETPALETTE) + if (surface_callbacks.dwFlags & DDHAL_SURFCB32_SETPALETTE) pDirectDraw->DdSetPalette = surface_callbacks.SetPalette; - if (palette_callbacks.dwFlags && DDHAL_PALCB32_DESTROYPALETTE) + if (palette_callbacks.dwFlags & DDHAL_PALCB32_DESTROYPALETTE) pDirectDraw->DdDestroyPalette = palette_callbacks.DestroyPalette; - if (palette_callbacks.dwFlags && DDHAL_PALCB32_SETENTRIES) + if (palette_callbacks.dwFlags & DDHAL_PALCB32_SETENTRIES) pDirectDraw->DdSetEntries = palette_callbacks.SetEntries; - GDIOBJ_UnlockObj(hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW); + GDIOBJ_UnlockObj(hDirectDraw); DC_UnlockDc(hdc); return hDirectDraw; @@ -178,7 +131,7 @@ BOOL STDCALL NtGdiDdDeleteDirectDrawObject( HANDLE hDirectDrawLocal ) { - return GDIOBJ_FreeObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW, 0); + return GDIOBJ_FreeObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW); } BOOL STDCALL NtGdiDdQueryDirectDrawObject( @@ -209,7 +162,7 @@ BOOL STDCALL NtGdiDdQueryDirectDrawObject( if (!success) { - GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW); + GDIOBJ_UnlockObj(hDirectDrawLocal); return FALSE; } @@ -235,7 +188,7 @@ BOOL STDCALL NtGdiDdQueryDirectDrawObject( pDirectDraw->DdUnlockD3DBuffer = puD3dBufferCallbacks->UnlockD3DBuffer; } - GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW); + GDIOBJ_UnlockObj(hDirectDrawLocal); return TRUE; } @@ -244,17 +197,8 @@ BOOL STDCALL NtGdiDdQueryDirectDrawObject( /* SURFACE OBJECT */ /************************************************************************/ -typedef struct -{ - DD_SURFACE_LOCAL Local; - DD_SURFACE_MORE More; - DD_SURFACE_GLOBAL Global; - DD_ATTACHLIST AttachList; - DD_ATTACHLIST AttachListFrom; - BOOL bComplete; -} DD_SURFACE, *PDD_SURFACE; - -static BOOL FASTCALL DDSurfaceCleanup(PDD_SURFACE pSurface) +BOOL FASTCALL +DDSURF_Cleanup(PDD_SURFACE pDDSurf) { //FIXME: implement return TRUE; @@ -274,10 +218,11 @@ HANDLE STDCALL NtGdiDdCreateSurfaceObject( return NULL; if (!hSurface) - hSurface = GDIOBJ_AllocObj(sizeof(DD_SURFACE), GDI_OBJECT_TYPE_DD_SURFACE, (GDICLEANUPPROC)DDSurfaceCleanup); + hSurface = GDIOBJ_AllocObj(GDI_OBJECT_TYPE_DD_SURFACE); PDD_SURFACE pSurface = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE); - + /* FIXME - Handle pSurface == NULL!!!! */ + RtlMoveMemory(&pSurface->Local, puSurfaceLocal, sizeof(DD_SURFACE_LOCAL)); RtlMoveMemory(&pSurface->More, puSurfaceMore, sizeof(DD_SURFACE_MORE)); RtlMoveMemory(&pSurface->Global, puSurfaceGlobal, sizeof(DD_SURFACE_GLOBAL)); @@ -289,8 +234,8 @@ HANDLE STDCALL NtGdiDdCreateSurfaceObject( // FIXME: figure out how to use this pSurface->bComplete = bComplete; - GDIOBJ_UnlockObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE); - GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW); + GDIOBJ_UnlockObj(hSurface); + GDIOBJ_UnlockObj(hDirectDrawLocal); return hSurface; } @@ -299,7 +244,7 @@ BOOL STDCALL NtGdiDdDeleteSurfaceObject( HANDLE hSurface ) { - return GDIOBJ_FreeObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE, 0); + return GDIOBJ_FreeObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE); } /* @@ -314,7 +259,7 @@ BOOL STDCALL NtGdiDdAttachSurface( PDD_SURFACE pSurfaceTo = GDIOBJ_LockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE); if (!pSurfaceTo) { - GDIOBJ_UnlockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE); + GDIOBJ_UnlockObj(hSurfaceFrom); return FALSE; } @@ -323,8 +268,8 @@ BOOL STDCALL NtGdiDdAttachSurface( pSurfaceFrom->Local.lpAttachListFrom = pSurfaceFrom->AttachListFrom; } - GDIOBJ_UnlockObj(hSurfaceFrom, GDI_OBJECT_TYPE_DD_SURFACE); - GDIOBJ_UnlockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE); + GDIOBJ_UnlockObj(hSurfaceFrom); + GDIOBJ_UnlockObj(hSurfaceTo); return TRUE; } */ diff --git a/reactos/subsys/win32k/objects/cursoricon.c b/reactos/subsys/win32k/ntuser/cursoricon.c similarity index 95% rename from reactos/subsys/win32k/objects/cursoricon.c rename to reactos/subsys/win32k/ntuser/cursoricon.c index 6e1ecf6da5a..5b69597bd5b 100644 --- a/reactos/subsys/win32k/objects/cursoricon.c +++ b/reactos/subsys/win32k/ntuser/cursoricon.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: cursoricon.c,v 1.66 2004/11/21 21:23:24 weiden Exp $ */ +/* $Id: cursoricon.c,v 1.1 2004/12/12 01:40:38 weiden Exp $ */ #include PCURICON_OBJECT FASTCALL @@ -46,11 +46,10 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, PSYSTEM_CURSORINFO CurInfo; PCURICON_OBJECT OldCursor; HCURSOR Ret = (HCURSOR)0; - HBITMAP hColor = (HBITMAP)0; + HBITMAP dcbmp, hColor = (HBITMAP)0; HBITMAP hMask = 0; SURFOBJ *soMask = NULL, *soColor = NULL; XLATEOBJ *XlateObj = NULL; - RECTL PointerRect; HDC Screen; CurInfo = IntGetSysCursorInfo(WinStaObject); @@ -64,7 +63,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, { return Ret; } - + else { if(!(Screen = IntGetScreenDC())) { @@ -77,11 +76,13 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, { return Ret; } - - BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); - SurfObj = &BitmapObj->SurfObj; + dcbmp = dc->w.hBitmap; DevInfo = dc->DevInfo; DC_UnlockDc(Screen); + + BitmapObj = BITMAPOBJ_LockBitmap(dcbmp); + /* FIXME - BitmapObj can be NULL!!!!! */ + SurfObj = &BitmapObj->SurfObj; } if (!NewCursor && (CurInfo->CurrentCursorObject || ForceChange)) @@ -89,22 +90,21 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, if (NULL != CurInfo->CurrentCursorObject && CurInfo->ShowingCursor) { /* Remove the cursor if it was displayed */ - if (GDIDEV(SurfObj)->MovePointer) - GDIDEV(SurfObj)->MovePointer(SurfObj, -1, -1, &PointerRect); - SetPointerRect(CurInfo, &PointerRect); + if (GDIDEV(SurfObj)->Pointer.MovePointer) + GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, -1, -1, NULL); } - GDIDEV(SurfObj)->PointerStatus = SPS_ACCEPT_NOEXCLUDE; + GDIDEV(SurfObj)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE; CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */ CurInfo->ShowingCursor = 0; - BITMAPOBJ_UnlockBitmap(SurfObj->hsurf); + BITMAPOBJ_UnlockBitmap(dcbmp); return Ret; } if (!NewCursor) { - BITMAPOBJ_UnlockBitmap(SurfObj->hsurf); + BITMAPOBJ_UnlockBitmap(dcbmp); return Ret; } @@ -119,7 +119,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, if (maskBpp != 1) { DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n"); - BITMAPOBJ_UnlockBitmap(SurfObj->hsurf); + BITMAPOBJ_UnlockBitmap(dcbmp); return Ret; } @@ -180,43 +180,41 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, if (GDIDEVFUNCS(SurfObj).SetPointerShape) { - GDIDEV(SurfObj)->PointerStatus = + GDIDEV(SurfObj)->Pointer.Status = GDIDEVFUNCS(SurfObj).SetPointerShape( SurfObj, soMask, soColor, XlateObj, NewCursor->IconInfo.xHotspot, NewCursor->IconInfo.yHotspot, CurInfo->x, CurInfo->y, - &PointerRect, + NULL, SPS_CHANGE); DPRINT("SetCursor: DrvSetPointerShape() returned %x\n", - GDIDEV(SurfObj)->PointerStatus); + GDIDEV(SurfObj)->Pointer.Status); } else { - GDIDEV(SurfObj)->PointerStatus = SPS_DECLINE; + GDIDEV(SurfObj)->Pointer.Status = SPS_DECLINE; } - if(GDIDEV(SurfObj)->PointerStatus == SPS_DECLINE) + if(GDIDEV(SurfObj)->Pointer.Status == SPS_DECLINE) { - GDIDEV(SurfObj)->PointerStatus = EngSetPointerShape( + GDIDEV(SurfObj)->Pointer.Status = EngSetPointerShape( SurfObj, soMask, soColor, XlateObj, NewCursor->IconInfo.xHotspot, NewCursor->IconInfo.yHotspot, CurInfo->x, CurInfo->y, - &PointerRect, + NULL, SPS_CHANGE); - GDIDEV(SurfObj)->MovePointer = EngMovePointer; + GDIDEV(SurfObj)->Pointer.MovePointer = EngMovePointer; } else { - GDIDEV(SurfObj)->MovePointer = GDIDEVFUNCS(SurfObj).MovePointer; + GDIDEV(SurfObj)->Pointer.MovePointer = GDIDEVFUNCS(SurfObj).MovePointer; } - SetPointerRect(CurInfo, &PointerRect); - - BITMAPOBJ_UnlockBitmap(SurfObj->hsurf); + BITMAPOBJ_UnlockBitmap(dcbmp); if(hMask) { EngUnlockSurface(soMask); @@ -231,7 +229,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, EngDeleteXlate(XlateObj); } - if(GDIDEV(SurfObj)->PointerStatus == SPS_ERROR) + if(GDIDEV(SurfObj)->Pointer.Status == SPS_ERROR) DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n"); return Ret; @@ -355,9 +353,15 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL Rem /* delete bitmaps */ if(bmpMask) + { + GDIOBJ_SetOwnership(bmpMask, PsGetCurrentProcess()); NtGdiDeleteObject(bmpMask); + } if(bmpColor) + { + GDIOBJ_SetOwnership(bmpColor, PsGetCurrentProcess()); NtGdiDeleteObject(bmpColor); + } ObmDereferenceObject(Object); @@ -427,6 +431,7 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect) CurIconObject->Size.cx = bmp->SurfObj.sizlBitmap.cx; CurIconObject->Size.cy = bmp->SurfObj.sizlBitmap.cy; BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor); + GDIOBJ_SetOwnership(CurIconObject->IconInfo.hbmColor, NULL); } else { @@ -436,6 +441,7 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect) CurIconObject->Size.cx = bmp->SurfObj.sizlBitmap.cx; CurIconObject->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2; BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmMask); + GDIOBJ_SetOwnership(CurIconObject->IconInfo.hbmMask, NULL); } } } @@ -894,6 +900,7 @@ NtUserSetCursorIconContents( CurIconObject->Size.cx = bmp->SurfObj.sizlBitmap.cx; CurIconObject->Size.cy = bmp->SurfObj.sizlBitmap.cy; BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor); + GDIOBJ_SetOwnership(CurIconObject->IconInfo.hbmColor, NULL); } else { @@ -905,6 +912,7 @@ NtUserSetCursorIconContents( CurIconObject->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2; BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmMask); + GDIOBJ_SetOwnership(CurIconObject->IconInfo.hbmMask, NULL); } Ret = TRUE; diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c index 3430d0a2f3b..90fbd10ce82 100644 --- a/reactos/subsys/win32k/ntuser/desktop.c +++ b/reactos/subsys/win32k/ntuser/desktop.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: desktop.c,v 1.27 2004/12/10 16:52:04 navaraf Exp $ + * $Id: desktop.c,v 1.28 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -287,6 +287,7 @@ IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect) PDC dc; BITMAPOBJ *BitmapObj; dc = DC_LockDc(ScreenDeviceContext); + /* FIXME - Handle dc == NULL!!!! */ BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); if(BitmapObj) { diff --git a/reactos/subsys/win32k/ntuser/input.c b/reactos/subsys/win32k/ntuser/input.c index b665e59ca67..b56e3132ab0 100644 --- a/reactos/subsys/win32k/ntuser/input.c +++ b/reactos/subsys/win32k/ntuser/input.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: input.c,v 1.38 2004/09/28 15:02:30 weiden Exp $ +/* $Id: input.c,v 1.39 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -543,7 +543,6 @@ IntMouseInput(MOUSEINPUT *mi) BITMAPOBJ *BitmapObj; SURFOBJ *SurfObj; PDC dc; - RECTL PointerRect; PWINDOW_OBJECT DesktopWindow; NTSTATUS Status; @@ -649,16 +648,12 @@ IntMouseInput(MOUSEINPUT *mi) { SurfObj = &BitmapObj->SurfObj; - if (GDIDEV(SurfObj)->MovePointer) + if (GDIDEV(SurfObj)->Pointer.MovePointer) { - GDIDEV(SurfObj)->MovePointer(SurfObj, MousePos.x, MousePos.y, &PointerRect); + GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, MousePos.x, MousePos.y, NULL); } BITMAPOBJ_UnlockBitmap(hBitmap); - - ExAcquireFastMutex(&CurInfo->CursorMutex); - SetPointerRect(CurInfo, &PointerRect); - ExReleaseFastMutex(&CurInfo->CursorMutex); } } } diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index 8f67dd07de6..7772a2c03b3 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.90 2004/12/10 16:52:04 navaraf Exp $ +/* $Id: misc.c,v 1.91 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -130,9 +130,9 @@ NtUserCallNoParam(DWORD Routine) case NOPARAM_ROUTINE_CSRSS_INITIALIZED: Result = (DWORD)CsrInit(); break; - + case NOPARAM_ROUTINE_GDI_QUERY_TABLE: - /* not used yet */ + Result = (DWORD)GDI_MapHandleTable(NtCurrentProcess()); break; default: @@ -222,7 +222,9 @@ NtUserCallOneParam( if (!NT_SUCCESS(Status)) return (DWORD)FALSE; - Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); + /* FIXME + Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */ + Result = 0; ObDereferenceObject(WinStaObject); return Result; @@ -512,6 +514,100 @@ NtUserCallTwoParam( case TWOPARAM_ROUTINE_REGISTERLOGONPROC: return (DWORD)IntRegisterLogonProcess(Param1, (BOOL)Param2); + + case TWOPARAM_ROUTINE_SETSYSCOLORS: + { + DWORD Ret = 0; + PVOID Buffer; + struct + { + INT *Elements; + COLORREF *Colors; + } ChangeSysColors; + + /* FIXME - we should make use of SEH here... */ + + Status = MmCopyFromCaller(&ChangeSysColors, (PVOID)Param1, sizeof(ChangeSysColors)); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return 0; + } + + Buffer = ExAllocatePool(PagedPool, (Param2 * sizeof(INT)) + (Param2 * sizeof(COLORREF))); + if(Buffer != NULL) + { + INT *Elements = (INT*)Buffer; + COLORREF *Colors = (COLORREF*)Buffer + Param2; + + Status = MmCopyFromCaller(Elements, ChangeSysColors.Elements, Param2 * sizeof(INT)); + if(NT_SUCCESS(Status)) + { + Status = MmCopyFromCaller(Colors, ChangeSysColors.Colors, Param2 * sizeof(COLORREF)); + if(NT_SUCCESS(Status)) + { + Ret = (DWORD)IntSetSysColors((UINT)Param2, Elements, Colors); + } + else + SetLastNtError(Status); + } + else + SetLastNtError(Status); + + ExFreePool(Buffer); + } + return Ret; + } + + case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES: + case TWOPARAM_ROUTINE_GETSYSCOLORPENS: + case TWOPARAM_ROUTINE_GETSYSCOLORS: + { + DWORD Ret; + union + { + PVOID Pointer; + HBRUSH *Brushes; + HPEN *Pens; + COLORREF *Colors; + } Buffer; + + /* FIXME - we should make use of SEH here... */ + + Buffer.Pointer = ExAllocatePool(PagedPool, Param2 * sizeof(HANDLE)); + if(Buffer.Pointer != NULL) + { + switch(Routine) + { + case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES: + Ret = (DWORD)IntGetSysColorBrushes(Buffer.Brushes, (UINT)Param2); + break; + case TWOPARAM_ROUTINE_GETSYSCOLORPENS: + Ret = (DWORD)IntGetSysColorPens(Buffer.Pens, (UINT)Param2); + break; + case TWOPARAM_ROUTINE_GETSYSCOLORS: + Ret = (DWORD)IntGetSysColors(Buffer.Colors, (UINT)Param2); + break; + default: + Ret = 0; + break; + } + + if(Ret > 0) + { + Status = MmCopyToCaller((PVOID)Param1, Buffer.Pointer, Param2 * sizeof(HANDLE)); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + Ret = 0; + } + } + + ExFreePool(Buffer.Pointer); + } + + return Ret; + } } DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n", diff --git a/reactos/subsys/win32k/ntuser/stubs.c b/reactos/subsys/win32k/ntuser/stubs.c index 0e88e8db123..4daa3c327a9 100644 --- a/reactos/subsys/win32k/ntuser/stubs.c +++ b/reactos/subsys/win32k/ntuser/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.48 2004/12/06 02:23:05 navaraf Exp $ +/* $Id: stubs.c,v 1.49 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -8,8 +8,7 @@ * REVISION HISTORY: * 04-06-2001 CSH Created */ -#include -#include +#include #define NDEBUG #include diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 962cdc4aebe..f715dcae718 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.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: windc.c,v 1.67 2004/08/03 19:55:57 blight Exp $ +/* $Id: windc.c,v 1.68 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -586,25 +586,26 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) return(Dce->hDC); } -BOOL FASTCALL -DCE_InternalDelete(PDCE Dce) +BOOL INTERNAL_CALL +DCE_Cleanup(PVOID ObjectBody) { PDCE PrevInList; + PDCE pDce = (PDCE)ObjectBody; DCE_LockList(); - if (Dce == FirstDce) + if (pDce == FirstDce) { - FirstDce = Dce->next; - PrevInList = Dce; + FirstDce = pDce->next; + PrevInList = pDce; } else { for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next) { - if (Dce == PrevInList->next) + if (pDce == PrevInList->next) { - PrevInList->next = Dce->next; + PrevInList->next = pDce->next; break; } } @@ -665,7 +666,7 @@ NtUserReleaseDC(HWND hWnd, HDC hDc) * DceFreeDCE */ PDCE FASTCALL -DceFreeDCE(PDCE dce) +DceFreeDCE(PDCE dce, BOOLEAN Force) { DCE *ret; HANDLE hDce; @@ -681,6 +682,13 @@ DceFreeDCE(PDCE dce) SetDCHook(dce->hDC, NULL, 0L); #endif + if(Force && !GDIOBJ_OwnedByCurrentProcess(dce->hDC)) + { + /* FIXME - changing ownership to current process only works for global objects! */ + GDIOBJ_SetOwnership(dce->hDC, PsGetCurrentProcess()); + DC_SetOwnership(dce->hDC, PsGetCurrentProcess()); + } + NtGdiDeleteDC(dce->hDC); if (dce->hClipRgn && ! (dce->DCXFlags & DCX_KEEPCLIPRGN)) { @@ -688,6 +696,11 @@ DceFreeDCE(PDCE dce) } hDce = dce->Self; + if(Force && !GDIOBJ_OwnedByCurrentProcess(hDce)) + { + /* FIXME - changing ownership to current process only works for global objects! */ + GDIOBJ_SetOwnership(hDce, PsGetCurrentProcess()); + } DCEOBJ_FreeDCE(hDce); return ret; @@ -715,7 +728,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window) { if (Window->Class->style & CS_OWNDC) /* owned DCE*/ { - pDCE = DceFreeDCE(pDCE); + pDCE = DceFreeDCE(pDCE, FALSE); Window->Dce = NULL; continue; } @@ -756,7 +769,7 @@ DceEmptyCache() DCE_LockList(); while (FirstDce != NULL) { - DceFreeDCE(FirstDce); + DceFreeDCE(FirstDce, TRUE); } DCE_UnlockList(); } @@ -793,9 +806,16 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window, int DeltaX, int DeltaY) continue; } } + if (!GDIOBJ_OwnedByCurrentProcess(pDCE->hDC)) + { + /* skip DCs we don't even own */ + goto skip; + } + dc = DC_LockDc(pDCE->hDC); if (dc == NULL) { +skip: if (Window->Self != pDCE->hwndCurrent) { IntReleaseWindowObject(CurrentWindow); diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 173a52d5555..1159f77dda3 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.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: window.c,v 1.252 2004/12/11 21:19:41 weiden Exp $ +/* $Id: window.c,v 1.253 2004/12/12 01:40:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -2506,7 +2506,10 @@ NtUserFindWindowEx(HWND hwndParent, } #endif - ClassDereferenceObject(ClassObject); + if (ClassObject != NULL) + { + ClassDereferenceObject(ClassObject); + } Cleanup: if(ClassName.Length > 0 && ClassName.Buffer) diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index 208b2c19b36..5120de74d20 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.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: winpos.c,v 1.125 2004/12/11 19:39:18 weiden Exp $ +/* $Id: winpos.c,v 1.126 2004/12/12 01:40:38 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1046,7 +1046,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, * there's nothing to copy. Also, it's no use copying bits onto * themselves. */ - VisRgn = NULL; if ((VisRgn = (PROSRGNDATA)RGNDATA_LockRgn(CopyRgn)) && UnsafeIntGetRgnBox(VisRgn, &CopyRect) == NULLREGION) { diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 5cf023f2c1b..d06aceac0b1 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.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: winsta.c,v 1.67 2004/11/21 13:02:02 weiden Exp $ + * $Id: winsta.c,v 1.68 2004/12/12 01:40:38 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -197,8 +197,6 @@ IntInitializeDesktopGraphics(VOID) } DC_SetOwnership(ScreenDeviceContext, NULL); - EnableMouse(ScreenDeviceContext); - NtUserAcquireOrReleaseInputOwnership(FALSE); return TRUE; @@ -208,7 +206,6 @@ VOID FASTCALL IntEndDesktopGraphics(VOID) { NtUserAcquireOrReleaseInputOwnership(TRUE); - EnableMouse(FALSE); if (NULL != ScreenDeviceContext) { DC_SetOwnership(ScreenDeviceContext, PsGetCurrentProcess()); @@ -401,8 +398,6 @@ NtUserCreateWindowStation( /* FIXME: Obtain the following information from the registry */ CurInfo->SwapButtons = FALSE; - CurInfo->SafetySwitch = FALSE; - CurInfo->SafetyRemoveCount = 0; CurInfo->DblClickSpeed = 500; CurInfo->DblClickWidth = 4; CurInfo->DblClickHeight = 4; diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index f17d6754744..bf45a038f5e 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.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: bitmaps.c,v 1.81 2004/11/21 10:55:29 navaraf Exp $ */ +/* $Id: bitmaps.c,v 1.82 2004/12/12 01:40:38 weiden Exp $ */ #include #define IN_RECT(r,x,y) \ @@ -126,6 +126,14 @@ NtGdiBitBlt( { DC_UnlockDc(hDCSrc); } + if(BitmapDest != NULL) + { + BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap); + } + if(BitmapSrc != NULL && BitmapSrc != BitmapDest) + { + BITMAPOBJ_UnlockBitmap(DCSrc->w.hBitmap); + } DC_UnlockDc(hDCDest); SetLastWin32Error(ERROR_INVALID_HANDLE); return FALSE; @@ -173,6 +181,18 @@ NtGdiBitBlt( DC_UnlockDc(hDCSrc); } DC_UnlockDc(hDCDest); + if(BitmapDest != NULL) + { + BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap); + } + if(BitmapSrc != NULL && BitmapSrc != BitmapDest) + { + BITMAPOBJ_UnlockBitmap(DCSrc->w.hBitmap); + } + if(BrushObj != NULL) + { + BRUSHOBJ_UnlockBrush(DCDest->w.hBrush); + } SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); return FALSE; } @@ -185,12 +205,16 @@ NtGdiBitBlt( if (UsesSource && XlateObj != NULL) EngDeleteXlate(XlateObj); - BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap); - if (UsesSource && DCSrc->w.hBitmap != DCDest->w.hBitmap) + + if(BitmapDest != NULL) + { + BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap); + } + if (UsesSource && BitmapSrc != BitmapDest) { BITMAPOBJ_UnlockBitmap(DCSrc->w.hBitmap); } - if (UsesPattern) + if (BrushObj != NULL) { BRUSHOBJ_UnlockBrush(DCDest->w.hBrush); } @@ -296,8 +320,10 @@ NtGdiTransparentBlt( XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette); BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap); + /* FIXME - BitmapDest can be NULL!!!! Don't assert here! */ ASSERT(BitmapDest); BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap); + /* FIXME - BitmapSrc can be NULL!!!! Don't assert here! */ ASSERT(BitmapSrc); rcDest.left = xDst; @@ -374,6 +400,7 @@ NtGdiCreateBitmap( Size.cx, Size.cy, BitsPerPel, hBitmap); bmp = BITMAPOBJ_LockBitmap( hBitmap ); + /* FIXME - bmp can be NULL!!!!!! */ bmp->flFlags = BITMAPOBJ_IS_APIBITMAP; BITMAPOBJ_UnlockBitmap( hBitmap ); @@ -391,11 +418,10 @@ NtGdiCreateBitmap( return hBitmap; } -BOOL FASTCALL -Bitmap_InternalDelete( PBITMAPOBJ pBmp ) +BOOL INTERNAL_CALL +BITMAP_Cleanup(PVOID ObjectBody) { - ASSERT( pBmp ); - + PBITMAPOBJ pBmp = (PBITMAPOBJ)ObjectBody; if (pBmp->SurfObj.pvBits != NULL && (pBmp->flFlags & BITMAPOBJ_IS_APIBITMAP)) { @@ -572,8 +598,8 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) } EngDeleteXlate(XlateObj); } + BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); } - BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); } DC_UnlockDc(hDC); diff --git a/reactos/subsys/win32k/objects/brush.c b/reactos/subsys/win32k/objects/brush.c index 29671b98cd7..b487ff4912d 100644 --- a/reactos/subsys/win32k/objects/brush.c +++ b/reactos/subsys/win32k/objects/brush.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: brush.c,v 1.41 2004/12/05 00:20:41 navaraf Exp $ + * $Id: brush.c,v 1.42 2004/12/12 01:40:38 weiden Exp $ */ #include @@ -31,11 +31,10 @@ static const USHORT HatchBrushes[NB_HATCH_STYLES][8] = {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81} /* HS_DIAGCROSS */ }; -BOOL FASTCALL -Brush_InternalDelete( PGDIBRUSHOBJ pBrush ) +BOOL INTERNAL_CALL +BRUSH_Cleanup(PVOID ObjectBody) { - ASSERT(pBrush); - + PGDIBRUSHOBJ pBrush = (PGDIBRUSHOBJ)ObjectBody; if(pBrush->flAttrs & (GDIBRUSH_IS_HATCH | GDIBRUSH_IS_BITMAP)) { ASSERT(pBrush->hbmPattern); @@ -132,40 +131,44 @@ IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush) } BrushObject = BRUSHOBJ_LockBrush(hBrush); - - switch (LogBrush->lbStyle) + if(BrushObject != NULL) { - case BS_NULL: - BrushObject->flAttrs |= GDIBRUSH_IS_NULL; - break; + switch (LogBrush->lbStyle) + { + case BS_NULL: + BrushObject->flAttrs |= GDIBRUSH_IS_NULL; + break; - case BS_SOLID: - BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; - BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; - /* FIXME: Fill in the rest of fields!!! */ - break; + case BS_SOLID: + BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; + BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; + /* FIXME: Fill in the rest of fields!!! */ + break; - case BS_HATCHED: - BrushObject->flAttrs |= GDIBRUSH_IS_HATCH; - BrushObject->hbmPattern = hPattern; - BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; - break; + case BS_HATCHED: + BrushObject->flAttrs |= GDIBRUSH_IS_HATCH; + BrushObject->hbmPattern = hPattern; + BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; + break; - case BS_PATTERN: - BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP; - BrushObject->hbmPattern = hPattern; - /* FIXME: Fill in the rest of fields!!! */ - break; + case BS_PATTERN: + BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP; + BrushObject->hbmPattern = hPattern; + /* FIXME: Fill in the rest of fields!!! */ + break; - default: - DPRINT1("Brush Style: %d\n", LogBrush->lbStyle); - UNIMPLEMENTED; + default: + DPRINT1("Brush Style: %d\n", LogBrush->lbStyle); + UNIMPLEMENTED; + break; + } + + BRUSHOBJ_UnlockBrush(hBrush); } if (hPattern != 0) GDIOBJ_SetOwnership(hPattern, NULL); - BRUSHOBJ_UnlockBrush(hBrush); return hBrush; } @@ -185,6 +188,8 @@ IntPatBlt( POINTL BrushOrigin; BOOL ret = TRUE; + ASSERT(BrushObj); + BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); if (BitmapObj == NULL) { @@ -192,7 +197,6 @@ IntPatBlt( return FALSE; } - ASSERT(BrushObj); if (!(BrushObj->flAttrs & GDIBRUSH_IS_NULL)) { if (Width > 0) @@ -264,15 +268,18 @@ IntGdiPolyPatBlt( for (r = pRects, i = 0; i < cRects; i++) { BrushObj = BRUSHOBJ_LockBrush(r->hBrush); - IntPatBlt( - dc, - r->r.left, - r->r.top, - r->r.right, - r->r.bottom, - dwRop, - BrushObj); - BRUSHOBJ_UnlockBrush(r->hBrush); + if(BrushObj != NULL) + { + IntPatBlt( + dc, + r->r.left, + r->r.top, + r->r.right, + r->r.bottom, + dwRop, + BrushObj); + BRUSHOBJ_UnlockBrush(r->hBrush); + } r++; } diff --git a/reactos/subsys/win32k/objects/cliprgn.c b/reactos/subsys/win32k/objects/cliprgn.c index d86fa9c0465..6c50e327202 100644 --- a/reactos/subsys/win32k/objects/cliprgn.c +++ b/reactos/subsys/win32k/objects/cliprgn.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: cliprgn.c,v 1.43 2004/12/07 19:53:44 royce Exp $ */ +/* $Id: cliprgn.c,v 1.44 2004/12/12 01:40:38 weiden Exp $ */ #include int FASTCALL @@ -33,35 +33,38 @@ CLIPPING_UpdateGCRegion(DC* Dc) NtGdiCombineRgn(Dc->w.hGCClipRgn, Dc->w.hClipRgn, Dc->w.hVisRgn, RGN_AND); NtGdiOffsetRgn(Dc->w.hGCClipRgn, Dc->w.DCOrgX, Dc->w.DCOrgY); - CombinedRegion = RGNDATA_LockRgn(Dc->w.hGCClipRgn); - ASSERT(CombinedRegion != NULL); + if((CombinedRegion = RGNDATA_LockRgn(Dc->w.hGCClipRgn))) + { + if (Dc->CombinedClip != NULL) + IntEngDeleteClipRegion(Dc->CombinedClip); - if (Dc->CombinedClip != NULL) - IntEngDeleteClipRegion(Dc->CombinedClip); + Dc->CombinedClip = IntEngCreateClipRegion( + CombinedRegion->rdh.nCount, + (PRECTL)CombinedRegion->Buffer, + (PRECTL)&CombinedRegion->rdh.rcBound); - Dc->CombinedClip = IntEngCreateClipRegion( - CombinedRegion->rdh.nCount, - (PRECTL)CombinedRegion->Buffer, - (PRECTL)&CombinedRegion->rdh.rcBound); + RGNDATA_UnlockRgn(Dc->w.hGCClipRgn); + } - RGNDATA_UnlockRgn(Dc->w.hGCClipRgn); if ( NULL == Dc->CombinedClip ) { DPRINT1("IntEngCreateClipRegion() failed\n"); return ERROR; } + return NtGdiOffsetRgn(Dc->w.hGCClipRgn, -Dc->w.DCOrgX, -Dc->w.DCOrgY); } HRGN WINAPI SaveVisRgn(HDC hdc) { HRGN copy; - PROSRGNDATA obj, copyObj; + PROSRGNDATA obj;/*, copyObj;*/ PDC dc = DC_LockDc(hdc); if (!dc) return 0; obj = RGNDATA_LockRgn(dc->w.hVisRgn); + /* FIXME - Handle obj == NULL!!! */ if(!(copy = NtGdiCreateRectRgn(0, 0, 0, 0))) { @@ -70,10 +73,10 @@ HRGN WINAPI SaveVisRgn(HDC hdc) return 0; } NtGdiCombineRgn(copy, dc->w.hVisRgn, 0, RGN_COPY); - copyObj = RGNDATA_LockRgn(copy); + /* copyObj = RGNDATA_LockRgn(copy); */ /* copyObj->header.hNext = obj->header.hNext; header.hNext = copy; */ - + DC_UnlockDc(hdc); return copy; } @@ -104,7 +107,7 @@ NtGdiSelectVisRgn(HDC hdc, HRGN hrgn) retval = NtGdiCombineRgn(dc->w.hVisRgn, hrgn, 0, RGN_COPY); if ( retval != ERROR ) - retval = CLIPPING_UpdateGCRegion(dc); + CLIPPING_UpdateGCRegion(dc); DC_UnlockDc( hdc ); return retval; diff --git a/reactos/subsys/win32k/objects/color.c b/reactos/subsys/win32k/objects/color.c index f9070b0bbbb..70ba4376774 100644 --- a/reactos/subsys/win32k/objects/color.c +++ b/reactos/subsys/win32k/objects/color.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: color.c,v 1.50 2004/07/14 20:48:58 navaraf Exp $ */ +/* $Id: color.c,v 1.51 2004/12/12 01:40:38 weiden Exp $ */ #include // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping @@ -123,6 +123,7 @@ HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette) 0, 0, 0); PalGDI = (PPALGDI) PALETTE_LockPalette(NewPalette); + /* FIXME - Handle PalGDI == NULL!!!! */ PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors); PalGDI->logicalToSystem = NULL; @@ -333,6 +334,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE); palGDI = PALETTE_LockPalette(dc->w.hPalette); palPtr = (PALOBJ*) palGDI; + /* FIXME - Handle palGDI == NULL!!!! */ // Step 1: Create mapping of system palette\DC palette #ifndef NO_MAPPING @@ -345,6 +347,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) sysGDI = PALETTE_LockPalette(systemPalette); sysPtr = (PALOBJ*) sysGDI; + /* FIXME - Handle sysGDI == NULL!!!!! */ // Step 2: // The RealizePalette function modifies the palette for the device associated with the specified device context. If the diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 79261acd300..d6cfe95e806 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.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: dc.c,v 1.148 2004/12/07 19:53:44 royce Exp $ +/* $Id: dc.c,v 1.149 2004/12/12 01:40:38 weiden Exp $ * * DC.C - Device context functions * @@ -465,6 +465,7 @@ IntCreatePrimarySurface() BOOL GotDriver; BOOL DoDefault; ULONG DisplayNumber; + RECTL SurfaceRect; for (DisplayNumber = 0; ; DisplayNumber++) { @@ -654,6 +655,11 @@ IntCreatePrimarySurface() SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle); SurfObj->dhpdev = PrimarySurface.PDev; SurfSize = SurfObj->sizlBitmap; + SurfSize = SurfObj->sizlBitmap; + SurfaceRect.left = SurfaceRect.top = 0; + SurfaceRect.right = SurfObj->sizlBitmap.cx; + SurfaceRect.bottom = SurfObj->sizlBitmap.cy; + EngEraseSurface(SurfObj, &SurfaceRect, 0); EngUnlockSurface(SurfObj); IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy); break; @@ -728,6 +734,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver, } NewDC = DC_LockDc( hNewDC ); + /* FIXME - NewDC can be NULL!!! Don't assert here! */ ASSERT( NewDC ); NewDC->DMW = PrimarySurface.DMW; @@ -846,8 +853,7 @@ NtGdiDeleteDC(HDC DCHandle) { return FALSE; } - DPRINT( "Deleting DC\n" ); - CHECKPOINT; + /* First delete all saved DCs */ while (DCToDelete->saveLevel) { @@ -862,7 +868,7 @@ NtGdiDeleteDC(HDC DCHandle) } DC_SetNextDC (DCToDelete, DC_GetNextDC (savedDC)); DCToDelete->saveLevel--; - DC_UnlockDc( savedHDC ); + DC_UnlockDc( savedHDC ); NtGdiDeleteDC (savedHDC); } @@ -1064,6 +1070,7 @@ NtGdiGetDCState(HDC hDC) 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; @@ -1247,7 +1254,7 @@ NtGdiSetDCState ( HDC hDC, HDC hDCSave ) GDISelectPalette16( hDC, dcs->w.hPalette, FALSE ); #endif } else { - DC_UnlockDc(hDC); + DC_UnlockDc(hDC); } DC_UnlockDc ( hDCSave ); } else { @@ -1472,7 +1479,7 @@ DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode ) INT FASTCALL IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) { - PGDIOBJHDR GdiObject; + PVOID GdiObject; INT Result = 0; DWORD ObjectType; @@ -1517,7 +1524,7 @@ IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) break; } - GDIOBJ_UnlockObj(Handle, GDI_OBJECT_TYPE_DONTCARE); + GDIOBJ_UnlockObj(Handle); return Result; } @@ -1558,7 +1565,7 @@ DWORD STDCALL NtGdiGetObjectType(HANDLE handle) { GDIOBJHDR * ptr; - INT result = 0; + INT result; DWORD objectType; ptr = GDIOBJ_LockObj(handle, GDI_OBJECT_TYPE_DONTCARE); @@ -1610,11 +1617,13 @@ NtGdiGetObjectType(HANDLE handle) 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_UnlockObj(handle); return result; } @@ -1723,7 +1732,7 @@ NtGdiSaveDC(HDC hDC) dc = DC_LockDc (hDC); if (dc == NULL) { - DC_UnlockDc(dc); + DC_UnlockDc(hdcs); SetLastWin32Error(ERROR_INVALID_HANDLE); return 0; } @@ -1788,7 +1797,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) } XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed); - PENOBJ_UnlockPen((HPEN) hGDIObj); + PENOBJ_UnlockPen(hGDIObj); if (Failed) { SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); @@ -1811,7 +1820,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) } XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed); - BRUSHOBJ_UnlockBrush((HPEN) hGDIObj); + BRUSHOBJ_UnlockBrush(hGDIObj); if (Failed) { SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); @@ -1826,9 +1835,11 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) 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: @@ -1882,9 +1893,9 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) DC_UnlockDc ( hDC ); hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy ); + BITMAPOBJ_UnlockBitmap( hGDIObj ); NtGdiSelectVisRgn ( hDC, hVisRgn ); NtGdiDeleteObject ( hVisRgn ); - BITMAPOBJ_UnlockBitmap(hGDIObj); return objOrg; @@ -1963,7 +1974,7 @@ DC_AllocDC(PUNICODE_STRING Driver) 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) @@ -1974,6 +1985,7 @@ DC_AllocDC(PUNICODE_STRING Driver) } NewDC = DC_LockDc(hDC); + /* FIXME - Handle NewDC == NULL! */ if (Driver != NULL) { @@ -2038,17 +2050,17 @@ DC_InitDC(HDC DCHandle) 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; } diff --git a/reactos/subsys/win32k/objects/dib.c b/reactos/subsys/win32k/objects/dib.c index dc770e87006..a68b14a2a1e 100644 --- a/reactos/subsys/win32k/objects/dib.c +++ b/reactos/subsys/win32k/objects/dib.c @@ -1,5 +1,5 @@ /* - * $Id: dib.c,v 1.56 2004/07/03 13:55:36 navaraf Exp $ + * $Id: dib.c,v 1.57 2004/12/12 01:40:38 weiden Exp $ * * ReactOS W32 Subsystem * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team @@ -385,11 +385,13 @@ NtGdiGetDIBits(HDC hDC, DestSurfObj = EngLockSurface((HSURF)DestBitmap); SourcePalette = PALETTE_LockPalette(hSourcePalette); + /* FIXME - SourcePalette can be NULL!!! Don't assert here! */ ASSERT(SourcePalette); SourcePaletteType = SourcePalette->Mode; PALETTE_UnlockPalette(hSourcePalette); DestPalette = PALETTE_LockPalette(hDestPalette); + /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */ ASSERT(DestPalette); DestPaletteType = DestPalette->Mode; diff --git a/reactos/subsys/win32k/objects/fillshap.c b/reactos/subsys/win32k/objects/fillshap.c index 3894c2b303e..fd0166a8ac5 100644 --- a/reactos/subsys/win32k/objects/fillshap.c +++ b/reactos/subsys/win32k/objects/fillshap.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: fillshap.c,v 1.52 2004/07/14 20:48:58 navaraf Exp $ */ +/* $Id: fillshap.c,v 1.53 2004/12/12 01:40:38 weiden Exp $ */ #include /* @@ -59,6 +59,7 @@ IntGdiPolygon(PDC dc, } BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - BitmapObj can be NULL!!!! don't assert but handle this case gracefully! */ ASSERT(BitmapObj); /* Convert to screen coordinates */ @@ -87,6 +88,7 @@ IntGdiPolygon(PDC dc, /* Now fill the polygon with the current brush. */ FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush); + /* FIXME - FillBrushObj can be NULL!!!!!!!! Don't Assert! */ ASSERT(FillBrushObj); if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)) { @@ -97,6 +99,7 @@ IntGdiPolygon(PDC dc, /* get BRUSHOBJ from current pen. */ PenBrushObj = PENOBJ_LockPen(dc->w.hPen); + /* FIXME - handle PenBrushObj == NULL !!!!! */ IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen); // Draw the Polygon Edges with the current pen ( if not a NULL pen ) @@ -128,10 +131,10 @@ IntGdiPolygon(PDC dc, dc->w.ROPmode); /* MIX */ } } + PENOBJ_UnlockPen( dc->w.hPen ); } BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); - PENOBJ_UnlockPen( dc->w.hPen ); return ret; } @@ -250,13 +253,14 @@ NtGdiEllipse( PenBrush = PENOBJ_LockPen(dc->w.hPen); if (NULL == PenBrush) { - PENOBJ_UnlockPen(dc->w.hPen); + BRUSHOBJ_UnlockBrush(dc->w.hBrush); DC_UnlockDc(hDC); SetLastWin32Error(ERROR_INTERNAL_ERROR); return FALSE; } BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - BitmapObj can be NULL!!!! Don't assert but handle this case gracefully! */ ASSERT(BitmapObj); IntGdiInitBrushInstance(&FillBrushInst, FillBrush, dc->XlateBrush); @@ -937,6 +941,7 @@ IntRectangle(PDC dc, RECTL DestRect; ASSERT ( dc ); // caller's responsibility to set this up + /* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */ ASSERT ( BitmapObj ); if ( PATH_IsPathOpen(dc->w.path) ) @@ -956,6 +961,7 @@ IntRectangle(PDC dc, DestRect.bottom = BottomRect; FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush); + /* FIXME - Handle FillBrushObj == NULL !!!! */ IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush); if ( FillBrushObj ) @@ -1105,9 +1111,11 @@ IntRoundRect( RectBounds.bottom = bottom; BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - BitmapObj can be NULL!!!! Handle this case gracefully instead of ASSERT! */ ASSERT(BitmapObj); FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush); + /* FIXME - Don't assert if FillBrushObj == NULL, handle this case !!!! */ ASSERT(FillBrushObj); if (FillBrushObj->flAttrs & GDIBRUSH_IS_NULL) { @@ -1116,6 +1124,7 @@ IntRoundRect( } PenBrushObj = PENOBJ_LockPen(dc->w.hPen); + /* FIXME - PenBrushObject can be NULL!!! Don't assert!!!! */ ASSERT(PenBrushObj); if (PenBrushObj->flAttrs & GDIBRUSH_IS_NULL) { @@ -1304,7 +1313,8 @@ IntRoundRect( } BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); - PENOBJ_UnlockPen(dc->w.hPen); + if(PenBrushObj != NULL) + PENOBJ_UnlockPen(dc->w.hPen); BRUSHOBJ_UnlockBrush(dc->w.hBrush); return ret; @@ -1410,9 +1420,11 @@ IntGdiGradientFill( Extent.bottom += DitherOrg.y; BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */ ASSERT(BitmapObj); PalDestGDI = PALETTE_LockPalette(dc->w.hPalette); + /* FIXME - PalDestGDI can be NULL!!! Don't assert but handle this case gracefully! */ ASSERT(PalDestGDI); Mode = PalDestGDI->Mode; PALETTE_UnlockPalette(dc->w.hPalette); diff --git a/reactos/subsys/win32k/objects/gdiobj.c b/reactos/subsys/win32k/objects/gdiobj.c index 149680d6460..0cb071feb8f 100644 --- a/reactos/subsys/win32k/objects/gdiobj.c +++ b/reactos/subsys/win32k/objects/gdiobj.c @@ -1,6 +1,6 @@ /* * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team + * Copyright (C) 1998 - 2004 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,348 +19,290 @@ /* * GDIOBJ.C - GDI object manipulation routines * - * $Id: gdiobj.c,v 1.73 2004/10/02 16:48:12 navaraf Exp $ - * + * $Id: gdiobj.c,v 1.74 2004/12/12 01:40:38 weiden Exp $ */ #include -/* count all gdi objects */ -#define GDI_COUNT_OBJECTS 1 +#define NDEBUG +#include -/*! Size of the GDI handle table - * http://www.windevnet.com/documents/s=7290/wdj9902b/9902b.htm - * gdi handle table can hold 0x4000 handles -*/ -#define GDI_HANDLE_COUNT 0x4000 +#ifdef __USE_W32API +/* F*(&#$ header mess!!!! */ +HANDLE +STDCALL PsGetProcessId( + PEPROCESS Process + ); +#endif /* __USE_W32API */ -#define GDI_GLOBAL_PROCESS ((HANDLE) 0xffffffff) -#define GDI_HANDLE_INDEX_MASK (GDI_HANDLE_COUNT - 1) -#define GDI_HANDLE_TYPE_MASK 0x007f0000 -#define GDI_HANDLE_STOCK_MASK 0x00800000 -#define GDI_HANDLE_CREATE(i, t) ((HANDLE)(((i) & GDI_HANDLE_INDEX_MASK) | ((t) & GDI_HANDLE_TYPE_MASK))) -#define GDI_HANDLE_GET_INDEX(h) (((DWORD)(h)) & GDI_HANDLE_INDEX_MASK) -#define GDI_HANDLE_GET_TYPE(h) (((DWORD)(h)) & GDI_HANDLE_TYPE_MASK) -#define GDI_HANDLE_IS_TYPE(h, t) ((t) == (((DWORD)(h)) & GDI_HANDLE_TYPE_MASK)) -#define GDI_HANDLE_IS_STOCKOBJ(h) (0 != (((DWORD)(h)) & GDI_HANDLE_STOCK_MASK)) -#define GDI_HANDLE_SET_STOCKOBJ(h) ((h) = (HANDLE)(((DWORD)(h)) | GDI_HANDLE_STOCK_MASK)) -#define GDI_TYPE_TO_MAGIC(t) ((WORD) ((t) >> 16)) -#define GDI_MAGIC_TO_TYPE(m) ((DWORD)(m) << 16) +#define GDI_ENTRY_TO_INDEX(ht, e) \ + (((ULONG_PTR)(e) - (ULONG_PTR)&((ht)->Entries[0])) / sizeof(GDI_TABLE_ENTRY)) +#define GDI_HANDLE_GET_ENTRY(HandleTable, h) \ + (&(HandleTable)->Entries[GDI_HANDLE_GET_INDEX((h))]) -/* FIXME Ownership of GDI objects by processes not properly implemented yet */ -#if 0 -#define GDI_VALID_OBJECT(h, obj, t, f) \ - (NULL != (obj) \ - && (GDI_MAGIC_TO_TYPE((obj)->Magic) == (t) || GDI_OBJECT_TYPE_DONTCARE == (t)) \ - && (GDI_HANDLE_GET_TYPE((h)) == GDI_MAGIC_TO_TYPE((obj)->Magic)) \ - && (((obj)->hProcessId == PsGetCurrentProcessId()) \ - || (GDI_GLOBAL_PROCESS == (obj)->hProcessId) \ - || ((f) & GDIOBJFLAG_IGNOREPID))) -#else -#define GDI_VALID_OBJECT(h, obj, t, f) \ - (NULL != (obj) \ - && (GDI_MAGIC_TO_TYPE((obj)->Magic) == (t) || GDI_OBJECT_TYPE_DONTCARE == (t)) \ - && (GDI_HANDLE_GET_TYPE((h)) == GDI_MAGIC_TO_TYPE((obj)->Magic))) -#endif +#define GDIBdyToHdr(body) \ + ((PGDIOBJHDR)(body) - 1) +#define GDIHdrToBdy(hdr) \ + (PGDIOBJ)((PGDIOBJHDR)(hdr) + 1) + +/* apparently the first 10 entries are never used in windows as they are empty */ +#define RESERVE_ENTRIES_COUNT 10 typedef struct _GDI_HANDLE_TABLE { - WORD wTableSize; - WORD AllocationHint; - #if GDI_COUNT_OBJECTS - ULONG HandlesCount; - #endif + LONG HandlesCount; + LONG nEntries; PPAGED_LOOKASIDE_LIST LookasideLists; - PGDIOBJHDR Handles[1]; + + PGDI_TABLE_ENTRY EntriesEnd; + + GDI_TABLE_ENTRY Entries[1]; } GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE; typedef struct { ULONG Type; ULONG Size; -} GDI_OBJ_SIZE; + GDICLEANUPPROC CleanupProc; +} GDI_OBJ_INFO, *PGDI_OBJ_INFO; -const -GDI_OBJ_SIZE ObjSizes[] = -{ - /* Testing shows that regions are the most used GDIObj type, - so put that one first for performance */ - {GDI_OBJECT_TYPE_REGION, sizeof(ROSRGNDATA)}, - {GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ)}, - {GDI_OBJECT_TYPE_DC, sizeof(DC)}, - {GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI)}, - {GDI_OBJECT_TYPE_BRUSH, sizeof(GDIBRUSHOBJ)}, - {GDI_OBJECT_TYPE_PEN, sizeof(GDIBRUSHOBJ)}, - {GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ)}, - {GDI_OBJECT_TYPE_DCE, sizeof(DCE)}, /* - {GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW)}, - {GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE)}, -*/ - {GDI_OBJECT_TYPE_EXTPEN, 0}, - {GDI_OBJECT_TYPE_METADC, 0}, - {GDI_OBJECT_TYPE_METAFILE, 0}, - {GDI_OBJECT_TYPE_ENHMETAFILE, 0}, - {GDI_OBJECT_TYPE_ENHMETADC, 0}, - {GDI_OBJECT_TYPE_MEMDC, 0}, - {GDI_OBJECT_TYPE_EMF, 0} + * Dummy GDI Cleanup Callback + */ +BOOL INTERNAL_CALL +GDI_CleanupDummy(PVOID ObjectBody) +{ + return TRUE; +} + +/* Testing shows that regions are the most used GDIObj type, + so put that one first for performance */ +const +GDI_OBJ_INFO ObjInfo[] = +{ + /* Type */ /* Size */ /* CleanupProc */ + {GDI_OBJECT_TYPE_REGION, sizeof(ROSRGNDATA), RGNDATA_Cleanup}, + {GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ), BITMAP_Cleanup}, + {GDI_OBJECT_TYPE_DC, sizeof(DC), DC_Cleanup}, + {GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI), PALETTE_Cleanup}, + {GDI_OBJECT_TYPE_BRUSH, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup}, + {GDI_OBJECT_TYPE_PEN, sizeof(GDIBRUSHOBJ), GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ), GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_DCE, sizeof(DCE), DCE_Cleanup}, +/*{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW), DD_Cleanup}, + {GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE), DDSURF_Cleanup},*/ + {GDI_OBJECT_TYPE_EXTPEN, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_METADC, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_METAFILE, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_ENHMETAFILE, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_ENHMETADC, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_MEMDC, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_EMF, 0, GDI_CleanupDummy} }; -#define OBJTYPE_COUNT (sizeof(ObjSizes) / sizeof(ObjSizes[0])) +#define OBJTYPE_COUNT (sizeof(ObjInfo) / sizeof(ObjInfo[0])) -/* GDI stock objects */ +static PGDI_HANDLE_TABLE HandleTable = NULL; +static LARGE_INTEGER ShortDelay; -static LOGBRUSH WhiteBrush = -{ BS_SOLID, RGB(255,255,255), 0 }; - -static LOGBRUSH LtGrayBrush = -/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ -{ BS_SOLID, RGB(192,192,192), 0 }; - -static LOGBRUSH GrayBrush = -/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ -{ BS_SOLID, RGB(128,128,128), 0 }; - -static LOGBRUSH DkGrayBrush = -/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */ -/* NB_HATCH_STYLES is an index into HatchBrushes */ -{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES }; - -static LOGBRUSH BlackBrush = -{ BS_SOLID, RGB(0,0,0), 0 }; - -static LOGBRUSH NullBrush = -{ BS_NULL, 0, 0 }; - -static LOGPEN WhitePen = -{ PS_SOLID, { 0, 0 }, RGB(255,255,255) }; - -static LOGPEN BlackPen = -{ PS_SOLID, { 0, 0 }, RGB(0,0,0) }; - -static LOGPEN NullPen = -{ PS_NULL, { 0, 0 }, 0 }; - -static LOGFONTW OEMFixedFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; - -static LOGFONTW AnsiFixedFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; - -/*static LOGFONTW AnsiVarFont = - *{ 10, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - * 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; */ - -static LOGFONTW SystemFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; - -static LOGFONTW DeviceDefaultFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; - -static LOGFONTW SystemFixedFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; - -/* FIXME: Is this correct? */ -static LOGFONTW DefaultGuiFont = -{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, - 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; - -#define NB_STOCK_OBJECTS (DEFAULT_GUI_FONT + 1) - -static HGDIOBJ StockObjects[NB_STOCK_OBJECTS]; -static PGDI_HANDLE_TABLE HandleTable = 0; -static FAST_MUTEX HandleTableMutex; -static FAST_MUTEX RefCountHandling; -static LARGE_INTEGER ShortDelay; +#define DelayExecution() \ + DPRINT("%s:%i: Delay\n", __FILE__, __LINE__); \ + KeDelayExecutionThread(KernelMode, FALSE, &ShortDelay) /*! * Allocate GDI object table. * \param Size - number of entries in the object table. - * Notes:: Must be called at IRQL < DISPATCH_LEVEL. */ -static PGDI_HANDLE_TABLE FASTCALL -GDIOBJ_iAllocHandleTable (WORD Size) +static PGDI_HANDLE_TABLE INTERNAL_CALL +GDIOBJ_iAllocHandleTable(ULONG Entries) { - PGDI_HANDLE_TABLE handleTable; - ULONG MemSize; + PGDI_HANDLE_TABLE handleTable; UINT ObjType; - - MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size; + ULONG MemSize = sizeof(GDI_HANDLE_TABLE) + (sizeof(GDI_TABLE_ENTRY) * (Entries - 1)); - ExAcquireFastMutex(&HandleTableMutex); - handleTable = ExAllocatePoolWithTag(PagedPool, MemSize, TAG_GDIHNDTBLE); + handleTable = ExAllocatePoolWithTag(NonPagedPool, MemSize, TAG_GDIHNDTBLE); ASSERT( handleTable ); - memset (handleTable, 0, MemSize); -#if GDI_COUNT_OBJECTS + RtlZeroMemory(handleTable, MemSize); + handleTable->HandlesCount = 0; -#endif - handleTable->wTableSize = Size; - handleTable->AllocationHint = 1; - handleTable->LookasideLists = ExAllocatePoolWithTag(PagedPool, + handleTable->nEntries = Entries; + + handleTable->EntriesEnd = &handleTable->Entries[Entries]; + + handleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool, OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST), TAG_GDIHNDTBLE); - if (NULL == handleTable->LookasideLists) - { - ExFreePool(handleTable); - ExReleaseFastMutex(&HandleTableMutex); - return NULL; - } - for (ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++) - { - ExInitializePagedLookasideList(handleTable->LookasideLists + ObjType, NULL, NULL, 0, - ObjSizes[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ, 0); - } - ExReleaseFastMutex(&HandleTableMutex); + if(handleTable->LookasideLists == NULL) + { + ExFreePool(handleTable); + return NULL; + } + + for(ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++) + { + ExInitializePagedLookasideList(handleTable->LookasideLists + ObjType, NULL, NULL, 0, + ObjInfo[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ, 0); + } + + ShortDelay.QuadPart = -5000LL; /* FIXME - 0.5 ms? */ return handleTable; } -/*! - * Returns the entry into the handle table by index. -*/ -static PGDIOBJHDR FASTCALL -GDIOBJ_iGetObjectForIndex(WORD TableIndex) -{ - if (0 == TableIndex || HandleTable->wTableSize < TableIndex) - { - DPRINT1("Invalid TableIndex %u\n", (unsigned) TableIndex); - return NULL; - } - - return HandleTable->Handles[TableIndex]; -} - -/*! - * Finds next free entry in the GDI handle table. - * \return index into the table is successful, zero otherwise. -*/ -static WORD FASTCALL -GDIOBJ_iGetNextOpenHandleIndex (void) -{ - WORD tableIndex; - - for (tableIndex = HandleTable->AllocationHint; - tableIndex < HandleTable->wTableSize; - tableIndex++) - { - if (HandleTable->Handles[tableIndex] == NULL) - { - HandleTable->AllocationHint = tableIndex + 1; - return tableIndex; - } - } - - for (tableIndex = 1; - tableIndex < HandleTable->AllocationHint; - tableIndex++) - { - if (HandleTable->Handles[tableIndex] == NULL) - { - HandleTable->AllocationHint = tableIndex + 1; - return tableIndex; - } - } - - return 0; -} - -static PPAGED_LOOKASIDE_LIST FASTCALL +static inline PPAGED_LOOKASIDE_LIST FindLookasideList(DWORD ObjectType) { int Index; for (Index = 0; Index < OBJTYPE_COUNT; Index++) + { + if (ObjInfo[Index].Type == ObjectType) { - if (ObjSizes[Index].Type == ObjectType) - { - return HandleTable->LookasideLists + Index; - } + return HandleTable->LookasideLists + Index; } + } DPRINT1("Can't find lookaside list for object type 0x%08x\n", ObjectType); return NULL; } +static inline BOOL +RunCleanupCallback(PGDIOBJ pObj, DWORD ObjectType) +{ + int Index; + + for (Index = 0; Index < OBJTYPE_COUNT; Index++) + { + if (ObjInfo[Index].Type == ObjectType) + { + return ((GDICLEANUPPROC)ObjInfo[Index].CleanupProc)(pObj); + } + } + + DPRINT1("Can't find cleanup callback for object type 0x%08x\n", ObjectType); + return TRUE; +} + +static inline ULONG +GetObjectSize(DWORD ObjectType) +{ + int Index; + + for (Index = 0; Index < OBJTYPE_COUNT; Index++) + { + if (ObjInfo[Index].Type == ObjectType) + { + return ObjInfo[Index].Size; + } + } + + DPRINT1("Can't find size for object type 0x%08x\n", ObjectType); + return 0; +} + /*! * Allocate memory for GDI object and return handle to it. * - * \param Size - size of the GDI object. This shouldn't to include the size of GDIOBJHDR. - * The actual amount of allocated memory is sizeof(GDIOBJHDR)+Size * \param ObjectType - type of object \ref GDI object types - * \param CleanupProcPtr - Routine to be called on destruction of object * * \return Handle of the allocated object. * * \note Use GDIOBJ_Lock() to obtain pointer to the new object. + * \todo return the object pointer and lock it by default. */ -HGDIOBJ FASTCALL -GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc) +HGDIOBJ INTERNAL_CALL +GDIOBJ_AllocObj(ULONG ObjectType) { PW32PROCESS W32Process; PGDIOBJHDR newObject; - WORD Index; PPAGED_LOOKASIDE_LIST LookasideList; + LONG CurrentProcessId, LockedProcessId; - ExAcquireFastMutex(&HandleTableMutex); - Index = GDIOBJ_iGetNextOpenHandleIndex (); - if (0 == Index) - { - ExReleaseFastMutex(&HandleTableMutex); - DPRINT1("Out of GDI handles\n"); - return NULL; - } + ASSERT(ObjectType != GDI_OBJECT_TYPE_DONTCARE); LookasideList = FindLookasideList(ObjectType); - if (NULL == LookasideList) - { - ExReleaseFastMutex(&HandleTableMutex); - return NULL; - } - newObject = ExAllocateFromPagedLookasideList(LookasideList); - if (NULL == newObject) - { - ExReleaseFastMutex(&HandleTableMutex); - DPRINT1("Unable to allocate GDI object from lookaside list\n"); - return NULL; - } - RtlZeroMemory (newObject, Size + sizeof(GDIOBJHDR)); - - newObject->wTableIndex = Index; - - newObject->dwCount = 0; - newObject->hProcessId = PsGetCurrentProcessId (); - newObject->CleanupProc = CleanupProc; - newObject->Magic = GDI_TYPE_TO_MAGIC(ObjectType); - newObject->lockfile = NULL; - newObject->lockline = 0; -#ifdef GDIOBJ_USE_FASTMUTEX - ExInitializeFastMutex(&newObject->Lock); - newObject->RecursiveLockCount = 0; -#else - newObject->LockTid = 0; - newObject->LockCount = 0; -#endif - HandleTable->Handles[Index] = newObject; -#if GDI_COUNT_OBJECTS - HandleTable->HandlesCount++; -#endif - ExReleaseFastMutex(&HandleTableMutex); - - W32Process = PsGetCurrentProcess()->Win32Process; - if(W32Process) + if(LookasideList != NULL) { - W32Process->GDIObjects++; - } + newObject = ExAllocateFromPagedLookasideList(LookasideList); + if(newObject != NULL) + { + PGDI_TABLE_ENTRY Entry; + PGDIOBJ ObjectBody; + LONG TypeInfo; - return GDI_HANDLE_CREATE(Index, ObjectType); + /* shift the process id to the left so we can use the first bit to lock + the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + CurrentProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = CurrentProcessId | 0x1; + W32Process = PsGetWin32Process(); + + newObject->LockingThread = NULL; + newObject->Locks = 0; + +#ifdef GDI_DEBUG + newObject->lockfile = NULL; + newObject->lockline = 0; +#endif + + ObjectBody = GDIHdrToBdy(newObject); + + RtlZeroMemory(ObjectBody, GetObjectSize(ObjectType)); + + TypeInfo = (ObjectType & 0xFFFF0000) | (ObjectType >> 16); + + /* Search for a free handle entry */ + for(Entry = &HandleTable->Entries[RESERVE_ENTRIES_COUNT]; + Entry < HandleTable->EntriesEnd; + Entry++) + { + LONG PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, 0); + if(PrevProcId == 0) + { + if(InterlockedCompareExchangePointer(&Entry->KernelData, ObjectBody, NULL) == NULL) + { + HGDIOBJ Handle; + UINT Index = GDI_ENTRY_TO_INDEX(HandleTable, Entry); + + Handle = (HGDIOBJ)((Index & 0xFFFF) | (ObjectType & 0xFFFF0000)); + + /* we found a free entry, no need to exchange this field atomically + since we're holding the lock */ + Entry->Type = TypeInfo; + + InterlockedExchange(&Entry->ProcessId, CurrentProcessId); + + if(W32Process != NULL) + { + InterlockedIncrement(&W32Process->GDIObjects); + } + + DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, ObjectBody); + return Handle; + } + else + { + InterlockedExchange(&Entry->ProcessId, PrevProcId); + } + } + } + + ExFreeToPagedLookasideList(LookasideList, newObject); + DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n"); + } + else + { + DPRINT1("Not enough memory to allocate gdi object!\n"); + } + } + else + { + DPRINT1("Failed to find lookaside list for object type 0x%x\n", ObjectType); + } + return NULL; } /*! @@ -368,77 +310,137 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc) * appropriate cleanup routine. * * \param hObj - handle of the object to be deleted. - * \param ObjectType - one of the \ref GDI object types - * or GDI_OBJECT_TYPE_DONTCARE. - * \param Flag - if set to GDIOBJFLAG_IGNOREPID then the routine doesn't check if the process that - * tries to delete the object is the same one that created it. * * \return Returns TRUE if succesful. - * - * \note You should only use GDIOBJFLAG_IGNOREPID if you are cleaning up after the process that terminated. - * \note This function deferres object deletion if it is still in use. + * \return Returns FALSE if the cleanup routine returned FALSE or the object doesn't belong + * to the calling process. */ -BOOL STDCALL -GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType, DWORD Flag) +BOOL INTERNAL_CALL +#ifdef GDI_DEBUG +GDIOBJ_FreeObjDbg(const char* file, int line, HGDIOBJ hObj, DWORD ObjectType) +#else /* !GDI_DEBUG */ +GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType) +#endif /* GDI_DEBUG */ { - PW32PROCESS W32Process; - PGDIOBJHDR objectHeader; - PGDIOBJ Obj; + PGDI_TABLE_ENTRY Entry; PPAGED_LOOKASIDE_LIST LookasideList; - BOOL bRet = TRUE; - - objectHeader = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj)); - DPRINT("GDIOBJ_FreeObj: hObj: 0x%08x, object: %x\n", hObj, objectHeader); - - if (! GDI_VALID_OBJECT(hObj, objectHeader, ObjectType, Flag) - || GDI_GLOBAL_PROCESS == objectHeader->hProcessId) - - { - DPRINT1("Can't delete hObj:0x%08x, type:0x%08x, flag:%d\n", hObj, ObjectType, Flag); - return FALSE; - } - - DPRINT("FreeObj: locks: %x\n", objectHeader->dwCount ); - if (!(Flag & GDIOBJFLAG_IGNORELOCK)) - { - /* check that the reference count is zero. if not then set flag - * and delete object when releaseobj is called */ - ExAcquireFastMutex(&RefCountHandling); - if ((objectHeader->dwCount & ~0x80000000) > 0 ) - { - DPRINT("GDIOBJ_FreeObj: delayed object deletion: count %d\n", objectHeader->dwCount); - objectHeader->dwCount |= 0x80000000; - ExReleaseFastMutex(&RefCountHandling); - return TRUE; - } - ExReleaseFastMutex(&RefCountHandling); - } - - /* allow object to delete internal data */ - if (NULL != objectHeader->CleanupProc) - { - Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR)); - bRet = (*(objectHeader->CleanupProc))(Obj); - } - LookasideList = FindLookasideList(GDI_MAGIC_TO_TYPE(objectHeader->Magic)); - if (NULL != LookasideList) - { - ExFreeToPagedLookasideList(LookasideList, objectHeader); - } - ExAcquireFastMutexUnsafe (&HandleTableMutex); - HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL; -#if GDI_COUNT_OBJECTS - HandleTable->HandlesCount--; + LONG ProcessId, LockedProcessId, PrevProcId, ExpectedType; +#ifdef GDI_DEBUG + ULONG Attempts = 0; #endif - ExReleaseFastMutexUnsafe (&HandleTableMutex); + + DPRINT("GDIOBJ_FreeObj: hObj: 0x%08x\n", hObj); - W32Process = PsGetCurrentProcess()->Win32Process; - if(W32Process) + if(GDI_HANDLE_IS_STOCKOBJ(hObj)) { - W32Process->GDIObjects--; + DPRINT1("GDIOBJ_FreeObj() failed, can't delete stock object handle: 0x%x !!!\n", hObj); +#ifdef GDI_DEBUG + DPRINT1("-> called from %s:%i\n", file, line); +#endif + return FALSE; } - return bRet; + /* shift the process id to the left so we can use the first bit to lock the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = ProcessId | 0x1; + + ExpectedType = ((ObjectType != GDI_OBJECT_TYPE_DONTCARE) ? ObjectType : 0); + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, hObj); + +LockHandle: + /* lock the object, we must not delete global objects, so don't exchange the locking + process ID to zero when attempting to lock a global object... */ + PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, ProcessId); + if(PrevProcId == ProcessId) + { + if(Entry->Type != 0 && Entry->KernelData != NULL && (ExpectedType == 0 || ((Entry->Type << 16) == ExpectedType))) + { + PGDIOBJHDR GdiHdr; + + GdiHdr = GDIBdyToHdr(Entry->KernelData); + + if(GdiHdr->LockingThread == NULL) + { + BOOL Ret; + ULONG Type = Entry->Type << 16; + + /* Clear the type field so when unlocking the handle it gets finally deleted */ + Entry->Type = 0; + Entry->KernelData = NULL; + + /* unlock the handle slot */ + InterlockedExchange(&Entry->ProcessId, 0); + + /* call the cleanup routine. */ + Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type); + + /* Now it's time to free the memory */ + LookasideList = FindLookasideList(Type); + if(LookasideList != NULL) + { + ExFreeToPagedLookasideList(LookasideList, GdiHdr); + } + + return Ret; + } + else + { + /* the object is currently locked. just clear the type field so when the + object gets unlocked it will be finally deleted from the table. */ + Entry->Type = 0; + + /* unlock the handle slot */ + InterlockedExchange(&Entry->ProcessId, 0); + + /* report a successful deletion as the object is actually removed from the table */ + return TRUE; + } + } + else + { + if(Entry->Type != 0) + { + DPRINT1("Attempted to delete object 0x%x, type mismatch (0x%x : 0x%x)\n", hObj, ObjectType, ExpectedType); + } + else + { + DPRINT1("Attempted to delete object 0x%x which was already deleted!\n", hObj); + } + InterlockedExchange(&Entry->ProcessId, PrevProcId); + } + } + else if(PrevProcId == LockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); + } +#endif + /* the object is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else + { + if((PrevProcId >> 1) == 0) + { + DPRINT1("Attempted to free global gdi handle 0x%x, caller needs to get ownership first!!!", hObj); + } + else + { + DPRINT1("Attempted to free foreign handle: 0x%x Owner: 0x%x from Caller: 0x%x\n", hObj, PrevProcId >> 1, ProcessId >> 1); + } +#ifdef GDI_DEBUG + DPRINT1("-> called from %s:%i\n", file, line); +#endif + } + + return FALSE; } /*! @@ -451,7 +453,7 @@ GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType, DWORD Flag) * * \note this function uses an O(n^2) algoritm because we shouldn't need to call it with more than 3 or 4 objects. */ -BOOL FASTCALL +BOOL INTERNAL_CALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj) { INT i, j; @@ -493,7 +495,7 @@ GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj) * * \note this function uses O(n^2) algoritm because we shouldn't need to call it with more than 3 or 4 objects. */ -BOOL FASTCALL +BOOL INTERNAL_CALL GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj) { INT i, j; @@ -512,7 +514,7 @@ GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj) pList[j].pObj = NULL; } } - GDIOBJ_UnlockObj(pList[i].hObj, pList[i].ObjectType); + GDIOBJ_UnlockObj(pList[i].hObj); pList[i].pObj = NULL; } } @@ -520,102 +522,16 @@ GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj) return TRUE; } -/*! - * Get the type of the object. - * \param ObjectHandle - handle of the object. - * \return One of the \ref GDI object types -*/ -DWORD FASTCALL -GDIOBJ_GetObjectType(HGDIOBJ ObjectHandle) -{ - PGDIOBJHDR ObjHdr; - - ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); - if (NULL == ObjHdr - || ! GDI_VALID_OBJECT(ObjectHandle, ObjHdr, GDI_MAGIC_TO_TYPE(ObjHdr->Magic), 0)) - { - DPRINT1("Invalid ObjectHandle 0x%08x\n", ObjectHandle); - return 0; - } - DPRINT("GDIOBJ_GetObjectType for handle 0x%08x returns 0x%08x\n", ObjectHandle, - GDI_MAGIC_TO_TYPE(ObjHdr->Magic)); - - return GDI_MAGIC_TO_TYPE(ObjHdr->Magic); -} - /*! * Initialization of the GDI object engine. */ -VOID FASTCALL +VOID INTERNAL_CALL InitGdiObjectHandleTable (VOID) { DPRINT("InitGdiObjectHandleTable\n"); - ExInitializeFastMutex (&HandleTableMutex); - ExInitializeFastMutex (&RefCountHandling); - - ShortDelay.QuadPart = -100; HandleTable = GDIOBJ_iAllocHandleTable (GDI_HANDLE_COUNT); - DPRINT("HandleTable: %x\n", HandleTable ); - - InitEngHandleTable(); -} - -/*! - * Creates a bunch of stock objects: brushes, pens, fonts. -*/ -VOID FASTCALL -CreateStockObjects(void) -{ - unsigned Object; - - DPRINT("Beginning creation of stock objects\n"); - - /* Create GDI Stock Objects from the logical structures we've defined */ - - StockObjects[WHITE_BRUSH] = IntGdiCreateBrushIndirect(&WhiteBrush); - StockObjects[LTGRAY_BRUSH] = IntGdiCreateBrushIndirect(&LtGrayBrush); - StockObjects[GRAY_BRUSH] = IntGdiCreateBrushIndirect(&GrayBrush); - StockObjects[DKGRAY_BRUSH] = IntGdiCreateBrushIndirect(&DkGrayBrush); - StockObjects[BLACK_BRUSH] = IntGdiCreateBrushIndirect(&BlackBrush); - StockObjects[NULL_BRUSH] = IntGdiCreateBrushIndirect(&NullBrush); - - StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen); - StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen); - StockObjects[NULL_PEN] = IntGdiCreatePenIndirect(&NullPen); - - (void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]); - (void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]); - (void) TextIntCreateFontIndirect(&SystemFont, (HFONT*)&StockObjects[SYSTEM_FONT]); - (void) TextIntCreateFontIndirect(&DeviceDefaultFont, (HFONT*)&StockObjects[DEVICE_DEFAULT_FONT]); - (void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]); - (void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]); - - StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); - - for (Object = 0; Object < NB_STOCK_OBJECTS; Object++) - { - if (NULL != StockObjects[Object]) - { - GDIOBJ_SetOwnership(StockObjects[Object], NULL); -/* GDI_HANDLE_SET_STOCKOBJ(StockObjects[Object]);*/ - } - } - - DPRINT("Completed creation of stock objects\n"); -} - -/*! - * Return stock object. - * \param Object - stock object id. - * \return Handle to the object. -*/ -HGDIOBJ STDCALL -NtGdiGetStockObject(INT Object) -{ - DPRINT("NtGdiGetStockObject index %d\n", Object); - - return ((Object < 0) || (NB_STOCK_OBJECTS <= Object)) ? NULL : StockObjects[Object]; + DPRINT("HandleTable: %x\n", HandleTable); } /*! @@ -629,19 +545,21 @@ NtGdiDeleteObject(HGDIOBJ hObject) DPRINT("NtGdiDeleteObject handle 0x%08x\n", hObject); return NULL != hObject - ? GDIOBJ_FreeObj(hObject, GDI_OBJECT_TYPE_DONTCARE, GDIOBJFLAG_DEFAULT) : FALSE; + ? GDIOBJ_FreeObj(hObject, GDI_OBJECT_TYPE_DONTCARE) : FALSE; } /*! * Internal function. Called when the process is destroyed to free the remaining GDI handles. * \param Process - PID of the process that will be destroyed. */ -BOOL FASTCALL -CleanupForProcess (struct _EPROCESS *Process, INT Pid) +BOOL INTERNAL_CALL +GDI_CleanupForProcess (struct _EPROCESS *Process) { - DWORD i; - PGDIOBJHDR objectHeader; + PGDI_TABLE_ENTRY Entry; PEPROCESS CurrentProcess; + PW32PROCESS W32Process; + LONG ProcId; + ULONG Index = RESERVE_ENTRIES_COUNT; DPRINT("Starting CleanupForProcess prochandle %x Pid %d\n", Process, Pid); CurrentProcess = PsGetCurrentProcess(); @@ -649,19 +567,39 @@ CleanupForProcess (struct _EPROCESS *Process, INT Pid) { KeAttachProcess(Process); } + W32Process = Process->Win32Process; + ASSERT(W32Process); - for(i = 1; i < HandleTable->wTableSize; i++) + if(W32Process->GDIObjects > 0) + { + /* FIXME - Instead of building the handle here and delete it using GDIOBJ_FreeObj + we should delete it directly here! */ + ProcId = ((LONG)Process->UniqueProcessId << 1); + + for(Entry = &HandleTable->Entries[RESERVE_ENTRIES_COUNT]; + Entry < HandleTable->EntriesEnd; + Entry++, Index++) { - objectHeader = GDIOBJ_iGetObjectForIndex(i); - if (NULL != objectHeader && - (INT) objectHeader->hProcessId == Pid) - { - DPRINT("CleanupForProcess: %d, process: %d, locks: %d, magic: 0x%x", i, objectHeader->hProcessId, objectHeader->dwCount, objectHeader->Magic); - GDIOBJ_FreeObj(GDI_HANDLE_CREATE(i, GDI_MAGIC_TO_TYPE(objectHeader->Magic)), - GDI_MAGIC_TO_TYPE(objectHeader->Magic), - GDIOBJFLAG_IGNOREPID | GDIOBJFLAG_IGNORELOCK); - } + /* ignore the lock bit */ + if((Entry->ProcessId & ~0x1) == ProcId && Entry->Type != 0) + { + HGDIOBJ ObjectHandle; + + /* Create the object handle for the entry, the upper 16 bit of the + Type field includes the type of the object including the stock + object flag - but since stock objects don't have a process id we can + simply ignore this fact here. */ + ObjectHandle = (HGDIOBJ)(Index | (Entry->Type & 0xFFFF0000)); + + if(GDIOBJ_FreeObj(ObjectHandle, GDI_OBJECT_TYPE_DONTCARE) && + W32Process->GDIObjects == 0) + { + /* there are no more gdi handles for this process, bail */ + break; + } + } } + } if (CurrentProcess != Process) { @@ -673,342 +611,720 @@ CleanupForProcess (struct _EPROCESS *Process, INT Pid) return TRUE; } -#define GDIOBJ_TRACKLOCKS - -#ifdef GDIOBJ_LockObj -#undef GDIOBJ_LockObj -PGDIOBJ FASTCALL -GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType) -{ - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj)); -#ifndef GDIOBJ_USE_FASTMUTEX - DWORD CurrentTid = (DWORD)PsGetCurrentThreadId(); -#endif - - DPRINT("(%s:%i) GDIOBJ_LockObjDbg(0x%08x,0x%08x)\n", file, line, hObj, ObjectType); - if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT)) - { - int reason = 0; - if (NULL == ObjHdr) - { - reason = 1; - } - else if (GDI_MAGIC_TO_TYPE(ObjHdr->Magic) != ObjectType && ObjectType != GDI_OBJECT_TYPE_DONTCARE) - { - reason = 2; - } - else if (ObjHdr->hProcessId != GDI_GLOBAL_PROCESS - && ObjHdr->hProcessId != PsGetCurrentProcessId()) - { - reason = 3; - } - else if (GDI_HANDLE_GET_TYPE(hObj) != ObjectType && ObjectType != GDI_OBJECT_TYPE_DONTCARE) - { - reason = 4; - } - DPRINT1("GDIOBJ_LockObj failed for 0x%08x, reqtype 0x%08x reason %d\n", - hObj, ObjectType, reason ); - DPRINT1("\tcalled from: %s:%i\n", file, line ); - return NULL; - } - -#ifdef GDIOBJ_USE_FASTMUTEX - if (ObjHdr->Lock.Owner == KeGetCurrentThread()) - { - ObjHdr->RecursiveLockCount++; - } - else - { -#ifdef NDEBUG - ExAcquireFastMutex(&ObjHdr->Lock); -#else /* NDEBUG */ - if (! ExTryToAcquireFastMutex(&ObjHdr->Lock)) - { - DPRINT1("Caution! GDIOBJ_LockObj trying to lock object 0x%x second time\n", hObj); - DPRINT1(" called from: %s:%i (thread %x)\n", file, line, KeGetCurrentThread()); - if (NULL != ObjHdr->lockfile) - { - DPRINT1(" previously locked from: %s:%i (thread %x)\n", ObjHdr->lockfile, ObjHdr->lockline, ObjHdr->Lock.Owner); - } - ExAcquireFastMutex(&ObjHdr->Lock); - DPRINT1(" Disregard previous message about object 0x%x, it's ok\n", hObj); - } -#endif /* NDEBUG */ - ObjHdr->RecursiveLockCount++; - } -#else - if (ObjHdr->LockTid == CurrentTid) - { - InterlockedIncrement(&ObjHdr->LockCount); - } - else - { - for (;;) - { - if (InterlockedCompareExchange(&ObjHdr->LockTid, CurrentTid, 0) == CurrentTid) - { - InterlockedIncrement(&ObjHdr->LockCount); - break; - } - /* FIXME: KeDelayExecutionThread(KernelMode, FALSE, &ShortDelay); */ - } - } -#endif - - ExAcquireFastMutex(&RefCountHandling); - ObjHdr->dwCount++; - ExReleaseFastMutex(&RefCountHandling); - - if (NULL == ObjHdr->lockfile) - { - ObjHdr->lockfile = file; - ObjHdr->lockline = line; - } - - return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR)); -} -#endif//GDIOBJ_LockObj - -#ifdef GDIOBJ_UnlockObj -#undef GDIOBJ_UnlockObj -BOOL FASTCALL -GDIOBJ_UnlockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType) -{ - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj)); - - if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT)) - { - DPRINT1("GDIBOJ_UnlockObj failed for 0x%08x, reqtype 0x%08x\n", - hObj, ObjectType); - DPRINT1("\tcalled from: %s:%i\n", file, line); - return FALSE; - } - DPRINT("(%s:%i) GDIOBJ_UnlockObj(0x%08x,0x%08x)\n", file, line, hObj, ObjectType); - ObjHdr->lockfile = NULL; - ObjHdr->lockline = 0; - - return GDIOBJ_UnlockObj(hObj, ObjectType); -} -#endif//GDIOBJ_LockObj - /*! * Return pointer to the object by handle. * * \param hObj Object handle - * \param ObjectType one of the object types defined in \ref GDI object types * \return Pointer to the object. * * \note Process can only get pointer to the objects it created or global objects. * - * \todo Don't allow to lock the objects twice! Synchronization! + * \todo Get rid of the ObjectType parameter! */ -PGDIOBJ FASTCALL -GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ObjectType) +PGDIOBJ INTERNAL_CALL +#ifdef GDI_DEBUG +GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType) +#else /* !GDI_DEBUG */ +GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType) +#endif /* GDI_DEBUG */ { - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj)); -#ifndef GDIOBJ_USE_FASTMUTEX - DWORD CurrentTid = (DWORD)PsGetCurrentThreadId(); + PGDI_TABLE_ENTRY Entry; + PETHREAD Thread; + LONG ProcessId, LockedProcessId, PrevProcId, ExpectedType; +#ifdef GDI_DEBUG + ULONG Attempts = 0; #endif - DPRINT("GDIOBJ_LockObj: hObj: 0x%08x, type: 0x%08x, objhdr: %x\n", hObj, ObjectType, ObjHdr); - if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT)) - { - DPRINT1("GDIBOJ_LockObj failed for 0x%08x, type 0x%08x\n", - hObj, ObjectType); - return NULL; - } + DPRINT("GDIOBJ_LockObj: hObj: 0x%08x\n", hObj); + + Thread = PsGetCurrentThread(); -#ifdef GDIOBJ_USE_FASTMUTEX - if (ObjHdr->Lock.Owner == KeGetCurrentThread()) + /* shift the process id to the left so we can use the first bit to lock the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = ProcessId | 0x1; + + ExpectedType = ((ObjectType != GDI_OBJECT_TYPE_DONTCARE) ? ObjectType : 0); + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, hObj); + +LockHandle: + /* lock the object, we must not delete stock objects, so don't check!!! */ + PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, ProcessId); + if(PrevProcId == ProcessId) + { + LONG EntryType = Entry->Type << 16; + + /* we're locking an object that belongs to our process or it's a global + object if ProcessId == 0 here. ProcessId can only be 0 here if it previously + failed to lock the object and it turned out to be a global object. */ + if(EntryType != 0 && Entry->KernelData != NULL && (ExpectedType == 0 || (EntryType == ExpectedType))) { - ObjHdr->RecursiveLockCount++; - } - else - { - ExAcquireFastMutex(&ObjHdr->Lock); - ObjHdr->RecursiveLockCount++; - } -#else - if (ObjHdr->LockTid == CurrentTid) - { - InterlockedIncrement(&ObjHdr->LockCount); - } - else - { - for (;;) + PETHREAD PrevThread; + PGDIOBJHDR GdiHdr; + + GdiHdr = GDIBdyToHdr(Entry->KernelData); + + /* save the pointer to the calling thread so we know it was this thread + that locked the object. There's no need to do this atomically as we're + holding the lock of the handle slot, but this way it's easier ;) */ + PrevThread = InterlockedCompareExchangePointer(&GdiHdr->LockingThread, Thread, NULL); + + if(PrevThread == NULL || PrevThread == Thread) + { + if(++GdiHdr->Locks == 1) { - if (InterlockedCompareExchange(&ObjHdr->LockTid, CurrentTid, 0) == CurrentTid) - { - InterlockedIncrement(&ObjHdr->LockCount); - break; - } - /* FIXME: KeDelayExecutionThread(KernelMode, FALSE, &ShortDelay); */ +#ifdef GDI_DEBUG + GdiHdr->lockfile = file; + GdiHdr->lockline = line; +#endif + } + + InterlockedExchange(&Entry->ProcessId, PrevProcId); + + /* we're done, return the object body */ + return GDIHdrToBdy(GdiHdr); + } + else + { + InterlockedExchange(&Entry->ProcessId, PrevProcId); + +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting at %s:%i as 0x%x on 0x%x\n", Attempts, file, line, Thread, PrevThread); } - } #endif - ExAcquireFastMutex(&RefCountHandling); - ObjHdr->dwCount++; - ExReleaseFastMutex(&RefCountHandling); - return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR)); + DelayExecution(); + goto LockHandle; + } + } + else + { + InterlockedExchange(&Entry->ProcessId, PrevProcId); + + if(EntryType == 0) + { + DPRINT1("Attempted to lock object 0x%x that is deleted!\n", hObj); + } + else + { + DPRINT1("Attempted to lock object 0x%x, type mismatch (0x%x : 0x%x)\n", hObj, EntryType, ExpectedType); + } + } + } + else if(PrevProcId == LockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting from %s:%i on 0x%x\n", Attempts, file, line, hObj); + } +#endif + /* the handle is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else if((PrevProcId & ~0x1) == 0) + { + /* we're trying to lock a global object, change the ProcessId to 0 and try again */ + ProcessId = 0x0; + LockedProcessId = ProcessId |0x1; + + goto LockHandle; + } + else + { + DPRINT1("Attempted to lock foreign handle: 0x%x, Owner: 0x%x locked: 0x%x Caller: 0x%x, stockobj: 0x%x\n", hObj, PrevProcId >> 1, PrevProcId & 0x1, PsGetCurrentProcessId(), GDI_HANDLE_IS_STOCKOBJ(hObj)); +#ifdef GDI_DEBUG + DPRINT1("-> called from %s:%i\n", file, line); +#endif + } + + return NULL; } + /*! * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. You should unlock the object * as soon as you don't need to have access to it's data. * \param hObj Object handle - * \param ObjectType one of the object types defined in \ref GDI object types * * \note This function performs delayed cleanup. If the object is locked when GDI_FreeObj() is called * then \em this function frees the object when reference count is zero. - * - * \todo Change synchronization algorithm. */ -#undef GDIOBJ_UnlockObj -BOOL FASTCALL -GDIOBJ_UnlockObj(HGDIOBJ hObj, DWORD ObjectType) +BOOL INTERNAL_CALL +#ifdef GDI_DEBUG +GDIOBJ_UnlockObjDbg (const char* file, int line, HGDIOBJ hObj) +#else /* !GDI_DEBUG */ +GDIOBJ_UnlockObj (HGDIOBJ hObj) +#endif /* GDI_DEBUG */ { - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj)); - - DPRINT("GDIOBJ_UnlockObj: hObj: 0x%08x, type: 0x%08x, objhdr: %x\n", hObj, ObjectType, ObjHdr); - if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT)) - { - DPRINT1( "GDIOBJ_UnLockObj: failed\n"); - return FALSE; - } - -#ifdef GDIOBJ_USE_FASTMUTEX - if (--ObjHdr->RecursiveLockCount == 0) - ExReleaseFastMutex(&ObjHdr->Lock); -#else - if (InterlockedDecrement(&ObjHdr->LockCount) == 0) - { - InterlockedExchange(&ObjHdr->LockTid, 0); - } + PGDI_TABLE_ENTRY Entry; + PETHREAD Thread; + LONG ProcessId, LockedProcessId, PrevProcId; +#ifdef GDI_DEBUG + ULONG Attempts = 0; #endif - ExAcquireFastMutex(&RefCountHandling); - if (0 == (ObjHdr->dwCount & ~0x80000000)) + DPRINT("GDIOBJ_UnlockObj: hObj: 0x%08x\n", hObj); + Thread = PsGetCurrentThread(); + + /* shift the process id to the left so we can use the first bit to lock the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = ProcessId | 0x1; + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, hObj); + +LockHandle: + /* lock the handle, we must not delete stock objects, so don't check!!! */ + PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, ProcessId); + if(PrevProcId == ProcessId) + { + /* we're unlocking an object that belongs to our process or it's a global + object if ProcessId == 0 here. ProcessId can only be 0 here if it previously + failed to lock the object and it turned out to be a global object. */ + if(Entry->KernelData != NULL) { - ExReleaseFastMutex(&RefCountHandling); - DPRINT1( "GDIOBJ_UnLockObj: unlock object (0x%x) that is not locked\n", hObj ); - return FALSE; + PETHREAD PrevThread; + PGDIOBJHDR GdiHdr; + + GdiHdr = GDIBdyToHdr(Entry->KernelData); + + PrevThread = GdiHdr->LockingThread; + if(PrevThread == Thread) + { + BOOL Ret; + + if(--GdiHdr->Locks == 0) + { + GdiHdr->LockingThread = NULL; + +#ifdef GDI_DEBUG + GdiHdr->lockfile = NULL; + GdiHdr->lockline = 0; +#endif + } + + if(Entry->Type == 0 && GdiHdr->Locks == 0) + { + PPAGED_LOOKASIDE_LIST LookasideList; + DWORD Type = GDI_HANDLE_GET_TYPE(hObj); + + ASSERT(ProcessId != 0); /* must not delete a global handle!!!! */ + + /* we should delete the handle */ + Entry->KernelData = NULL; + InterlockedExchange(&Entry->ProcessId, 0); + + /* call the cleanup routine. */ + Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type); + + /* Now it's time to free the memory */ + LookasideList = FindLookasideList(Type); + if(LookasideList != NULL) + { + ExFreeToPagedLookasideList(LookasideList, GdiHdr); + } + } + else + { + /* remove the handle slot lock */ + InterlockedExchange(&Entry->ProcessId, PrevProcId); + Ret = TRUE; + } + + /* we're done*/ + return Ret; + } +#ifdef GDI_DEBUG + else if(PrevThread != NULL) + { + DPRINT1("Attempted to unlock object 0x%x, previously locked by other thread (0x%x) from %s:%i (called from %s:%i)\n", + hObj, PrevThread, GdiHdr->lockfile, GdiHdr->lockline, file, line); + InterlockedExchange(&Entry->ProcessId, PrevProcId); + } +#endif + else + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting at %s:%i as 0x%x on 0x%x\n", Attempts, file, line, Thread, PrevThread); + } +#endif + /* FIXME - we should give up after some time unless we want to wait forever! */ + InterlockedExchange(&Entry->ProcessId, PrevProcId); + + DelayExecution(); + goto LockHandle; + } } - - ObjHdr->dwCount--; - - if (ObjHdr->dwCount == 0x80000000) + else { - //delayed object release - ObjHdr->dwCount = 0; - ExReleaseFastMutex(&RefCountHandling); - DPRINT("GDIOBJ_UnlockObj: delayed delete\n"); - return GDIOBJ_FreeObj(hObj, ObjectType, GDIOBJFLAG_DEFAULT); + InterlockedExchange(&Entry->ProcessId, PrevProcId); + DPRINT1("Attempted to unlock object 0x%x that is deleted!\n", hObj); } - ExReleaseFastMutex(&RefCountHandling); + } + else if(PrevProcId == LockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting from %s:%i on 0x%x\n", Attempts, file, line, hObj); + } +#endif + /* the handle is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else if((PrevProcId & ~0x1) == 0) + { + /* we're trying to unlock a global object, change the ProcessId to 0 and try again */ + ProcessId = 0x0; + LockedProcessId = ProcessId |0x1; - return TRUE; + goto LockHandle; + } + else + { + DPRINT1("Attempted to unlock foreign handle: 0x%x, Owner: 0x%x locked: 0x%x Caller: 0x%x, stockobj: 0x%x\n", hObj, PrevProcId >> 1, PrevProcId & 0x1, PsGetCurrentProcessId(), GDI_HANDLE_IS_STOCKOBJ(hObj)); + } + + return FALSE; } -BOOL FASTCALL +BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle) { - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); + PGDI_TABLE_ENTRY Entry; + LONG ProcessId; + BOOL Ret; DPRINT("GDIOBJ_OwnedByCurrentProcess: ObjectHandle: 0x%08x\n", ObjectHandle); - ASSERT(GDI_VALID_OBJECT(ObjectHandle, ObjHdr, GDI_OBJECT_TYPE_DONTCARE, GDIOBJFLAG_IGNOREPID)); - return ObjHdr->hProcessId == PsGetCurrentProcessId(); + if(!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) + { + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, ObjectHandle); + Ret = Entry->KernelData != NULL && + Entry->Type != 0 && + (Entry->ProcessId & ~0x1) == ProcessId; + + return Ret; + } + + return FALSE; } -void FASTCALL +BOOL INTERNAL_CALL +GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj) +{ +/* + * FIXME !!!!! THIS FUNCTION NEEDS TO BE FIXED - IT IS NOT SAFE WHEN OTHER THREADS + * MIGHT ATTEMPT TO LOCK THE OBJECT DURING THIS CALL!!! + */ + PGDI_TABLE_ENTRY Entry; + LONG ProcessId, LockedProcessId, PrevProcId; + PETHREAD Thread; +#ifdef GDI_DEBUG + ULONG Attempts = 0; +#endif + + ASSERT(hObj); + + DPRINT("GDIOBJ_ConvertToStockObj: hObj: 0x%08x\n", *hObj); + + Thread = PsGetCurrentThread(); + + if(!GDI_HANDLE_IS_STOCKOBJ(*hObj)) + { + /* shift the process id to the left so we can use the first bit to lock the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = ProcessId | 0x1; + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, *hObj); + +LockHandle: + /* lock the object, we must not convert stock objects, so don't check!!! */ + PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, ProcessId); + if(PrevProcId == ProcessId) + { + LONG NewType, PrevType, OldType; + + /* we're locking an object that belongs to our process. First calculate + the new object type including the stock object flag and then try to + exchange it.*/ + NewType = GDI_HANDLE_GET_TYPE(*hObj); + NewType |= NewType >> 16; + /* This is the type that the object should have right now, save it */ + OldType = NewType; + /* As the object should be a stock object, set it's flag, but only in the upper 16 bits */ + NewType |= GDI_HANDLE_STOCK_MASK; + + /* Try to exchange the type field - but only if the old (previous type) matches! */ + PrevType = InterlockedCompareExchange(&Entry->Type, NewType, OldType); + if(PrevType == OldType && Entry->KernelData != NULL) + { + PETHREAD PrevThread; + PGDIOBJHDR GdiHdr; + + /* We successfully set the stock object flag. + KernelData should never be NULL here!!! */ + ASSERT(Entry->KernelData); + + GdiHdr = GDIBdyToHdr(Entry->KernelData); + + PrevThread = GdiHdr->LockingThread; + if(PrevThread == NULL || PrevThread == Thread) + { + /* dereference the process' object counter */ + if(PrevProcId != GDI_GLOBAL_PROCESS) + { + PEPROCESS OldProcess; + PW32PROCESS W32Process; + NTSTATUS Status; + + /* FIXME */ + Status = PsLookupProcessByProcessId((PVOID)(PrevProcId >> 1), &OldProcess); + if(NT_SUCCESS(Status)) + { + W32Process = OldProcess->Win32Process; + if(W32Process != NULL) + { + InterlockedDecrement(&W32Process->GDIObjects); + } + ObDereferenceObject(OldProcess); + } + } + + /* remove the process id lock and make it global */ + InterlockedExchange(&Entry->ProcessId, GDI_GLOBAL_PROCESS); + + *hObj = (HGDIOBJ)((ULONG)(*hObj) | GDI_HANDLE_STOCK_MASK); + + /* we're done, successfully converted the object */ + return TRUE; + } + else + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + if(GdiHdr->lockfile != NULL) + { + DPRINT1("[%d]Locked %s:%i by 0x%x (we're 0x%x)\n", Attempts, GdiHdr->lockfile, GdiHdr->lockline, PrevThread, Thread); + } + } +#endif + /* WTF?! The object is already locked by a different thread! + Release the lock, wait a bit and try again! + FIXME - we should give up after some time unless we want to wait forever! */ + InterlockedExchange(&Entry->ProcessId, PrevProcId); + + DelayExecution(); + goto LockHandle; + } + } + else + { + DPRINT1("Attempted to convert object 0x%x that is deleted! Should never get here!!!\n", hObj); + } + } + else if(PrevProcId == LockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); + } +#endif + /* the object is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else + { + DPRINT1("Attempted to convert invalid handle: 0x%x\n", hObj); + } + } + + return FALSE; +} + +void INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS NewOwner) { - PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); - PEPROCESS OldProcess; - PW32PROCESS W32Process; - NTSTATUS Status; + PGDI_TABLE_ENTRY Entry; + LONG ProcessId, LockedProcessId, PrevProcId; + PETHREAD Thread; +#ifdef GDI_DEBUG + ULONG Attempts = 0; +#endif - DPRINT("GDIOBJ_OwnedByCurrentProcess: ObjectHandle: 0x%08x\n", ObjectHandle); - ASSERT(GDI_VALID_OBJECT(ObjectHandle, ObjHdr, GDI_OBJECT_TYPE_DONTCARE, GDIOBJFLAG_IGNOREPID)); + DPRINT("GDIOBJ_SetOwnership: hObj: 0x%x, NewProcess: 0x%x\n", ObjectHandle, (NewOwner ? PsGetProcessId(NewOwner) : 0)); + + Thread = PsGetCurrentThread(); - if ((NULL == NewOwner && GDI_GLOBAL_PROCESS != ObjHdr->hProcessId) - || (NULL != NewOwner && ObjHdr->hProcessId != (HANDLE) NewOwner->UniqueProcessId)) + if(!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) + { + /* shift the process id to the left so we can use the first bit to lock the object. + FIXME - don't shift once ROS' PIDs match with nt! */ + ProcessId = (LONG)PsGetCurrentProcessId() << 1; + LockedProcessId = ProcessId | 0x1; + + Entry = GDI_HANDLE_GET_ENTRY(HandleTable, ObjectHandle); + +LockHandle: + /* lock the object, we must not convert stock objects, so don't check!!! */ + PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, ProcessId, LockedProcessId); + if(PrevProcId == ProcessId) { - Status = PsLookupProcessByProcessId((PVOID)ObjHdr->hProcessId, &OldProcess); - if (NT_SUCCESS(Status)) + PETHREAD PrevThread; + + if(Entry->Type != 0 && Entry->KernelData != NULL) + { + PGDIOBJHDR GdiHdr = GDIBdyToHdr(Entry->KernelData); + + PrevThread = GdiHdr->LockingThread; + if(PrevThread == NULL || PrevThread == Thread) { - W32Process = OldProcess->Win32Process; - if (W32Process) + PEPROCESS OldProcess; + PW32PROCESS W32Process; + NTSTATUS Status; + + /* dereference the process' object counter */ + /* FIXME */ + Status = PsLookupProcessByProcessId((PVOID)(PrevProcId >> 1), &OldProcess); + if(NT_SUCCESS(Status)) + { + W32Process = OldProcess->Win32Process; + if(W32Process != NULL) { - W32Process->GDIObjects--; + InterlockedDecrement(&W32Process->GDIObjects); } - ObDereferenceObject(OldProcess); - } - } + ObDereferenceObject(OldProcess); + } - if (NULL == NewOwner) - { - ObjHdr->hProcessId = GDI_GLOBAL_PROCESS; - } - else if (ObjHdr->hProcessId != (HANDLE) NewOwner->UniqueProcessId) - { - ObjHdr->hProcessId = (HANDLE) NewOwner->UniqueProcessId; - W32Process = NewOwner->Win32Process; - if (W32Process) - { - W32Process->GDIObjects++; + if(NewOwner != NULL) + { + /* FIXME */ + ProcessId = (LONG)PsGetProcessId(NewOwner) << 1; + + /* Increase the new process' object counter */ + W32Process = NewOwner->Win32Process; + if(W32Process != NULL) + { + InterlockedIncrement(&W32Process->GDIObjects); + } + } + else + ProcessId = 0; + + /* remove the process id lock and change it to the new process id */ + InterlockedExchange(&Entry->ProcessId, ProcessId); + + /* we're done! */ + return; } + else + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + if(GdiHdr->lockfile != NULL) + { + DPRINT1("[%d]Locked from %s:%i by 0x%x (we're 0x%x)\n", Attempts, GdiHdr->lockfile, GdiHdr->lockline, PrevThread, Thread); + } + } +#endif + /* WTF?! The object is already locked by a different thread! + Release the lock, wait a bit and try again! DO reset the pid lock + so we make sure we don't access invalid memory in case the object is + being deleted in the meantime (because we don't have aquired a reference + at this point). + FIXME - we should give up after some time unless we want to wait forever! */ + InterlockedExchange(&Entry->ProcessId, PrevProcId); + + DelayExecution(); + goto LockHandle; + } + } + else + { + DPRINT1("Attempted to change ownership of an object 0x%x currently being destroyed!!!\n", ObjectHandle); + } } + else if(PrevProcId == LockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, ObjectHandle); + } +#endif + /* the object is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else if((PrevProcId >> 1) == 0) + { + /* allow changing ownership of global objects */ + ProcessId = 0; + LockedProcessId = ProcessId | 0x1; + goto LockHandle; + } + else if((PrevProcId >> 1) != (LONG)PsGetCurrentProcessId()) + { + /* FIXME - should we really allow changing the ownership of objects we don't own? */ + DPRINT1("WARNING! Changing ownership of object 0x%x (pid: 0x%x) from pid 0x%x!!!\n", ObjectHandle, PrevProcId >> 1, PsGetCurrentProcessId()); + ProcessId = PrevProcId & ~0x1; + LockedProcessId = ProcessId | 0x1; + goto LockHandle; + } + else + { + DPRINT1("Attempted to change owner of invalid handle: 0x%x\n", ObjectHandle); + } + } } -void FASTCALL +void INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo) { - PGDIOBJHDR ObjHdrFrom = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(CopyFrom)); - PGDIOBJHDR ObjHdrTo = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(CopyTo)); - NTSTATUS Status; - PEPROCESS ProcessFrom; - PEPROCESS CurrentProcess; + PGDI_TABLE_ENTRY FromEntry; + PETHREAD Thread; + LONG FromProcessId, FromLockedProcessId, FromPrevProcId; +#ifdef GDI_DEBUG + ULONG Attempts = 0; +#endif - ASSERT(NULL != ObjHdrFrom && NULL != ObjHdrTo); - if (NULL != ObjHdrFrom && NULL != ObjHdrTo - && ObjHdrTo->hProcessId != ObjHdrFrom->hProcessId) + DPRINT("GDIOBJ_CopyOwnership: from: 0x%x, to: 0x%x\n", CopyFrom, CopyTo); + + Thread = PsGetCurrentThread(); + + if(!GDI_HANDLE_IS_STOCKOBJ(CopyFrom) && !GDI_HANDLE_IS_STOCKOBJ(CopyTo)) + { + FromEntry = GDI_HANDLE_GET_ENTRY(HandleTable, CopyFrom); + + FromProcessId = FromEntry->ProcessId & ~0x1; + FromLockedProcessId = FromProcessId | 0x1; + +LockHandleFrom: + /* lock the object, we must not convert stock objects, so don't check!!! */ + FromPrevProcId = InterlockedCompareExchange(&FromEntry->ProcessId, FromProcessId, FromLockedProcessId); + if(FromPrevProcId == FromProcessId) { - if (ObjHdrFrom->hProcessId == GDI_GLOBAL_PROCESS) + PETHREAD PrevThread; + PGDIOBJHDR GdiHdr; + + if(FromEntry->Type != 0 && FromEntry->KernelData != NULL) + { + GdiHdr = GDIBdyToHdr(FromEntry->KernelData); + + /* save the pointer to the calling thread so we know it was this thread + that locked the object */ + PrevThread = GdiHdr->LockingThread; + if(PrevThread == NULL || PrevThread == Thread) { - GDIOBJ_SetOwnership(CopyTo, NULL); - } - else - { - /* Warning: ugly hack ahead - * - * During process cleanup, we can't call PsLookupProcessByProcessId - * for the current process, 'cause that function will try to - * reference the process, and since the process is closing down - * that will result in a bugcheck. - * So, instead, we call PsGetCurrentProcess, which doesn't reference - * the process. If the current process is indeed the one we're - * looking for, we use it, otherwise we can (safely) call - * PsLookupProcessByProcessId - */ - CurrentProcess = PsGetCurrentProcess(); - if (ObjHdrFrom->hProcessId == (HANDLE) CurrentProcess->UniqueProcessId) + /* now let's change the ownership of the target object */ + + if((FromPrevProcId & ~0x1) != 0) + { + PEPROCESS ProcessTo; + /* FIXME */ + if(NT_SUCCESS(PsLookupProcessByProcessId((PVOID)(FromPrevProcId >> 1), &ProcessTo))) { - GDIOBJ_SetOwnership(CopyTo, CurrentProcess); + GDIOBJ_SetOwnership(CopyTo, ProcessTo); + ObDereferenceObject(ProcessTo); } + } else - { - Status = PsLookupProcessByProcessId((PVOID) ObjHdrFrom->hProcessId, &ProcessFrom); - if (NT_SUCCESS(Status)) - { - GDIOBJ_SetOwnership(CopyTo, ProcessFrom); - ObDereferenceObject(ProcessFrom); - } - } + { + /* mark the object as global */ + GDIOBJ_SetOwnership(CopyTo, NULL); + } + + InterlockedExchange(&FromEntry->ProcessId, FromPrevProcId); } + else + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + if(GdiHdr->lockfile != NULL) + { + DPRINT1("[%d]Locked from %s:%i by 0x%x (we're 0x%x)\n", Attempts, GdiHdr->lockfile, GdiHdr->lockline, PrevThread, Thread); + } + } +#endif + /* WTF?! The object is already locked by a different thread! + Release the lock, wait a bit and try again! DO reset the pid lock + so we make sure we don't access invalid memory in case the object is + being deleted in the meantime (because we don't have aquired a reference + at this point). + FIXME - we should give up after some time unless we want to wait forever! */ + InterlockedExchange(&FromEntry->ProcessId, FromPrevProcId); + + DelayExecution(); + goto LockHandleFrom; + } + } + else + { + DPRINT1("Attempted to copy ownership from an object 0x%x currently being destroyed!!!\n", CopyFrom); + } } + else if(FromPrevProcId == FromLockedProcessId) + { +#ifdef GDI_DEBUG + if(++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, CopyFrom); + } +#endif + /* the object is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandleFrom; + } + else if((FromPrevProcId >> 1) != (LONG)PsGetCurrentProcessId()) + { + /* FIXME - should we really allow copying ownership from objects that we don't even own? */ + DPRINT1("WARNING! Changing copying ownership of object 0x%x (pid: 0x%x) to pid 0x%x!!!\n", CopyFrom, FromPrevProcId >> 1, PsGetCurrentProcessId()); + FromProcessId = FromPrevProcId & ~0x1; + FromLockedProcessId = FromProcessId | 0x1; + goto LockHandleFrom; + } + else + { + DPRINT1("Attempted to copy ownership from invalid handle: 0x%x\n", CopyFrom); + } + } +} + +PVOID INTERNAL_CALL +GDI_MapHandleTable(HANDLE hProcess) +{ + DPRINT("%s:%i: %s(): FIXME - Map handle table into the process memory space!\n", + __FILE__, __LINE__, __FUNCTION__); + /* FIXME - Map the entire gdi handle table read-only to userland into the + scope of hProcess and return the pointer */ + return NULL; } /* EOF */ diff --git a/reactos/subsys/win32k/objects/line.c b/reactos/subsys/win32k/objects/line.c index e80509be181..7db530ba7bd 100644 --- a/reactos/subsys/win32k/objects/line.c +++ b/reactos/subsys/win32k/objects/line.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: line.c,v 1.37 2004/07/14 20:48:58 navaraf Exp $ */ +/* $Id: line.c,v 1.38 2004/12/12 01:40:38 weiden Exp $ */ #include // Some code from the WINE project source (www.winehq.com) @@ -98,6 +98,7 @@ IntGdiLineTo(DC *dc, /* get BRUSHOBJ from current pen. */ PenBrushObj = PENOBJ_LockPen( dc->w.hPen ); + /* FIXME - PenBrushObj can be NULL!!!! Don't assert here! */ ASSERT(PenBrushObj); if (!(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)) @@ -202,6 +203,7 @@ IntGdiPolyline(DC *dc, /* Get BRUSHOBJ from current pen. */ PenBrushObj = PENOBJ_LockPen(dc->w.hPen); + /* FIXME - PenBrushObj can be NULL! Don't assert here! */ ASSERT(PenBrushObj); if (!(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)) @@ -210,6 +212,7 @@ IntGdiPolyline(DC *dc, if (Points != NULL) { BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - BitmapObj can be NULL!!!! Don't assert but handle this case gracefully! */ ASSERT(BitmapObj); RtlCopyMemory(Points, pt, Count * sizeof(POINT)); diff --git a/reactos/subsys/win32k/objects/palette.c b/reactos/subsys/win32k/objects/palette.c index 617eac8a57a..97abee7d3a5 100644 --- a/reactos/subsys/win32k/objects/palette.c +++ b/reactos/subsys/win32k/objects/palette.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: palette.c,v 1.20 2004/06/22 20:08:17 gvg Exp $ */ +/* $Id: palette.c,v 1.21 2004/12/12 01:40:38 weiden Exp $ */ #include #ifndef NO_MAPPING @@ -36,12 +36,13 @@ PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID) return COLOR_sysPal; } -static BOOL FASTCALL -PALETTE_InternalDelete(PPALGDI Palette) +BOOL INTERNAL_CALL +PALETTE_Cleanup(PVOID ObjectBody) { - if (NULL != Palette->IndexedColors) + PPALGDI pPal = (PPALGDI)ObjectBody; + if (NULL != pPal->IndexedColors) { - ExFreePool(Palette->IndexedColors); + ExFreePool(pPal->IndexedColors); } return TRUE; @@ -58,13 +59,14 @@ PALETTE_AllocPalette(ULONG Mode, HPALETTE NewPalette; PPALGDI PalGDI; - NewPalette = (HPALETTE) GDIOBJ_AllocObj(sizeof(PALGDI), GDI_OBJECT_TYPE_PALETTE, (GDICLEANUPPROC) PALETTE_InternalDelete); + NewPalette = (HPALETTE) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_PALETTE); if (NULL == NewPalette) { return NULL; } PalGDI = PALETTE_LockPalette(NewPalette); + /* FIXME - PalGDI can be NULL!!! Don't assert here! */ ASSERT( PalGDI ); PalGDI->Self = NewPalette; @@ -106,13 +108,14 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, PPALGDI PalGDI; unsigned i; - NewPalette = (HPALETTE) GDIOBJ_AllocObj(sizeof(PALGDI), GDI_OBJECT_TYPE_PALETTE, (GDICLEANUPPROC) PALETTE_InternalDelete); + NewPalette = (HPALETTE) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_PALETTE); if (NULL == NewPalette) { return NULL; } PalGDI = PALETTE_LockPalette(NewPalette); + /* FIXME - PalGDI can be NULL!!! Don't assert here! */ ASSERT( PalGDI ); PalGDI->Self = NewPalette; @@ -227,6 +230,7 @@ INT STDCALL PALETTE_SetMapping(PALOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapO HPALETTE hSysPal = NtGdiGetStockObject(DEFAULT_PALETTE); PPALGDI pSysPal = PALETTE_LockPalette(hSysPal); PPALGDI palGDI = (PPALGDI) palPtr; + /* FIXME - handle pSysPal == NULL!!!!!!! */ COLOR_sysPal = pSysPal->IndexedColors; PALETTE_UnlockPalette(hSysPal); // FIXME: Is this a right way to obtain pointer to the system palette? diff --git a/reactos/subsys/win32k/objects/pen.c b/reactos/subsys/win32k/objects/pen.c index d267a43365c..61f732a8c47 100644 --- a/reactos/subsys/win32k/objects/pen.c +++ b/reactos/subsys/win32k/objects/pen.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: pen.c,v 1.16 2004/07/14 20:48:58 navaraf Exp $ + * $Id: pen.c,v 1.17 2004/12/12 01:40:38 weiden Exp $ */ #include @@ -42,6 +42,7 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) } PenObject = PENOBJ_LockPen(hPen); + /* FIXME - Handle PenObject == NULL!!! */ PenObject->ptPenWidth = LogPen->lopnWidth; PenObject->ulPenStyle = LogPen->lopnStyle; PenObject->BrushAttr.lbColor = LogPen->lopnColor; diff --git a/reactos/subsys/win32k/objects/print.c b/reactos/subsys/win32k/objects/print.c index fa9191a81d0..bd9655ed81d 100644 --- a/reactos/subsys/win32k/objects/print.c +++ b/reactos/subsys/win32k/objects/print.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: print.c,v 1.23 2004/07/17 17:37:41 blight Exp $ */ +/* $Id: print.c,v 1.24 2004/12/12 01:40:38 weiden Exp $ */ #include INT @@ -85,6 +85,8 @@ IntGdiExtEscape( BITMAPOBJ *BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); INT Result; + /* FIXME - Handle BitmapObj == NULL !!!!!! */ + if ( NULL == dc->DriverFunctions.Escape ) { Result = IntEngExtEscape( diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index 7d2c85e5686..72f495d044f 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -113,12 +113,26 @@ SOFTWARE. * the y-x-banding that's so nice to have... */ -/* $Id: region.c,v 1.63 2004/12/11 22:39:38 weiden Exp $ */ +/* $Id: region.c,v 1.64 2004/12/12 01:40:38 weiden Exp $ */ #include #include // Internal Functions +#if 1 +#define COPY_RECTS(dest, src, nRects) \ + do { \ + PRECT xDest = (dest); \ + PRECT xSrc = (src); \ + UINT xRects = (nRects); \ + while(xRects-- > 0) { \ + *(xDest++) = *(xSrc++); \ + } \ + } while(0) +#else +#define COPY_RECTS(dest, src, nRects) RtlCopyMemory(dest, src, (nRects) * sizeof(RECT)) +#endif + #define EMPTY_REGION(pReg) { \ (pReg)->rdh.nCount = 0; \ (pReg)->rdh.rcBound.left = (pReg)->rdh.rcBound.top = 0; \ @@ -382,8 +396,6 @@ typedef struct _ScanLineListBlock { #define LARGE_COORDINATE 0x7fffffff /* FIXME */ #define SMALL_COORDINATE 0x80000000 - - /* * Check to see if there is enough memory in the present region. */ @@ -394,7 +406,10 @@ static inline int xmemcheck(ROSRGNDATA *reg, PRECT *rect, PRECT *firstrect ) { if (temp == 0) return 0; - RtlCopyMemory( temp, *firstrect, reg->rdh.nRgnSize ); + + /* copy the rectangles */ + COPY_RECTS(temp, *firstrect, reg->rdh.nCount); + reg->rdh.nRgnSize *= 2; if (*firstrect != ®->rdh.rcBound) ExFreePool( *firstrect ); @@ -473,7 +488,7 @@ static BOOL FASTCALL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src) dst->rdh.rcBound.right = src->rdh.rcBound.right; dst->rdh.rcBound.bottom = src->rdh.rcBound.bottom; dst->rdh.iType = src->rdh.iType; - RtlCopyMemory(dst->Buffer, src->Buffer, (int)(src->rdh.nCount * sizeof(RECT))); + COPY_RECTS(dst->Buffer, src->Buffer, src->rdh.nCount); } return TRUE; } @@ -546,7 +561,9 @@ static BOOL FASTCALL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT re ULONG i; if(rgnDst != rgnSrc) - RtlCopyMemory(rgnDst, rgnSrc, sizeof(ROSRGNDATA)); + { + *rgnDst = *rgnSrc; + } if(off->x || off->y) { @@ -563,7 +580,9 @@ static BOOL FASTCALL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT re rgnDst->rdh.rcBound.bottom += off->y; } else - RtlCopyMemory(xrect, rgnSrc->Buffer, rgnDst->rdh.nCount * sizeof(RECT)); + { + COPY_RECTS(xrect, rgnSrc->Buffer, rgnDst->rdh.nCount); + } rgnDst->Buffer = xrect; } else @@ -1137,7 +1156,7 @@ REGION_RegionOp( newReg->Buffer = prev_rects; else{ newReg->rdh.nRgnSize = newReg->rdh.nCount*sizeof(RECT); - RtlCopyMemory( newReg->Buffer, prev_rects, newReg->rdh.nRgnSize ); + COPY_RECTS(newReg->Buffer, prev_rects, newReg->rdh.nCount); if (prev_rects != &newReg->rdh.rcBound) ExFreePool( prev_rects ); } @@ -1883,8 +1902,7 @@ HRGN FASTCALL RGNDATA_AllocRgn(INT n) PROSRGNDATA pReg; BOOL bRet; - if ((hReg = (HRGN) GDIOBJ_AllocObj(sizeof(ROSRGNDATA), GDI_OBJECT_TYPE_REGION, - (GDICLEANUPPROC) RGNDATA_InternalDelete))) + if ((hReg = (HRGN) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_REGION))) { if (NULL != (pReg = RGNDATA_LockRgn(hReg))) { @@ -1921,9 +1939,10 @@ HRGN FASTCALL RGNDATA_AllocRgn(INT n) return NULL; } -BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA pRgn ) +BOOL INTERNAL_CALL +RGNDATA_Cleanup(PVOID ObjectBody) { - ASSERT(pRgn); + PROSRGNDATA pRgn = (PROSRGNDATA)ObjectBody; if(pRgn->Buffer && pRgn->Buffer != &pRgn->rdh.rcBound) ExFreePool(pRgn->Buffer); return TRUE; @@ -2237,8 +2256,8 @@ NtGdiFillRgn(HDC hDC, HRGN hRgn, HBRUSH hBrush) NtGdiPatBlt(hDC, r->left, r->top, r->right - r->left, r->bottom - r->top, PATCOPY); } - NtGdiSelectObject(hDC, oldhBrush); RGNDATA_UnlockRgn( hRgn ); + NtGdiSelectObject(hDC, oldhBrush); return TRUE; } @@ -2438,6 +2457,7 @@ NtGdiPaintRgn(HDC hDC, BrushOrigin.x = dc->w.brushOrgX; BrushOrigin.y = dc->w.brushOrgY; BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + /* FIXME - Handle BitmapObj == NULL !!!! */ bRet = IntEngPaint(BitmapObj, ClipRegion, @@ -2446,7 +2466,7 @@ NtGdiPaintRgn(HDC hDC, 0xFFFF);//FIXME:don't know what to put here BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); - RGNDATA_UnlockRgn( tmpVisRgn ); + RGNDATA_UnlockRgn( hRgn ); // Fill the region DC_UnlockDc( hDC ); @@ -2571,7 +2591,7 @@ NtGdiUnionRectWithRgn(HRGN hDest, CONST PRECT UnsafeRect) RECT SafeRect; PROSRGNDATA Rgn; - if(!(Rgn = (PROSRGNDATA)RGNDATA_UnlockRgn(hDest))) + if(!(Rgn = (PROSRGNDATA)RGNDATA_LockRgn(hDest))) { SetLastWin32Error(ERROR_INVALID_HANDLE); return NULL; @@ -2870,7 +2890,7 @@ static int FASTCALL REGION_PtsToRegion(int numFullPtBlocks, int iCurPtBlock, } if(reg->Buffer != NULL) { - RtlCopyMemory(temp, reg->Buffer, reg->rdh.nCount * sizeof(RECT)); + COPY_RECTS(temp, reg->Buffer, reg->rdh.nCount); if(reg->Buffer != ®->rdh.rcBound) ExFreePool(reg->Buffer); } diff --git a/reactos/subsys/win32k/objects/stockobj.c b/reactos/subsys/win32k/objects/stockobj.c new file mode 100644 index 00000000000..e0a2e814827 --- /dev/null +++ b/reactos/subsys/win32k/objects/stockobj.c @@ -0,0 +1,319 @@ +/* + * ReactOS W32 Subsystem + * Copyright (C) 1998 - 2004 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * STOCKOBJ.C - GDI Stock Objects + * + * $Id: stockobj.c,v 1.2 2004/12/12 01:40:39 weiden Exp $ + * + */ +#include + +#define NDEBUG +#include + +static COLORREF SysColors[] = +{ + RGB(212, 208, 200), /* COLOR_SCROLLBAR */ + RGB(58, 110, 165), /* COLOR_BACKGROUND */ + RGB(10, 36, 106), /* COLOR_ACTIVECAPTION */ + RGB(128, 128, 128), /* COLOR_INACTIVECAPTION */ + RGB(212, 208, 200), /* COLOR_MENU */ + RGB(255, 255, 255), /* COLOR_WINDOW */ + RGB(0, 0, 0), /* COLOR_WINDOWFRAME */ + RGB(0, 0, 0), /* COLOR_MENUTEXT */ + RGB(0, 0, 0), /* COLOR_WINDOWTEXT */ + RGB(255, 255, 255), /* COLOR_CAPTIONTEXT */ + RGB(212, 208, 200), /* COLOR_ACTIVEBORDER */ + RGB(212, 208, 200), /* COLOR_INACTIVEBORDER */ + RGB(128, 128, 128), /* COLOR_APPWORKSPACE */ + RGB(10, 36, 106), /* COLOR_HIGHLIGHT */ + RGB(255, 255, 255), /* COLOR_HIGHLIGHTTEXT */ + RGB(212, 208, 200), /* COLOR_BTNFACE */ + RGB(128, 128, 128), /* COLOR_BTNSHADOW */ + RGB(128, 128, 128), /* COLOR_GRAYTEXT */ + RGB(0, 0, 0), /* COLOR_BTNTEXT */ + RGB(212, 208, 200), /* COLOR_INACTIVECAPTIONTEXT */ + RGB(255, 255, 255), /* COLOR_BTNHIGHLIGHT */ + RGB(64, 64, 64), /* COLOR_3DDKSHADOW */ + RGB(212, 208, 200), /* COLOR_3DLIGHT */ + RGB(0, 0, 0), /* COLOR_INFOTEXT */ + RGB(255, 255, 225), /* COLOR_INFOBK */ + RGB(181, 181, 181), /* COLOR_UNKNOWN */ + RGB(0, 0, 128), /* COLOR_HOTLIGHT */ + RGB(166, 202, 240), /* COLOR_GRADIENTACTIVECAPTION */ + RGB(192, 192, 192), /* COLOR_GRADIENTINACTIVECAPTION */ + RGB(49, 106, 197), /* COLOR_MENUHILIGHT */ + RGB(236, 233, 216) /* COLOR_MENUBAR */ +}; +#define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0])) + +static HPEN SysColorPens[NUM_SYSCOLORS]; +static HBRUSH SysColorBrushes[NUM_SYSCOLORS]; + +/* GDI stock objects */ + +static LOGBRUSH WhiteBrush = +{ BS_SOLID, RGB(255,255,255), 0 }; + +static LOGBRUSH LtGrayBrush = +/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ +{ BS_SOLID, RGB(192,192,192), 0 }; + +static LOGBRUSH GrayBrush = +/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ +{ BS_SOLID, RGB(128,128,128), 0 }; + +static LOGBRUSH DkGrayBrush = +/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */ +/* NB_HATCH_STYLES is an index into HatchBrushes */ +{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES }; + +static LOGBRUSH BlackBrush = +{ BS_SOLID, RGB(0,0,0), 0 }; + +static LOGBRUSH NullBrush = +{ BS_NULL, 0, 0 }; + +static LOGPEN WhitePen = +{ PS_SOLID, { 0, 0 }, RGB(255,255,255) }; + +static LOGPEN BlackPen = +{ PS_SOLID, { 0, 0 }, RGB(0,0,0) }; + +static LOGPEN NullPen = +{ PS_NULL, { 0, 0 }, 0 }; + +static LOGFONTW OEMFixedFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, + 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; + +static LOGFONTW AnsiFixedFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; + +/*static LOGFONTW AnsiVarFont = + *{ 10, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + * 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; */ + +static LOGFONTW SystemFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; + +static LOGFONTW DeviceDefaultFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; + +static LOGFONTW SystemFixedFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Bitstream Vera Sans Mono" }; + +/* FIXME: Is this correct? */ +static LOGFONTW DefaultGuiFont = +{ 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, + 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"Bitstream Vera Sans" }; + +#define NB_STOCK_OBJECTS (DEFAULT_GUI_FONT + 1) + +static HGDIOBJ StockObjects[NB_STOCK_OBJECTS]; + +/*! + * Creates a bunch of stock objects: brushes, pens, fonts. +*/ +VOID FASTCALL +CreateStockObjects(void) +{ + UINT Object; + + DPRINT("Beginning creation of stock objects\n"); + + /* Create GDI Stock Objects from the logical structures we've defined */ + + StockObjects[WHITE_BRUSH] = IntGdiCreateBrushIndirect(&WhiteBrush); + StockObjects[LTGRAY_BRUSH] = IntGdiCreateBrushIndirect(&LtGrayBrush); + StockObjects[GRAY_BRUSH] = IntGdiCreateBrushIndirect(&GrayBrush); + StockObjects[DKGRAY_BRUSH] = IntGdiCreateBrushIndirect(&DkGrayBrush); + StockObjects[BLACK_BRUSH] = IntGdiCreateBrushIndirect(&BlackBrush); + StockObjects[NULL_BRUSH] = IntGdiCreateBrushIndirect(&NullBrush); + + StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen); + StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen); + StockObjects[NULL_PEN] = IntGdiCreatePenIndirect(&NullPen); + + (void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]); + (void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]); + (void) TextIntCreateFontIndirect(&SystemFont, (HFONT*)&StockObjects[SYSTEM_FONT]); + (void) TextIntCreateFontIndirect(&DeviceDefaultFont, (HFONT*)&StockObjects[DEVICE_DEFAULT_FONT]); + (void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]); + (void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]); + + StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); + + for (Object = 0; Object < NB_STOCK_OBJECTS; Object++) + { + if (NULL != StockObjects[Object]) + { + GDIOBJ_ConvertToStockObj(&StockObjects[Object]); + } + } + + DPRINT("Completed creation of stock objects\n"); +} + +/*! + * Return stock object. + * \param Object - stock object id. + * \return Handle to the object. +*/ +HGDIOBJ STDCALL +NtGdiGetStockObject(INT Object) +{ + DPRINT("NtGdiGetStockObject index %d\n", Object); + + return ((Object < 0) || (NB_STOCK_OBJECTS <= Object)) ? NULL : StockObjects[Object]; +} + +BOOL FASTCALL +IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors) +{ + UINT i; + + ASSERT(Elements); + ASSERT(Colors); + + for(i = 0; i < nColors; i++) + { + if((*Elements) >= 0 && (*Elements) < NUM_SYSCOLORS) + { + SysColors[*Elements] = *Colors; + /* FIXME - update the syscolor pens and brushes */ + } + Elements++; + Colors++; + } + + return nColors > 0; +} + +BOOL FASTCALL +IntGetSysColorBrushes(HBRUSH *Brushes, UINT nBrushes) +{ + UINT i; + + ASSERT(Brushes); + + if(nBrushes > NUM_SYSCOLORS) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + for(i = 0; i < nBrushes; i++) + { + *(Brushes++) = SysColorBrushes[i]; + } + + return nBrushes > 0; +} + +BOOL FASTCALL +IntGetSysColorPens(HPEN *Pens, UINT nPens) +{ + UINT i; + + ASSERT(Pens); + + if(nPens > NUM_SYSCOLORS) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + for(i = 0; i < nPens; i++) + { + *(Pens++) = SysColorPens[i]; + } + + return nPens > 0; +} + +BOOL FASTCALL +IntGetSysColors(COLORREF *Colors, UINT nColors) +{ + UINT i; + COLORREF *col; + + ASSERT(Colors); + + if(nColors > NUM_SYSCOLORS) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + col = &SysColors[0]; + for(i = 0; i < nColors; i++) + { + *(Colors++) = *(col++); + } + + return nColors > 0; +} + +VOID FASTCALL +CreateSysColorObjects(VOID) +{ + UINT i; + LOGBRUSH Brush; + LOGPEN Pen; + + /* Create the syscolor brushes */ + Brush.lbStyle = BS_SOLID; + Brush.lbHatch = 0; + for(i = 0; i < NUM_SYSCOLORS; i++) + { + if(SysColorBrushes[i] == NULL) + { + Brush.lbColor = SysColors[i]; + SysColorBrushes[i] = IntGdiCreateBrushIndirect(&Brush); + if(SysColorBrushes[i] != NULL) + { + GDIOBJ_ConvertToStockObj((HGDIOBJ*)&SysColorBrushes[i]); + } + } + } + + /* Create the syscolor pens */ + Pen.lopnStyle = PS_SOLID; + Pen.lopnWidth.x = 0; + Pen.lopnWidth.y = 0; + for(i = 0; i < NUM_SYSCOLORS; i++) + { + if(SysColorPens[i] == NULL) + { + Pen.lopnColor = SysColors[i]; + SysColorPens[i] = IntGdiCreatePenIndirect(&Pen); + if(SysColorPens[i] != NULL) + { + GDIOBJ_ConvertToStockObj((HGDIOBJ*)&SysColorPens[i]); + } + } + } +} + +/* EOF */ diff --git a/reactos/subsys/win32k/objects/text.c b/reactos/subsys/win32k/objects/text.c index 8c94e7b1fd6..b1f82398ee8 100644 --- a/reactos/subsys/win32k/objects/text.c +++ b/reactos/subsys/win32k/objects/text.c @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: text.c,v 1.112 2004/10/07 05:26:54 sedwards Exp $ */ +/* $Id: text.c,v 1.113 2004/12/12 01:40:38 weiden Exp $ */ #include #include @@ -33,7 +33,7 @@ FT_Library library; typedef struct _FONT_ENTRY { LIST_ENTRY ListEntry; - HFONT hFont; + FONTGDI *Font; UNICODE_STRING FaceName; BYTE NotEnum; } FONT_ENTRY, *PFONT_ENTRY; @@ -247,9 +247,7 @@ IntLoadSystemFonts(VOID) INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) { - HFONT NewFont; - FONTOBJ *FontObj; - PFONTGDI FontGDI; + FONTGDI *FontGDI; NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; @@ -261,20 +259,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) ANSI_STRING AnsiFaceName; PFONT_ENTRY Entry; - /* Create handle for the font */ - - NewFont = (HFONT)CreateGDIHandle( - sizeof(FONTGDI), - sizeof(FONTOBJ), - (PVOID*)&FontGDI, - (PVOID*)&FontObj); - - if (NewFont == 0) - { - DPRINT("Could not allocate a new GDI font object\n"); - return 0; - } - /* Open the font file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); @@ -289,7 +273,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) if (!NT_SUCCESS(Status)) { DPRINT("Could not font file: %wZ\n", FileName); - NtGdiDeleteObject(NewFont); return 0; } @@ -305,7 +288,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) if (!NT_SUCCESS(Status)) { DPRINT("Could not get file size\n"); - NtGdiDeleteObject(NewFont); ZwClose(FileHandle); return 0; } @@ -315,12 +297,11 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) Buffer = ExAllocatePoolWithTag( PagedPool, FileStdInfo.EndOfFile.u.LowPart, - TAG_GDITEXT); + TAG_FNTFILE); if (Buffer == NULL) { DPRINT("Could not allocate memory for font"); - NtGdiDeleteObject(NewFont); ZwClose(FileHandle); return 0; } @@ -342,7 +323,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) { DPRINT("Could not read the font file into memory"); ExFreePool(Buffer); - NtGdiDeleteObject(NewFont); ZwClose(FileHandle); return 0; } @@ -365,7 +345,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) else DPRINT("Error reading font file (error code: %u)\n", Error); ExFreePool(Buffer); - NtGdiDeleteObject(NewFont); return 0; } @@ -378,6 +357,16 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) return 0; } + FontGDI = EngAllocMem(0, sizeof(FONTGDI), TAG_FONTOBJ); + if(FontGDI == NULL) + { + FT_Done_Face(Face); + ExFreePool(Buffer); + ExFreePool(Entry); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + /* FontGDI->Filename = FileName; perform strcpy */ FontGDI->face = Face; @@ -392,7 +381,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) /* Add this font resource to the font table */ - Entry->hFont = NewFont; + Entry->Font = FontGDI; Entry->NotEnum = (Characteristics & FR_NOT_ENUM); RtlInitAnsiString(&AnsiFaceName, (LPSTR)Face->family_name); RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiFaceName, TRUE); @@ -451,39 +440,6 @@ IntGetFontRenderMode(LOGFONTW *logfont) } return FT_RENDER_MODE_MONO; } -static NTSTATUS STDCALL -GetFontObjectsFromTextObj(PTEXTOBJ TextObj, HFONT *FontHandle, FONTOBJ **FontObj, PFONTGDI *FontGDI) -{ - FONTOBJ *FntObj; - NTSTATUS Status = STATUS_SUCCESS; - - ASSERT(NULL != TextObj && NULL != TextObj->GDIFontHandle); - if (NULL != TextObj && NULL != TextObj->GDIFontHandle) - { - if (NULL != FontHandle) - { - *FontHandle = TextObj->GDIFontHandle; - } - FntObj = (FONTOBJ*)AccessUserObject((ULONG) TextObj->GDIFontHandle); - if (NULL != FontObj) - { - *FontObj = FntObj; - if (NULL == *FontObj) - { - ASSERT(FALSE); - Status = STATUS_INVALID_HANDLE; - } - } - if (NT_SUCCESS(Status) && NULL != FontGDI) - { - *FontGDI = AccessInternalObjectFromUserObject(FntObj); - } - - return Status; - } - - return STATUS_INVALID_HANDLE; -} int STDCALL @@ -1007,18 +963,16 @@ FindFaceNameInList(PUNICODE_STRING FaceName, PLIST_ENTRY Head) PFONT_ENTRY CurrentEntry; ANSI_STRING EntryFaceNameA; UNICODE_STRING EntryFaceNameW; - PFONTGDI FontGDI; + FONTGDI *FontGDI; Entry = Head->Flink; while (Entry != Head) { CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); - if (NULL == (FontGDI = AccessInternalObject((ULONG) CurrentEntry->hFont))) - { - Entry = Entry->Flink; - continue; - } + FontGDI = CurrentEntry->Font; + ASSERT(FontGDI); + RtlInitAnsiString(&EntryFaceNameA, FontGDI->face->family_name); RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE); if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length) @@ -1275,18 +1229,16 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont, PFONT_ENTRY CurrentEntry; ANSI_STRING EntryFaceNameA; UNICODE_STRING EntryFaceNameW; - PFONTGDI FontGDI; + FONTGDI *FontGDI; Entry = Head->Flink; while (Entry != Head) { CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); - if (NULL == (FontGDI = AccessInternalObject((ULONG) CurrentEntry->hFont))) - { - Entry = Entry->Flink; - continue; - } + FontGDI = CurrentEntry->Font; + ASSERT(FontGDI); + RtlInitAnsiString(&EntryFaceNameA, FontGDI->face->family_name); RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE); if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length) @@ -1605,6 +1557,7 @@ NtGdiExtTextOut( if (hBrushBg) { BrushBg = BRUSHOBJ_LockBrush(hBrushBg); + /* FIXME - Handle BrushBg == NULL !!!!! */ IntGdiInitBrushInstance(&BrushBgInst, BrushBg, NULL); } else @@ -1652,12 +1605,14 @@ NtGdiExtTextOut( } TextObj = TEXTOBJ_LockText(dc->w.hFont); - - if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI))) + if(TextObj == NULL) { - goto fail; + goto fail; } + FontObj = TextObj->Font; + FontGDI = ObjToGDI(FontObj, FONT); + face = FontGDI->face; if (face->charmap == NULL) { @@ -1913,7 +1868,8 @@ NtGdiExtTextOut( EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj2); BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); - TEXTOBJ_UnlockText(dc->w.hFont); + if(TextObj != NULL) + TEXTOBJ_UnlockText(dc->w.hFont); if (hBrushBg != NULL) { BRUSHOBJ_UnlockBrush(hBrushBg); @@ -1925,12 +1881,13 @@ NtGdiExtTextOut( { ExFreePool(Dx); } - DC_UnlockDc(hDC); + DC_UnlockDc( hDC ); return TRUE; fail: - TEXTOBJ_UnlockText(dc->w.hFont); + if(TextObj != NULL) + TEXTOBJ_UnlockText(dc->w.hFont); BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); if (hBrushBg != NULL) { @@ -2043,13 +2000,7 @@ NtGdiGetCharWidth32(HDC hDC, return FALSE; } - if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI))) - { - ExFreePool(SafeBuffer); - SetLastWin32Error(ERROR_INVALID_HANDLE); - TEXTOBJ_UnlockText(hFont); - return FALSE; - } + FontGDI = ObjToGDI(TextObj->Font, FONT); face = FontGDI->face; if (face->charmap == NULL) @@ -2197,10 +2148,7 @@ TextIntGetTextExtentPoint(HDC hDC, FT_CharMap charmap, found = NULL; BOOL use_kerning; - if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI))) - { - return FALSE; - } + FontGDI = ObjToGDI(TextObj->Font, FONT); face = FontGDI->face; if (NULL != Fit) @@ -2381,6 +2329,7 @@ NtGdiGetTextExtentExPoint(HDC hDC, return FALSE; } TextObj = TEXTOBJ_LockText(dc->w.hFont); + /* FIXME - TextObj can be NULL!!!! Handle this case!!! */ DC_UnlockDc(hDC); Result = TextIntGetTextExtentPoint(hDC, TextObj, String, Count, MaxExtent, NULL == UnsafeFit ? NULL : &Fit, Dx, &Size); @@ -2503,6 +2452,7 @@ NtGdiGetTextExtentPoint32(HDC hDC, return FALSE; } TextObj = TEXTOBJ_LockText(dc->w.hFont); + /* FIXME - TextObj can be NULL!!! Handle this case!!! */ DC_UnlockDc(hDC); Result = TextIntGetTextExtentPoint ( hDC, TextObj, String, Count, 0, NULL, NULL, &Size); @@ -2583,9 +2533,8 @@ NtGdiGetTextMetrics(HDC hDC, TextObj = TEXTOBJ_LockText(dc->w.hFont); if (NULL != TextObj) { - Status = GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI); - if (NT_SUCCESS(Status)) - { + FontGDI = ObjToGDI(TextObj->Font, FONT); + Face = FontGDI->face; IntLockFreeType; Error = FT_Set_Pixel_Sizes(Face, @@ -2625,7 +2574,6 @@ NtGdiGetTextMetrics(HDC hDC, } Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW)); } - } TEXTOBJ_UnlockText(dc->w.hFont); } else @@ -2748,7 +2696,6 @@ NtGdiGetFontData( PTEXTOBJ TextObj; PFONTGDI FontGdi; DWORD Result = GDI_ERROR; - NTSTATUS Status; Dc = DC_LockDc(hDC); if (Dc == NULL) @@ -2766,27 +2713,25 @@ NtGdiGetFontData( return GDI_ERROR; } - Status = GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGdi); - if (NT_SUCCESS(Status)) + FontGdi = ObjToGDI(TextObj->Font, FONT); + + IntLockFreeType; + + if (FT_IS_SFNT(FontGdi->face)) { - IntLockFreeType; + if (Table) + Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) | + (Table << 8 & 0xFF0000); - if (FT_IS_SFNT(FontGdi->face)) - { - if (Table) - Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) | - (Table << 8 & 0xFF0000); + if (Buffer == NULL) + Size = 0; - if (Buffer == NULL) - Size = 0; - - if (!FT_Load_Sfnt_Table(FontGdi->face, Table, Offset, Buffer, &Size)) - Result = Size; - } - - IntUnLockFreeType; + if (!FT_Load_Sfnt_Table(FontGdi->face, Table, Offset, Buffer, &Size)) + Result = Size; } + IntUnLockFreeType; + TEXTOBJ_UnlockText(hFont); return Result; @@ -2847,35 +2792,34 @@ GetFontScore(LOGFONTW *LogFont, PUNICODE_STRING FaceName, PFONTGDI FontGDI) return Score; } -static VOID FASTCALL -FindBestFontFromList(HFONT *Font, UINT *MatchScore, LOGFONTW *LogFont, +static inline VOID +FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont, PUNICODE_STRING FaceName, PLIST_ENTRY Head) { PLIST_ENTRY Entry; PFONT_ENTRY CurrentEntry; - PFONTGDI FontGDI; + FONTGDI *FontGDI; UINT Score; Entry = Head->Flink; while (Entry != Head) { CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); - if (NULL == (FontGDI = AccessInternalObject((ULONG) CurrentEntry->hFont))) - { - Entry = Entry->Flink; - continue; - } + + FontGDI = CurrentEntry->Font; + ASSERT(FontGDI); + Score = GetFontScore(LogFont, FaceName, FontGDI); if (*MatchScore == 0 || *MatchScore < Score) { - *Font = CurrentEntry->hFont; + *FontObj = GDIToObj(FontGDI, FONT); *MatchScore = Score; } Entry = Entry->Flink; } } -static BOOLEAN FASTCALL +static inline BOOLEAN SubstituteFontFamilyKey(PUNICODE_STRING FaceName, LPCWSTR Key) { @@ -2911,7 +2855,7 @@ SubstituteFontFamilyKey(PUNICODE_STRING FaceName, return NT_SUCCESS(Status); } -static void FASTCALL +static inline void SubstituteFontFamily(PUNICODE_STRING FaceName, UINT Level) { if (10 < Level) /* Enough is enough */ @@ -2948,34 +2892,38 @@ TextIntRealizeFont(HFONT FontHandle) } SubstituteFontFamily(&FaceName, 0); MatchScore = 0; - TextObj->GDIFontHandle = NULL; + TextObj->Font = NULL; /* First search private fonts */ Win32Process = PsGetWin32Process(); IntLockProcessPrivateFonts(Win32Process); - FindBestFontFromList(&TextObj->GDIFontHandle, &MatchScore, + FindBestFontFromList(&TextObj->Font, &MatchScore, &TextObj->logfont, &FaceName, &Win32Process->PrivateFontListHead); IntUnLockProcessPrivateFonts(Win32Process); /* Search system fonts */ IntLockGlobalFonts; - FindBestFontFromList(&TextObj->GDIFontHandle, &MatchScore, + FindBestFontFromList(&TextObj->Font, &MatchScore, &TextObj->logfont, &FaceName, &FontListHead); IntUnLockGlobalFonts; - if (NULL == TextObj->GDIFontHandle) + if (NULL == TextObj->Font) { DPRINT1("Requested font %S not found, no fonts loaded at all\n", TextObj->logfont.lfFaceName); Status = STATUS_NOT_FOUND; } + else + { + Status = STATUS_SUCCESS; + } RtlFreeUnicodeString(&FaceName); TEXTOBJ_UnlockText(FontHandle); - ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->GDIFontHandle)) != 0); + ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0); return Status; } diff --git a/reactos/subsys/win32k/stubs/stubs.c b/reactos/subsys/win32k/stubs/stubs.c index f3ec22b3d4a..0106c62a764 100644 --- a/reactos/subsys/win32k/stubs/stubs.c +++ b/reactos/subsys/win32k/stubs/stubs.c @@ -2,15 +2,7 @@ * Stubs for unimplemented WIN32K.SYS exports */ -#undef WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include "../eng/objects.h" -#include +#include #define STUB(x) void x(void) { DbgPrint("WIN32K: Stub for %s\n", #x); } diff --git a/reactos/subsys/win32k/stubs/xpstubs.c b/reactos/subsys/win32k/stubs/xpstubs.c index d7920ad7844..310ea75b233 100644 --- a/reactos/subsys/win32k/stubs/xpstubs.c +++ b/reactos/subsys/win32k/stubs/xpstubs.c @@ -3,15 +3,7 @@ * in Windows XP and beyond ( i.e. a low priority for us right now ) */ -#undef WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include "../eng/objects.h" -#include +#include #define STUB(x) void x(void) { DbgPrint("WIN32K: Stub for %s\n", #x); } diff --git a/reactos/subsys/win32k/w32k.h b/reactos/subsys/win32k/w32k.h index 10b6a2f7e87..c9f8c2e2cf6 100644 --- a/reactos/subsys/win32k/w32k.h +++ b/reactos/subsys/win32k/w32k.h @@ -74,8 +74,6 @@ #include #include -#include -#include #include