:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / objects / gdiobj.c
1 /*
2  * GDIOBJ.C - GDI object manipulation routines
3  *
4  * $Id$
5  *
6  */
7
8 #undef WIN32_LEAN_AND_MEAN
9 #include <windows.h>
10 #include <ddk/ntddk.h>
11 #include <win32k/gdiobj.h>
12 #include <win32k/brush.h>
13 #include <win32k/pen.h>
14 #include <win32k/text.h>
15 #include <win32k/dc.h>
16 #include <win32k/bitmaps.h>
17 #include <win32k/region.h>
18 #define NDEBUG
19 #include <win32k/debug1.h>
20
21 //  GDI stock objects
22
23 static LOGBRUSH WhiteBrush =
24 { BS_SOLID, RGB(255,255,255), 0 };
25
26 static LOGBRUSH LtGrayBrush =
27 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
28 { BS_SOLID, RGB(192,192,192), 0 };
29
30 static LOGBRUSH GrayBrush =
31 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
32 { BS_SOLID, RGB(128,128,128), 0 };
33
34 static LOGBRUSH DkGrayBrush =
35 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
36 /* NB_HATCH_STYLES is an index into HatchBrushes */
37 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
38
39 static LOGBRUSH BlackBrush =
40 { BS_SOLID, RGB(0,0,0), 0 };
41
42 static LOGBRUSH NullBrush =
43 { BS_NULL, 0, 0 };
44
45 static LOGPEN WhitePen =
46 { PS_SOLID, { 0, 0 }, RGB(255,255,255) };
47
48 static LOGPEN BlackPen =
49 { PS_SOLID, { 0, 0 }, RGB(0,0,0) };
50
51 static LOGPEN NullPen =
52 { PS_NULL, { 0, 0 }, 0 };
53
54 static LOGFONT OEMFixedFont =
55 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
56   0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" };
57
58 /* Filler to make the location counter dword aligned again.  This is necessary
59    since (a) LOGFONT is packed, (b) gcc places initialised variables in the code
60    segment, and (c) Solaris assembler is stupid.  */
61 static UINT align_OEMFixedFont = 1;
62
63 static LOGFONT AnsiFixedFont =
64 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
65   0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" };
66
67 static UINT align_AnsiFixedFont = 1;
68
69 static LOGFONT AnsiVarFont =
70 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
71   0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" };
72
73 static UINT align_AnsiVarFont = 1;
74
75 static LOGFONT SystemFont =
76 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
77   0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"System" };
78
79 static UINT align_SystemFont = 1;
80
81 static LOGFONT DeviceDefaultFont =
82 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
83   0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"" };
84
85 static UINT align_DeviceDefaultFont = 1;
86
87 static LOGFONT SystemFixedFont =
88 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
89   0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" };
90
91 static UINT align_SystemFixedFont = 1;
92
93 /* FIXME: Is this correct? */
94 static LOGFONT DefaultGuiFont =
95 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
96   0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" };
97
98 static UINT align_DefaultGuiFont = 1;
99
100 static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
101                                                 // the way handles work, so it's more dynamic now
102
103
104 HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
105
106 static PGDI_HANDLE_TABLE  HandleTable = 0;
107 static FAST_MUTEX  HandleTableMutex;
108 static FAST_MUTEX  RefCountHandling;
109
110 #define GDI_HANDLE_NUMBER  0x4000
111
112 static PGDI_HANDLE_TABLE
113 GDIOBJ_iAllocHandleTable (WORD Size)
114 {
115   PGDI_HANDLE_TABLE  handleTable;
116
117   ExAcquireFastMutexUnsafe (&HandleTableMutex);
118   handleTable = ExAllocatePool(PagedPool,
119                                sizeof (GDI_HANDLE_TABLE) +
120                                  sizeof (GDI_HANDLE_ENTRY) * Size);
121   ASSERT( handleTable );
122   memset (handleTable,
123           0,
124           sizeof (GDI_HANDLE_TABLE) + sizeof (GDI_HANDLE_ENTRY) * Size);
125   handleTable->wTableSize = Size;
126   ExReleaseFastMutexUnsafe (&HandleTableMutex);
127
128   return  handleTable;
129 }
130
131 static PGDI_HANDLE_ENTRY
132 GDIOBJ_iGetHandleEntryForIndex (WORD TableIndex)
133 {
134   //DPRINT("GDIOBJ_iGetHandleEntryForIndex: TableIndex: %d,\n handle: %x, ptr: %x\n", TableIndex, HandleTable->Handles [TableIndex], &(HandleTable->Handles [TableIndex])  );
135   //DPRINT("GIG: HandleTable: %x, Handles: %x, \n TableIndex: %x, pt: %x\n", HandleTable,  HandleTable->Handles, TableIndex, ((PGDI_HANDLE_ENTRY)HandleTable->Handles+TableIndex));
136   //DPRINT("GIG: Hndl: %x, mag: %x\n", ((PGDI_HANDLE_ENTRY)HandleTable->Handles+TableIndex), ((PGDI_HANDLE_ENTRY)HandleTable->Handles+TableIndex)->wMagic);
137   return  ((PGDI_HANDLE_ENTRY)HandleTable->Handles+TableIndex);
138 }
139
140 static WORD
141 GDIOBJ_iGetNextOpenHandleIndex (void)
142 {
143   WORD  tableIndex;
144
145   ExAcquireFastMutexUnsafe (&HandleTableMutex);
146   for (tableIndex = 1; tableIndex < HandleTable->wTableSize; tableIndex++)
147   {
148     if (HandleTable->Handles [tableIndex].wMagic == 0)
149     {
150       HandleTable->Handles [tableIndex].wMagic = GO_MAGIC_DONTCARE;
151       break;
152     }
153   }
154   ExReleaseFastMutexUnsafe (&HandleTableMutex);
155
156   return  (tableIndex < HandleTable->wTableSize) ? tableIndex : 0;
157 }
158
159 /*-----------------7/12/2002 11:38AM----------------
160  * Allocate memory for GDI object and return handle to it
161  * Use GDIOBJ_Lock to obtain pointer to the new object.
162  * --------------------------------------------------*/
163 HGDIOBJ GDIOBJ_AllocObj(WORD Size, WORD Magic)
164 {
165         PGDIOBJHDR  newObject;
166         PGDI_HANDLE_ENTRY  handleEntry;
167
168         DPRINT("GDIOBJ_AllocObj: size: %d, magic: %x\n", Size, Magic);
169         newObject = ExAllocatePool (PagedPool, Size + sizeof (GDIOBJHDR));
170         if (newObject == NULL)
171         {
172           DPRINT("GDIOBJ_AllocObj: failed\n");
173           return  NULL;
174         }
175         RtlZeroMemory (newObject, Size + sizeof (GDIOBJHDR));
176
177         newObject->wTableIndex = GDIOBJ_iGetNextOpenHandleIndex ();
178         newObject->dwCount = 0;
179         handleEntry = GDIOBJ_iGetHandleEntryForIndex (newObject->wTableIndex);
180         handleEntry->wMagic = Magic;
181         handleEntry->hProcessId = PsGetCurrentProcessId ();
182         handleEntry->pObject = newObject;
183         DPRINT("GDIOBJ_AllocObj: object handle %d\n", newObject->wTableIndex );
184         return  (HGDIOBJ) newObject->wTableIndex;
185 }
186
187 BOOL  GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag)
188 {
189         PGDIOBJHDR  objectHeader;
190         PGDI_HANDLE_ENTRY  handleEntry;
191         PGDIOBJ         Obj;
192         BOOL    bRet = TRUE;
193
194         handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)hObj & 0xffff);
195         DPRINT("GDIOBJ_FreeObj: hObj: %d, magic: %x, handleEntry: %x\n", (WORD)hObj & 0xffff, Magic, handleEntry );
196         if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
197              || ((handleEntry->hProcessId != PsGetCurrentProcessId()) && !(Flag & GDIOBJFLAG_IGNOREPID))){
198           DPRINT("Can't Delete hObj: %d, magic: %x, pid:%d\n currpid:%d, flag:%d, hmm:%d\n",(WORD)hObj & 0xffff, handleEntry->wMagic, handleEntry->hProcessId, PsGetCurrentProcessId(), (Flag&GDIOBJFLAG_IGNOREPID), ((handleEntry->hProcessId != PsGetCurrentProcessId()) && !(Flag&GDIOBJFLAG_IGNOREPID)) );
199           return  FALSE;
200         }
201
202         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
203         ASSERT(objectHeader);
204         DPRINT("FreeObj: locks: %x\n", objectHeader->dwCount );
205         if( !(Flag & GDIOBJFLAG_IGNORELOCK) ){
206                 // check that the reference count is zero. if not then set flag
207                 // and delete object when releaseobj is called
208                 ExAcquireFastMutex(&RefCountHandling);
209                 if( ( objectHeader->dwCount & ~0x80000000 ) > 0 ){
210                         DPRINT("GDIOBJ_FreeObj: delayed object deletion: count %d\n", objectHeader->dwCount);
211                         objectHeader->dwCount |= 0x80000000;
212                         ExReleaseFastMutex(&RefCountHandling);
213                         return TRUE;
214                 }
215                 ExReleaseFastMutex(&RefCountHandling);
216         }
217
218         //allow object to delete internal data
219         Obj = (PGDIOBJ)((PCHAR)handleEntry->pObject + sizeof(GDIOBJHDR));
220         switch( handleEntry->wMagic ){
221                 case GO_REGION_MAGIC:
222                         bRet = RGNDATA_InternalDelete( (PROSRGNDATA) Obj );
223                         break;
224                 case GO_BITMAP_MAGIC:
225                         bRet = Bitmap_InternalDelete( (PBITMAPOBJ) Obj );
226                         break;
227                 case GO_DC_MAGIC:
228                         bRet = DC_InternalDeleteDC( (PDC) Obj );
229                         break;
230                 case GO_PEN_MAGIC:
231                 case GO_PALETTE_MAGIC:
232                 case GO_DISABLED_DC_MAGIC:
233                 case GO_META_DC_MAGIC:
234                 case GO_METAFILE_MAGIC:
235                 case GO_METAFILE_DC_MAGIC:
236                 case GO_ENHMETAFILE_MAGIC:
237                 case GO_ENHMETAFILE_DC_MAGIC:
238
239                 case GO_BRUSH_MAGIC:
240                 case GO_FONT_MAGIC:
241                         break;
242         }
243         handleEntry->hProcessId = 0;
244         ExFreePool (handleEntry->pObject);
245         handleEntry->pObject = 0;
246         // (RJJ) set wMagic last to avoid race condition
247         handleEntry->wMagic = 0;
248
249
250         return  TRUE;
251 }
252
253 PGDIOBJ GDIOBJ_LockObj( HGDIOBJ hObj, WORD Magic )
254 {
255         PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff);
256         PGDIOBJHDR  objectHeader;
257
258         DPRINT("GDIOBJ_LockObj: hObj: %d, magic: %x, \n handleEntry: %x, mag %x\n", hObj, Magic, handleEntry, handleEntry->wMagic);
259         if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
260              || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF &&
261                  handleEntry->hProcessId != PsGetCurrentProcessId ())){
262           DPRINT("GDIBOJ_LockObj failed for %d, magic: %d, reqMagic\n",(WORD) hObj & 0xffff, handleEntry->wMagic, Magic);
263           return  NULL;
264         }
265
266         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
267         ASSERT(objectHeader);
268
269         ExAcquireFastMutex(&RefCountHandling);
270         objectHeader->dwCount++;
271         ExReleaseFastMutex(&RefCountHandling);
272
273         DPRINT("GDIOBJ_LockObj: PGDIOBJ %x\n",  ((PCHAR)objectHeader + sizeof(GDIOBJHDR)) );
274         return (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
275 }
276
277 BOOL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic )
278 {
279         PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff);
280         PGDIOBJHDR  objectHeader;
281
282         DPRINT("GDIOBJ_UnlockObj: hObj: %d, magic: %x, \n handleEntry: %x\n", hObj, Magic, handleEntry);
283         if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
284               || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF &&
285                  handleEntry->hProcessId != PsGetCurrentProcessId ())){
286           DPRINT( "GDIOBJ_UnLockObj: failed\n");
287           return  FALSE;
288         }
289
290         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
291         ASSERT(objectHeader);
292
293         ExAcquireFastMutex(&RefCountHandling);
294         if( ( objectHeader->dwCount & ~0x80000000 ) == 0 ){
295                 ExReleaseFastMutex(&RefCountHandling);
296                 DPRINT( "GDIOBJ_UnLockObj: unlock object that is not locked\n" );
297                 return FALSE;
298         }
299
300         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
301         ASSERT(objectHeader);
302         objectHeader->dwCount--;
303
304         if( objectHeader->dwCount  == 0x80000000 ){
305                 //delayed object release
306                 objectHeader->dwCount = 0;
307                 ExReleaseFastMutex(&RefCountHandling);
308                 DPRINT("GDIOBJ_UnlockObj: delayed delete\n");
309                 return GDIOBJ_FreeObj( hObj, Magic, GDIOBJFLAG_DEFAULT );
310         }
311         ExReleaseFastMutex(&RefCountHandling);
312         return TRUE;
313 }
314
315 /*
316 PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
317 {
318   PGDIOBJHDR  newObject;
319   PGDI_HANDLE_ENTRY  handleEntry;
320
321   newObject = ExAllocatePool (PagedPool, Size + sizeof (GDIOBJHDR));
322   if (newObject == NULL)
323   {
324     return  NULL;
325   }
326   RtlZeroMemory (newObject, Size + sizeof (GDIOBJHDR));
327
328   newObject->wTableIndex = GDIOBJ_iGetNextOpenHandleIndex ();
329   handleEntry = GDIOBJ_iGetHandleEntryForIndex (newObject->wTableIndex);
330   handleEntry->wMagic = Magic;
331   handleEntry->hProcessId = PsGetCurrentProcessId ();
332   handleEntry->pObject = newObject;
333
334   return  (PGDIOBJ)(((PCHAR) newObject) + sizeof (GDIOBJHDR));
335 }
336
337 BOOL  GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
338 {
339   PGDIOBJHDR  objectHeader;
340   PGDI_HANDLE_ENTRY  handleEntry;
341
342   objectHeader = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
343   handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex);
344   if (handleEntry == 0 || handleEntry->wMagic != Magic)
345     return  FALSE;
346   handleEntry->hProcessId = 0;
347   handleEntry->pObject = 0;
348   // (RJJ) set wMagic last to avoid race condition
349   handleEntry->wMagic = 0;
350   ExFreePool (objectHeader);
351
352   return  TRUE;
353 }
354
355 HGDIOBJ  GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
356 {
357   PGDIOBJHDR  objectHeader;
358   PGDI_HANDLE_ENTRY  handleEntry;
359
360   if (Obj == NULL)
361     return  NULL;
362   objectHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
363   handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex);
364   if (handleEntry == 0 ||
365       handleEntry->wMagic != Magic ||
366       handleEntry->hProcessId != PsGetCurrentProcessId () )
367     return  NULL;
368
369   return  (HGDIOBJ) objectHeader->wTableIndex;
370 }
371
372 PGDIOBJ  GDIOBJ_HandleToPtr (HGDIOBJ ObjectHandle, WORD Magic)
373 {
374   PGDI_HANDLE_ENTRY  handleEntry;
375
376   if (ObjectHandle == NULL)
377     return NULL;
378
379   handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff);
380   if (handleEntry == 0 ||
381       (Magic != GO_MAGIC_DONTCARE && Magic != Magic) ||
382       handleEntry->hProcessId != PsGetCurrentProcessId () )
383     return  NULL;
384
385   return  (PGDIOBJ) (((PCHAR)handleEntry->pObject) + sizeof (GDIOBJHDR));
386 }
387 */
388
389 VOID GDIOBJ_MarkObjectGlobal(HGDIOBJ ObjectHandle)
390 {
391   PGDI_HANDLE_ENTRY  handleEntry;
392
393   if (ObjectHandle == NULL)
394     return;
395
396   handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff);
397   if (handleEntry == 0)
398     return;
399
400   handleEntry->hProcessId = (HANDLE)0xFFFFFFFF;
401 }
402
403 WORD  GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle)
404 {
405   PGDI_HANDLE_ENTRY  handleEntry;
406
407   if (ObjectHandle == NULL)
408     return  0;
409
410   handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff);
411   if (handleEntry == 0 ||
412       (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF &&
413        handleEntry->hProcessId != PsGetCurrentProcessId ()))
414     return  0;
415
416   return  handleEntry->wMagic;
417 }
418
419 VOID
420 InitGdiObjectHandleTable (void)
421 {
422   DPRINT ("InitGdiObjectHandleTable\n");
423   ExInitializeFastMutex (&HandleTableMutex);
424   ExInitializeFastMutex (&RefCountHandling);
425   //per http://www.wd-mag.com/articles/1999/9902/9902b/9902b.htm?topic=articles
426   //gdi handle table can hold 0x4000 handles
427   HandleTable = GDIOBJ_iAllocHandleTable (GDI_HANDLE_NUMBER);
428   DPRINT("HandleTable: %x\n", HandleTable );
429
430   InitEngHandleTable();
431 }
432
433 VOID CreateStockObjects(void)
434 {
435   // Create GDI Stock Objects from the logical structures we've defined
436
437   StockObjects[WHITE_BRUSH] =  W32kCreateBrushIndirect(&WhiteBrush);
438   GDIOBJ_MarkObjectGlobal(StockObjects[WHITE_BRUSH]);
439   StockObjects[LTGRAY_BRUSH] = W32kCreateBrushIndirect(&LtGrayBrush);
440   GDIOBJ_MarkObjectGlobal(StockObjects[LTGRAY_BRUSH]);
441   StockObjects[GRAY_BRUSH] =   W32kCreateBrushIndirect(&GrayBrush);
442   GDIOBJ_MarkObjectGlobal(StockObjects[GRAY_BRUSH]);
443   StockObjects[DKGRAY_BRUSH] = W32kCreateBrushIndirect(&DkGrayBrush);
444   GDIOBJ_MarkObjectGlobal(StockObjects[DKGRAY_BRUSH]);
445   StockObjects[BLACK_BRUSH] =  W32kCreateBrushIndirect(&BlackBrush);
446   GDIOBJ_MarkObjectGlobal(StockObjects[BLACK_BRUSH]);
447   StockObjects[NULL_BRUSH] =   W32kCreateBrushIndirect(&NullBrush);
448   GDIOBJ_MarkObjectGlobal(StockObjects[NULL_BRUSH]);
449
450   StockObjects[WHITE_PEN] = W32kCreatePenIndirect(&WhitePen);
451   GDIOBJ_MarkObjectGlobal(StockObjects[WHITE_PEN]);
452   StockObjects[BLACK_PEN] = W32kCreatePenIndirect(&BlackPen);
453   GDIOBJ_MarkObjectGlobal(StockObjects[BLACK_PEN]);
454   StockObjects[NULL_PEN] =  W32kCreatePenIndirect(&NullPen);
455   GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]);
456
457   StockObjects[OEM_FIXED_FONT] =      W32kCreateFontIndirect(&OEMFixedFont);
458   GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]);
459   StockObjects[ANSI_FIXED_FONT] =     W32kCreateFontIndirect(&AnsiFixedFont);
460   GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]);
461   StockObjects[SYSTEM_FONT] =         W32kCreateFontIndirect(&SystemFont);
462   GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]);
463   StockObjects[DEVICE_DEFAULT_FONT] =
464     W32kCreateFontIndirect(&DeviceDefaultFont);
465   GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]);
466   StockObjects[SYSTEM_FIXED_FONT] =   W32kCreateFontIndirect(&SystemFixedFont);
467   GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]);
468   StockObjects[DEFAULT_GUI_FONT] =    W32kCreateFontIndirect(&DefaultGuiFont);
469   GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]);
470
471   StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init();
472 }
473
474 HGDIOBJ STDCALL  W32kGetStockObject(INT  Object)
475 {
476   HGDIOBJ ret;
477
478 /*  if ((Object < 0) || (Object >= NB_STOCK_OBJECTS)) return 0;
479   if (!StockObjects[Object]) return 0;
480   ret = FIRST_STOCK_HANDLE + Object;
481
482   return ret; */
483
484   return StockObjects[Object]; // FIXME........
485 }
486
487 BOOL STDCALL  W32kDeleteObject(HGDIOBJ hObject)
488 {
489   return GDIOBJ_FreeObj( hObject, GO_MAGIC_DONTCARE, GDIOBJFLAG_DEFAULT );
490 }
491
492 BOOL STDCALL W32kCleanupForProcess( INT Process )
493 {
494         DWORD i;
495         PGDI_HANDLE_ENTRY handleEntry;
496         PGDIOBJHDR  objectHeader;
497
498         for( i=1; i < GDI_HANDLE_NUMBER; i++ ){
499                 handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) i & 0xffff);
500                 if( handleEntry && handleEntry->wMagic != 0 && handleEntry->hProcessId == Process){
501                         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
502                         DPRINT("\nW32kCleanup: %d, magic: %x \n process: %d, locks: %d", i, handleEntry->wMagic, handleEntry->hProcessId, objectHeader->dwCount);
503                         GDIOBJ_FreeObj( (WORD) i & 0xffff, GO_MAGIC_DONTCARE, GDIOBJFLAG_IGNOREPID|GDIOBJFLAG_IGNORELOCK );
504                 }
505         }
506         return TRUE;
507 }
508
509 // dump all the objects for process. if process == 0 dump all the objects
510 VOID STDCALL W32kDumpGdiObjects( INT Process )
511 {
512         DWORD i;
513         PGDI_HANDLE_ENTRY handleEntry;
514         PGDIOBJHDR  objectHeader;
515
516         for( i=1; i < GDI_HANDLE_NUMBER; i++ ){
517                 handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) i & 0xffff);
518                 if( handleEntry && handleEntry->wMagic != 0 ){
519                         objectHeader = (PGDIOBJHDR) handleEntry->pObject;
520                         DPRINT("\nHandle: %d, magic: %x \n process: %d, locks: %d", i, handleEntry->wMagic, handleEntry->hProcessId, objectHeader->dwCount);
521                 }
522         }
523
524 }