3 * Copyright (C) 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS gdi32.dll
22 * FILE: lib/gdi32/misc/misc.c
23 * PURPOSE: Miscellaneous functions
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
34 PGDI_TABLE_ENTRY GdiHandleTable
= NULL
;
35 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable
= NULL
;
36 HANDLE CurrentProcessId
= NULL
;
37 DWORD GDI_BatchLimit
= 1;
53 BLENDFUNCTION BlendFunction
56 if ( hDCSrc
== NULL
) return FALSE
;
58 if (GDI_HANDLE_GET_TYPE(hDCSrc
) == GDI_OBJECT_TYPE_METADC
) return FALSE
;
60 return NtGdiAlphaBlend(
80 GdiFixUpHandle(HGDIOBJ hGdiObj
)
82 PGDI_TABLE_ENTRY Entry
;
84 if (((ULONG_PTR
)(hGdiObj
)) & GDI_HANDLE_UPPER_MASK
)
89 /* FIXME is this right ?? */
91 Entry
= GdiHandleTable
+ GDI_HANDLE_GET_INDEX(hGdiObj
);
93 /* Rebuild handle for Object */
94 return hGdiObj
= (HGDIOBJ
)(((LONG_PTR
)(hGdiObj
)) | (Entry
->Type
<< GDI_ENTRY_UPPER_SHIFT
));
104 return (PVOID
)GdiHandleTable
;
107 BOOL
GdiIsHandleValid(HGDIOBJ hGdiObj
)
109 PGDI_TABLE_ENTRY Entry
= GdiHandleTable
+ GDI_HANDLE_GET_INDEX(hGdiObj
);
110 // We are only looking for TYPE not the rest here, and why is FullUnique filled up with CRAP!?
111 // DPRINT1("FullUnique -> %x\n", Entry->FullUnique);
112 if((Entry
->Type
& GDI_ENTRY_BASETYPE_MASK
) != 0 &&
113 ( (Entry
->Type
<< GDI_ENTRY_UPPER_SHIFT
) & GDI_HANDLE_TYPE_MASK
) ==
114 GDI_HANDLE_GET_TYPE(hGdiObj
))
116 HANDLE pid
= (HANDLE
)((ULONG_PTR
)Entry
->ProcessId
& ~0x1);
117 if(pid
== NULL
|| pid
== CurrentProcessId
)
125 BOOL
GdiGetHandleUserData(HGDIOBJ hGdiObj
, DWORD ObjectType
, PVOID
*UserData
)
127 if ( !GdiHandleTable
)
129 // FIXME HAX!! Due to the "Dll Initialization Bug" set the local handle table pointer.
130 GdiHandleTable
= NtCurrentTeb()->ProcessEnvironmentBlock
->GdiSharedHandleTable
;
132 PGDI_TABLE_ENTRY Entry
= GdiHandleTable
+ GDI_HANDLE_GET_INDEX(hGdiObj
);
133 if((Entry
->Type
& GDI_ENTRY_BASETYPE_MASK
) == ObjectType
&&
134 ( (Entry
->Type
<< GDI_ENTRY_UPPER_SHIFT
) & GDI_HANDLE_TYPE_MASK
) ==
135 GDI_HANDLE_GET_TYPE(hGdiObj
))
137 HANDLE pid
= (HANDLE
)((ULONG_PTR
)Entry
->ProcessId
& ~0x1);
138 if(pid
== NULL
|| pid
== CurrentProcessId
)
141 // Need to test if we have Read & Write access to the VM address space.
146 volatile CHAR
*Current
= (volatile CHAR
*)Entry
->UserData
;
151 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
158 Result
= FALSE
; // Can not be zero.
159 if (Result
) *UserData
= Entry
->UserData
;
163 SetLastError(ERROR_INVALID_PARAMETER
);
171 if ( !GdiHandleTable
)
173 // FIXME HAX!! Due to the "Dll Initialization Bug" set the local handle table pointer.
174 GdiHandleTable
= NtCurrentTeb()->ProcessEnvironmentBlock
->GdiSharedHandleTable
;
177 PGDI_TABLE_ENTRY Entry
= GdiHandleTable
+ GDI_HANDLE_GET_INDEX((HGDIOBJ
) hDC
);
178 HANDLE pid
= (HANDLE
)((ULONG_PTR
)Entry
->ProcessId
& ~0x1);
179 // Don't check the mask, just the object type.
180 if ( Entry
->ObjectType
== GDIObjType_DC_TYPE
&&
181 (pid
== NULL
|| pid
== CurrentProcessId
) )
186 volatile CHAR
*Current
= (volatile CHAR
*)Entry
->UserData
;
191 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
202 Dc_Attr
= (PDC_ATTR
)Entry
->UserData
;
203 return Dc_Attr
->pvLDC
;
209 VOID
GdiSAPCallback(PLDC pldc
)
211 DWORD Time
, NewTime
= GetTickCount();
213 Time
= NewTime
- pldc
->CallBackTick
;
215 if ( Time
< SAPCALLBACKDELAY
) return;
217 pldc
->CallBackTick
= NewTime
;
219 if ( !pldc
->pAbortProc(pldc
->hDC
, 0) )
231 GdiSetBatchLimit(DWORD Limit
)
233 DWORD OldLimit
= GDI_BatchLimit
;
236 (Limit
>= GDI_BATCH_LIMIT
))
242 GDI_BatchLimit
= Limit
;
254 return GDI_BatchLimit
;
262 GdiReleaseDC(HDC hdc
)
276 return NtGdiExtEscape(hDC
, NULL
, 0, nEscape
, cbInput
, (LPSTR
)lpszInData
, cbOutput
, lpszOutData
);
284 GdiSetLastError(DWORD dwErrCode
)
286 NtCurrentTeb()->LastErrorValue
= (ULONG
) dwErrCode
;
291 GdiAddGlsBounds(HDC hdc
,LPRECT prc
)
293 //FIXME: Lookup what 0x8000 means
294 return NtGdiSetBoundsRect(hdc
, prc
, 0x8000 | DCB_ACCUMULATE
) ? TRUE
: FALSE
;