From 50b193239bd9554a4e7cf671a001dc12ec726454 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 12 Dec 2004 01:40:39 +0000 Subject: [PATCH] 1. remove mouse cursor hacks from eng/mouse 2. implemented more win2k-like gdi handle table (handle entry lookup is not yet optimized/cached!) 3. moved cursoricon.c from objects to ntuser as it's part of the user api and not of the gdi 4. get rid of the eng handle table 5. minor fixes svn path=/trunk/; revision=12035 --- reactos/config | 2 +- reactos/include/napi/win32.h | 4 +- reactos/include/win32k/bitmaps.h | 8 +- reactos/include/win32k/brush.h | 7 +- reactos/include/win32k/dc.h | 40 +- reactos/include/win32k/gdiobj.h | 83 +- reactos/include/win32k/kapi.h | 5 + reactos/include/win32k/ntuser.h | 16 +- reactos/include/win32k/pen.h | 6 +- reactos/include/win32k/region.h | 7 +- reactos/include/win32k/text.h | 8 +- reactos/lib/user32/include/user32.h | 32 +- reactos/lib/user32/include/window.h | 31 +- reactos/lib/user32/misc/dllmain.c | 1 + reactos/lib/user32/misc/stubs.c | 17 +- reactos/lib/user32/windows/defwnd.c | 215 +- reactos/subsys/win32k/eng/bitblt.c | 41 +- reactos/subsys/win32k/eng/clip.c | 270 +-- reactos/subsys/win32k/eng/clip.h | 44 - reactos/subsys/win32k/eng/handle.c | 134 -- reactos/subsys/win32k/eng/handle.h | 44 - reactos/subsys/win32k/eng/mouse.c | 514 +++-- reactos/subsys/win32k/eng/objects.h | 39 +- reactos/subsys/win32k/eng/surface.c | 13 +- reactos/subsys/win32k/eng/xlate.c | 146 +- reactos/subsys/win32k/include/cursoricon.h | 6 - reactos/subsys/win32k/include/dce.h | 10 +- reactos/subsys/win32k/include/intddraw.h | 67 + reactos/subsys/win32k/include/inteng.h | 34 +- reactos/subsys/win32k/include/intgdi.h | 14 + reactos/subsys/win32k/include/mouse.h | 10 +- reactos/subsys/win32k/include/object.h | 17 +- reactos/subsys/win32k/include/palette.h | 5 +- reactos/subsys/win32k/include/tags.h | 10 +- reactos/subsys/win32k/main/dllmain.c | 7 +- reactos/subsys/win32k/makefile | 15 +- reactos/subsys/win32k/misc/object.c | 5 +- reactos/subsys/win32k/ntddraw/ddraw.c | 141 +- .../win32k/{objects => ntuser}/cursoricon.c | 62 +- reactos/subsys/win32k/ntuser/desktop.c | 3 +- reactos/subsys/win32k/ntuser/input.c | 11 +- reactos/subsys/win32k/ntuser/misc.c | 104 +- reactos/subsys/win32k/ntuser/stubs.c | 5 +- reactos/subsys/win32k/ntuser/windc.c | 42 +- reactos/subsys/win32k/ntuser/window.c | 7 +- reactos/subsys/win32k/ntuser/winpos.c | 3 +- reactos/subsys/win32k/ntuser/winsta.c | 7 +- reactos/subsys/win32k/objects/bitmaps.c | 44 +- reactos/subsys/win32k/objects/brush.c | 85 +- reactos/subsys/win32k/objects/cliprgn.c | 31 +- reactos/subsys/win32k/objects/color.c | 5 +- reactos/subsys/win32k/objects/dc.c | 56 +- reactos/subsys/win32k/objects/dib.c | 4 +- reactos/subsys/win32k/objects/fillshap.c | 20 +- reactos/subsys/win32k/objects/gdiobj.c | 1726 ++++++++++------- reactos/subsys/win32k/objects/line.c | 5 +- reactos/subsys/win32k/objects/palette.c | 18 +- reactos/subsys/win32k/objects/pen.c | 3 +- reactos/subsys/win32k/objects/print.c | 4 +- reactos/subsys/win32k/objects/region.c | 52 +- reactos/subsys/win32k/objects/stockobj.c | 319 +++ reactos/subsys/win32k/objects/text.c | 198 +- reactos/subsys/win32k/stubs/stubs.c | 10 +- reactos/subsys/win32k/stubs/xpstubs.c | 10 +- reactos/subsys/win32k/w32k.h | 2 - 65 files changed, 2745 insertions(+), 2159 deletions(-) delete mode 100644 reactos/subsys/win32k/eng/clip.h delete mode 100644 reactos/subsys/win32k/eng/handle.c delete mode 100644 reactos/subsys/win32k/eng/handle.h create mode 100644 reactos/subsys/win32k/include/intddraw.h rename reactos/subsys/win32k/{objects => ntuser}/cursoricon.c (95%) create mode 100644 reactos/subsys/win32k/objects/stockobj.c 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