[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / include / gdiobj.h
1 /*
2 * GDI object common header definition
3 *
4 */
5
6 #pragma once
7
8 /* Public GDI Object/Handle definitions */
9 #include <win32k/ntgdihdl.h>
10 #include "win32.h"
11
12 /* apparently the first 10 entries are never used in windows as they are empty */
13 #define RESERVE_ENTRIES_COUNT 10
14
15 typedef struct _GDI_HANDLE_TABLE
16 {
17 /* The table must be located at the beginning of this structure so it can be
18 * properly mapped!
19 */
20 //////////////////////////////////////////////////////////////////////////////
21 GDI_TABLE_ENTRY Entries[GDI_HANDLE_COUNT];
22 DEVCAPS DevCaps; // Device Capabilities.
23 FLONG flDeviceUniq; // Device settings uniqueness.
24 PVOID pvLangPack; // Language Pack.
25 CFONT cfPublic[GDI_CFONT_MAX]; // Public Fonts.
26 DWORD dwCFCount;
27 //////////////////////////////////////////////////////////////////////////////
28 PPAGED_LOOKASIDE_LIST LookasideLists;
29
30 ULONG FirstFree;
31 ULONG FirstUnused;
32
33 } GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
34
35 extern PGDI_HANDLE_TABLE GdiHandleTable;
36
37 typedef PVOID PGDIOBJ;
38
39 typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody);
40
41 /* Every GDI Object must have this standard type of header.
42 * It's for thread locking. */
43 typedef struct _BASEOBJECT
44 {
45 HGDIOBJ hHmgr;
46 ULONG ulShareCount;
47 USHORT cExclusiveLock;
48 USHORT BaseFlags;
49 PTHREADINFO Tid;
50 } BASEOBJECT, *POBJ;
51
52 typedef struct _CLIENTOBJ
53 {
54 BASEOBJECT BaseObject;
55 } CLIENTOBJ, *PCLIENTOBJ;
56
57 enum BASEFLAGS
58 {
59 BASEFLAG_LOOKASIDE = 0x80,
60
61 /* ReactOS specific: */
62 BASEFLAG_READY_TO_DIE = 0x1000
63 };
64
65 extern PSECTION_OBJECT GdiTableSection;
66
67 BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle);
68 BOOL INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner);
69 BOOL INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo);
70 BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj);
71 //VOID INTERNAL_CALL GDIOBJ_ShareUnlockObjByPtr(POBJ Object);
72 BOOL INTERNAL_CALL GDIOBJ_ValidateHandle(HGDIOBJ hObj, ULONG ObjectType);
73 POBJ INTERNAL_CALL GDIOBJ_AllocObj(UCHAR ObjectType);
74 POBJ INTERNAL_CALL GDIOBJ_AllocObjWithHandle(ULONG ObjectType);
75 VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType);
76 BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType);
77 PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
78 PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType);
79 VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
80
81 PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
82
83 INIT_FUNCTION
84 NTSTATUS
85 NTAPI
86 InitGdiHandleTable();
87
88 #define GDIOBJ_GetObjectType(Handle) \
89 GDI_HANDLE_GET_TYPE(Handle)
90
91 #define GDIOBJFLAG_DEFAULT (0x0)
92 #define GDIOBJFLAG_IGNOREPID (0x1)
93 #define GDIOBJFLAG_IGNORELOCK (0x2)
94
95 BOOL FASTCALL GreDeleteObject(HGDIOBJ hObject);
96 BOOL FASTCALL IsObjectDead(HGDIOBJ);
97 BOOL FASTCALL IntGdiSetDCOwnerEx( HDC, DWORD, BOOL);
98 BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
99
100 /*!
101 * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked.
102 * You should unlock the object
103 * as soon as you don't need to have access to it's data.
104
105 * \param Object Object pointer (as returned by GDIOBJ_LockObj).
106 */
107 ULONG
108 FORCEINLINE
109 GDIOBJ_UnlockObjByPtr(POBJ Object)
110 {
111 #if DBG
112 PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
113 if (pti)
114 {
115 if (pti->cExclusiveLocks < 1)
116 {
117 DbgPrint("cExclusiveLocks = %ld, object: %ld\n",
118 pti->cExclusiveLocks, Object->cExclusiveLock);
119 ASSERT(FALSE);
120 }
121 pti->cExclusiveLocks--;
122 }
123 #endif
124 INT cLocks = InterlockedDecrement((PLONG)&Object->cExclusiveLock);
125 ASSERT(cLocks >= 0);
126 return cLocks;
127 }
128
129 ULONG
130 FORCEINLINE
131 GDIOBJ_ShareUnlockObjByPtr(POBJ Object)
132 {
133 HGDIOBJ hobj = Object->hHmgr;
134 USHORT flags = Object->BaseFlags;
135 INT cLocks = InterlockedDecrement((PLONG)&Object->ulShareCount);
136 ASSERT(cLocks >= 0);
137 if ((flags & BASEFLAG_READY_TO_DIE) && (cLocks == 0))
138 {
139 ASSERT(Object->cExclusiveLock == 0);
140 GDIOBJ_SetOwnership(hobj, PsGetCurrentProcess());
141 GDIOBJ_FreeObjByHandle(hobj, GDI_OBJECT_TYPE_DONTCARE);
142 }
143 return cLocks;
144 }
145
146 #ifdef GDI_DEBUG
147 ULONG FASTCALL GDIOBJ_IncrementShareCount(POBJ Object);
148 #else
149 ULONG
150 FORCEINLINE
151 GDIOBJ_IncrementShareCount(POBJ Object)
152 {
153 INT cLocks = InterlockedIncrement((PLONG)&Object->ulShareCount);
154 ASSERT(cLocks >= 1);
155 return cLocks;
156 }
157 #endif
158
159 INT FASTCALL GreGetObjectOwner(HGDIOBJ, GDIOBJTYPE);
160
161 #define GDIOBJ_GetKernelObj(Handle) \
162 ((PGDI_TABLE_ENTRY)&GdiHandleTable->Entries[GDI_HANDLE_GET_INDEX(Handle)])->KernelData
163 #define GDI_ENTRY_TO_INDEX(ht, e) \
164 (((ULONG_PTR)(e) - (ULONG_PTR)&((ht)->Entries[0])) / sizeof(GDI_TABLE_ENTRY))
165 #define GDI_HANDLE_GET_ENTRY(HandleTable, h) \
166 (&(HandleTable)->Entries[GDI_HANDLE_GET_INDEX((h))])